Trees be freaking out yo
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
f113f45317
commit
fe1680b7d9
@ -1,5 +1,6 @@
|
||||
package electrosphere.engine.loadingthreads;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
@ -239,12 +240,17 @@ public class ClientLoading {
|
||||
}
|
||||
});
|
||||
|
||||
// for(int i = 0; i < 6; i++){
|
||||
Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", 0);
|
||||
Random rand = new Random(0);
|
||||
{
|
||||
Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", rand.nextLong());
|
||||
EntityUtils.getPosition(tree).set(5,0,5);
|
||||
EntityUtils.getScale(tree).set(0.5f);
|
||||
EntityUtils.getRotation(tree).rotateLocalX(0.5);
|
||||
// EntityUtils.getPosition(tree).set(5,0,i * 3);
|
||||
}
|
||||
// for(int i = 0; i < 6; i++){
|
||||
// Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", rand.nextLong());
|
||||
// // EntityUtils.getPosition(tree).set(5,0,5);
|
||||
// // EntityUtils.getScale(tree).set(0.5f);
|
||||
// // EntityUtils.getRotation(tree).rotateLocalX(0.5);
|
||||
// EntityUtils.getPosition(tree).set(5,0,i * 5);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@ -252,6 +252,15 @@ public class AttachUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the transform for the attachment
|
||||
* @param toAttach The entity that is attached
|
||||
* @param transform The transform
|
||||
*/
|
||||
public static void updateAttachTransform(Entity toAttach, Matrix4f transform){
|
||||
toAttach.putData(EntityDataStrings.ATTACH_TRANSFORM, transform);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Semantically attaches an entity to another entity
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package electrosphere.entity.types.tree;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@ -10,6 +12,7 @@ import org.joml.Quaterniond;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
@ -95,25 +98,17 @@ public class ProceduralTree {
|
||||
instancedActor.setAttribute(boneMatrixAttribute, new Matrix4f().identity());
|
||||
instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity());
|
||||
instancedActor.setAttribute(baseSizeAttribute, 1.0f);
|
||||
// EntityCreationUtils.makeEntityDrawable(trunkChild, "Models/proceduralTree2/proceduralTree2.fbx");
|
||||
|
||||
//call recursive branching routine to generate branches from trunk + leaf blobs
|
||||
Matrix4f transform = new Matrix4f().identity().translate(0,3,0);
|
||||
FoliageType foliageType = Globals.gameConfigCurrent.getFoliageMap().getFoliage(type);
|
||||
TreeModel treeModel = foliageType.getTreeModel();
|
||||
// clientGenerateBranches(
|
||||
// treeModel,
|
||||
// trunkChild,
|
||||
// treeRandom,
|
||||
// transform,
|
||||
// 1,
|
||||
// 1,
|
||||
// true
|
||||
// );
|
||||
//generate branches
|
||||
clientGenerateBranchesAlt(
|
||||
treeModel,
|
||||
trunkChild,
|
||||
treeRandom,
|
||||
0,
|
||||
0,
|
||||
new Vector3d(0,0,0),
|
||||
new Quaterniond(0,0,0,1),
|
||||
new Vector3d(0,3,0),
|
||||
@ -123,17 +118,15 @@ public class ProceduralTree {
|
||||
true
|
||||
);
|
||||
|
||||
//attach btress
|
||||
//..attach wind
|
||||
//...
|
||||
|
||||
return trunkChild;
|
||||
}
|
||||
|
||||
public static void clientGenerateBranchesAlt(
|
||||
public static List<Entity> clientGenerateBranchesAlt(
|
||||
TreeModel type,
|
||||
Entity parent,
|
||||
Random rand,
|
||||
double parentPeel,
|
||||
double parentRotationOffset,
|
||||
Vector3d parentPosition, // The parent's origin bone's position in space
|
||||
Quaterniond parentRotation, // The parent's origin bone's rotation
|
||||
Vector3d offsetFromParent, // The offset from the parent's origin bone that this branch's origin bone should be at
|
||||
@ -142,6 +135,7 @@ public class ProceduralTree {
|
||||
int currentSegmentNumber,
|
||||
boolean isCentralTrunk
|
||||
){
|
||||
List<Entity> rVal = new LinkedList<Entity>();
|
||||
//how fast do the branches shrink in size
|
||||
float scalarFalloffFactor = type.getLimbScalarFalloffFactor();
|
||||
//the minimum branch size before we stop generating branch segments/trunk segments
|
||||
@ -245,14 +239,6 @@ public class ProceduralTree {
|
||||
//calculates the bone transform matrix
|
||||
Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation);
|
||||
|
||||
//calculate attachment transform
|
||||
// Matrix4f attachmentTransform = new Matrix4f().identity().rotate(new Quaternionf(
|
||||
// (float)currentAbsoluteRotation.x,
|
||||
// (float)currentAbsoluteRotation.y,
|
||||
// (float)currentAbsoluteRotation.z,
|
||||
// (float)currentAbsoluteRotation.w
|
||||
// )).translate(0,treeSegmentHeight,0);
|
||||
|
||||
//new position transform
|
||||
Matrix4f newPositionTransform = new Matrix4f().rotate(boneRotation).translate(0,treeSegmentHeight,0);
|
||||
|
||||
@ -263,7 +249,12 @@ public class ProceduralTree {
|
||||
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));
|
||||
@ -277,27 +268,41 @@ public class ProceduralTree {
|
||||
// AttachUtils.clientAttachEntityAtCurrentOffset(parent, branch);
|
||||
AttachUtils.clientAttachEntityAtTransform(parent, branch, transformFromParent);
|
||||
|
||||
//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);
|
||||
rVal.add(branch);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//attach leaf blobs
|
||||
if(
|
||||
!isCentralTrunk &&
|
||||
currentSegmentNumber >= minimumSegmentToSpawnLeaves
|
||||
){
|
||||
// createLeafBlobsOnBranch(type,rand,transform,boneTransform,branch);
|
||||
createLeafBlobsOnBranch(
|
||||
type,
|
||||
branch,
|
||||
rand,
|
||||
currentPosition,
|
||||
currentAbsoluteRotation,
|
||||
newPosition,
|
||||
boneRotation,
|
||||
scalar - scalarFalloffFactor,
|
||||
currentSegmentNumber + 1,
|
||||
false //can't be central trunk
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//recurse
|
||||
clientGenerateBranchesAlt(
|
||||
List<Entity> childBranches = clientGenerateBranchesAlt(
|
||||
type,
|
||||
branch,
|
||||
rand,
|
||||
peelRotation,
|
||||
offsetRotation,
|
||||
currentPosition,
|
||||
currentAbsoluteRotation,
|
||||
newPosition,
|
||||
@ -306,8 +311,22 @@ public class ProceduralTree {
|
||||
currentSegmentNumber + 1,
|
||||
false //can't be central trunk
|
||||
);
|
||||
|
||||
//add behavior tree to update all child branch attachment points to new point
|
||||
if(childBranches.size() > 0){
|
||||
Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BranchBehaviorTree(
|
||||
parent,
|
||||
branch,
|
||||
childBranches,
|
||||
newScalar,
|
||||
parentPeel,
|
||||
offsetRotation,
|
||||
treeSegmentHeight
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -528,22 +547,293 @@ public class ProceduralTree {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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,
|
||||
Entity parent,
|
||||
Random rand,
|
||||
Vector3d parentPosition, // The parent's origin bone's position in space
|
||||
Quaterniond parentRotation, // The parent's origin bone's rotation
|
||||
Vector3d offsetFromParent, // The offset from the parent's origin bone that this branch's origin bone should be at
|
||||
Quaternionf rotationFromParent, // The rotation of the parent's extended bone. Should be equivalent to the origin bone's rotation on this branch
|
||||
float scalar,
|
||||
int currentSegmentNumber,
|
||||
boolean isCentralTrunk
|
||||
){
|
||||
//get type data
|
||||
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++){
|
||||
//what we want to solve for:
|
||||
//get parent position + rotation
|
||||
//get an offset from the parent position for this position
|
||||
//get a rotation from the parent rotation for this rotation
|
||||
|
||||
//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;
|
||||
|
||||
//calculate the transform from parent
|
||||
Quaterniond parentLocalRotationFromVertical = new Quaterniond().rotationTo(new Vector3d(0,1,0), offsetFromParent);
|
||||
Vector4d transformedPos = parentLocalRotationFromVertical.transform(new Vector4d(xOffset,positionAlongBranch,zOffset,1));
|
||||
|
||||
//calculate transform from parent entity
|
||||
//this is the transform that will be applied every time the attachutils updates
|
||||
Matrix4f transformFromParent = new Matrix4f()
|
||||
.translate(new Vector3f(
|
||||
(float)transformedPos.x,
|
||||
(float)transformedPos.y,
|
||||
(float)transformedPos.z
|
||||
))
|
||||
.rotate(new Quaternionf(
|
||||
(float)rotationFromParent.x,
|
||||
(float)rotationFromParent.y,
|
||||
(float)rotationFromParent.z,
|
||||
(float)rotationFromParent.w
|
||||
));
|
||||
|
||||
|
||||
//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(parent, leaf);
|
||||
// AttachUtils.clientAttachEntityAtCurrentOffset(parent, branch);
|
||||
AttachUtils.clientAttachEntityAtTransform(parent, leaf, transformFromParent);
|
||||
}
|
||||
}
|
||||
// for(int i = 0; i < branchNum; i++){
|
||||
|
||||
// //what we want to solve for:
|
||||
// //get parent position + rotation
|
||||
// //get an offset from the parent position for this position
|
||||
// //get a rotation from the parent rotation for this rotation
|
||||
|
||||
// Quaterniond parentLocalRotationFromVertical = new Quaterniond().rotationTo(new Vector3d(0,1,0), offsetFromParent);
|
||||
// parentLocalRotationFromVertical.transform(new Vector4d(0,0,0,1));
|
||||
|
||||
// //calculate transform from parent entity
|
||||
// //this is the transform that will be applied every time the attachutils updates
|
||||
// Matrix4f transformFromParent = new Matrix4f()
|
||||
// .translate(new Vector3f(
|
||||
// (float)offsetFromParent.x,
|
||||
// (float)offsetFromParent.y,
|
||||
// (float)offsetFromParent.z
|
||||
// ))
|
||||
// .rotate(new Quaternionf(
|
||||
// (float)rotationFromParent.x,
|
||||
// (float)rotationFromParent.y,
|
||||
// (float)rotationFromParent.z,
|
||||
// (float)rotationFromParent.w
|
||||
// ));
|
||||
|
||||
// //calculate combined transform
|
||||
// Matrix4f combinedTransform = new Matrix4f().translate(new Vector3f(
|
||||
// (float)parentPosition.x,
|
||||
// (float)parentPosition.y,
|
||||
// (float)parentPosition.z
|
||||
// )).rotate(new Quaternionf(
|
||||
// (float)parentRotation.x,
|
||||
// (float)parentRotation.y,
|
||||
// (float)parentRotation.z,
|
||||
// (float)parentRotation.w
|
||||
// )).mul(transformFromParent);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// //calculate current branch's stuff
|
||||
// //get current position
|
||||
// Vector4f currentPositionf = combinedTransform.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 = combinedTransform.getNormalizedRotation(new Quaterniond()).normalize();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// //calculate child stuff
|
||||
|
||||
// //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();
|
||||
|
||||
|
||||
// //calculates the bone transform matrix
|
||||
// Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation);
|
||||
|
||||
// //new position transform
|
||||
// Matrix4f newPositionTransform = new Matrix4f().rotate(boneRotation).translate(0,treeSegmentHeight,0);
|
||||
|
||||
// Vector4f newPositionRaw = newPositionTransform.transform(new Vector4f(0,0,0,1));
|
||||
// Vector3d newPosition = new Vector3d(newPositionRaw.x,newPositionRaw.y,newPositionRaw.z);
|
||||
|
||||
// //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());
|
||||
|
||||
// //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, transformFromParent);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* The behavior tree for branches swaying in the wind
|
||||
*/
|
||||
static class BranchBehaviorTree implements BehaviorTree {
|
||||
|
||||
//The parent that the branch is attached to
|
||||
Entity parent;
|
||||
|
||||
//The branch that is having its offset changed
|
||||
Entity branch;
|
||||
|
||||
//the initial peel for the branch
|
||||
double initialPeel;
|
||||
|
||||
//The current peel for the branch
|
||||
double currentPeel;
|
||||
|
||||
//The initial yaw for the branch
|
||||
double initialYaw;
|
||||
|
||||
//the current yaw for the branch
|
||||
double currentYaw;
|
||||
|
||||
//The height of the
|
||||
float treeSegmentHeight;
|
||||
|
||||
//Every child branch
|
||||
List<Entity> children;
|
||||
|
||||
//The current scalar of the branch
|
||||
double currentScalar;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param branch The branch entity
|
||||
*/
|
||||
protected BranchBehaviorTree(Entity branch){
|
||||
|
||||
protected BranchBehaviorTree(Entity parent, Entity branch, List<Entity> children, double currentScalar, double peel, double yaw, float treeSegmentHeight){
|
||||
this.parent = parent;
|
||||
this.branch = branch;
|
||||
this.initialPeel = peel;
|
||||
this.currentPeel = peel;
|
||||
this.initialYaw = yaw;
|
||||
this.currentYaw = yaw;
|
||||
this.treeSegmentHeight = treeSegmentHeight;
|
||||
this.children = children;
|
||||
this.currentScalar = currentScalar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simulate(float deltaTime) {
|
||||
|
||||
|
||||
System.out.println(currentYaw);
|
||||
// currentYaw = currentYaw * Math.abs(currentYaw - initialYaw) + new Random().nextDouble() * (1 - Math.abs(currentYaw - initialYaw));
|
||||
currentPeel = initialPeel * Math.abs(currentPeel - initialPeel) + new Random().nextDouble() * (1 - Math.abs(currentPeel - initialPeel));
|
||||
|
||||
//get new rotation
|
||||
double pitchFactor = Math.sin(currentYaw);
|
||||
double rollFactor = Math.cos(currentYaw);
|
||||
|
||||
//the rotation applied to the bone
|
||||
Quaternionf boneRotation = new Quaternionf(0,0,0,1).rotateLocalX((float)(pitchFactor * currentPeel)).rotateLocalZ((float)(rollFactor * currentPeel)).normalize();
|
||||
|
||||
|
||||
//calculates the bone transform matrix
|
||||
Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation);
|
||||
|
||||
//new position transform
|
||||
Matrix4f newPositionTransform = new Matrix4f().rotate(boneRotation).translate(0,treeSegmentHeight,0);
|
||||
Vector4f newPositionRaw = newPositionTransform.transform(new Vector4f(0,0,0,1));
|
||||
|
||||
Matrix4f transformFromParent = new Matrix4f()
|
||||
.translate(new Vector3f(
|
||||
(float)newPositionRaw.x,
|
||||
(float)newPositionRaw.y,
|
||||
(float)newPositionRaw.z
|
||||
))
|
||||
.rotate(new Quaternionf(
|
||||
(float)boneRotation.x,
|
||||
(float)boneRotation.y,
|
||||
(float)boneRotation.z,
|
||||
(float)boneRotation.w
|
||||
));
|
||||
|
||||
|
||||
//update branch actor branch matrix
|
||||
InstancedActor branchActor = InstancedActor.getInstancedActor(branch);
|
||||
branchActor.setAttribute(boneMatrixAttribute, new Matrix4f(transformFromParent).scale((float)currentScalar,1,(float)currentScalar));
|
||||
|
||||
//update children positions
|
||||
for(Entity child : children){
|
||||
AttachUtils.updateAttachTransform(child,transformFromParent);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user