Model/Mesh pretransforms

This commit is contained in:
austin 2022-12-30 16:38:06 -05:00
parent 9d9adea61f
commit a5c9158875
10 changed files with 205 additions and 27 deletions

View File

@ -112,7 +112,7 @@
"acceleration" : 10.0,
"maxVelocity" : 0.035,
"minVelocity": 0.001,
"maxRotationSpeed" : 1.0
"maxRotationSpeed" : 0.01
}
],
"rotatorSystem" : {

View 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]
}
]
}
]
}

View File

@ -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;

View File

@ -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));

View File

@ -23,7 +23,7 @@ public class AirplaneMovementSystem implements MovementSystem {
return minVelocity;
}
public float maxRotationSpeed(){
public float getMaxRotationSpeed(){
return maxRotationSpeed;
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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));
}
}
}