diff --git a/.vscode/launch.json b/.vscode/launch.json index 084d7b2a..f7bfb872 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -32,6 +32,14 @@ "mainClass": "electrosphere.engine.Main", "projectName": "Renderer", "args" : "--headless" + }, + { + "type": "java", + "name": "Launch Main (Macro Simulate)", + "request": "launch", + "mainClass": "electrosphere.engine.Main", + "projectName": "Renderer", + "args" : "--macro-simulate" } ] } \ No newline at end of file diff --git a/assets/Data/foliage.json b/assets/Data/foliage.json index 8fdd2ef3..88cce696 100644 --- a/assets/Data/foliage.json +++ b/assets/Data/foliage.json @@ -69,7 +69,17 @@ "yawVariance": 0.2, "yawMinimum": 0.1, "minimumScalarToGenerateSwayTree": 0.5, - "maximumScalarToGenerateSwayTree": 1.0 + "maximumScalarToGenerateSwayTree": 1.0, + "physicsCutoff": 3, + "physicsBody": { + "type" : "CYLINDER", + "dimension1" : 3, + "dimension2" : 1, + "dimension3" : 1, + "offsetX" : 0, + "offsetY" : 1.5, + "offsetZ" : 0 + } }, "modelPath" : "Models/proceduralTree2/proceduralTree2v2.fbx" } diff --git a/docs/src/documentation/doxygen.md b/docs/src/documentation/doxygen.md new file mode 100644 index 00000000..6acff02c --- /dev/null +++ b/docs/src/documentation/doxygen.md @@ -0,0 +1,13 @@ +# Documentation System Explanation +The engine uses doxygen to document its features, code, and organization. + +## Building +On windows, doxywizard can be used to build the documentation in a gui format. Simply open Renderer/docs as the working directory from the top, then open the file "Doxyfile". The project should be preconfigured. Lastly move to the "Run" tab, click "Run doxygen" to generate documentation. You can then optionally click "Show HTML Output" to navigate to the documentation locally via native browser. + +TODO: Linux instructions + + +## Usage Notes + +### Images +Images have proven to be tricky with doxygen on windows. Relative paths only kind of work. Unfortunately this means all images need to be in Renderer/docs/src/images without conflicting names. Potential solutions to look in to are namespacing the file names to the page they show up in. \ No newline at end of file diff --git a/docs/src/physics/collision.md b/docs/src/physics/collision.md new file mode 100644 index 00000000..3c90b125 --- /dev/null +++ b/docs/src/physics/collision.md @@ -0,0 +1,108 @@ +# Collision Engine + + + + +## High Level Overview +The goal of the collision engine system is to allow parallel collision detection of different classes of objects. + +For instance, you could have a collision system dedicated to fire and things that are flammable, where only objects in one of those two categories are present. Or, you could have a collision system dedicated to interactible object prompts, where if the player entity is within one of these zones it performs some prompting logic. + +The big case for this engine is the main physics system. The goal is to provide different classes of things for entities to collide with such that they can control the collision physics differently (think a tree vs the ground vs a slippery floor). + + + + + + + + + + + +## Major Usage Notes + + - All geometries are aligned along z by default in the library (ie your cylinders will be on their sides) + + + + + + + + + + + + + + + + + + + + + + + +## Main Classes + +[CollisionEngine.java](@ref #electrosphere.collision.CollisionEngine) - Represents a specific collision system. It may be helpful to think of it as viewing the world through a specific lens. Keeps track of all entities that do its type of collisions and fires callbacks on collision. Should be updated each tick. + +[Collidable.java](@ref #electrosphere.collision.collidable.Collidable) - Contains the collision information for a single object in a given collision system. Stores both the description of the collidable (is it a tree, a frog, or the ground, etc) as well as a list of impulses to be applied. + + + + + + + + + + +## Library Explanation + +The library currently in use is Ode4J. There are a couple main classes that will be explained now. + + - DSpace - The main class representing the overall simulation + - DWorld - A 'world' within the space that can have geometries inside it that collide. Must be used to create bodies. Probably stores stuff like gravity. + - DBody - A rigid body that has some physical properties. Can contain many different geometries. + - DGeom - A geometry shape (capsule, box, etc) + + + + + + + + + + + + +## Code Organization and Best Practices + +#### Startup +Each client scene creates a collision engine for physics on connection. Each scene the server manages also creates a collision engine for physics. + + +#### Usage + + + + + + + + + + + + + + +## Future Goals + + - Ability to turn off impulse generation for when we purely care about whether things are colliding or not (hitboxes, fire system, ui system, etc) + - As always, code organization \ No newline at end of file diff --git a/docs/src/physics/physics.md b/docs/src/physics/physics.md new file mode 100644 index 00000000..5f10e002 --- /dev/null +++ b/docs/src/physics/physics.md @@ -0,0 +1,23 @@ +# Physics Engine + +## High Level Overview +The goal of the physics engine is to wrap around the collision engine to allow physics to occur within the game. + + + + +## Major Usage Notes + + + +## Main Classes + + + +## Code Organization and Best Practices + + + +## Future Goals + + diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 28dd5b6a..4f7014c6 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -52,7 +52,7 @@ import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.logger.LoggerInterface; /** - * + * The main collision engine class. Tracks all entities that collide in its system and fires callbacks when they do. */ public class CollisionEngine { diff --git a/src/main/java/electrosphere/collision/CollisionMasks.java b/src/main/java/electrosphere/collision/CollisionMasks.java deleted file mode 100644 index 6d83a494..00000000 --- a/src/main/java/electrosphere/collision/CollisionMasks.java +++ /dev/null @@ -1,24 +0,0 @@ -package electrosphere.collision; - -import java.util.LinkedList; - -import electrosphere.collision.collidable.Collidable; - -/** - * Contains masks for different collision engine functions - */ -public class CollisionMasks { - - //Only terrain - public static final LinkedList terrainMask = new LinkedList(); - - - /** - * Fills in all the collision engine masks - */ - public static void initMasks(){ - //terrain mask - terrainMask.add(Collidable.TYPE_TERRAIN); - } - -} diff --git a/src/main/java/electrosphere/collision/PhysicsUtils.java b/src/main/java/electrosphere/collision/PhysicsUtils.java index 305541da..b48fcfcd 100644 --- a/src/main/java/electrosphere/collision/PhysicsUtils.java +++ b/src/main/java/electrosphere/collision/PhysicsUtils.java @@ -28,8 +28,7 @@ import electrosphere.entity.types.terrain.TerrainChunkData; import electrosphere.server.datacell.Realm; /** - * - * @author amaterasu + * Utilities for leveraging the collision system to perform physics */ public class PhysicsUtils { diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index ada81b75..64b6bbb9 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -21,7 +21,6 @@ import electrosphere.client.sim.ClientSimulation; import electrosphere.client.terrain.cells.DrawCellManager; import electrosphere.client.terrain.manager.ClientTerrainManager; import electrosphere.collision.CollisionEngine; -import electrosphere.collision.CollisionMasks; import electrosphere.collision.CollisionWorldData; import electrosphere.controls.CameraHandler; import electrosphere.controls.ControlCallback; @@ -397,8 +396,6 @@ public class Globals { if(Globals.userSettings.getNetRunNetMonitor()){ netMonitor = new NetMonitor(); } - //init collision masks - CollisionMasks.initMasks(); } public static void initDefaultAudioResources(){ diff --git a/src/main/java/electrosphere/engine/cli/CLIParser.java b/src/main/java/electrosphere/engine/cli/CLIParser.java index be389eb3..ce34b8c3 100644 --- a/src/main/java/electrosphere/engine/cli/CLIParser.java +++ b/src/main/java/electrosphere/engine/cli/CLIParser.java @@ -17,6 +17,9 @@ public class CLIParser { Globals.RUN_SERVER = true; Globals.HEADLESS = true; } break; + case "--macro-simulate": { + //TODO: macro simulate + } break; } } } diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index b4fe76c7..ce95ae58 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -15,6 +15,7 @@ import electrosphere.client.terrain.cells.DrawCellManager; import electrosphere.collision.CollisionEngine; import electrosphere.controls.ControlHandler; import electrosphere.engine.Globals; +import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.DrawableUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; @@ -256,7 +257,7 @@ public class ClientLoading { for(int x = 0; x < 5; x++){ for(int z = 0; z < 5; z++){ Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", rand.nextLong()); - EntityUtils.getPosition(tree).set(5 + x * 5,0,5 + z * 5); + ClientEntityUtils.initiallyPositionEntity(tree, new Vector3d(5 + x * 5,0,5 + z * 5)); } } diff --git a/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java b/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java index 65040773..92266208 100644 --- a/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java +++ b/src/main/java/electrosphere/entity/state/gravity/ClientGravityTree.java @@ -10,7 +10,6 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.ode4j.ode.DBody; -import electrosphere.collision.CollisionMasks; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; import electrosphere.entity.Entity; diff --git a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java index 0a42cec7..9384a426 100644 --- a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java @@ -229,11 +229,11 @@ public class GroundMovementTree implements BehaviorTree { // System.out.println(EntityUtils.getEntityPosition(parent)); // System.out.println(message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ()); //this should only fire on the client, we don't want the server snap updating due to client position reporting - if(position.distance(message.getpositionX(),message.getpositionY(),message.getpositionZ()) > STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD){ - EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ()); - } else if(position.distance(message.getpositionX(),message.getpositionY(),message.getpositionZ()) > STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD){ - EntityUtils.getPosition(parent).add(new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()).mul(SOFT_UPDATE_MULTIPLIER)); - } + // if(position.distance(message.getpositionX(),message.getpositionY(),message.getpositionZ()) > STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD){ + // EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ()); + // } else if(position.distance(message.getpositionX(),message.getpositionY(),message.getpositionZ()) > STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD){ + // EntityUtils.getPosition(parent).add(new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()).mul(SOFT_UPDATE_MULTIPLIER)); + // } //we want to always update the server facing vector with where the client says they're facing EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW()); // CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ())); diff --git a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java index c4431cb6..f152efad 100644 --- a/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java +++ b/src/main/java/electrosphere/entity/types/tree/ProceduralTree.java @@ -14,11 +14,16 @@ import org.joml.Vector3d; import org.joml.Vector3f; import org.joml.Vector4d; import org.joml.Vector4f; +import org.ode4j.ode.DBody; +import electrosphere.collision.PhysicsUtils; +import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; import electrosphere.entity.DrawableUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.BehaviorTree; import electrosphere.entity.types.attach.AttachUtils; @@ -56,6 +61,8 @@ public class ProceduralTree { static final ShaderAttribute leafColorAttribute = new ShaderAttribute(9); + static final float TREE_MASS = 1.0f; + //The static setup logic static { //create map of attributes and register them @@ -92,6 +99,10 @@ public class ProceduralTree { public static Entity clientGenerateProceduralTree(String type, long seed){ Random treeRandom = new Random(seed); + //call recursive branching routine to generate branches from trunk + leaf blobs + FoliageType foliageType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type); + TreeModel treeModel = foliageType.getTreeModel(); + //generate trunk Entity trunkChild = EntityCreationUtils.createClientSpatialEntity(); InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(trunkChild, branchInstanceTemplate, modelMatrixAttribute); @@ -99,9 +110,25 @@ public class ProceduralTree { instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); instancedActor.setAttribute(baseSizeAttribute, 1.0f); - //call recursive branching routine to generate branches from trunk + leaf blobs - FoliageType foliageType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type); - TreeModel treeModel = foliageType.getTreeModel(); + //attach physics + DBody rigidBody = PhysicsUtils.createCylinderBody( + Globals.clientSceneWrapper.getCollisionEngine(), + treeModel.getPhysicsBody().getDimension1(), + treeModel.getPhysicsBody().getDimension2() + ); + Collidable collidable = new Collidable(trunkChild, Collidable.TYPE_OBJECT); + trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody); + trunkChild.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(0,treeModel.getPhysicsBody().getOffsetY(),0)); + trunkChild.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, treeModel.getPhysicsBody()); + trunkChild.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable); + + trunkChild.putData(EntityDataStrings.PHYSICS_MASS, TREE_MASS); + + Globals.clientSceneWrapper.getCollisionEngine().registerPhysicsEntity(trunkChild); + Globals.clientSceneWrapper.getCollisionEngine().registerDynamicPhysicsEntity(trunkChild); + Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable); + + //generate branches clientGenerateBranchesAlt( treeModel, @@ -331,223 +358,223 @@ public class ProceduralTree { return rVal; } - /** - * Generates branches - * @param type The type of branch - * @param parent The immediate parent of the branch - * @param rand The random - * @param transform The current ik transform for the branch - * @param scalar The scalar for the current width of the branch - * @param isCentralTrunk True if the tree should generate a central trunk with branches coming off of it - */ - public static void clientGenerateBranches( - TreeModel type, - Entity parent, - Random rand, - Matrix4f transform, - float scalar, - int currentSegmentNumber, - boolean isCentralTrunk - ){ - //how fast do the branches shrink in size - float scalarFalloffFactor = type.getLimbScalarFalloffFactor(); - //the minimum branch size before we stop generating branch segments/trunk segments - float minimumScalar = type.getMinimumLimbScalar(); - //how high is the model for a single branch segment - float treeSegmentHeight = type.getBranchHeight(); - //how much to spread the branches along the current segment - float minimumSegmentDispersion = type.getMinimumLimbDispersion(); - float dispersionSpread = type.getMaximumLimbDispersion() - type.getMinimumLimbDispersion(); - //the number of branches to make per segment - int minBranches = type.getMinimumNumberForks(); - int maxBranches = type.getMaximumNumberForks(); - //the maximum number of segments in an single arc for both trunk and branches - int maximumTrunkSegments = type.getMaximumTrunkSegments(); - int maximumBranchSegments = type.getMaximumBranchSegments(); + // /** + // * Generates branches + // * @param type The type of branch + // * @param parent The immediate parent of the branch + // * @param rand The random + // * @param transform The current ik transform for the branch + // * @param scalar The scalar for the current width of the branch + // * @param isCentralTrunk True if the tree should generate a central trunk with branches coming off of it + // */ + // public static void clientGenerateBranches( + // TreeModel type, + // Entity parent, + // Random rand, + // Matrix4f transform, + // float scalar, + // int currentSegmentNumber, + // boolean isCentralTrunk + // ){ + // //how fast do the branches shrink in size + // float scalarFalloffFactor = type.getLimbScalarFalloffFactor(); + // //the minimum branch size before we stop generating branch segments/trunk segments + // float minimumScalar = type.getMinimumLimbScalar(); + // //how high is the model for a single branch segment + // float treeSegmentHeight = type.getBranchHeight(); + // //how much to spread the branches along the current segment + // float minimumSegmentDispersion = type.getMinimumLimbDispersion(); + // float dispersionSpread = type.getMaximumLimbDispersion() - type.getMinimumLimbDispersion(); + // //the number of branches to make per segment + // int minBranches = type.getMinimumNumberForks(); + // int maxBranches = type.getMaximumNumberForks(); + // //the maximum number of segments in an single arc for both trunk and branches + // int maximumTrunkSegments = type.getMaximumTrunkSegments(); + // int maximumBranchSegments = type.getMaximumBranchSegments(); - if(scalar > minimumScalar && currentSegmentNumber < maximumTrunkSegments){ - boolean hasCentralTrunk = type.getCentralTrunk(); - //if there is a central trunk and this is the central trunk, generate the next central trunk segment - if(isCentralTrunk && hasCentralTrunk){ - //the rotation applied to the bone - Quaternionf boneRotation = new Quaternionf(0,0,0,1).normalize(); + // if(scalar > minimumScalar && currentSegmentNumber < maximumTrunkSegments){ + // boolean hasCentralTrunk = type.getCentralTrunk(); + // //if there is a central trunk and this is the central trunk, generate the next central trunk segment + // if(isCentralTrunk && hasCentralTrunk){ + // //the rotation applied to the bone + // Quaternionf boneRotation = new Quaternionf(0,0,0,1).normalize(); - //get current position - Vector4f currentPositionf = transform.transform(new Vector4f(0,0,0,1)); - Vector3d currentPosition = new Vector3d(currentPositionf.x,currentPositionf.y,currentPositionf.z); + // //get current position + // Vector4f currentPositionf = transform.transform(new Vector4f(0,0,0,1)); + // Vector3d currentPosition = new Vector3d(currentPositionf.x,currentPositionf.y,currentPositionf.z); - //The new absolute rotation at the end of the bone - Quaterniond currentAbsoluteRotation = transform.getNormalizedRotation(new Quaterniond()).normalize(); + // //The new absolute rotation at the end of the bone + // Quaterniond currentAbsoluteRotation = transform.getNormalizedRotation(new Quaterniond()).normalize(); - //calculates the bone transform matrix - Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation); + // //calculates the bone transform matrix + // Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation); - //calculate attachment transform - Matrix4f attachmentTransform = new Matrix4f().identity().translate(0,treeSegmentHeight,0).rotate(boneRotation); + // //calculate attachment transform + // Matrix4f attachmentTransform = new Matrix4f().identity().translate(0,treeSegmentHeight,0).rotate(boneRotation); - //new position transform - Matrix4f newPositionTransform = new Matrix4f(transform).mul(boneTransform); + // //new position transform + // Matrix4f newPositionTransform = new Matrix4f(transform).mul(boneTransform); - //get new scalar - float newScalar = scalar - scalarFalloffFactor; + // //get new scalar + // float newScalar = scalar - scalarFalloffFactor; - //create entity - Entity branch = EntityCreationUtils.createClientSpatialEntity(); - InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(branch, branchInstanceTemplate, modelMatrixAttribute); - instancedActor.setAttribute(boneMatrixAttribute, boneTransform.scale(newScalar,1,newScalar)); - instancedActor.setAttribute(baseSizeAttribute, scalar); - instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); + // //create entity + // Entity branch = EntityCreationUtils.createClientSpatialEntity(); + // InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(branch, branchInstanceTemplate, modelMatrixAttribute); + // instancedActor.setAttribute(boneMatrixAttribute, boneTransform.scale(newScalar,1,newScalar)); + // instancedActor.setAttribute(baseSizeAttribute, scalar); + // instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); - //set entity stuuff - EntityUtils.getPosition(branch).set(currentPosition); - EntityUtils.getScale(branch).set(1,1,1); - EntityUtils.getRotation(branch).set(currentAbsoluteRotation); - // AttachUtils.clientAttachEntityAtCurrentOffset(parent, branch); - // AttachUtils.clientAttachEntityAtTransform(parent, branch, attachmentTransform); + // //set entity stuuff + // EntityUtils.getPosition(branch).set(currentPosition); + // EntityUtils.getScale(branch).set(1,1,1); + // EntityUtils.getRotation(branch).set(currentAbsoluteRotation); + // // AttachUtils.clientAttachEntityAtCurrentOffset(parent, branch); + // // AttachUtils.clientAttachEntityAtTransform(parent, branch, attachmentTransform); - //recurse - clientGenerateBranches( - type, - branch, - rand, - newPositionTransform, - scalar - scalarFalloffFactor, - currentSegmentNumber + 1, - true //can't be central trunk - ); - } - } + // //recurse + // clientGenerateBranches( + // type, + // branch, + // rand, + // newPositionTransform, + // scalar - scalarFalloffFactor, + // currentSegmentNumber + 1, + // true //can't be central trunk + // ); + // } + // } - if(scalar > minimumScalar && currentSegmentNumber < maximumBranchSegments){ - int minimumSegmentToSpawnLeaves = type.getMinimumSegmentToSpawnLeaves(); + // if(scalar > minimumScalar && currentSegmentNumber < maximumBranchSegments){ + // int minimumSegmentToSpawnLeaves = type.getMinimumSegmentToSpawnLeaves(); - //how much does it peel off of the current vector - double peelRotation = (rand.nextFloat() * dispersionSpread + minimumSegmentDispersion); - //the initial rotation around Y that the branch will peel towards - double offsetRotation = 0; - double rotationInitialOffset = rand.nextFloat(); - int branchNum = rand.nextInt(maxBranches - minBranches) + minBranches; - for(int i = 0; i < branchNum; i++){ - //update offsetrotation - offsetRotation = rotationInitialOffset + (i + 1) * (2.0 * Math.PI / (float)branchNum); - //get new rotation - double pitchFactor = Math.sin(offsetRotation); - double rollFactor = Math.cos(offsetRotation); + // //how much does it peel off of the current vector + // double peelRotation = (rand.nextFloat() * dispersionSpread + minimumSegmentDispersion); + // //the initial rotation around Y that the branch will peel towards + // double offsetRotation = 0; + // double rotationInitialOffset = rand.nextFloat(); + // int branchNum = rand.nextInt(maxBranches - minBranches) + minBranches; + // for(int i = 0; i < branchNum; i++){ + // //update offsetrotation + // offsetRotation = rotationInitialOffset + (i + 1) * (2.0 * Math.PI / (float)branchNum); + // //get new rotation + // double pitchFactor = Math.sin(offsetRotation); + // double rollFactor = Math.cos(offsetRotation); - //the rotation applied to the bone - Quaternionf boneRotation = new Quaternionf(0,0,0,1).rotateLocalX((float)(pitchFactor * peelRotation)).rotateLocalZ((float)(rollFactor * peelRotation)).normalize(); + // //the rotation applied to the bone + // Quaternionf boneRotation = new Quaternionf(0,0,0,1).rotateLocalX((float)(pitchFactor * peelRotation)).rotateLocalZ((float)(rollFactor * peelRotation)).normalize(); - //get current position - Vector4f currentPositionf = transform.transform(new Vector4f(0,0,0,1)); - Vector3d currentPosition = new Vector3d(currentPositionf.x,currentPositionf.y,currentPositionf.z); + // //get current position + // Vector4f currentPositionf = transform.transform(new Vector4f(0,0,0,1)); + // Vector3d currentPosition = new Vector3d(currentPositionf.x,currentPositionf.y,currentPositionf.z); - //The new absolute rotation at the end of the bone - Quaterniond currentAbsoluteRotation = transform.getNormalizedRotation(new Quaterniond()).normalize(); + // //The new absolute rotation at the end of the bone + // Quaterniond currentAbsoluteRotation = transform.getNormalizedRotation(new Quaterniond()).normalize(); - //calculates the bone transform matrix - Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation); + // //calculates the bone transform matrix + // Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation); - //new position transform - Matrix4f newPositionTransform = new Matrix4f(transform).mul(boneTransform).translate(0,treeSegmentHeight,0); + // //new position transform + // Matrix4f newPositionTransform = new Matrix4f(transform).mul(boneTransform).translate(0,treeSegmentHeight,0); - //get new scalar - float newScalar = scalar - scalarFalloffFactor; + // //get new scalar + // float newScalar = scalar - scalarFalloffFactor; - //create entity - Entity branch = EntityCreationUtils.createClientSpatialEntity(); - InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(branch, branchInstanceTemplate, modelMatrixAttribute); - instancedActor.setAttribute(boneMatrixAttribute, boneTransform.scale(newScalar,1,newScalar)); - instancedActor.setAttribute(baseSizeAttribute, scalar); - instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); + // //create entity + // Entity branch = EntityCreationUtils.createClientSpatialEntity(); + // InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(branch, branchInstanceTemplate, modelMatrixAttribute); + // instancedActor.setAttribute(boneMatrixAttribute, boneTransform.scale(newScalar,1,newScalar)); + // instancedActor.setAttribute(baseSizeAttribute, scalar); + // instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); - //set entity stuuff - EntityUtils.getPosition(branch).set(currentPosition); - EntityUtils.getScale(branch).set(1,1,1); - EntityUtils.getRotation(branch).set(currentAbsoluteRotation); - // AttachUtils.clientAttachEntityAtCurrentOffset(parent, branch); - // AttachUtils.clientAttachEntityAtTransform(parent, branch, attachmentTransform); + // //set entity stuuff + // EntityUtils.getPosition(branch).set(currentPosition); + // EntityUtils.getScale(branch).set(1,1,1); + // EntityUtils.getRotation(branch).set(currentAbsoluteRotation); + // // AttachUtils.clientAttachEntityAtCurrentOffset(parent, branch); + // // AttachUtils.clientAttachEntityAtTransform(parent, branch, attachmentTransform); - //debug stuff - // Vector4f newPositionF = newPositionTransform.transform(new Vector4f(0,0,0,1)); - // Vector3d newAbsolutePosition = new Vector3d(newPositionF.x,newPositionF.y,newPositionF.z); - // Entity debugSphere = EntityCreationUtils.createClientSpatialEntity(); - // EntityCreationUtils.makeEntityDrawable(debugSphere, "Models/unitsphere_1.fbx"); - // EntityUtils.getScale(debugSphere).set(0.5f); - // EntityUtils.getPosition(debugSphere).set(newAbsolutePosition); + // //debug stuff + // // Vector4f newPositionF = newPositionTransform.transform(new Vector4f(0,0,0,1)); + // // Vector3d newAbsolutePosition = new Vector3d(newPositionF.x,newPositionF.y,newPositionF.z); + // // Entity debugSphere = EntityCreationUtils.createClientSpatialEntity(); + // // EntityCreationUtils.makeEntityDrawable(debugSphere, "Models/unitsphere_1.fbx"); + // // EntityUtils.getScale(debugSphere).set(0.5f); + // // EntityUtils.getPosition(debugSphere).set(newAbsolutePosition); - //attach leaf blobs - if( - !isCentralTrunk && - currentSegmentNumber >= minimumSegmentToSpawnLeaves - ){ - createLeafBlobsOnBranch(type,rand,transform,boneTransform,branch); - } + // //attach leaf blobs + // if( + // !isCentralTrunk && + // currentSegmentNumber >= minimumSegmentToSpawnLeaves + // ){ + // createLeafBlobsOnBranch(type,rand,transform,boneTransform,branch); + // } - //recurse - clientGenerateBranches( - type, - branch, - rand, - newPositionTransform, - scalar - scalarFalloffFactor, - currentSegmentNumber + 1, - false //can't be central trunk - ); - } - } - } + // //recurse + // clientGenerateBranches( + // type, + // branch, + // rand, + // newPositionTransform, + // scalar - scalarFalloffFactor, + // currentSegmentNumber + 1, + // false //can't be central trunk + // ); + // } + // } + // } - /** - * Creates leaf blobs around branch segments - * @param type The type of tree - * @param rand The random - * @param transform The current branch segment transform - * @param boneTransform The bone transform to the next branch segment - * @param branch The branch entity - */ - private static void createLeafBlobsOnBranch(TreeModel type, Random rand, Matrix4f transform, Matrix4f boneTransform, Entity branch){ - //how high is the model for a single branch segment - float treeSegmentHeight = type.getBranchHeight(); + // /** + // * Creates leaf blobs around branch segments + // * @param type The type of tree + // * @param rand The random + // * @param transform The current branch segment transform + // * @param boneTransform The bone transform to the next branch segment + // * @param branch The branch entity + // */ + // private static void createLeafBlobsOnBranch(TreeModel type, Random rand, Matrix4f transform, Matrix4f boneTransform, Entity branch){ + // //how high is the model for a single branch segment + // float treeSegmentHeight = type.getBranchHeight(); - float minBranchHeightToStartSpawningLeaves = type.getMinBranchHeightToStartSpawningLeaves(); - float maxBranchHeightToStartSpawningLeaves = type.getMaxBranchHeightToStartSpawningLeaves(); - float leafIncrement = type.getLeafIncrement(); - int minLeavesToSpawnPerPoint = type.getMinLeavesToSpawnPerPoint(); - int maxLeavesToSpawnPerPoint = type.getMaxLeavesToSpawnPerPoint(); - for( - float positionAlongBranch = minBranchHeightToStartSpawningLeaves; - positionAlongBranch < maxBranchHeightToStartSpawningLeaves; - positionAlongBranch = positionAlongBranch + leafIncrement - ){ - int numToSpawn = rand.nextInt(maxLeavesToSpawnPerPoint - minLeavesToSpawnPerPoint) + minLeavesToSpawnPerPoint; - double currentLeafRotation = rand.nextFloat(); - float distanceFromCenter = type.getLeafDistanceFromCenter(); - for(int leafIncrementer = 0; leafIncrementer < numToSpawn; leafIncrementer++){ - //offset radially - float xOffset = (float)Math.sin(currentLeafRotation) * distanceFromCenter; - float zOffset = (float)Math.cos(currentLeafRotation) * distanceFromCenter; - //update offsetrotation - currentLeafRotation = currentLeafRotation + (leafIncrementer + 1) * 2.0 * Math.PI / (float)numToSpawn; - //construct model matrix - Matrix4f leafPositionTransform = new Matrix4f(transform).mul(boneTransform).translate(xOffset,positionAlongBranch,zOffset); - Vector4f leafCurrentPositionf = leafPositionTransform.transform(new Vector4f(0,0,0,1)); - Vector3d leafCurrentPosition = new Vector3d(leafCurrentPositionf.x,leafCurrentPositionf.y,leafCurrentPositionf.z); - //create entity - Entity leaf = EntityCreationUtils.createClientSpatialEntity(); - InstancedActor leafInstancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(leaf, leafInstanceTemplate, modelMatrixAttribute); - leafInstancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); - leafInstancedActor.setAttribute(leafColorAttribute, new Vector3f(36/255.0f,173/255.0f,31/255.0f)); + // float minBranchHeightToStartSpawningLeaves = type.getMinBranchHeightToStartSpawningLeaves(); + // float maxBranchHeightToStartSpawningLeaves = type.getMaxBranchHeightToStartSpawningLeaves(); + // float leafIncrement = type.getLeafIncrement(); + // int minLeavesToSpawnPerPoint = type.getMinLeavesToSpawnPerPoint(); + // int maxLeavesToSpawnPerPoint = type.getMaxLeavesToSpawnPerPoint(); + // for( + // float positionAlongBranch = minBranchHeightToStartSpawningLeaves; + // positionAlongBranch < maxBranchHeightToStartSpawningLeaves; + // positionAlongBranch = positionAlongBranch + leafIncrement + // ){ + // int numToSpawn = rand.nextInt(maxLeavesToSpawnPerPoint - minLeavesToSpawnPerPoint) + minLeavesToSpawnPerPoint; + // double currentLeafRotation = rand.nextFloat(); + // float distanceFromCenter = type.getLeafDistanceFromCenter(); + // for(int leafIncrementer = 0; leafIncrementer < numToSpawn; leafIncrementer++){ + // //offset radially + // float xOffset = (float)Math.sin(currentLeafRotation) * distanceFromCenter; + // float zOffset = (float)Math.cos(currentLeafRotation) * distanceFromCenter; + // //update offsetrotation + // currentLeafRotation = currentLeafRotation + (leafIncrementer + 1) * 2.0 * Math.PI / (float)numToSpawn; + // //construct model matrix + // Matrix4f leafPositionTransform = new Matrix4f(transform).mul(boneTransform).translate(xOffset,positionAlongBranch,zOffset); + // Vector4f leafCurrentPositionf = leafPositionTransform.transform(new Vector4f(0,0,0,1)); + // Vector3d leafCurrentPosition = new Vector3d(leafCurrentPositionf.x,leafCurrentPositionf.y,leafCurrentPositionf.z); + // //create entity + // Entity leaf = EntityCreationUtils.createClientSpatialEntity(); + // InstancedActor leafInstancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(leaf, leafInstanceTemplate, modelMatrixAttribute); + // leafInstancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity()); + // leafInstancedActor.setAttribute(leafColorAttribute, new Vector3f(36/255.0f,173/255.0f,31/255.0f)); - //set entity stuuff - EntityUtils.getPosition(leaf).set(leafCurrentPosition); - EntityUtils.getScale(leaf).set(1,1,1); - EntityUtils.getRotation(leaf).set(new Quaterniond().identity()); - AttachUtils.clientAttachEntityAtCurrentOffset(branch, leaf); - } - } - } + // //set entity stuuff + // EntityUtils.getPosition(leaf).set(leafCurrentPosition); + // EntityUtils.getScale(leaf).set(1,1,1); + // EntityUtils.getRotation(leaf).set(new Quaterniond().identity()); + // AttachUtils.clientAttachEntityAtCurrentOffset(branch, leaf); + // } + // } + // } diff --git a/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java b/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java index 2967f8fb..71755e30 100644 --- a/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java +++ b/src/main/java/electrosphere/game/data/foliage/type/TreeModel.java @@ -1,5 +1,7 @@ package electrosphere.game.data.foliage.type; +import electrosphere.game.data.creature.type.CollidableTemplate; + /** * Describes characteristics about a type of tree (how do the limbs dispere, where to the leaves start growing, how sturdy is it, etc) */ @@ -59,6 +61,12 @@ public class TreeModel { //The distance from the central line of a branch to spawn a leaf at float leafDistanceFromCenter; + //The branch count to stop generating physics for each branch + int physicsCutoff; + + //The rigid body definition for a full scale tree branch + CollidableTemplate physicsBody; + // //Tree branch sway factors @@ -304,7 +312,24 @@ public class TreeModel { * @return */ public float getMaximumScalarToGenerateSwayTree(){ - return maximumScalarToGenerateSwayTree; + return this.maximumScalarToGenerateSwayTree; + } + + + /** + * The branch count to stop generating physics for each branch + * @return + */ + public int getPhysicsCutoff(){ + return this.physicsCutoff; + } + + /** + * The rigid body definition for a full scale tree branch + * @return + */ + public CollidableTemplate getPhysicsBody(){ + return this.physicsBody; } } diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 7bd1a79d..4a0af0b4 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -940,7 +940,7 @@ public class RenderingEngine { modelTransformMatrix.translate(cameraModifiedPosition); modelTransformMatrix.rotate(EntityUtils.getRotation(physicsEntity)); // modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere - modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3()); + modelTransformMatrix.scale(template.getDimension1() * 0.5,template.getDimension2() * 0.5,template.getDimension3() * 0.5); physicsGraphicsModel.modelMatrix = modelTransformMatrix; physicsGraphicsModel.draw(renderPipelineState); }