Fix scene collision mesh generation
This commit is contained in:
		
							parent
							
								
									ac2d76cd01
								
							
						
					
					
						commit
						478acb1f54
					
				| @ -30,6 +30,16 @@ | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "objectId" : "geometrytest1", | ||||
|             "modelPath" : "Models/geometry1.fbx", | ||||
|             "tokens" : [ | ||||
|                 "DISABLE_COLLISION_REACTION", | ||||
|                 "GENERATE_COLLISION_TERRAIN" | ||||
|             ], | ||||
|             "collidable": null, | ||||
|             "graphicsTemplate": null | ||||
|         } | ||||
| 
 | ||||
|     ], | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								assets/Models/geometry1.fbx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/Models/geometry1.fbx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -3,9 +3,9 @@ | ||||
|         { | ||||
|             "type": "object", | ||||
|             "subtype": "terrain1", | ||||
|             "posX": 3, | ||||
|             "posY": 5, | ||||
|             "posZ": 5, | ||||
|             "posX": 2, | ||||
|             "posY": 1, | ||||
|             "posZ": 2, | ||||
|             "rotX": -0.7071068, | ||||
|             "rotY": 0, | ||||
|             "rotZ": 0, | ||||
|  | ||||
| @ -761,11 +761,11 @@ public class LoadingThread extends Thread { | ||||
|         // EntityUtils.getPosition(myCube).set(3,1,3); | ||||
| 
 | ||||
|         //work on smoke shader | ||||
|         Entity myCube = EntityUtils.spawnDrawableEntity("Models/unitcube.fbx"); | ||||
|         EntityUtils.getActor(myCube).maskShader("Cube", "Shaders/smoke1/smoke1.vs", "Shaders/smoke1/smoke1.fs"); | ||||
|         Globals.assetManager.addShaderToQueue("Shaders/smoke1/smoke1.vs", "Shaders/smoke1/smoke1.fs"); | ||||
|         myCube.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true); | ||||
|         EntityUtils.getPosition(myCube).set(3,1,3); | ||||
|         // Entity myCube = EntityUtils.spawnDrawableEntity("Models/unitcube.fbx"); | ||||
|         // EntityUtils.getActor(myCube).maskShader("Cube", "Shaders/smoke1/smoke1.vs", "Shaders/smoke1/smoke1.fs"); | ||||
|         // Globals.assetManager.addShaderToQueue("Shaders/smoke1/smoke1.vs", "Shaders/smoke1/smoke1.fs"); | ||||
|         // myCube.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true); | ||||
|         // EntityUtils.getPosition(myCube).set(3,1,3); | ||||
| 
 | ||||
|         SceneLoader loader = new SceneLoader(); | ||||
|         loader.serverInstantiateSceneFile("Scenes/testscene1/testscene1.json"); | ||||
|  | ||||
| @ -56,7 +56,7 @@ public class AssetManager { | ||||
|             if(physicsMeshesToLoad.contains(currentPath)){ | ||||
|                 //create physics | ||||
|                 physicsMeshesToLoad.remove(currentPath); | ||||
|                 physicsMeshesLoadedIntoMemory.put(currentPath,PhysicsUtils.generateRigidBodyFromAISCene(scene)); | ||||
|                 physicsMeshesLoadedIntoMemory.put(currentPath,PhysicsUtils.generateRigidBodyFromAIScene(scene)); | ||||
|             } | ||||
|         } | ||||
|         for(String currentPath : texturesInQueue){ | ||||
| @ -282,7 +282,19 @@ public class AssetManager { | ||||
|      | ||||
|      | ||||
|      | ||||
|      | ||||
|     // | ||||
|     //COLLISION MESH | ||||
|     // | ||||
|     public void addCollisionMeshToQueue(String path){ | ||||
|         if(!physicsMeshesToLoad.contains(path) && !physicsMeshesLoadedIntoMemory.containsKey(path)){ | ||||
|             physicsMeshesToLoad.add(path); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public CollisionObject fetchCollisionObject(String path){ | ||||
|         return physicsMeshesLoadedIntoMemory.get(path); | ||||
|     } | ||||
| 
 | ||||
|      | ||||
|      | ||||
|      | ||||
|  | ||||
| @ -169,6 +169,37 @@ public class CollisionObjUtils { | ||||
|          | ||||
|         return rVal; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Attach a collision object to a provided entity | ||||
|      * @param entity The entity to attach a collision object to | ||||
|      * @param collisionObject The jBulletF collision object to attach to the entity | ||||
|      * @param mass The mass of the collidable | ||||
|      * @param collidableType The type of collidable we are attaching. For instance, "Terrain", "Creature", "Item", etc. Refer to Collidable class for options. | ||||
|      */ | ||||
|     public static void attachCollisionObjectToEntity(Entity entity, CollisionObject collisionObject, float mass, String collidableType){ | ||||
|         Vector3d position = EntityUtils.getPosition(entity); | ||||
|         Vector3f scale = EntityUtils.getScale(entity); | ||||
|         Collidable collidable = new Collidable(entity, collidableType); | ||||
|         Globals.collisionEngine.registerCollisionObject(collisionObject, collidable); | ||||
| 
 | ||||
|         Globals.collisionEngine.registerPhysicsEntity(entity); | ||||
|         entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject); | ||||
| 
 | ||||
|         //update world transform of collision object | ||||
|         positionCharacter(entity,position); | ||||
|          | ||||
|         entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, collisionObject); | ||||
|         entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable); | ||||
|         entity.putData(EntityDataStrings.PHYSICS_MASS, mass); | ||||
|         //inertia tensor | ||||
|         //https://scienceworld.wolfram.com/physics/MomentofInertiaCylinder.html | ||||
|         Matrix4f inertiaTensor = new Matrix4f(); | ||||
|         inertiaTensor.m00(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); | ||||
|         inertiaTensor.m11(mass * scale.y * scale.y / 12.0f + mass * scale.x * scale.x / 4.0f); | ||||
|         inertiaTensor.m22(mass * scale.x * scale.x / 2.0f); | ||||
|         entity.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert()); | ||||
|     } | ||||
|      | ||||
|     public static CollisionObject getCollisionBody(Entity e){ | ||||
|         return (CollisionObject)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); | ||||
|  | ||||
| @ -7,6 +7,7 @@ import electrosphere.collision.dispatch.CollisionObject; | ||||
| import electrosphere.entity.Entity; | ||||
| import electrosphere.entity.EntityDataStrings; | ||||
| import electrosphere.entity.EntityUtils; | ||||
| import electrosphere.entity.state.BehaviorTree; | ||||
| import electrosphere.entity.state.IdleTree; | ||||
| import electrosphere.entity.state.collidable.CollidableTree; | ||||
| import electrosphere.entity.state.gravity.GravityTree; | ||||
| @ -36,8 +37,25 @@ public class ObjectUtils { | ||||
|                 case "DISABLE_COLLISION_REACTION": { | ||||
|                     collisionMakeDynamic = false; | ||||
|                 } break; | ||||
|                 case "GENERATE_COLLISION_OBJECT": { | ||||
|                     Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath()); | ||||
|                     Globals.entityManager.registerBehaviorTree(new BehaviorTree() {public void simulate() { | ||||
|                         CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath()); | ||||
|                         if(collisionObject != null){ | ||||
|                             Globals.entityManager.removeBehaviorTree(this); | ||||
|                             CollisionObjUtils.attachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_OBJECT); | ||||
|                         } | ||||
|                     }}); | ||||
|                 } break; | ||||
|                 case "GENERATE_COLLISION_TERRAIN": { | ||||
| 
 | ||||
|                     Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath()); | ||||
|                     Globals.entityManager.registerBehaviorTree(new BehaviorTree() {public void simulate() { | ||||
|                         CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath()); | ||||
|                         if(collisionObject != null){ | ||||
|                             Globals.entityManager.removeBehaviorTree(this); | ||||
|                             CollisionObjUtils.attachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_TERRAIN); | ||||
|                         } | ||||
|                     }}); | ||||
|                 } break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @ -178,32 +178,54 @@ public class PhysicsUtils { | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public static RigidBody generateRigidBodyFromAISCene(AIScene scene){ | ||||
|          | ||||
|         Vector3d position = EntityUtils.getPosition(terrain); | ||||
|          | ||||
|         int arrayLength = heightfield.length; | ||||
|         int arrayWidth = heightfield[0].length; | ||||
|     // | ||||
|     // This has to use arrays and I have no fucking clue why | ||||
|     // If you buffer one at a time it just breaks??????????? | ||||
|     // | ||||
|     /** | ||||
|      * Generates a rigid body from an AIScene | ||||
|      * @param scene The AIScene to generate a rigid body off of | ||||
|      * @return A rigid body based on the AIScene | ||||
|      */ | ||||
|     public static RigidBody generateRigidBodyFromAIScene(AIScene scene){ | ||||
| 
 | ||||
|         //was 0.08 | ||||
|         float collisionMargin = 0.08f; | ||||
|          | ||||
|         /* | ||||
|         Traditional buffer code not working for some reason | ||||
|         the approach of | ||||
|         https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider | ||||
|         works much better | ||||
|         IDK why | ||||
|         */ | ||||
|          | ||||
| 
 | ||||
|         //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html | ||||
|         electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray(); | ||||
|          | ||||
|          | ||||
|         PointerBuffer meshesBuffer = scene.mMeshes(); | ||||
|         while(meshesBuffer.hasRemaining()){ | ||||
|             AIMesh aiMesh = AIMesh.create(meshesBuffer.get()); | ||||
|             //create indexed mesh | ||||
|             //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html | ||||
|             electrosphere.collision.shapes.IndexedMesh indexedMesh = new electrosphere.collision.shapes.IndexedMesh(); | ||||
|             //allocate buffer for vertices | ||||
|             indexedMesh.vertexBase = ByteBuffer.allocateDirect(aiMesh.mNumVertices()*3*Float.BYTES).order(ByteOrder.nativeOrder()); | ||||
|             indexedMesh.numVertices = aiMesh.mNumVertices(); | ||||
|             indexedMesh.vertexStride = 3 * Float.BYTES; | ||||
|             float[] verts = new float[indexedMesh.numVertices * 3]; | ||||
|             //read vertices | ||||
|             AIVector3D.Buffer vertexBuffer = aiMesh.mVertices(); | ||||
|             int vertPos = 0; | ||||
|             while(vertexBuffer.hasRemaining()){ | ||||
|                 vertexBuffer.get(); | ||||
|                 // numVertices++; | ||||
|                 AIVector3D vector = vertexBuffer.get(); | ||||
|                 verts[vertPos+0] = vector.x(); | ||||
|                 verts[vertPos+1] = vector.y(); | ||||
|                 verts[vertPos+2] = vector.z(); | ||||
|                 vertPos = vertPos + 3; | ||||
|             } | ||||
|             indexedMesh.vertexBase.asFloatBuffer().put(verts); | ||||
|             //allocate buffer for indices | ||||
|             indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(aiMesh.mNumFaces()*3*Float.BYTES).order(ByteOrder.nativeOrder()); | ||||
|             indexedMesh.numTriangles = aiMesh.mNumFaces(); | ||||
|             indexedMesh.triangleIndexStride = 3 * Float.BYTES; | ||||
|             int[] indices = new int[indexedMesh.numTriangles * 3]; | ||||
|             int indicesPos = 0; | ||||
|             //read faces | ||||
|             AIFace.Buffer faceBuffer = aiMesh.mFaces(); | ||||
|             while(faceBuffer.hasRemaining()){ | ||||
| @ -211,85 +233,19 @@ public class PhysicsUtils { | ||||
|                 IntBuffer indexBuffer = currentFace.mIndices(); | ||||
|                 while(indexBuffer.hasRemaining()){ | ||||
|                     int index = indexBuffer.get(); | ||||
|                     indices[indicesPos] = index; | ||||
|                     indicesPos++; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         int numberTriangles = (arrayLength - 1) * (arrayWidth - 1) * 2; | ||||
|         int triangleStride = 0; | ||||
|          | ||||
|         int numberVertices = arrayLength * arrayWidth; | ||||
|         int vertexStride = 0; | ||||
|          | ||||
|         float[] vertices = new float[numberVertices * 3]; | ||||
|         int vertexInserterPos = 0; | ||||
|         int[] indices = new int[numberTriangles * 3]; | ||||
|         int indexInserterPos = 0; | ||||
|          | ||||
|         for(int x = 0; x < arrayLength; x++){ | ||||
|             for(int y = 0; y < arrayWidth; y++){ | ||||
|                 vertices[vertexInserterPos] = x; | ||||
|                 vertexInserterPos++; | ||||
|                 vertices[vertexInserterPos] = heightfield[x][y] - collisionMargin; | ||||
|                 vertexInserterPos++; | ||||
|                 vertices[vertexInserterPos] = y; | ||||
|                 vertexInserterPos++; | ||||
|                 if(x < arrayLength - 1 && y < arrayWidth - 1){ | ||||
|                     //if we should also add a triangle index | ||||
|                     /* | ||||
|                     as copied from ModelUtil's terrain mesh generation function | ||||
|                     faces.put((x / stride + 0) * actualHeight + (y / stride + 0)); | ||||
|                     faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); | ||||
|                     faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); | ||||
|                     faces.put((x / stride + 1) * actualHeight + (y / stride + 0)); | ||||
|                     faces.put((x / stride + 0) * actualHeight + (y / stride + 1)); | ||||
|                     faces.put((x / stride + 1) * actualHeight + (y / stride + 1)); | ||||
|                     */ | ||||
|                     indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 0); | ||||
|                     indexInserterPos++; | ||||
|                     indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1); | ||||
|                     indexInserterPos++; | ||||
|                     indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0); | ||||
|                     indexInserterPos++; | ||||
|                     indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0); | ||||
|                     indexInserterPos++; | ||||
|                     indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1); | ||||
|                     indexInserterPos++; | ||||
|                     indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 1); | ||||
|                     indexInserterPos++; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|          | ||||
|          | ||||
|         javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f(); | ||||
|         javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f(); | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
|         //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html | ||||
|         electrosphere.collision.shapes.IndexedMesh indexedMesh = new electrosphere.collision.shapes.IndexedMesh(); | ||||
|          | ||||
|         indexedMesh.numTriangles = indices.length / 3; | ||||
|         indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder()); | ||||
|         indexedMesh.triangleIndexBase.asIntBuffer().put(indices); | ||||
|         indexedMesh.triangleIndexStride = 3 * Float.BYTES; | ||||
|          | ||||
|         indexedMesh.numVertices = vertices.length / 3; | ||||
|         indexedMesh.vertexBase = ByteBuffer.allocateDirect(vertices.length*Float.BYTES).order(ByteOrder.nativeOrder()); | ||||
|         indexedMesh.vertexBase.asFloatBuffer().put(vertices); | ||||
|         indexedMesh.vertexStride = 3 * Float.BYTES; | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
|         //http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html | ||||
|         electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray(); | ||||
|         triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer | ||||
|             indexedMesh.triangleIndexBase.asIntBuffer().put(indices); | ||||
|             //push indexed mesh into triangle index array | ||||
|             triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer | ||||
| //        triangleIndexArray.calculateAabbBruteForce(aabbMin, aabbMax); | ||||
|         } | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
|          | ||||
| @ -302,22 +258,16 @@ public class PhysicsUtils { | ||||
|         //uncomment if we start falling through things again | ||||
|        terrainShape.setMargin(collisionMargin); | ||||
|          | ||||
|         DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f((float)position.x,(float)position.y,(float)position.z),1.0f))); | ||||
| //        terrainShape.localGetSupportingVertex(new javax.vecmath.Vector3f(1,0,0), aabbMin); | ||||
| //        terrainShape.recalcLocalAabb(); | ||||
| //        terrainShape.getLocalAabbMin(aabbMin); | ||||
| //        terrainShape.getLocalAabbMax(aabbMax); | ||||
|          | ||||
|          | ||||
|         DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f))); | ||||
|         RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape); | ||||
|         RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI); | ||||
|          | ||||
| //        terrainRigidBody.setFriction(1f); | ||||
|          | ||||
|          | ||||
|         Globals.collisionEngine.registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN)); | ||||
|          | ||||
| //        terrainRigidBody.getAabb(aabbMin, aabbMax); | ||||
| //         | ||||
| //        System.out.println("aabbMin: " + aabbMin + "    aabbMax: " + aabbMax); | ||||
|          | ||||
|          | ||||
|         terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainRigidBody); | ||||
|          | ||||
| 
 | ||||
|         return terrainRigidBody; | ||||
|          | ||||
|     } | ||||
|  | ||||
| @ -11,6 +11,7 @@ import org.lwjgl.glfw.GLFWErrorCallback; | ||||
| 
 | ||||
| import electrosphere.audio.AudioEngine; | ||||
| import electrosphere.auth.AuthenticationManager; | ||||
| import electrosphere.collision.dispatch.CollisionObject; | ||||
| import electrosphere.controls.CameraHandler; | ||||
| import electrosphere.controls.ControlCallback; | ||||
| import electrosphere.controls.ControlHandler; | ||||
| @ -223,7 +224,6 @@ public class Globals { | ||||
|      | ||||
|      | ||||
|      | ||||
|      | ||||
|     // | ||||
|     //Engine - Main managers/variables | ||||
|     // | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user