Model/Mesh pretransforms
This commit is contained in:
parent
9d9adea61f
commit
a5c9158875
@ -112,7 +112,7 @@
|
||||
"acceleration" : 10.0,
|
||||
"maxVelocity" : 0.035,
|
||||
"minVelocity": 0.001,
|
||||
"maxRotationSpeed" : 1.0
|
||||
"maxRotationSpeed" : 0.01
|
||||
}
|
||||
],
|
||||
"rotatorSystem" : {
|
||||
|
||||
26
assets/Models/modelPretransforms.json
Normal file
26
assets/Models/modelPretransforms.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"models" : [
|
||||
{
|
||||
"path" : "Models/testPretransform.fbx",
|
||||
"meshes" : [
|
||||
{
|
||||
"meshName" : "Cube",
|
||||
"rotation" : [0.0, 0.0, 0.0, 1.0],
|
||||
"offset" : [1.0, 1.0, 1.0],
|
||||
"scale" : [1.0, 1.0, 1.0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path" : "Models/f15.fbx",
|
||||
"meshes" : [
|
||||
{
|
||||
"meshName" : "Cube.001",
|
||||
"rotation" : [0.0, 0.0, -0.7071068, 0.7071068],
|
||||
"offset" : [0.0, 0.0, 0.0],
|
||||
"scale" : [0.3, 0.3, 0.3]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -7,8 +7,8 @@ import electrosphere.renderer.Mesh;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.ShaderProgram;
|
||||
import electrosphere.renderer.actor.ActorShaderMask;
|
||||
import electrosphere.renderer.loading.ModelLoader;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import electrosphere.util.ModelLoader;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@ -57,7 +57,7 @@ import electrosphere.renderer.actor.ActorBoneRotator;
|
||||
import electrosphere.renderer.actor.ActorStaticMorph;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
import electrosphere.renderer.light.PointLight;
|
||||
import electrosphere.util.ModelLoader;
|
||||
import electrosphere.renderer.loading.ModelLoader;
|
||||
import electrosphere.util.Utilities;
|
||||
|
||||
import java.util.LinkedList;
|
||||
@ -262,6 +262,7 @@ public class CreatureUtils {
|
||||
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, airplaneMovementSystem.getAcceleration());
|
||||
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
|
||||
airplaneMovementTree.setMinimumVelocity(airplaneMovementSystem.getMinVelocity());
|
||||
airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed());
|
||||
//register misc stuff
|
||||
rVal.putData(EntityDataStrings.DATA_STRING_MOVEMENT_BT, airplaneMovementTree);
|
||||
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,0));
|
||||
|
||||
@ -23,7 +23,7 @@ public class AirplaneMovementSystem implements MovementSystem {
|
||||
return minVelocity;
|
||||
}
|
||||
|
||||
public float maxRotationSpeed(){
|
||||
public float getMaxRotationSpeed(){
|
||||
return maxRotationSpeed;
|
||||
}
|
||||
|
||||
|
||||
@ -51,6 +51,7 @@ import electrosphere.renderer.RenderingEngine;
|
||||
import electrosphere.renderer.ShaderProgram;
|
||||
import electrosphere.renderer.light.PointLight;
|
||||
import electrosphere.renderer.light.SpotLight;
|
||||
import electrosphere.renderer.loading.ModelPretransforms;
|
||||
import electrosphere.renderer.shader.ShaderOptionMap;
|
||||
import electrosphere.renderer.texture.TextureMap;
|
||||
import electrosphere.renderer.ui.ElementManager;
|
||||
@ -214,6 +215,7 @@ public class Globals {
|
||||
public static SpotLight lightSpotDefault;
|
||||
|
||||
public static TextureMap textureMapDefault;
|
||||
public static ModelPretransforms modelPretransforms;
|
||||
|
||||
public static ShaderProgram defaultMeshShader;
|
||||
public static ShaderProgram terrainShaderProgram;
|
||||
@ -328,6 +330,9 @@ public class Globals {
|
||||
LoggerInterface.loggerStartup.INFO("Initialize global variables");
|
||||
//load in default texture map
|
||||
textureMapDefault = FileUtils.loadObjectFromAssetPath("Textures/default_texture_map.json", TextureMap.class);
|
||||
//load model pretransforms
|
||||
modelPretransforms = FileUtils.loadObjectFromAssetPath("Models/modelPretransforms.json", ModelPretransforms.class);
|
||||
modelPretransforms.init();
|
||||
//load in shader options map
|
||||
shaderOptionMap = FileUtils.loadObjectFromAssetPath("Shaders/shaderoptions.json", ShaderOptionMap.class);
|
||||
shaderOptionMap.debug();
|
||||
|
||||
@ -6,6 +6,7 @@ import electrosphere.main.Globals;
|
||||
import electrosphere.main.Main;
|
||||
import electrosphere.renderer.actor.ActorTextureMask;
|
||||
import electrosphere.renderer.light.LightManager;
|
||||
import electrosphere.renderer.loading.ModelPretransforms;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
@ -13,8 +14,12 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIBone;
|
||||
@ -97,7 +102,7 @@ public class Mesh {
|
||||
|
||||
Material material;
|
||||
|
||||
public static Mesh create_mesh_from_aimesh(AIMesh mesh){
|
||||
public static Mesh create_mesh_from_aimesh(AIMesh mesh, ModelPretransforms.MeshMetadata metadata){
|
||||
boolean has_bones = false;
|
||||
boolean apply_lighting = true;
|
||||
|
||||
@ -111,25 +116,25 @@ public class Mesh {
|
||||
rVal.vertexArrayObject = glGenVertexArrays();
|
||||
glBindVertexArray(rVal.vertexArrayObject);
|
||||
|
||||
|
||||
|
||||
|
||||
//Basic checks
|
||||
//check num vertices
|
||||
int numVertices = 0;
|
||||
int numVertices = mesh.mNumVertices();
|
||||
AIVector3D.Buffer vertexData = mesh.mVertices();
|
||||
while(vertexData.hasRemaining()){
|
||||
vertexData.get();
|
||||
numVertices++;
|
||||
}
|
||||
vertexData = vertexData.rewind();
|
||||
// while(vertexData.hasRemaining()){
|
||||
// vertexData.get();
|
||||
// numVertices++;
|
||||
// }
|
||||
// vertexData = vertexData.rewind();
|
||||
//check num normals
|
||||
int numNormals = 0;
|
||||
AIVector3D.Buffer normalData = mesh.mNormals();
|
||||
while(normalData.hasRemaining()){
|
||||
normalData.get();
|
||||
numNormals++;
|
||||
}
|
||||
normalData.rewind();
|
||||
int numNormals = mesh.mNumVertices();
|
||||
// AIVector3D.Buffer normalData = mesh.mNormals();
|
||||
// while(normalData.hasRemaining()){
|
||||
// normalData.get();
|
||||
// numNormals++;
|
||||
// }
|
||||
// normalData.rewind();
|
||||
if(numVertices != numNormals){
|
||||
System.out.println("Catastrophic failure: Number of vertices =/= Number of normals");
|
||||
System.exit(1);
|
||||
@ -144,7 +149,11 @@ public class Mesh {
|
||||
|
||||
|
||||
|
||||
|
||||
Matrix4d vertexPretransform = new Matrix4d().identity();
|
||||
if(metadata != null){
|
||||
System.out.println("Pretransforming");
|
||||
vertexPretransform.translationRotateScale(metadata.getOffset(), metadata.getRotation(), metadata.getScale());
|
||||
}
|
||||
|
||||
//
|
||||
//Buffer data to GPU
|
||||
@ -175,9 +184,10 @@ public class Mesh {
|
||||
minY = maxY = y;
|
||||
minZ = maxZ = z;
|
||||
}
|
||||
temp[0] = x;
|
||||
temp[1] = y;
|
||||
temp[2] = z;
|
||||
Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0));
|
||||
temp[0] = (float)transformedVertex.x;
|
||||
temp[1] = (float)transformedVertex.y;
|
||||
temp[2] = (float)transformedVertex.z;
|
||||
VertexArrayBufferData.put(temp);
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@ import electrosphere.renderer.actor.ActorStaticMorph;
|
||||
import electrosphere.renderer.actor.ActorTextureMask;
|
||||
import electrosphere.renderer.anim.AnimChannel;
|
||||
import electrosphere.renderer.anim.Animation;
|
||||
import electrosphere.renderer.loading.ModelPretransforms;
|
||||
import electrosphere.renderer.loading.ModelPretransforms.MeshMetadata;
|
||||
import electrosphere.renderer.anim.AnimNode;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.main.Globals;
|
||||
@ -66,12 +68,14 @@ public class Model {
|
||||
Map<String,ActorShaderMask> shaderMask = new HashMap<String,ActorShaderMask>();
|
||||
Map<String,ActorTextureMask> textureMap = null;
|
||||
|
||||
public static Model createModelFromAiscene(AIScene s){
|
||||
public static Model createModelFromAiscene(String path, AIScene s){
|
||||
Model rVal = new Model();
|
||||
//
|
||||
//set the scene
|
||||
//
|
||||
rVal.scene = s;
|
||||
|
||||
ModelPretransforms.ModelMetadata modelMetadata = Globals.modelPretransforms.getModel(path);
|
||||
|
||||
//
|
||||
//load meshes
|
||||
@ -80,7 +84,12 @@ public class Model {
|
||||
PointerBuffer meshesBuffer = s.mMeshes();
|
||||
rVal.meshes = new ArrayList<Mesh>();
|
||||
while(meshesBuffer.hasRemaining()){
|
||||
Mesh currentMesh = Mesh.create_mesh_from_aimesh(AIMesh.create(meshesBuffer.get()));
|
||||
AIMesh aiMesh = AIMesh.create(meshesBuffer.get());
|
||||
ModelPretransforms.MeshMetadata meshMetadata = null;
|
||||
if(modelMetadata != null){
|
||||
meshMetadata = modelMetadata.getMesh(aiMesh.mName().dataString());
|
||||
}
|
||||
Mesh currentMesh = Mesh.create_mesh_from_aimesh(aiMesh, meshMetadata);
|
||||
rVal.meshes.add(currentMesh);
|
||||
currentMesh.parent = rVal;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package electrosphere.util;
|
||||
package electrosphere.renderer.loading;
|
||||
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.main.Globals;
|
||||
@ -8,6 +8,8 @@ import electrosphere.renderer.Mesh;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import electrosphere.renderer.texture.TextureMap;
|
||||
import electrosphere.util.FileUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@ -45,7 +47,7 @@ public class ModelLoader {
|
||||
|
||||
public static Model createModelFromAiScene(AIScene scene, String path){
|
||||
Model rVal;
|
||||
rVal = Model.createModelFromAiscene(scene);
|
||||
rVal = Model.createModelFromAiscene(path, scene);
|
||||
attemptAddTexturesFromPathname(path, rVal);
|
||||
return rVal;
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
package electrosphere.renderer.loading;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
|
||||
/**
|
||||
* Holds metadata for all models to pretransform their meshes while they're
|
||||
* being loaded from disk
|
||||
* TODO: Validate all data read from disk (ie all rotations in MeshMetadatas have at least 4 doubles in them)
|
||||
* TODO: Transform Animations
|
||||
*/
|
||||
public class ModelPretransforms {
|
||||
//List of models as read from disk, not used after being init'd
|
||||
List<ModelMetadata> models;
|
||||
//Map relating path->model metadata
|
||||
Map<String,ModelMetadata> modelDataMap;
|
||||
|
||||
/**
|
||||
* Initializes the model pretransform storage
|
||||
*/
|
||||
public void init(){
|
||||
this.modelDataMap = new HashMap<String,ModelMetadata>();
|
||||
for(ModelMetadata metadata : models){
|
||||
modelDataMap.put(metadata.getPath(), metadata);
|
||||
metadata.init();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the model metadata for a given path
|
||||
* @param path The path to search for
|
||||
* @return The model metadata if found, or null if not found
|
||||
*/
|
||||
public ModelMetadata getModel(String path){
|
||||
return modelDataMap.get(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores metadata about a single model
|
||||
*/
|
||||
public class ModelMetadata {
|
||||
//The path of the model
|
||||
String path;
|
||||
//List of meshes as read from disk, not used after being init'd
|
||||
List<MeshMetadata> meshes;
|
||||
//Map relating path->mesh metadata
|
||||
Map<String,MeshMetadata> meshDataMap;
|
||||
|
||||
/**
|
||||
* Initializes the ModelMetadata object
|
||||
*/
|
||||
public void init(){
|
||||
this.meshDataMap = new HashMap<String,MeshMetadata>();
|
||||
for(MeshMetadata metadata : meshes){
|
||||
meshDataMap.put(metadata.getMeshName(), metadata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the mesh metadata for a given mesh name
|
||||
* @param meshName The name to search for
|
||||
* @return The mesh metadata if found, or null if not found
|
||||
*/
|
||||
public MeshMetadata getMesh(String meshName){
|
||||
return meshDataMap.get(meshName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path of this model
|
||||
* @return The path of the model
|
||||
*/
|
||||
public String getPath(){
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds metadata for pretransforming a mesh while it is being loaded from disk
|
||||
*/
|
||||
public class MeshMetadata {
|
||||
String meshName;
|
||||
List<Double> rotation;
|
||||
List<Double> offset;
|
||||
List<Double> scale;
|
||||
|
||||
/**
|
||||
* Gets the name of the mesh
|
||||
* @return The name of the mesh
|
||||
*/
|
||||
public String getMeshName(){
|
||||
return meshName;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the rotation of the transform as a JOML Quaterniond
|
||||
* !!WARNING!! unsafe: If there aren't at least 4 doubles in the array it out of bounds
|
||||
* @return The rotation of the transform
|
||||
*/
|
||||
public Quaterniond getRotation(){
|
||||
return new Quaterniond(rotation.get(0),rotation.get(1),rotation.get(2),rotation.get(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the offset of the transform as a JOML vector3d
|
||||
* !!WARNING!! unsafe: If there aren't at least 3 doubles in the array it out of bounds
|
||||
* @return The offset of the transform
|
||||
*/
|
||||
public Vector3d getOffset(){
|
||||
return new Vector3d(offset.get(0),offset.get(1),offset.get(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the scale of the transform as a JOML vector3d
|
||||
* !!WARNING!! unsafe: If there aren't at least 3 doubles in the array it out of bounds
|
||||
* @return The scale of the transform
|
||||
*/
|
||||
public Vector3d getScale(){
|
||||
return new Vector3d(scale.get(0),scale.get(1),scale.get(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user