tree system work
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
5f54e5034c
commit
a68e56285a
@ -17,6 +17,79 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id" : "pine",
|
||||
"tokens" : [
|
||||
"TREE",
|
||||
"REACTS_TO_WIND",
|
||||
"GROWS_BACK",
|
||||
"FLAMMABLE",
|
||||
"SEEDED"
|
||||
],
|
||||
"growthModel": {
|
||||
"growthRate" : 0.001
|
||||
},
|
||||
"ambientAudio": {
|
||||
"responseWindAudioFilePath": "Audio/ambienceWind1SeamlessMono.ogg",
|
||||
"responseWindLoops": true,
|
||||
"randomizeOffset": true,
|
||||
"gainMultiplier": 0.9,
|
||||
"emitterSpatialOffset": [0,3,0]
|
||||
},
|
||||
"graphicsTemplate": {
|
||||
"proceduralModel": {
|
||||
"treeModel": {
|
||||
"trunkModel": {
|
||||
"trunkScalarFalloffFactor": 0.2,
|
||||
"minimumTrunkScalar": 0.2,
|
||||
"maximumTrunkSegments": 6,
|
||||
"physicsCutoff": 3,
|
||||
"centralTrunk": true
|
||||
},
|
||||
"branchModel": {
|
||||
"limbScalarFalloffFactor": 0.3,
|
||||
"minimumLimbScalar": 0.25,
|
||||
"maximumLimbDispersion": 0.5,
|
||||
"minimumLimbDispersion": 0.3,
|
||||
"minimumNumberForks": 3,
|
||||
"maximumNumberForks": 5,
|
||||
"maximumBranchSegments": 3,
|
||||
"maxBranchSegmentFalloffFactor": 1,
|
||||
"minimumSegmentToSpawnLeaves": 2
|
||||
},
|
||||
"minBranchHeightToStartSpawningLeaves": 1.5,
|
||||
"maxBranchHeightToStartSpawningLeaves": 3.01,
|
||||
"leafIncrement": 0.5,
|
||||
"minLeavesToSpawnPerPoint": 3,
|
||||
"maxLeavesToSpawnPerPoint": 5,
|
||||
"leafDistanceFromCenter": 1.2,
|
||||
"peelVariance": 0.2,
|
||||
"peelMinimum": 0.1,
|
||||
"swaySigmoidFactor": 2,
|
||||
"minimumSwayTime": 500,
|
||||
"swayTimeVariance": 500,
|
||||
"yawVariance": 0.2,
|
||||
"yawMinimum": 0.1,
|
||||
"minimumScalarToGenerateSwayTree": 0.5,
|
||||
"maximumScalarToGenerateSwayTree": 1.0,
|
||||
"branchHeight": 3,
|
||||
"physicsBody": {
|
||||
"type" : "CYLINDER",
|
||||
"dimension1" : 0.5,
|
||||
"dimension2" : 3,
|
||||
"dimension3" : 0.5,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 1.5,
|
||||
"offsetZ" : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id" : "oak",
|
||||
"tokens" : [
|
||||
@ -39,18 +112,22 @@
|
||||
"graphicsTemplate": {
|
||||
"proceduralModel": {
|
||||
"treeModel": {
|
||||
"limbScalarFalloffFactor": 0.3,
|
||||
"minimumLimbScalar": 0.25,
|
||||
"maximumLimbDispersion": 0.5,
|
||||
"minimumLimbDispersion": 0.3,
|
||||
"minimumNumberForks": 3,
|
||||
"maximumNumberForks": 5,
|
||||
"branchHeight": 3,
|
||||
"centralTrunk": false,
|
||||
"maximumTrunkSegments": 4,
|
||||
"maximumBranchSegments": 3,
|
||||
"maxBranchSegmentFalloffFactor": 1,
|
||||
"minimumSegmentToSpawnLeaves": 2,
|
||||
"trunkModel": {
|
||||
"maximumTrunkSegments": 4,
|
||||
"physicsCutoff": 3,
|
||||
"centralTrunk": false
|
||||
},
|
||||
"branchModel": {
|
||||
"limbScalarFalloffFactor": 0.3,
|
||||
"minimumLimbScalar": 0.25,
|
||||
"maximumLimbDispersion": 0.5,
|
||||
"minimumLimbDispersion": 0.3,
|
||||
"minimumNumberForks": 3,
|
||||
"maximumNumberForks": 5,
|
||||
"maximumBranchSegments": 3,
|
||||
"maxBranchSegmentFalloffFactor": 1,
|
||||
"minimumSegmentToSpawnLeaves": 2
|
||||
},
|
||||
"minBranchHeightToStartSpawningLeaves": 1.5,
|
||||
"maxBranchHeightToStartSpawningLeaves": 3.01,
|
||||
"leafIncrement": 0.5,
|
||||
@ -66,7 +143,7 @@
|
||||
"yawMinimum": 0.1,
|
||||
"minimumScalarToGenerateSwayTree": 0.5,
|
||||
"maximumScalarToGenerateSwayTree": 1.0,
|
||||
"physicsCutoff": 3,
|
||||
"branchHeight": 3,
|
||||
"physicsBody": {
|
||||
"type" : "CYLINDER",
|
||||
"dimension1" : 0.5,
|
||||
|
||||
@ -338,7 +338,7 @@
|
||||
},
|
||||
"graphicsTemplate": {
|
||||
"model": {
|
||||
"path" : "Models/basic/geometry/unitvector.glb"
|
||||
"path" : "Models/items/weapons/shovel1.glb"
|
||||
}
|
||||
},
|
||||
"clientSidePrimary": "ADD_VOXEL",
|
||||
@ -370,7 +370,7 @@
|
||||
},
|
||||
"graphicsTemplate": {
|
||||
"model": {
|
||||
"path" : "Models/basic/geometry/unitcapsule.glb"
|
||||
"path" : "Models/basic/geometry/unitvector.glb"
|
||||
}
|
||||
},
|
||||
"clientSidePrimary": "LEVEL_EDIT_SPAWN",
|
||||
|
||||
BIN
assets/Models/items/weapons/shovel1.glb
Normal file
BIN
assets/Models/items/weapons/shovel1.glb
Normal file
Binary file not shown.
@ -17,6 +17,10 @@
|
||||
Add punching/unarmed combat
|
||||
- Weapon raised/lowered component
|
||||
Implement gadgets
|
||||
- Chemistry System
|
||||
- Emitters
|
||||
- Subscribers
|
||||
- Dedicated collision engine on server
|
||||
- Trap
|
||||
- Bear
|
||||
- Freeze
|
||||
|
||||
@ -861,6 +861,8 @@ Items executing script engine hooks on usage
|
||||
Fix server attack tree regressions
|
||||
Editing voxels hook and extensions for voxel palette item
|
||||
Entity spawning palette item actually working via hooks
|
||||
Model fix for shovel, shuffling item models
|
||||
Work on separating procedural tree generation steps
|
||||
|
||||
# TODO
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import electrosphere.entity.state.attach.AttachUtils;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.entity.types.tree.ProceduralTree;
|
||||
import electrosphere.game.data.common.CommonEntityType;
|
||||
import electrosphere.game.data.foliage.type.ProceduralTreeBranchModel;
|
||||
import electrosphere.game.data.foliage.type.TreeModel;
|
||||
import electrosphere.game.data.graphics.ProceduralModel;
|
||||
import electrosphere.renderer.actor.instance.InstancedActor;
|
||||
@ -63,59 +64,62 @@ public class ImGuiEntityInstancedActorTab {
|
||||
TreeModel treeModel = proceduralModel.getTreeModel();
|
||||
|
||||
|
||||
maximumTrunkSegments[0] = treeModel.getMaximumTrunkSegments();
|
||||
if(ImGui.sliderInt("maximumTrunkSegments", maximumTrunkSegments, 1, 8)){
|
||||
treeModel.setMaximumTrunkSegments(maximumTrunkSegments[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
if(ImGui.collapsingHeader("Trunk")){
|
||||
maximumTrunkSegments[0] = treeModel.getTrunkModel().getMaximumTrunkSegments();
|
||||
if(ImGui.sliderInt("maximumTrunkSegments", maximumTrunkSegments, 1, 8)){
|
||||
treeModel.getTrunkModel().setMaximumTrunkSegments(maximumTrunkSegments[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(ImGui.collapsingHeader("Branches")){
|
||||
limbScalarFalloffFactor[0] = treeModel.getLimbScalarFalloffFactor();
|
||||
ProceduralTreeBranchModel branchModel = treeModel.getBranchModel();
|
||||
limbScalarFalloffFactor[0] = branchModel.getLimbScalarFalloffFactor();
|
||||
if(ImGui.sliderFloat("limbScalarFalloffFactor", limbScalarFalloffFactor, 0.01f, 1f)){
|
||||
treeModel.setLimbScalarFalloffFactor(limbScalarFalloffFactor[0]);
|
||||
branchModel.setLimbScalarFalloffFactor(limbScalarFalloffFactor[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
minimumLimbScalar[0] = treeModel.getMinimumLimbScalar();
|
||||
minimumLimbScalar[0] = branchModel.getMinimumLimbScalar();
|
||||
if(ImGui.sliderFloat("minimumLimbScalar", minimumLimbScalar, 0.01f, 1f)){
|
||||
treeModel.setLimbScalarFalloffFactor(minimumLimbScalar[0]);
|
||||
branchModel.setLimbScalarFalloffFactor(minimumLimbScalar[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
maximumLimbDispersion[0] = treeModel.getMaximumLimbDispersion();
|
||||
maximumLimbDispersion[0] = branchModel.getMaximumLimbDispersion();
|
||||
if(ImGui.sliderFloat("maximumLimbDispersion", maximumLimbDispersion, 0.01f, 1f)){
|
||||
treeModel.setMaximumLimbDispersion(maximumLimbDispersion[0]);
|
||||
branchModel.setMaximumLimbDispersion(maximumLimbDispersion[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
minimumLimbDispersion[0] = treeModel.getMinimumLimbDispersion();
|
||||
minimumLimbDispersion[0] = branchModel.getMinimumLimbDispersion();
|
||||
if(ImGui.sliderFloat("minimumLimbDispersion", minimumLimbDispersion, 0.01f, 1f)){
|
||||
treeModel.setMinimumLimbDispersion(minimumLimbDispersion[0]);
|
||||
branchModel.setMinimumLimbDispersion(minimumLimbDispersion[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
minimumNumberForks[0] = treeModel.getMinimumNumberForks();
|
||||
minimumNumberForks[0] = branchModel.getMinimumNumberForks();
|
||||
if(ImGui.sliderInt("minimumNumberForks", minimumNumberForks, 1, 8)){
|
||||
treeModel.setMinimumNumberForks(minimumNumberForks[0]);
|
||||
branchModel.setMinimumNumberForks(minimumNumberForks[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
maximumNumberForks[0] = treeModel.getMaximumNumberForks();
|
||||
maximumNumberForks[0] = branchModel.getMaximumNumberForks();
|
||||
if(ImGui.sliderInt("maximumNumberForks", maximumNumberForks, 1, 8)){
|
||||
treeModel.setMaximumNumberForks(maximumNumberForks[0]);
|
||||
branchModel.setMaximumNumberForks(maximumNumberForks[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
maximumBranchSegments[0] = treeModel.getMaximumBranchSegments();
|
||||
maximumBranchSegments[0] = branchModel.getMaximumBranchSegments();
|
||||
if(ImGui.sliderInt("maximumBranchSegments", maximumBranchSegments, 1, 8)){
|
||||
treeModel.setMaximumBranchSegments(maximumBranchSegments[0]);
|
||||
branchModel.setMaximumBranchSegments(maximumBranchSegments[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
maxBranchSegmentFalloffFactor[0] = treeModel.getMaxBranchSegmentFalloffFactor();
|
||||
maxBranchSegmentFalloffFactor[0] = branchModel.getMaxBranchSegmentFalloffFactor();
|
||||
if(ImGui.sliderFloat("maxBranchSegmentFalloffFactor", maxBranchSegmentFalloffFactor, 0.01f, 1f)){
|
||||
treeModel.setMaxBranchSegmentFalloffFactor(maxBranchSegmentFalloffFactor[0]);
|
||||
branchModel.setMaxBranchSegmentFalloffFactor(maxBranchSegmentFalloffFactor[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
}
|
||||
@ -179,9 +183,11 @@ public class ImGuiEntityInstancedActorTab {
|
||||
|
||||
|
||||
if(ImGui.collapsingHeader("Leaves")){
|
||||
minimumSegmentToSpawnLeaves[0] = treeModel.getMinimumSegmentToSpawnLeaves();
|
||||
ProceduralTreeBranchModel branchModel = treeModel.getBranchModel();
|
||||
|
||||
minimumSegmentToSpawnLeaves[0] = branchModel.getMinimumSegmentToSpawnLeaves();
|
||||
if(ImGui.sliderInt("minimumSegmentToSpawnLeaves", minimumSegmentToSpawnLeaves, 1, 8)){
|
||||
treeModel.setMinimumSegmentToSpawnLeaves(minimumSegmentToSpawnLeaves[0]);
|
||||
branchModel.setMinimumSegmentToSpawnLeaves(minimumSegmentToSpawnLeaves[0]);
|
||||
ImGuiEntityInstancedActorTab.regenerateModel(detailViewEntity,proceduralModel);
|
||||
}
|
||||
|
||||
|
||||
@ -37,32 +37,44 @@ public class ScriptLevelEditorUtils {
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||
CollisionEngine clientCollisionEngine = Globals.clientSceneWrapper.getCollisionEngine(); //using client collision engine so ray doesn't collide with player entity
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||
CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, Globals.selectedSpawntype.getId(), null);
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
||||
if(cursorPos != null){
|
||||
cursorPos = cursorPos.add(cursorVerticalOffset);
|
||||
CreatureUtils.serverSpawnBasicCreature(realm, cursorPos, Globals.selectedSpawntype.getId(), null);
|
||||
}
|
||||
} else if(Globals.selectedSpawntype instanceof Item){
|
||||
LoggerInterface.loggerEngine.INFO("spawn " + Globals.selectedSpawntype.getId() + "!");
|
||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||
CollisionEngine clientCollisionEngine = Globals.clientSceneWrapper.getCollisionEngine(); //using client collision engine so ray doesn't collide with player entity
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||
ItemUtils.serverSpawnBasicItem(realm, cursorPos, Globals.selectedSpawntype.getId());
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
||||
if(cursorPos != null){
|
||||
cursorPos = cursorPos.add(cursorVerticalOffset);
|
||||
ItemUtils.serverSpawnBasicItem(realm, cursorPos, Globals.selectedSpawntype.getId());
|
||||
}
|
||||
} else if(Globals.selectedSpawntype instanceof FoliageType){
|
||||
LoggerInterface.loggerEngine.INFO("spawn " + Globals.selectedSpawntype.getId() + "!");
|
||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||
CollisionEngine clientCollisionEngine = Globals.clientSceneWrapper.getCollisionEngine(); //using client collision engine so ray doesn't collide with player entity
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||
FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, Globals.selectedSpawntype.getId(), new Random().nextLong());
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
||||
if(cursorPos != null){
|
||||
cursorPos = cursorPos.add(cursorVerticalOffset);
|
||||
FoliageUtils.serverSpawnTreeFoliage(realm, cursorPos, Globals.selectedSpawntype.getId(), new Random().nextLong());
|
||||
}
|
||||
} else {
|
||||
LoggerInterface.loggerEngine.INFO("spawn " + Globals.selectedSpawntype.getId() + "!");
|
||||
Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera));
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
|
||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||
CollisionEngine clientCollisionEngine = Globals.clientSceneWrapper.getCollisionEngine(); //using client collision engine so ray doesn't collide with player entity
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset);
|
||||
CommonEntityUtils.serverSpawnBasicObject(realm, cursorPos, Globals.selectedSpawntype.getId());
|
||||
Vector3d cursorPos = clientCollisionEngine.rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0);
|
||||
if(cursorPos != null){
|
||||
cursorPos = cursorPos.add(cursorVerticalOffset);
|
||||
CommonEntityUtils.serverSpawnBasicObject(realm, cursorPos, Globals.selectedSpawntype.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -894,9 +894,9 @@ public class ControlHandler {
|
||||
if(Globals.playerEntity != null && ClientToolbarState.getClientToolbarState(Globals.playerEntity) != null){
|
||||
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
|
||||
if(scrollEvent.getScrollAmount() > 0){
|
||||
clientToolbarState.attemptChangeSelection(clientToolbarState.getSelectedSlot() + 1);
|
||||
} else {
|
||||
clientToolbarState.attemptChangeSelection(clientToolbarState.getSelectedSlot() - 1);
|
||||
} else {
|
||||
clientToolbarState.attemptChangeSelection(clientToolbarState.getSelectedSlot() + 1);
|
||||
}
|
||||
}
|
||||
}});
|
||||
|
||||
@ -30,6 +30,8 @@ import electrosphere.entity.EntityUtils;
|
||||
import electrosphere.entity.btree.BehaviorTree;
|
||||
import electrosphere.entity.state.attach.AttachUtils;
|
||||
import electrosphere.game.data.foliage.type.FoliageType;
|
||||
import electrosphere.game.data.foliage.type.ProceduralTreeBranchModel;
|
||||
import electrosphere.game.data.foliage.type.ProceduralTreeTrunkModel;
|
||||
import electrosphere.game.data.foliage.type.TreeModel;
|
||||
import electrosphere.renderer.actor.instance.InstancedActor;
|
||||
import electrosphere.renderer.buffer.ShaderAttribute;
|
||||
@ -148,57 +150,188 @@ public class ProceduralTree {
|
||||
|
||||
|
||||
//generate branches
|
||||
clientGenerateBranchesAlt(
|
||||
clientGenerateTrunk(
|
||||
treeModel,
|
||||
trunkChild,
|
||||
treeRandom,
|
||||
0,
|
||||
0,
|
||||
new Vector3d(0,0,0),
|
||||
new Quaterniond(0,0,0,1),
|
||||
new Vector3d(0,3,0),
|
||||
new Quaternionf(0,0,0,1),
|
||||
1,
|
||||
1,
|
||||
true
|
||||
new TreeSegment(
|
||||
0,
|
||||
0,
|
||||
new Vector3d(0,0,0),
|
||||
new Quaterniond(0,0,0,1),
|
||||
new Vector3d(0,3,0),
|
||||
new Quaternionf(0,0,0,1),
|
||||
1,
|
||||
1,
|
||||
true,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
ClientEntityUtils.initiallyPositionEntity(trunkChild, EntityUtils.getPosition(trunkChild), EntityUtils.getRotation(trunkChild));
|
||||
}
|
||||
|
||||
private static List<Entity> clientGenerateBranchesAlt(
|
||||
/**
|
||||
* Generates trunk segments
|
||||
* @param type The type of tree
|
||||
* @param parent The parent entity
|
||||
* @param rand The randomizer
|
||||
* @param segment The current segment
|
||||
* @return The entities that were generated
|
||||
*/
|
||||
private static List<Entity> clientGenerateTrunk(
|
||||
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
|
||||
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
|
||||
TreeSegment segment
|
||||
){
|
||||
List<Entity> rVal = new LinkedList<Entity>();
|
||||
|
||||
ProceduralTreeTrunkModel trunkModel = type.getTrunkModel();
|
||||
ProceduralTreeBranchModel branchModel = type.getBranchModel();
|
||||
|
||||
//spawn trunk segments
|
||||
if(
|
||||
trunkModel.getCentralTrunk() &&
|
||||
segment.scalar > trunkModel.getMinimumTrunkScalar() &&
|
||||
segment.currentSegmentNumber < trunkModel.getMaximumTrunkSegments()
|
||||
){
|
||||
//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
|
||||
//get an offset from the current position for the child position
|
||||
//get a rotation from the current rotation for the child rotation
|
||||
|
||||
//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)segment.offsetFromParent.x,
|
||||
(float)segment.offsetFromParent.y,
|
||||
(float)segment.offsetFromParent.z
|
||||
))
|
||||
.rotate(new Quaternionf(
|
||||
(float)segment.rotationFromParent.x,
|
||||
(float)segment.rotationFromParent.y,
|
||||
(float)segment.rotationFromParent.z,
|
||||
(float)segment.rotationFromParent.w
|
||||
));
|
||||
|
||||
//calculate combined transform
|
||||
Matrix4f combinedTransform = new Matrix4f().translate(new Vector3f(
|
||||
(float)segment.parentPosition.x,
|
||||
(float)segment.parentPosition.y,
|
||||
(float)segment.parentPosition.z
|
||||
)).rotate(new Quaternionf(
|
||||
(float)segment.parentRotation.x,
|
||||
(float)segment.parentRotation.y,
|
||||
(float)segment.parentRotation.z,
|
||||
(float)segment.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();
|
||||
|
||||
//the rotation applied to the bone
|
||||
Quaternionf boneRotation = new Quaternionf(0,0,0,1);
|
||||
|
||||
//calculates the bone transform matrix
|
||||
Matrix4f boneTransform = new Matrix4f().identity().rotate(boneRotation);
|
||||
|
||||
//new position transform
|
||||
Matrix4f newPositionTransform = new Matrix4f().rotate(boneRotation).translate(0,type.getBranchHeight(),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 = segment.scalar - trunkModel.getTrunkScalarFalloffFactor();
|
||||
|
||||
//create entity
|
||||
|
||||
Entity trunkSegment = EntityCreationUtils.createClientSpatialEntity();
|
||||
InstancedActor instancedActor = InstancedEntityUtils.makeEntityInstancedWithModelTransform(trunkSegment, branchInstanceTemplate, modelMatrixAttribute);
|
||||
instancedActor.setAttribute(boneMatrixAttribute, boneTransform.scale(newScalar,1,newScalar));
|
||||
instancedActor.setAttribute(baseSizeAttribute, segment.scalar);
|
||||
instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity());
|
||||
|
||||
//set entity stuuff
|
||||
EntityUtils.getPosition(trunkSegment).set(currentPosition);
|
||||
EntityUtils.getScale(trunkSegment).set(1,1,1);
|
||||
EntityUtils.getRotation(trunkSegment).set(currentAbsoluteRotation);
|
||||
// AttachUtils.clientAttachEntityAtCurrentOffset(parent, branch);
|
||||
AttachUtils.clientAttachEntityAtTransform(parent, trunkSegment, transformFromParent);
|
||||
|
||||
rVal.add(trunkSegment);
|
||||
clientGenerateTrunk(
|
||||
type,
|
||||
parent,
|
||||
rand,
|
||||
new TreeSegment(
|
||||
0,
|
||||
0,
|
||||
currentPosition,
|
||||
currentAbsoluteRotation,
|
||||
newPosition,
|
||||
boneRotation,
|
||||
segment.scalar - trunkModel.getTrunkScalarFalloffFactor(),
|
||||
segment.currentSegmentNumber + 1,
|
||||
false, //can't be central trunk
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//spawn branches
|
||||
if(segment.scalar > branchModel.getMinimumLimbScalar() && segment.currentSegmentNumber < branchModel.getMaximumBranchSegments()){
|
||||
clientGenerateBranches(type,parent,rand,segment);
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
private static List<Entity> clientGenerateBranches(
|
||||
TreeModel type,
|
||||
Entity parent,
|
||||
Random rand,
|
||||
TreeSegment segment
|
||||
){
|
||||
List<Entity> rVal = new LinkedList<Entity>();
|
||||
|
||||
ProceduralTreeBranchModel branchModel = type.getBranchModel();
|
||||
//how fast do the branches shrink in size
|
||||
float scalarFalloffFactor = type.getLimbScalarFalloffFactor();
|
||||
float scalarFalloffFactor = branchModel.getLimbScalarFalloffFactor();
|
||||
//the minimum branch size before we stop generating branch segments/trunk segments
|
||||
float minimumScalar = type.getMinimumLimbScalar();
|
||||
float minimumScalar = branchModel.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();
|
||||
float minimumSegmentDispersion = branchModel.getMinimumLimbDispersion();
|
||||
float dispersionSpread = branchModel.getMaximumLimbDispersion() - branchModel.getMinimumLimbDispersion();
|
||||
//the number of branches to make per segment
|
||||
int minBranches = type.getMinimumNumberForks();
|
||||
int maxBranches = type.getMaximumNumberForks();
|
||||
int minBranches = branchModel.getMinimumNumberForks();
|
||||
int maxBranches = branchModel.getMaximumNumberForks();
|
||||
//the maximum number of segments in an single arc for both trunk and branches
|
||||
int maximumTrunkSegments = type.getMaximumTrunkSegments();
|
||||
int maximumBranchSegments = type.getMaximumBranchSegments();
|
||||
int maximumBranchSegments = branchModel.getMaximumBranchSegments();
|
||||
|
||||
if(scalar > minimumScalar && currentSegmentNumber < maximumBranchSegments){
|
||||
int minimumSegmentToSpawnLeaves = type.getMinimumSegmentToSpawnLeaves();
|
||||
if(segment.scalar > minimumScalar && segment.currentSegmentNumber < maximumBranchSegments){
|
||||
int minimumSegmentToSpawnLeaves = branchModel.getMinimumSegmentToSpawnLeaves();
|
||||
|
||||
//how much does it peel off of the current vector
|
||||
double peelRotation = (rand.nextFloat() * dispersionSpread + minimumSegmentDispersion);
|
||||
@ -219,27 +352,27 @@ public class ProceduralTree {
|
||||
//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
|
||||
(float)segment.offsetFromParent.x,
|
||||
(float)segment.offsetFromParent.y,
|
||||
(float)segment.offsetFromParent.z
|
||||
))
|
||||
.rotate(new Quaternionf(
|
||||
(float)rotationFromParent.x,
|
||||
(float)rotationFromParent.y,
|
||||
(float)rotationFromParent.z,
|
||||
(float)rotationFromParent.w
|
||||
(float)segment.rotationFromParent.x,
|
||||
(float)segment.rotationFromParent.y,
|
||||
(float)segment.rotationFromParent.z,
|
||||
(float)segment.rotationFromParent.w
|
||||
));
|
||||
|
||||
//calculate combined transform
|
||||
Matrix4f combinedTransform = new Matrix4f().translate(new Vector3f(
|
||||
(float)parentPosition.x,
|
||||
(float)parentPosition.y,
|
||||
(float)parentPosition.z
|
||||
(float)segment.parentPosition.x,
|
||||
(float)segment.parentPosition.y,
|
||||
(float)segment.parentPosition.z
|
||||
)).rotate(new Quaternionf(
|
||||
(float)parentRotation.x,
|
||||
(float)parentRotation.y,
|
||||
(float)parentRotation.z,
|
||||
(float)parentRotation.w
|
||||
(float)segment.parentRotation.x,
|
||||
(float)segment.parentRotation.y,
|
||||
(float)segment.parentRotation.z,
|
||||
(float)segment.parentRotation.w
|
||||
)).mul(transformFromParent);
|
||||
|
||||
|
||||
@ -291,7 +424,7 @@ public class ProceduralTree {
|
||||
Vector3d newPosition = new Vector3d(newPositionRaw.x,newPositionRaw.y,newPositionRaw.z);
|
||||
|
||||
//get new scalar
|
||||
float newScalar = scalar - scalarFalloffFactor;
|
||||
float newScalar = segment.scalar - scalarFalloffFactor;
|
||||
|
||||
|
||||
|
||||
@ -303,7 +436,7 @@ public class ProceduralTree {
|
||||
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(baseSizeAttribute, segment.scalar);
|
||||
instancedActor.setAttribute(modelMatrixAttribute, new Matrix4f().identity());
|
||||
|
||||
//set entity stuuff
|
||||
@ -321,20 +454,25 @@ public class ProceduralTree {
|
||||
|
||||
//attach leaf blobs
|
||||
if(
|
||||
!isCentralTrunk &&
|
||||
currentSegmentNumber >= minimumSegmentToSpawnLeaves
|
||||
!segment.isTrunk &&
|
||||
segment.currentSegmentNumber >= minimumSegmentToSpawnLeaves
|
||||
){
|
||||
createLeafBlobsOnBranch(
|
||||
type,
|
||||
branch,
|
||||
rand,
|
||||
currentPosition,
|
||||
currentAbsoluteRotation,
|
||||
newPosition,
|
||||
boneRotation,
|
||||
scalar - scalarFalloffFactor,
|
||||
currentSegmentNumber + 1,
|
||||
false //can't be central trunk
|
||||
new TreeSegment(
|
||||
peelRotation,
|
||||
offsetRotation,
|
||||
currentPosition,
|
||||
currentAbsoluteRotation,
|
||||
newPosition,
|
||||
boneRotation,
|
||||
segment.scalar - scalarFalloffFactor,
|
||||
segment.currentSegmentNumber + 1,
|
||||
false, //can't be central trunk
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -342,23 +480,26 @@ public class ProceduralTree {
|
||||
|
||||
|
||||
//recurse
|
||||
List<Entity> childBranches = clientGenerateBranchesAlt(
|
||||
List<Entity> childBranches = clientGenerateBranches(
|
||||
type,
|
||||
branch,
|
||||
rand,
|
||||
peelRotation,
|
||||
offsetRotation,
|
||||
currentPosition,
|
||||
currentAbsoluteRotation,
|
||||
newPosition,
|
||||
boneRotation,
|
||||
scalar - scalarFalloffFactor,
|
||||
currentSegmentNumber + 1,
|
||||
false //can't be central trunk
|
||||
new TreeSegment(
|
||||
peelRotation,
|
||||
offsetRotation,
|
||||
currentPosition,
|
||||
currentAbsoluteRotation,
|
||||
newPosition,
|
||||
boneRotation,
|
||||
segment.scalar - scalarFalloffFactor,
|
||||
segment.currentSegmentNumber + 1,
|
||||
false, //can't be central trunk
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
//add behavior tree to update all child branch attachment points to new point
|
||||
if(childBranches.size() > 0 && scalar >= type.getMinimumScalarToGenerateSwayTree() && scalar <= type.getMaximumScalarToGenerateSwayTree()){
|
||||
if(childBranches.size() > 0 && segment.scalar >= type.getMinimumScalarToGenerateSwayTree() && segment.scalar <= type.getMaximumScalarToGenerateSwayTree()){
|
||||
Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BranchBehaviorTree(
|
||||
type,
|
||||
parent,
|
||||
@ -647,13 +788,14 @@ public class ProceduralTree {
|
||||
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
|
||||
TreeSegment segment
|
||||
// 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();
|
||||
@ -684,7 +826,7 @@ public class ProceduralTree {
|
||||
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);
|
||||
Quaterniond parentLocalRotationFromVertical = new Quaterniond().rotationTo(new Vector3d(0,1,0), segment.offsetFromParent);
|
||||
Vector4d transformedPos = parentLocalRotationFromVertical.transform(new Vector4d(xOffset,positionAlongBranch,zOffset,1));
|
||||
|
||||
//calculate transform from parent entity
|
||||
@ -696,10 +838,10 @@ public class ProceduralTree {
|
||||
(float)transformedPos.z
|
||||
))
|
||||
.rotate(new Quaternionf(
|
||||
(float)rotationFromParent.x,
|
||||
(float)rotationFromParent.y,
|
||||
(float)rotationFromParent.z,
|
||||
(float)rotationFromParent.w
|
||||
(float)segment.rotationFromParent.x,
|
||||
(float)segment.rotationFromParent.y,
|
||||
(float)segment.rotationFromParent.z,
|
||||
(float)segment.rotationFromParent.w
|
||||
));
|
||||
|
||||
|
||||
@ -828,6 +970,46 @@ public class ProceduralTree {
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* A segment in a tree that is being generated
|
||||
*/
|
||||
static class TreeSegment {
|
||||
protected double parentPeel;
|
||||
protected double parentRotationOffset;
|
||||
protected Vector3d parentPosition; // The parent's origin bone's position in space
|
||||
protected Quaterniond parentRotation; // The parent's origin bone's rotation
|
||||
protected Vector3d offsetFromParent; // The offset from the parent's origin bone that this branch's origin bone should be at
|
||||
protected Quaternionf rotationFromParent; // The rotation of the parent's extended bone. Should be equivalent to the origin bone's rotation on this branch
|
||||
protected float scalar; //the current size scalar
|
||||
protected int currentSegmentNumber; //the current segment number
|
||||
protected boolean isTrunk; //true if this is a trunk segment
|
||||
protected boolean isBrandAdapter; //true if this adapts from the trunk to a position on the trunk to branch from
|
||||
|
||||
public TreeSegment(
|
||||
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
|
||||
Quaternionf rotationFromParent, // The rotation of the parent's extended bone. Should be equivalent to the origin bone's rotation on this branch
|
||||
float scalar, //the current size scalar
|
||||
int currentSegmentNumber, //the current segment number
|
||||
boolean isTrunk, //true if this is a trunk segment
|
||||
boolean isBrandAdapter //true if this adapts from the trunk to a position on the trunk to branch from
|
||||
){
|
||||
this.parentPeel = parentPeel;
|
||||
this.parentRotationOffset = parentRotationOffset;
|
||||
this.parentPosition = parentPosition;
|
||||
this.parentRotation = parentRotation;
|
||||
this.offsetFromParent = offsetFromParent;
|
||||
this.rotationFromParent = rotationFromParent;
|
||||
this.scalar = scalar;
|
||||
this.currentSegmentNumber = currentSegmentNumber;
|
||||
this.isTrunk = isTrunk;
|
||||
this.isBrandAdapter = isBrandAdapter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The behavior tree for branches swaying in the wind
|
||||
*/
|
||||
|
||||
@ -0,0 +1,143 @@
|
||||
package electrosphere.game.data.foliage.type;
|
||||
|
||||
/**
|
||||
* Data for creating branches on a procedural tree
|
||||
*/
|
||||
public class ProceduralTreeBranchModel {
|
||||
|
||||
//how quickly do the limbs shrink
|
||||
float limbScalarFalloffFactor;
|
||||
|
||||
//How small are the terminal limbs, basically how small can it get before it stops generating
|
||||
float minimumLimbScalar;
|
||||
|
||||
//The maximum a single branch can disperse from the current line
|
||||
float maximumLimbDispersion;
|
||||
|
||||
//The minimum a single branch must disperse from the current line
|
||||
float minimumLimbDispersion;
|
||||
|
||||
//The minimum number of branch forks per iteration
|
||||
int minimumNumberForks;
|
||||
|
||||
//The maximum number of branch forks per iteration
|
||||
int maximumNumberForks;
|
||||
|
||||
//The maximum number of linear segments for the branch (ie how many times can a function recurse)
|
||||
int maximumBranchSegments;
|
||||
|
||||
//The rate at which number of branch segments from the current trunk falls off over time
|
||||
float maxBranchSegmentFalloffFactor;
|
||||
|
||||
//The minimum segment number required to start spawning leaves
|
||||
int minimumSegmentToSpawnLeaves;
|
||||
|
||||
/**
|
||||
* how quickly do the limbs shrink
|
||||
* @return
|
||||
*/
|
||||
public float getLimbScalarFalloffFactor(){
|
||||
return limbScalarFalloffFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* How small are the terminal limbs
|
||||
* @return
|
||||
*/
|
||||
public float getMinimumLimbScalar(){
|
||||
return minimumLimbScalar;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum a single branch can disperse from the current line
|
||||
* @return
|
||||
*/
|
||||
public float getMaximumLimbDispersion(){
|
||||
return maximumLimbDispersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum a single branch must disperse from the current line
|
||||
* @return
|
||||
*/
|
||||
public float getMinimumLimbDispersion(){
|
||||
return minimumLimbDispersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum number of branch forks per iteration
|
||||
* @return
|
||||
*/
|
||||
public int getMinimumNumberForks(){
|
||||
return minimumNumberForks;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of branch forks per iteration
|
||||
* @return
|
||||
*/
|
||||
public int getMaximumNumberForks(){
|
||||
return maximumNumberForks;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of linear segments for the branch (ie how many times can a function recurse)
|
||||
* @return
|
||||
*/
|
||||
public int getMaximumBranchSegments(){
|
||||
return maximumBranchSegments;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rate at which number of branch segments from the current trunk falls off over time
|
||||
* @return
|
||||
*/
|
||||
public float getMaxBranchSegmentFalloffFactor(){
|
||||
return maxBranchSegmentFalloffFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum segment number required to start spawning leaves
|
||||
* @return
|
||||
*/
|
||||
public int getMinimumSegmentToSpawnLeaves(){
|
||||
return minimumSegmentToSpawnLeaves;
|
||||
}
|
||||
|
||||
public void setLimbScalarFalloffFactor(float limbScalarFalloffFactor) {
|
||||
this.limbScalarFalloffFactor = limbScalarFalloffFactor;
|
||||
}
|
||||
|
||||
public void setMinimumLimbScalar(float minimumLimbScalar) {
|
||||
this.minimumLimbScalar = minimumLimbScalar;
|
||||
}
|
||||
|
||||
public void setMaximumLimbDispersion(float maximumLimbDispersion) {
|
||||
this.maximumLimbDispersion = maximumLimbDispersion;
|
||||
}
|
||||
|
||||
public void setMinimumLimbDispersion(float minimumLimbDispersion) {
|
||||
this.minimumLimbDispersion = minimumLimbDispersion;
|
||||
}
|
||||
|
||||
public void setMinimumNumberForks(int minimumNumberForks) {
|
||||
this.minimumNumberForks = minimumNumberForks;
|
||||
}
|
||||
|
||||
public void setMaximumNumberForks(int maximumNumberForks) {
|
||||
this.maximumNumberForks = maximumNumberForks;
|
||||
}
|
||||
|
||||
public void setMaximumBranchSegments(int maximumBranchSegments) {
|
||||
this.maximumBranchSegments = maximumBranchSegments;
|
||||
}
|
||||
|
||||
public void setMaxBranchSegmentFalloffFactor(float maxBranchSegmentFalloffFactor) {
|
||||
this.maxBranchSegmentFalloffFactor = maxBranchSegmentFalloffFactor;
|
||||
}
|
||||
|
||||
public void setMinimumSegmentToSpawnLeaves(int minimumSegmentToSpawnLeaves) {
|
||||
this.minimumSegmentToSpawnLeaves = minimumSegmentToSpawnLeaves;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
package electrosphere.game.data.foliage.type;
|
||||
|
||||
/**
|
||||
* The data model for the trunk of the procedural tree
|
||||
*/
|
||||
public class ProceduralTreeTrunkModel {
|
||||
|
||||
//how quickly does the trunk shrink
|
||||
float trunkScalarFalloffFactor;
|
||||
|
||||
//How small are the trunk segments, basically how small can it get before it stops generating
|
||||
float minimumTrunkScalar;
|
||||
|
||||
//The minimum number of branch forks per iteration
|
||||
int minimumBranches;
|
||||
|
||||
//The maximum number of branch forks per iteration
|
||||
int maximumBranches;
|
||||
|
||||
//if true, always generates a central trunk
|
||||
boolean centralTrunk;
|
||||
|
||||
//The maximum number of linear segments for the trunk (ie how many times can a function recurse)
|
||||
int maximumTrunkSegments;
|
||||
|
||||
//The branch count to stop generating physics for each branch
|
||||
int physicsCutoff;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the scalar falloff factor (how fast does the trunk shrink)
|
||||
* @return The scalar falloff factor
|
||||
*/
|
||||
public float getTrunkScalarFalloffFactor(){
|
||||
return trunkScalarFalloffFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum scalar for a trunk segment
|
||||
* @return The minimum scalar
|
||||
*/
|
||||
public float getMinimumTrunkScalar(){
|
||||
return minimumTrunkScalar;
|
||||
}
|
||||
|
||||
/**
|
||||
* if true, always generates a central trunk
|
||||
* @return
|
||||
*/
|
||||
public boolean getCentralTrunk(){
|
||||
return centralTrunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of linear segments for the trunk (ie how many times can a function recurse)
|
||||
* @return
|
||||
*/
|
||||
public int getMaximumTrunkSegments(){
|
||||
return maximumTrunkSegments;
|
||||
}
|
||||
|
||||
/**
|
||||
* The branch count to stop generating physics for each branch
|
||||
* @return
|
||||
*/
|
||||
public int getPhysicsCutoff(){
|
||||
return this.physicsCutoff;
|
||||
}
|
||||
|
||||
public void setCentralTrunk(boolean centralTrunk) {
|
||||
this.centralTrunk = centralTrunk;
|
||||
}
|
||||
|
||||
public void setMaximumTrunkSegments(int maximumTrunkSegments) {
|
||||
this.maximumTrunkSegments = maximumTrunkSegments;
|
||||
}
|
||||
|
||||
public void setPhysicsCutoff(int physicsCutoff) {
|
||||
this.physicsCutoff = physicsCutoff;
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,42 +6,12 @@ import electrosphere.game.data.collidable.CollidableTemplate;
|
||||
* Describes characteristics about a type of tree (how do the limbs dispere, where to the leaves start growing, how sturdy is it, etc)
|
||||
*/
|
||||
public class TreeModel {
|
||||
|
||||
//how quickly do the limbs shrink
|
||||
float limbScalarFalloffFactor;
|
||||
|
||||
//How small are the terminal limbs, basically how small can it get before it stops generating
|
||||
float minimumLimbScalar;
|
||||
|
||||
//The maximum a single branch can disperse from the current line
|
||||
float maximumLimbDispersion;
|
||||
//trunk data
|
||||
ProceduralTreeTrunkModel trunkModel;
|
||||
|
||||
//The minimum a single branch must disperse from the current line
|
||||
float minimumLimbDispersion;
|
||||
|
||||
//The minimum number of branch forks per iteration
|
||||
int minimumNumberForks;
|
||||
|
||||
//The maximum number of branch forks per iteration
|
||||
int maximumNumberForks;
|
||||
|
||||
//The height of a single branch, should be the height of the model
|
||||
float branchHeight;
|
||||
|
||||
//if true, always generates a central trunk
|
||||
boolean centralTrunk;
|
||||
|
||||
//The maximum number of linear segments for the trunk (ie how many times can a function recurse)
|
||||
int maximumTrunkSegments;
|
||||
|
||||
//The maximum number of linear segments for the branch (ie how many times can a function recurse)
|
||||
int maximumBranchSegments;
|
||||
|
||||
//The rate at which number of branch segments from the current trunk falls off over time
|
||||
float maxBranchSegmentFalloffFactor;
|
||||
|
||||
//The minimum segment number required to start spawning leaves
|
||||
int minimumSegmentToSpawnLeaves;
|
||||
//branch data
|
||||
ProceduralTreeBranchModel branchModel;
|
||||
|
||||
//the minimum distance along a given segment to start spawning leaves at
|
||||
float minBranchHeightToStartSpawningLeaves;
|
||||
@ -61,9 +31,6 @@ 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;
|
||||
|
||||
@ -105,100 +72,23 @@ public class TreeModel {
|
||||
//the model for a leaf blob
|
||||
String leafModelPath;
|
||||
|
||||
//The height of a single branch, should be the height of the model
|
||||
float branchHeight;
|
||||
|
||||
/**
|
||||
* how quickly do the limbs shrink
|
||||
* @return
|
||||
* Gets the data model for the trunk
|
||||
* @return The data model for the trunk
|
||||
*/
|
||||
public float getLimbScalarFalloffFactor(){
|
||||
return limbScalarFalloffFactor;
|
||||
public ProceduralTreeTrunkModel getTrunkModel(){
|
||||
return trunkModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* How small are the terminal limbs
|
||||
* @return
|
||||
* Gets the data model for branches
|
||||
* @return The data model for branches
|
||||
*/
|
||||
public float getMinimumLimbScalar(){
|
||||
return minimumLimbScalar;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum a single branch can disperse from the current line
|
||||
* @return
|
||||
*/
|
||||
public float getMaximumLimbDispersion(){
|
||||
return maximumLimbDispersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum a single branch must disperse from the current line
|
||||
* @return
|
||||
*/
|
||||
public float getMinimumLimbDispersion(){
|
||||
return minimumLimbDispersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum number of branch forks per iteration
|
||||
* @return
|
||||
*/
|
||||
public int getMinimumNumberForks(){
|
||||
return minimumNumberForks;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of branch forks per iteration
|
||||
* @return
|
||||
*/
|
||||
public int getMaximumNumberForks(){
|
||||
return maximumNumberForks;
|
||||
}
|
||||
|
||||
/**
|
||||
* The height of a single branch, should be the height of the model
|
||||
* @return
|
||||
*/
|
||||
public float getBranchHeight(){
|
||||
return branchHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* if true, always generates a central trunk
|
||||
* @return
|
||||
*/
|
||||
public boolean getCentralTrunk(){
|
||||
return centralTrunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of linear segments for the trunk (ie how many times can a function recurse)
|
||||
* @return
|
||||
*/
|
||||
public int getMaximumTrunkSegments(){
|
||||
return maximumTrunkSegments;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum number of linear segments for the branch (ie how many times can a function recurse)
|
||||
* @return
|
||||
*/
|
||||
public int getMaximumBranchSegments(){
|
||||
return maximumBranchSegments;
|
||||
}
|
||||
|
||||
/**
|
||||
* The rate at which number of branch segments from the current trunk falls off over time
|
||||
* @return
|
||||
*/
|
||||
public float getMaxBranchSegmentFalloffFactor(){
|
||||
return maxBranchSegmentFalloffFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum segment number required to start spawning leaves
|
||||
* @return
|
||||
*/
|
||||
public int getMinimumSegmentToSpawnLeaves(){
|
||||
return minimumSegmentToSpawnLeaves;
|
||||
public ProceduralTreeBranchModel getBranchModel(){
|
||||
return branchModel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,15 +211,6 @@ public class TreeModel {
|
||||
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
|
||||
@ -354,52 +235,12 @@ public class TreeModel {
|
||||
return leafModelPath;
|
||||
}
|
||||
|
||||
public void setLimbScalarFalloffFactor(float limbScalarFalloffFactor) {
|
||||
this.limbScalarFalloffFactor = limbScalarFalloffFactor;
|
||||
}
|
||||
|
||||
public void setMinimumLimbScalar(float minimumLimbScalar) {
|
||||
this.minimumLimbScalar = minimumLimbScalar;
|
||||
}
|
||||
|
||||
public void setMaximumLimbDispersion(float maximumLimbDispersion) {
|
||||
this.maximumLimbDispersion = maximumLimbDispersion;
|
||||
}
|
||||
|
||||
public void setMinimumLimbDispersion(float minimumLimbDispersion) {
|
||||
this.minimumLimbDispersion = minimumLimbDispersion;
|
||||
}
|
||||
|
||||
public void setMinimumNumberForks(int minimumNumberForks) {
|
||||
this.minimumNumberForks = minimumNumberForks;
|
||||
}
|
||||
|
||||
public void setMaximumNumberForks(int maximumNumberForks) {
|
||||
this.maximumNumberForks = maximumNumberForks;
|
||||
}
|
||||
|
||||
public void setBranchHeight(float branchHeight) {
|
||||
this.branchHeight = branchHeight;
|
||||
}
|
||||
|
||||
public void setCentralTrunk(boolean centralTrunk) {
|
||||
this.centralTrunk = centralTrunk;
|
||||
}
|
||||
|
||||
public void setMaximumTrunkSegments(int maximumTrunkSegments) {
|
||||
this.maximumTrunkSegments = maximumTrunkSegments;
|
||||
}
|
||||
|
||||
public void setMaximumBranchSegments(int maximumBranchSegments) {
|
||||
this.maximumBranchSegments = maximumBranchSegments;
|
||||
}
|
||||
|
||||
public void setMaxBranchSegmentFalloffFactor(float maxBranchSegmentFalloffFactor) {
|
||||
this.maxBranchSegmentFalloffFactor = maxBranchSegmentFalloffFactor;
|
||||
}
|
||||
|
||||
public void setMinimumSegmentToSpawnLeaves(int minimumSegmentToSpawnLeaves) {
|
||||
this.minimumSegmentToSpawnLeaves = minimumSegmentToSpawnLeaves;
|
||||
/**
|
||||
* The height of a single branch, should be the height of the model
|
||||
* @return
|
||||
*/
|
||||
public float getBranchHeight(){
|
||||
return branchHeight;
|
||||
}
|
||||
|
||||
public void setMinBranchHeightToStartSpawningLeaves(float minBranchHeightToStartSpawningLeaves) {
|
||||
@ -426,10 +267,6 @@ public class TreeModel {
|
||||
this.leafDistanceFromCenter = leafDistanceFromCenter;
|
||||
}
|
||||
|
||||
public void setPhysicsCutoff(int physicsCutoff) {
|
||||
this.physicsCutoff = physicsCutoff;
|
||||
}
|
||||
|
||||
public void setPhysicsBody(CollidableTemplate physicsBody) {
|
||||
this.physicsBody = physicsBody;
|
||||
}
|
||||
@ -478,6 +315,10 @@ public class TreeModel {
|
||||
this.leafModelPath = leafModelPath;
|
||||
}
|
||||
|
||||
public void setBranchHeight(float branchHeight) {
|
||||
this.branchHeight = branchHeight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user