foliage fix, first person view model, other fixes
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-05-24 22:52:42 -04:00
parent bd244b151d
commit 29f5496e23
42 changed files with 1076 additions and 164 deletions

View File

@ -134,16 +134,25 @@
"length" : 1, "length" : 1,
"loops" : false "loops" : false
}, },
"animationFirstPersonStartup" : {
"name" : "Jog"
},
"animationLoop" : { "animationLoop" : {
"name" : "Jog", "name" : "Jog",
"length" : 1, "length" : 1,
"loops" : false "loops" : false
}, },
"animationFirstPersonLoop" : {
"name" : "Jog"
},
"animationWindDown" : { "animationWindDown" : {
"name" : "Jog", "name" : "Jog",
"length" : 1, "length" : 1,
"loops" : false "loops" : false
}, },
"animationFirstPersonWindDown" : {
"name" : "Jog"
},
"sprintSystem" : { "sprintSystem" : {
"maxVelocity" : 0.058, "maxVelocity" : 0.058,
"staminaMax" : 500, "staminaMax" : 500,
@ -167,6 +176,9 @@
"name" : "Jump", "name" : "Jump",
"length" : 1, "length" : 1,
"loops" : false "loops" : false
},
"animationFirstPersonJump" : {
"name" : "Jump"
} }
}, },
{ {
@ -176,10 +188,16 @@
"length" : 1, "length" : 1,
"loops" : true "loops" : true
}, },
"animationFirstPersonFall" : {
"name" : "Fall"
},
"animationLand" : { "animationLand" : {
"name" : "Land", "name" : "Land",
"length" : 1, "length" : 1,
"loops" : true "loops" : true
},
"animationFirstPersonLand" : {
"name" : "Land"
} }
} }
], ],
@ -224,6 +242,7 @@
{ {
"equipPointId" : "handLeft", "equipPointId" : "handLeft",
"bone" : "MiddleLower.L", "bone" : "MiddleLower.L",
"firstPersonBone" : "hand.L",
"offsetVector" : [], "offsetVector" : [],
"offsetRotation" : [], "offsetRotation" : [],
"equipClassWhitelist" : [ "equipClassWhitelist" : [
@ -235,6 +254,7 @@
{ {
"equipPointId" : "handRight", "equipPointId" : "handRight",
"bone" : "MiddleLower.R", "bone" : "MiddleLower.R",
"firstPersonBone" : "hand.R",
"offsetVector" : [], "offsetVector" : [],
"offsetRotation" : [0.3057,0.2926,0.09933,0.9006], "offsetRotation" : [0.3057,0.2926,0.09933,0.9006],
"equipClassWhitelist" : [ "equipClassWhitelist" : [
@ -294,7 +314,16 @@
"driftGoal" : 0.02, "driftGoal" : 0.02,
"driftFrameStart" : 7, "driftFrameStart" : 7,
"driftFrameEnd" : 15, "driftFrameEnd" : 15,
"initialMove" : true "initialMove" : true,
"animationFirstPersonWindup" : {
"name" : "Jump"
},
"animationFirstPersonHold" : {
"name" : "Jump"
},
"animationFirstPersonAttack" : {
"name" : "Jump"
}
}, },
{ {
"attackMoveId" : "Sword1HSlash2", "attackMoveId" : "Sword1HSlash2",
@ -310,7 +339,16 @@
"driftGoal" : 0.03, "driftGoal" : 0.03,
"driftFrameStart" : 1, "driftFrameStart" : 1,
"driftFrameEnd" : 10, "driftFrameEnd" : 10,
"initialMove" : false "initialMove" : false,
"animationFirstPersonWindup" : {
"name" : "Jump"
},
"animationFirstPersonHold" : {
"name" : "Jump"
},
"animationFirstPersonAttack" : {
"name" : "Jump"
}
}, },
{ {
"attackMoveId" : "Bow2HFire", "attackMoveId" : "Bow2HFire",
@ -327,14 +365,33 @@
"movementStart" : 0, "movementStart" : 0,
"movementEnd" : 0, "movementEnd" : 0,
"movementGoal" : 0, "movementGoal" : 0,
"initialMove" : true "initialMove" : true,
"animationFirstPersonWindup" : {
"name" : "Jump"
},
"animationFirstPersonHold" : {
"name" : "Jump"
},
"animationFirstPersonAttack" : {
"name" : "Jump"
}
} }
], ],
"healthSystem" : { "healthSystem" : {
"maxHealth" : 100, "maxHealth" : 100,
"onDamageIFrames" : 30 "onDamageIFrames" : 30
}, },
"modelPath" : "Models/creatures/person2/person2_1.glb" "idleData": {
"idleAnimation" : "Idle1",
"firstPersonIdleAnimation" : "Idle"
},
"modelPath" : "Models/creatures/person2/person2_1.glb",
"viewModelData" : {
"heightFromOrigin" : 0.8,
"cameraViewDirOffsetY" : -0.3,
"cameraViewDirOffsetZ" : 0.0,
"firstPersonModelPath" : "Models/creatures/viewmodel.glb"
}
} }
], ],
"files" : [] "files" : []

Binary file not shown.

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file #maven.buildNumber.plugin properties file
#Thu May 02 18:40:02 EDT 2024 #Sun May 19 19:34:37 EDT 2024
buildNumber=119 buildNumber=132

View File

@ -273,23 +273,46 @@ Ground Texture Atlas system
First Person Camera First Person Camera
# TODO (05/15/2024)
More consistent terrain editing
(05/16/2024)
Reintroduce strafing
(05/??/2024)
First person render pipeline First person render pipeline
- Dedicated client scene
- Properly compositing onto main texture - Properly compositing onto main texture
- Potentially look at storing the framebuffer for the pipeline in the pipeline class itself - Potentially look at storing the framebuffer for the pipeline in the pipeline class itself
Overhaul of 'attach' semantics (05/19/2024)
- Having different types of attach tree propagation
- Ability to turn on/off combinations of models at will (already exists, but needs review)
Character movement in particular feels off Character movement in particular feels off
- Bring back strafing - Bring back strafing
- Fix interaction with networking - Fix interaction with networking
- Potentially facing vector on server misaligned with client facing vector? - Nope! They're perfectly aligned - Potentially facing vector on server misaligned with client facing vector? - Nope! They're perfectly aligned
- May be in the ground move tree itself the hard setting velocity instead of applying a force is causing weirdness - May be in the ground move tree itself the hard setting velocity instead of applying a force is causing weirdness
(05/23/2024)
Viewmodel
- Fix hands placement
- Animations defined in data file
(05/24/2024)
Viewmodel
- Add animations queues in btrees
- idle
- jump
- ground movement
- land
- fall
- attack
Attaching items to hands in first person
Fix grass placement
# TODO
Fix being able to walk off far side of the world (ie in level editor) Fix being able to walk off far side of the world (ie in level editor)
Grass System properly LOD Grass System properly LOD
@ -308,6 +331,13 @@ Data Cleanup
Clean up Material class Clean up Material class
- fix storing textures in the mat class ( pain :c ) - fix storing textures in the mat class ( pain :c )
Clean up framebuffer class
- Comment everything
Overhaul of 'attach' semantics
- Having different types of attach tree propagation
- Ability to turn on/off combinations of models at will (already exists, but needs review)
More Debug menus More Debug menus
- Screen that shows the overall status of draw cell manager - Screen that shows the overall status of draw cell manager
- Screen that shows the overall status of fluid cell manager - Screen that shows the overall status of fluid cell manager

View File

@ -1,7 +1,6 @@
package electrosphere.client.foliagemanager; package electrosphere.client.foliagemanager;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -18,7 +17,6 @@ import org.joml.Vector3d;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.system.MemoryUtil;
import electrosphere.client.terrain.cache.ChunkData; import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
@ -395,17 +393,20 @@ public class ClientFoliageManager {
//get position to place //get position to place
double rand1 = placementRandomizer.nextDouble(); double rand1 = placementRandomizer.nextDouble();
double rand2 = placementRandomizer.nextDouble(); double rand2 = placementRandomizer.nextDouble();
double relativePositionOnGridX = x / (1.0 * TARGET_FOLIAGE_SPACING) - 0.5 + rand1 / TARGET_FOLIAGE_SPACING; double relativePositionOnGridX = x / (1.0 * TARGET_FOLIAGE_SPACING) + rand1 / TARGET_FOLIAGE_SPACING;
double relativePositionOnGridZ = z / (1.0 * TARGET_FOLIAGE_SPACING) - 0.5 + rand2 / TARGET_FOLIAGE_SPACING; double relativePositionOnGridZ = z / (1.0 * TARGET_FOLIAGE_SPACING) + rand2 / TARGET_FOLIAGE_SPACING;
double offsetX = relativePositionOnGridX; double offsetX = relativePositionOnGridX - 0.5;
double offsetZ = relativePositionOnGridZ; double offsetZ = relativePositionOnGridZ - 0.5;
//determine quadrant we're placing in //determine quadrant we're placing in
double offsetY = 0; double offsetY = 0;
boolean addBlade = false; boolean addBlade = false;
if(relativePositionOnGridX >=0){ if(relativePositionOnGridX >=0.5){
if(relativePositionOnGridZ >= 0){ if(relativePositionOnGridZ >= 0.5){
relativePositionOnGridX += 0.5; relativePositionOnGridX = relativePositionOnGridX - 0.5;
relativePositionOnGridZ += 0.5; relativePositionOnGridZ = relativePositionOnGridZ - 0.5;
relativePositionOnGridX /= 0.5;
relativePositionOnGridZ /= 0.5;
// System.out.println(relativePositionOnGridX + " " + relativePositionOnGridZ);
//if we have heights for all four surrounding spots, interpolate for y value //if we have heights for all four surrounding spots, interpolate for y value
if(sample_11 != null && sample_12 != null && sample_21 != null && sample_22 != null){ if(sample_11 != null && sample_12 != null && sample_21 != null && sample_22 != null){
offsetY = offsetY =
@ -416,8 +417,9 @@ public class ClientFoliageManager {
addBlade = true; addBlade = true;
} }
} else { } else {
relativePositionOnGridX += 0.5; relativePositionOnGridX = relativePositionOnGridX - 0.5;
relativePositionOnGridZ += 0.5; relativePositionOnGridX /= 0.5;
relativePositionOnGridZ /= 0.5;
//if we have heights for all four surrounding spots, interpolate for y value //if we have heights for all four surrounding spots, interpolate for y value
if(sample_10 != null && sample_11 != null && sample_20 != null && sample_21 != null){ if(sample_10 != null && sample_11 != null && sample_20 != null && sample_21 != null){
offsetY = offsetY =
@ -429,9 +431,10 @@ public class ClientFoliageManager {
} }
} }
} else { } else {
if(relativePositionOnGridZ >= 0){ if(relativePositionOnGridZ >= 0.5){
relativePositionOnGridX += 0.5; relativePositionOnGridZ = relativePositionOnGridZ - 0.5;
relativePositionOnGridZ += 0.5; relativePositionOnGridX /= 0.5;
relativePositionOnGridZ /= 0.5;
//if we have heights for all four surrounding spots, interpolate for y value //if we have heights for all four surrounding spots, interpolate for y value
if(sample_01 != null && sample_02 != null && sample_11 != null && sample_12 != null){ if(sample_01 != null && sample_02 != null && sample_11 != null && sample_12 != null){
offsetY = offsetY =
@ -442,8 +445,8 @@ public class ClientFoliageManager {
addBlade = true; addBlade = true;
} }
} else { } else {
relativePositionOnGridX += 0.5; relativePositionOnGridX /= 0.5;
relativePositionOnGridZ += 0.5; relativePositionOnGridZ /= 0.5;
//if we have heights for all four surrounding spots, interpolate for y value //if we have heights for all four surrounding spots, interpolate for y value
if(sample_00 != null && sample_01 != null && sample_10 != null && sample_11 != null){ if(sample_00 != null && sample_01 != null && sample_10 != null && sample_11 != null){
offsetY = offsetY =

View File

@ -475,14 +475,14 @@ public class ControlHandler {
if(movementTree instanceof ClientGroundMovementTree){ if(movementTree instanceof ClientGroundMovementTree){
ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT).isState()){ if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT).isState()){
Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(Math.PI/4.0).normalize(); Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(Math.PI/4.0).normalize();
CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector);
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.FORWARD_LEFT);
} else if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT).isState()){ } else if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT).isState()){
Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(-Math.PI/4.0).normalize(); Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(-Math.PI/4.0).normalize();
CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector);
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.FORWARD_RIGHT);
} else { } else {
Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize(); Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize();
CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector);
@ -497,14 +497,14 @@ public class ControlHandler {
if(movementTree instanceof ClientGroundMovementTree){ if(movementTree instanceof ClientGroundMovementTree){
ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT).isState()){ if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT).isState()){
Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(Math.PI/4.0).normalize(); Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(Math.PI/4.0).normalize();
CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector);
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.FORWARD_LEFT);
} else if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT).isState()){ } else if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT).isState()){
Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(-Math.PI/4.0).normalize(); Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(-Math.PI/4.0).normalize();
CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector);
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.FORWARD_RIGHT);
} else { } else {
Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize(); Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize();
CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector);
@ -532,15 +532,15 @@ public class ControlHandler {
if(movementTree instanceof ClientGroundMovementTree){ if(movementTree instanceof ClientGroundMovementTree){
ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT).isState()){ if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT).isState()){
CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(3.0/4.0*Math.PI).normalize()); CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(3.0/4.0*Math.PI).normalize());
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.BACKWARD_LEFT);
} else if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT).isState()){ } else if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT).isState()){
CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(5.0/4.0*Math.PI).normalize()); CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(5.0/4.0*Math.PI).normalize());
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.BACKWARD_RIGHT);
} else { } else {
CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(Math.PI).normalize()); CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize());
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.BACKWARD);
} }
} }
} }
@ -551,15 +551,15 @@ public class ControlHandler {
if(movementTree instanceof ClientGroundMovementTree){ if(movementTree instanceof ClientGroundMovementTree){
ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree;
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT).isState()){ if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_LEFT).isState()){
CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(3.0/4.0*Math.PI).normalize()); CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(3.0/4.0*Math.PI).normalize());
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.BACKWARD_LEFT);
} else if(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT).isState()){ } else if(controls.get(DATA_STRING_INPUT_CODE_STRAFE_RIGHT).isState()){
CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(5.0/4.0*Math.PI).normalize()); CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(5.0/4.0*Math.PI).normalize());
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.BACKWARD_RIGHT);
} else { } else {
CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(Math.PI).normalize()); CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize());
groundTree.start(MovementRelativeFacing.FORWARD); groundTree.start(MovementRelativeFacing.BACKWARD);
} }
} }
} }

View File

@ -369,6 +369,8 @@ public class Globals {
//the creature the player camera will orbit and will receive controlHandler movementTree updates //the creature the player camera will orbit and will receive controlHandler movementTree updates
public static Entity playerEntity; public static Entity playerEntity;
//the entity for the first person modal (view model)
public static Entity firstPersonEntity;
//client current selected voxel type //client current selected voxel type
public static VoxelType clientSelectedVoxelType = null; public static VoxelType clientSelectedVoxelType = null;

View File

@ -182,7 +182,7 @@ public class ClientLoading {
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(1,0,1), new Vector3f(0,0,1)); Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(1,0,1), new Vector3f(0,0,1));
} }
/* /*
Targeting crosshair Targeting crosshair

View File

@ -70,6 +70,7 @@ public class EntityDataStrings {
public static final String SERVER_JUMP_TREE = "serverJumpTree"; public static final String SERVER_JUMP_TREE = "serverJumpTree";
public static final String FALL_TREE = "fallTree"; public static final String FALL_TREE = "fallTree";
public static final String CREATURE_TEMPLATE = "creatureTemplate"; public static final String CREATURE_TEMPLATE = "creatureTemplate";
public static final String FIRST_PERSON_TREE = "firstPersonTree";
/* /*

View File

@ -11,6 +11,7 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
@ -48,6 +49,9 @@ import org.joml.Vector3f;
public class ClientAttackTree implements BehaviorTree { public class ClientAttackTree implements BehaviorTree {
@SynchronizableEnum @SynchronizableEnum
/**
* States available to the attack tree
*/
public static enum AttackTreeState { public static enum AttackTreeState {
WINDUP, WINDUP,
HOLD, HOLD,
@ -56,29 +60,39 @@ public class ClientAttackTree implements BehaviorTree {
IDLE, IDLE,
} }
//the state of drifting forward during the attack
@SynchronizableEnum @SynchronizableEnum
/**
* The state of drifting forward during the attack
*/
public static enum AttackTreeDriftState { public static enum AttackTreeDriftState {
DRIFT, DRIFT,
NO_DRIFT, NO_DRIFT,
} }
//the current state of the tree
@SyncedField @SyncedField
AttackTreeState state; AttackTreeState state;
//the current state of drifting caused by the tree
@SyncedField @SyncedField
AttackTreeDriftState driftState; AttackTreeDriftState driftState;
//the parent entity of this attack tree
Entity parent; Entity parent;
//the queue of network messages to process
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>(); CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
//the last time this tree was updated by server
long lastUpdateTime = 0; long lastUpdateTime = 0;
//the current frame of the current animation/move
float frameCurrent; float frameCurrent;
//the name of the current animation
String animationName = "SwingWeapon"; String animationName = "SwingWeapon";
//the max frame
int maxFrame = 60; int maxFrame = 60;
List<AttackMove> currentMoveset = null; List<AttackMove> currentMoveset = null;
@ -239,13 +253,14 @@ public class ClientAttackTree implements BehaviorTree {
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){ if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
RotatorTree.getClientRotatorTree(parent).setActive(true); RotatorTree.getClientRotatorTree(parent).setActive(true);
} }
if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationName)){
entityActor.playAnimation(animationName,1);
entityActor.incrementAnimationTime(0.0001);
}
}
if(currentMove != null && frameCurrent > currentMove.getWindupFrames()){ if(currentMove != null && frameCurrent > currentMove.getWindupFrames()){
if(entityActor != null){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getWindupAnimationName())){
entityActor.playAnimation(currentMove.getWindupAnimationName(),1);
entityActor.incrementAnimationTime(0.0001);
}
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getName());
}
if(currentMoveCanHold && stillHold){ if(currentMoveCanHold && stillHold){
state = AttackTreeState.HOLD; state = AttackTreeState.HOLD;
} else { } else {
@ -259,6 +274,7 @@ public class ClientAttackTree implements BehaviorTree {
entityActor.playAnimation(animationName,1); entityActor.playAnimation(animationName,1);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
} }
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getName());
} }
if(!stillHold){ if(!stillHold){
state = AttackTreeState.ATTACK; state = AttackTreeState.ATTACK;

View File

@ -1,4 +1,4 @@
package electrosphere.entity.state.ambientaudio; package electrosphere.entity.state.client.ambientaudio;
import org.joml.Vector3d; import org.joml.Vector3d;

View File

@ -0,0 +1,123 @@
package electrosphere.entity.state.client.firstPerson;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.renderer.actor.Actor;
/**
* Manages the animations for the first person view model
*/
public class FirstPersonTree implements BehaviorTree {
//the offset from the origin to place the viewmodel
double heightFromOrigin;
//the amount to pull below the camera
double cameraViewDirOffsetY;
//the amount to pull behind the camera
double cameraViewDirOffsetZ;
//the animation to play currently
String currentAnimation = "Idle";
@Override
public void simulate(float deltaTime) {
if(Globals.firstPersonEntity != null){
Actor actor = EntityUtils.getActor(Globals.firstPersonEntity);
if(
(!actor.isPlayingAnimation() || !actor.isPlayingAnimation(currentAnimation)) &&
(Globals.assetManager.fetchModel(actor.getModelPath()) != null && Globals.assetManager.fetchModel(actor.getModelPath()).getAnimation(currentAnimation) != null)
){
actor.playAnimation(currentAnimation,3);
actor.incrementAnimationTime(0.0001);
}
}
}
/**
* Attaches this tree to the entity.
* @param entity The entity to attach to
* @param heightFromOrigin How far from the origin of the creature to place the viewmodel
* @param cameraViewDirOffset How far to pull the view model behind the camera
*/
public static FirstPersonTree attachTree(Entity parent, double heightFromOrigin, double cameraViewDirOffsetY, double cameraViewDirOffsetZ){
FirstPersonTree rVal = new FirstPersonTree();
rVal.heightFromOrigin = heightFromOrigin;
rVal.cameraViewDirOffsetY = cameraViewDirOffsetY;
rVal.cameraViewDirOffsetZ = cameraViewDirOffsetZ;
//!!WARNING!! THIS WAS MANUALLY MODIFIED OH GOD
parent.putData(EntityDataStrings.FIRST_PERSON_TREE, rVal);
Globals.clientScene.registerBehaviorTree(rVal);
return rVal;
}
/**
* Gets the tree on the entity
* @param target the entity
* @return The tree
*/
public static FirstPersonTree getTree(Entity target){
return (FirstPersonTree)target.getData(EntityDataStrings.FIRST_PERSON_TREE);
}
/**
* Checks if the provided entity has the tree
* @param target the provided entity
* @return true if the entity has a FirstPersonTree, false otherwise
*/
public static boolean hasTree(Entity target){
return target.containsKey(EntityDataStrings.FIRST_PERSON_TREE);
}
/**
* the offset from the origin to place the viewmodel
* @return
*/
public double getHeightFromOrigin(){
return heightFromOrigin;
}
/**
* the amount to pull below the camera
* @return
*/
public double getCameraViewDirOffsetY(){
return cameraViewDirOffsetY;
}
/**
* the amount to pull behind the camera
* @return
*/
public double getCameraViewDirOffsetZ(){
return cameraViewDirOffsetZ;
}
/**
* Plays an animation if it exists
* @param animationName the name of the animation
*/
public void playAnimation(String animationName){
this.currentAnimation = animationName;
}
/**
* If the entity has a first person tree, plays the provided animation
* @param entity The entity
* @param animationName the name of the animation
*/
public static void conditionallyPlayAnimation(Entity entity, String animationName){
if(hasTree(entity)){
getTree(entity).playAnimation(animationName);
}
}
}

View File

@ -34,11 +34,20 @@ import electrosphere.renderer.actor.ActorMeshMask;
*/ */
public class ClientEquipState implements BehaviorTree { public class ClientEquipState implements BehaviorTree {
//the parent entity of the btree
Entity parent; Entity parent;
//the list of available equip points
List<EquipPoint> equipPoints = new LinkedList<EquipPoint>(); List<EquipPoint> equipPoints = new LinkedList<EquipPoint>();
//the map of point to the equipped entity
Map<String,Entity> equipMap = new HashMap<String,Entity>(); Map<String,Entity> equipMap = new HashMap<String,Entity>();
/**
* Creates the tree
* @param parent the entity this is attached to
* @param equipPoints the list of available points
*/
public ClientEquipState(Entity parent, List<EquipPoint> equipPoints){ public ClientEquipState(Entity parent, List<EquipPoint> equipPoints){
this.parent = parent; this.parent = parent;
for(EquipPoint point : equipPoints){ for(EquipPoint point : equipPoints){
@ -46,10 +55,19 @@ public class ClientEquipState implements BehaviorTree {
} }
} }
/**
* Gets the list of equipped points
* @return the list
*/
public List<String> equippedPoints(){ public List<String> equippedPoints(){
return new LinkedList<String>(equipMap.keySet()); return new LinkedList<String>(equipMap.keySet());
} }
/**
* Attempts to equip the item
* @param toEquip the item to equip
* @param point the point to equip to
*/
public void commandAttemptEquip(Entity toEquip, EquipPoint point){ public void commandAttemptEquip(Entity toEquip, EquipPoint point){
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId()); boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
boolean targetIsItem = ItemUtils.isItem(toEquip); boolean targetIsItem = ItemUtils.isItem(toEquip);
@ -117,7 +135,11 @@ public class ClientEquipState implements BehaviorTree {
} else { } else {
//since we're not replacing meshes we must be attaching to a bone //since we're not replacing meshes we must be attaching to a bone
equipMap.put(point.getEquipPointId(),toEquip); equipMap.put(point.getEquipPointId(),toEquip);
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation())); if(Globals.controlHandler.cameraIsThirdPerson()){
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
} else {
AttachUtils.clientAttachEntityToEntityAtBone(Globals.firstPersonEntity, toEquip, point.getFirstPersonBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
}
if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){ if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody); Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody);
@ -171,6 +193,11 @@ public class ClientEquipState implements BehaviorTree {
// } // }
} }
/**
* Gets the equip point by its name
* @param name the name of the equip point
* @return the equip point object if it exists, otherwise null
*/
public EquipPoint getEquipPoint(String name){ public EquipPoint getEquipPoint(String name){
for(EquipPoint point : equipPoints){ for(EquipPoint point : equipPoints){
if(point.getEquipPointId().equals(name)){ if(point.getEquipPointId().equals(name)){
@ -180,6 +207,11 @@ public class ClientEquipState implements BehaviorTree {
return null; return null;
} }
/**
* Gets the item equipped at a point
* @param point the point's name
* @return the item entity
*/
public Entity getEquippedItemAtPoint(String point){ public Entity getEquippedItemAtPoint(String point){
return equipMap.get(point); return equipMap.get(point);
} }
@ -223,6 +255,10 @@ public class ClientEquipState implements BehaviorTree {
// } // }
// } // }
/**
* Attempts to unequip the item at a given point
* @param pointId the id of the point
*/
public void commandAttemptUnequip(String pointId){ public void commandAttemptUnequip(String pointId){
boolean hasEquipped = hasEquippedAtPoint(pointId); boolean hasEquipped = hasEquippedAtPoint(pointId);
if(hasEquipped){ if(hasEquipped){
@ -266,6 +302,11 @@ public class ClientEquipState implements BehaviorTree {
} }
} }
/**
* Checks if a point has an item equipped
* @param point the equip point
* @return true if there is an item equipped, false otherwise
*/
public boolean hasEquippedAtPoint(String point){ public boolean hasEquippedAtPoint(String point){
return equipMap.containsKey(point); return equipMap.containsKey(point);
} }

View File

@ -3,6 +3,7 @@ package electrosphere.entity.state.idle;
import electrosphere.net.synchronization.BehaviorTreeIdEnums; import electrosphere.net.synchronization.BehaviorTreeIdEnums;
import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.movement.AirplaneMovementTree; import electrosphere.entity.state.movement.AirplaneMovementTree;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
@ -13,6 +14,8 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.IdleData;
import electrosphere.net.synchronization.annotation.SyncedField; import electrosphere.net.synchronization.annotation.SyncedField;
import electrosphere.net.synchronization.annotation.SynchronizableEnum; import electrosphere.net.synchronization.annotation.SynchronizableEnum;
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
@ -37,10 +40,13 @@ public class IdleTree implements BehaviorTree {
private IdleTreeState state; private IdleTreeState state;
Entity parent; Entity parent;
IdleData idleData;
public IdleTree(Entity e){ public IdleTree(Entity e){
state = IdleTreeState.IDLE; state = IdleTreeState.IDLE;
parent = e; parent = e;
CreatureType creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(parent));
idleData = creatureType.getIdleData();
} }
/** /**
@ -80,12 +86,14 @@ public class IdleTree implements BehaviorTree {
case IDLE: case IDLE:
if(entityActor != null){ if(entityActor != null){
if( if(
(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(Animation.ANIMATION_IDLE_1)) && idleData != null &&
(Globals.assetManager.fetchModel(entityActor.getModelPath()) != null && Globals.assetManager.fetchModel(entityActor.getModelPath()).getAnimation(Animation.ANIMATION_IDLE_1) != null) (!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(idleData.getIdleAnimation())) &&
(Globals.assetManager.fetchModel(entityActor.getModelPath()) != null && Globals.assetManager.fetchModel(entityActor.getModelPath()).getAnimation(idleData.getIdleAnimation()) != null)
){ ){
entityActor.playAnimation(Animation.ANIMATION_IDLE_1,3); entityActor.playAnimation(idleData.getIdleAnimation(),3);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, idleData.getFirstPersonIdleAnimation());
} }
} }
break; break;

View File

@ -1,29 +1,42 @@
package electrosphere.entity.state.movement; package electrosphere.entity.state.movement;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.game.data.creature.type.movement.FallMovementSystem;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
/**
* Behavior tree for playing animations when an entity is falling/landing
*/
public class FallTree implements BehaviorTree { public class FallTree implements BehaviorTree {
/**
* The state of the fall tree
*/
static enum FallState { static enum FallState {
ACTIVE, ACTIVE,
INACTIVE, INACTIVE,
} }
//the raw data from disk
FallMovementSystem fallMovementSystem;
//current state
FallState state = FallState.INACTIVE; FallState state = FallState.INACTIVE;
String animationFall = "Armature|Fall"; //the entity this is attached to
String animationLand = "Armature|Land";
Entity parent; Entity parent;
//the related jump tree
JumpTree jumpTree; JumpTree jumpTree;
public FallTree(Entity parent){ public FallTree(Entity parent, FallMovementSystem fallMovementSystem){
this.parent = parent; this.parent = parent;
this.fallMovementSystem = fallMovementSystem;
} }
@Override @Override
@ -32,13 +45,13 @@ public class FallTree implements BehaviorTree {
switch(state){ switch(state){
case ACTIVE: case ACTIVE:
if(entityActor != null){ if(entityActor != null){
String animationToPlay = determineCorrectAnimation();
if( if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay) && !entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getAnimationFall().getName()) &&
(jumpTree == null || !jumpTree.isJumping()) (jumpTree == null || !jumpTree.isJumping())
){ ){
entityActor.playAnimation(animationToPlay,1); entityActor.playAnimation(fallMovementSystem.getAnimationFall().getName(),1);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, fallMovementSystem.getAnimationFirstPersonFall().getName());
} }
} }
break; break;
@ -47,55 +60,55 @@ public class FallTree implements BehaviorTree {
} }
} }
/**
* Starts the falling tree
*/
public void start(){ public void start(){
state = FallState.ACTIVE; state = FallState.ACTIVE;
} }
/**
* Returns the status of the fall tree
* @return true if falling, false otherwise
*/
public boolean isFalling(){ public boolean isFalling(){
return state == FallState.ACTIVE; return state == FallState.ACTIVE;
} }
/**
* Triggers the falling tree to land
*/
public void land(){ public void land(){
if(state != FallState.INACTIVE){ if(state != FallState.INACTIVE){
state = FallState.INACTIVE; state = FallState.INACTIVE;
Actor entityActor = EntityUtils.getActor(parent); Actor entityActor = EntityUtils.getActor(parent);
if(entityActor != null){ if(entityActor != null){
String animationToPlay = determineCorrectAnimation();
if( if(
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay) !entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(fallMovementSystem.getAnimationLand().getName())
){ ){
entityActor.playAnimation(animationToPlay,1); entityActor.playAnimation(fallMovementSystem.getAnimationLand().getName(),1);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, fallMovementSystem.getAnimationFirstPersonLand().getName());
} }
} }
} }
} }
/**
* Gets the falling tree state of an entity
* @param parent the entity
* @return the state
*/
public static FallTree getFallTree(Entity parent){ public static FallTree getFallTree(Entity parent){
return (FallTree)parent.getData(EntityDataStrings.FALL_TREE); return (FallTree)parent.getData(EntityDataStrings.FALL_TREE);
} }
String determineCorrectAnimation(){ /**
switch(state){ * Sets the related jump tree
case ACTIVE: * @param jumpTree the jump tree that is related to this fall tree (on the same entity)
return animationFall; */
case INACTIVE:
return animationLand;
default:
return animationLand;
}
}
public void setJumpTree(JumpTree jumpTree){ public void setJumpTree(JumpTree jumpTree){
this.jumpTree = jumpTree; this.jumpTree = jumpTree;
} }
public void setAnimationFall(String animationName){
animationFall = animationName;
}
public void setAnimationLand(String animationName){
animationLand = animationName;
}
} }

View File

@ -7,13 +7,16 @@ import org.ode4j.ode.DBody;
import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.collision.PhysicsUtils; import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable; import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.GravityUtils; import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.data.creature.type.movement.JumpMovementSystem;
import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.Actor;
public class JumpTree implements BehaviorTree { public class JumpTree implements BehaviorTree {
@ -28,6 +31,8 @@ public class JumpTree implements BehaviorTree {
String animationJump = "Armature|Jump"; String animationJump = "Armature|Jump";
JumpMovementSystem jumpData;
Entity parent; Entity parent;
int jumpFrames = 0; int jumpFrames = 0;
@ -37,10 +42,11 @@ public class JumpTree implements BehaviorTree {
static final float jumpFalloff = 0.99f; static final float jumpFalloff = 0.99f;
public JumpTree(Entity parent, int jumpFrames, float jumpForce){ public JumpTree(Entity parent, int jumpFrames, float jumpForce, JumpMovementSystem jumpData){
this.parent = parent; this.parent = parent;
this.jumpFrames = jumpFrames; this.jumpFrames = jumpFrames;
this.jumpForce = jumpForce; this.jumpForce = jumpForce;
this.jumpData = jumpData;
} }
public void start(){ public void start(){
@ -58,10 +64,10 @@ public class JumpTree implements BehaviorTree {
switch(state){ switch(state){
case ACTIVE: case ACTIVE:
if(entityActor != null){ if(entityActor != null){
String animationToPlay = determineCorrectAnimation(); if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(jumpData.getAnimationJump().getName())){
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay)){ entityActor.playAnimation(jumpData.getAnimationJump().getName(),1);
entityActor.playAnimation(animationToPlay,1);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, jumpData.getAnimationFirstPersonJump().getName());
} }
} }
currentFrame++; currentFrame++;

View File

@ -15,6 +15,7 @@ import electrosphere.engine.Main;
import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.data.creature.type.movement.GroundMovementSystem;
import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
@ -22,6 +23,7 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState; import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.movement.FallTree; import electrosphere.entity.state.movement.FallTree;
import electrosphere.entity.state.movement.JumpTree; import electrosphere.entity.state.movement.JumpTree;
import electrosphere.entity.state.movement.SprintTree; import electrosphere.entity.state.movement.SprintTree;
@ -96,6 +98,8 @@ public class ClientGroundMovementTree implements BehaviorTree {
SprintTree sprintTree; SprintTree sprintTree;
JumpTree jumpTree; JumpTree jumpTree;
FallTree fallTree; FallTree fallTree;
GroundMovementSystem groundMovementData;
Entity parent; Entity parent;
@ -288,6 +292,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
){ ){
entityActor.playAnimation(animationToPlay,1); entityActor.playAnimation(animationToPlay,1);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonStartup().getName());
} }
} }
//run startup code //run startup code
@ -322,6 +327,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
){ ){
entityActor.playAnimation(animationToPlay,1); entityActor.playAnimation(animationToPlay,1);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonLoop().getName());
} }
} }
if(velocity != maxNaturalVelocity){ if(velocity != maxNaturalVelocity){
@ -350,6 +356,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
){ ){
entityActor.playAnimation(animationToPlay,1); entityActor.playAnimation(animationToPlay,1);
entityActor.incrementAnimationTime(0.0001); entityActor.incrementAnimationTime(0.0001);
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationFirstPersonWindDown().getName());
} }
} }
//velocity stuff //velocity stuff
@ -665,11 +672,12 @@ public class ClientGroundMovementTree implements BehaviorTree {
* @param entity The entity to attach to * @param entity The entity to attach to
* @param tree The behavior tree to attach * @param tree The behavior tree to attach
*/ */
public static ClientGroundMovementTree attachTree(Entity parent, Collidable collidable){ public static ClientGroundMovementTree attachTree(Entity parent, Collidable collidable, GroundMovementSystem groundMovementData){
ClientGroundMovementTree rVal = new ClientGroundMovementTree(parent); ClientGroundMovementTree rVal = new ClientGroundMovementTree(parent);
//put manual code here (setting params, etc) //put manual code here (setting params, etc)
rVal.collidable = collidable; rVal.collidable = collidable;
rVal.groundMovementData = groundMovementData;
//!!WARNING!! from here below should not be touched //!!WARNING!! from here below should not be touched
//This was generated automatically to properly alert various systems that the btree exists and should be tracked //This was generated automatically to properly alert various systems that the btree exists and should be tracked

View File

@ -148,9 +148,14 @@ public class ServerGroundMovementTree implements BehaviorTree {
} }
public void simulate(float deltaTime){ public void simulate(float deltaTime){
float velocity = CreatureUtils.getVelocity(parent); float velocity = 0;
float acceleration = CreatureUtils.getAcceleration(parent); float acceleration = 0;
float maxNaturalVelocity = sprintTree != null && sprintTree.getState() == SprintTreeState.SPRINTING ? sprintTree.getMaxVelocity() : CreatureUtils.getMaxNaturalVelocity(parent); float maxNaturalVelocity = 0;
if(CreatureUtils.hasVelocity(parent)){
velocity = CreatureUtils.getVelocity(parent);
acceleration = CreatureUtils.getAcceleration(parent);
maxNaturalVelocity = sprintTree != null && sprintTree.getState() == SprintTreeState.SPRINTING ? sprintTree.getMaxVelocity() : CreatureUtils.getMaxNaturalVelocity(parent);
}
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent); PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
// Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent)); // Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent));
Vector3d position = EntityUtils.getPosition(parent); Vector3d position = EntityUtils.getPosition(parent);
@ -208,27 +213,6 @@ public class ServerGroundMovementTree implements BehaviorTree {
case MOVEUPDATE: { case MOVEUPDATE: {
if(updateTime >= lastUpdateTime){ if(updateTime >= lastUpdateTime){
lastUpdateTime = updateTime; lastUpdateTime = updateTime;
switch(message.gettreeState()){
case 0:
state = MovementTreeState.STARTUP;
// System.out.println("Set state STARTUP");
GravityUtils.serverAttemptActivateGravity(parent);
break;
case 1:
state = MovementTreeState.MOVE;
// System.out.println("Set state MOVE");
GravityUtils.serverAttemptActivateGravity(parent);
break;
case 2:
state = MovementTreeState.SLOWDOWN;
// System.out.println("Set state SLOWDOWN");
GravityUtils.serverAttemptActivateGravity(parent);
break;
case 3:
state = MovementTreeState.IDLE;
// System.out.println("Set state IDLE");
break;
}
//we want to always update the server facing vector with where the client says they're facing //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()); EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW());
CreatureUtils.setFacingVector(parent, new Vector3d(0,0,1).rotate(EntityUtils.getRotation(parent))); CreatureUtils.setFacingVector(parent, new Vector3d(0,0,1).rotate(EntityUtils.getRotation(parent)));

View File

@ -24,8 +24,7 @@ import org.joml.Vector3f;
import org.joml.Vector4d; import org.joml.Vector4d;
/** /**
* * Utilities for attaching entities to entities
* @author amaterasu
*/ */
public class AttachUtils { public class AttachUtils {
@ -110,6 +109,9 @@ public class AttachUtils {
// Quaternionf rotation = parentActor.getBoneRotation(targetBone); // Quaternionf rotation = parentActor.getBoneRotation(targetBone);
// EntityUtils.getRotation(currentEntity).set(rotation).normalize(); // EntityUtils.getRotation(currentEntity).set(rotation).normalize();
Vector3d facingAngle = CreatureUtils.getFacingVector(parent); Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
if(facingAngle == null){
facingAngle = new Vector3d(0,0,1);
}
//calculate rotation of model //calculate rotation of model
EntityUtils.getRotation(currentEntity) EntityUtils.getRotation(currentEntity)
.rotationTo(new Vector3d(0,0,1), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z)) .rotationTo(new Vector3d(0,0,1), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z))

View File

@ -158,6 +158,26 @@ public class CameraEntityUtils {
public static float getCameraYaw(Entity camera){ public static float getCameraYaw(Entity camera){
return (float)camera.getData(EntityDataStrings.CAMERA_YAW); return (float)camera.getData(EntityDataStrings.CAMERA_YAW);
} }
/**
* Gets the quaternion containing the camera pitch
* @param camera
* @return
*/
public static Quaternionf getPitchQuat(Entity camera){
Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(1,0,0), -getCameraPitch(camera));
return pitchQuat;
}
/**
* Gets the quaternion containing the camera yaw
* @param camera
* @return
*/
public static Quaternionf getYawQuat(Entity camera){
Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(0,1,0), -getCameraYaw(camera));
return yawQuat;
}
public static void destroyCameraEntity(Entity e){ public static void destroyCameraEntity(Entity e){
if(e != null){ if(e != null){

View File

@ -101,6 +101,8 @@ public class CreatureUtils {
Entity rVal = EntityCreationUtils.createClientSpatialEntity(); Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath()); EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
Actor creatureActor = EntityUtils.getActor(rVal); Actor creatureActor = EntityUtils.getActor(rVal);
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
EntityUtils.setEntitySubtype(rVal, type);
for(HitboxData hitboxdata : rawType.getHitboxes()){ for(HitboxData hitboxdata : rawType.getHitboxes()){
List<Entity> hitboxList = new LinkedList<Entity>(); List<Entity> hitboxList = new LinkedList<Entity>();
List<Entity> hurtboxList = new LinkedList<Entity>(); List<Entity> hurtboxList = new LinkedList<Entity>();
@ -132,7 +134,7 @@ public class CreatureUtils {
// Generic ground // Generic ground
case GroundMovementSystem.GROUND_MOVEMENT_SYSTEM: case GroundMovementSystem.GROUND_MOVEMENT_SYSTEM:
GroundMovementSystem groundMovementSystem = (GroundMovementSystem)movementSystem; GroundMovementSystem groundMovementSystem = (GroundMovementSystem)movementSystem;
ClientGroundMovementTree moveTree = ClientGroundMovementTree.attachTree(rVal, CollisionObjUtils.getCollidable(rVal)); ClientGroundMovementTree moveTree = ClientGroundMovementTree.attachTree(rVal, CollisionObjUtils.getCollidable(rVal), groundMovementSystem);
if(groundMovementSystem.getAnimationStartup() != null){ if(groundMovementSystem.getAnimationStartup() != null){
moveTree.setAnimationStartUp(groundMovementSystem.getAnimationStartup().getName()); moveTree.setAnimationStartUp(groundMovementSystem.getAnimationStartup().getName());
} }
@ -174,7 +176,7 @@ public class CreatureUtils {
// Jump // Jump
case JumpMovementSystem.JUMP_MOVEMENT_SYSTEM: case JumpMovementSystem.JUMP_MOVEMENT_SYSTEM:
JumpMovementSystem jumpMovementSystem = (JumpMovementSystem)movementSystem; JumpMovementSystem jumpMovementSystem = (JumpMovementSystem)movementSystem;
JumpTree jumpTree = new JumpTree(rVal, jumpMovementSystem.getJumpFrames(), jumpMovementSystem.getJumpForce()); JumpTree jumpTree = new JumpTree(rVal, jumpMovementSystem.getJumpFrames(), jumpMovementSystem.getJumpForce(), jumpMovementSystem);
if(jumpMovementSystem.getAnimationJump() != null){ if(jumpMovementSystem.getAnimationJump() != null){
jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getName()); jumpTree.setAnimationJump(jumpMovementSystem.getAnimationJump().getName());
} }
@ -191,13 +193,7 @@ public class CreatureUtils {
// Falling // Falling
case FallMovementSystem.FALL_MOVEMENT_SYSTEM: case FallMovementSystem.FALL_MOVEMENT_SYSTEM:
FallMovementSystem fallMovementSystem = (FallMovementSystem)movementSystem; FallMovementSystem fallMovementSystem = (FallMovementSystem)movementSystem;
FallTree fallTree = new FallTree(rVal); FallTree fallTree = new FallTree(rVal, fallMovementSystem);
if(fallMovementSystem.getAnimationFall()!=null){
fallTree.setAnimationFall(fallMovementSystem.getAnimationFall().getName());
}
if(fallMovementSystem.getAnimationLand()!=null){
fallTree.setAnimationLand(fallMovementSystem.getAnimationLand().getName());
}
if(CreatureUtils.clientGetEntityMovementTree(rVal) != null && CreatureUtils.clientGetEntityMovementTree(rVal) instanceof ClientGroundMovementTree){ if(CreatureUtils.clientGetEntityMovementTree(rVal) != null && CreatureUtils.clientGetEntityMovementTree(rVal) instanceof ClientGroundMovementTree){
((ClientGroundMovementTree)CreatureUtils.clientGetEntityMovementTree(rVal)).setClientFallTree(fallTree); ((ClientGroundMovementTree)CreatureUtils.clientGetEntityMovementTree(rVal)).setClientFallTree(fallTree);
} }
@ -374,8 +370,6 @@ public class CreatureUtils {
rVal.putData(EntityDataStrings.TREE_IDLE, idleTree); rVal.putData(EntityDataStrings.TREE_IDLE, idleTree);
Globals.clientScene.registerBehaviorTree(idleTree); Globals.clientScene.registerBehaviorTree(idleTree);
Globals.clientScene.registerEntityToTag(rVal, EntityTags.CREATURE); Globals.clientScene.registerEntityToTag(rVal, EntityTags.CREATURE);
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
EntityUtils.setEntitySubtype(rVal, type);
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1)); CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true); rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
return rVal; return rVal;
@ -717,6 +711,10 @@ public class CreatureUtils {
public static void setAcceleration(Entity e, float scalar){ public static void setAcceleration(Entity e, float scalar){
e.putData(EntityDataStrings.DATA_STRING_ACCELERATION, scalar); e.putData(EntityDataStrings.DATA_STRING_ACCELERATION, scalar);
} }
public static boolean hasVelocity(Entity e){
return e.containsKey(EntityDataStrings.DATA_STRING_VELOCITY);
}
public static float getVelocity(Entity e){ public static float getVelocity(Entity e){
return (float)e.getData(EntityDataStrings.DATA_STRING_VELOCITY); return (float)e.getData(EntityDataStrings.DATA_STRING_VELOCITY);

View File

@ -11,7 +11,7 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags; import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.ambientaudio.ClientAmbientAudioTree; import electrosphere.entity.state.client.ambientaudio.ClientAmbientAudioTree;
import electrosphere.entity.state.idle.IdleTree; import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.tree.ProceduralTree; import electrosphere.entity.types.tree.ProceduralTree;

View File

@ -11,6 +11,9 @@ import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import java.util.List; import java.util.List;
/**
* A given type of creature
*/
public class CreatureType { public class CreatureType {
String creatureId; String creatureId;
List<HitboxData> hitboxes; List<HitboxData> hitboxes;
@ -24,6 +27,8 @@ public class CreatureType {
HealthSystem healthSystem; HealthSystem healthSystem;
LookAtSystem lookAtSystem; LookAtSystem lookAtSystem;
String modelPath; String modelPath;
ViewModelData viewModelData;
IdleData idleData;
AttackMoveResolver attackMoveResolver; AttackMoveResolver attackMoveResolver;
@ -82,6 +87,14 @@ public class CreatureType {
public AttackMoveResolver getAttackMoveResolver(){ public AttackMoveResolver getAttackMoveResolver(){
return attackMoveResolver; return attackMoveResolver;
} }
public ViewModelData getViewModelData(){
return viewModelData;
}
public IdleData getIdleData(){
return idleData;
}
} }

View File

@ -0,0 +1,30 @@
package electrosphere.game.data.creature.type;
/**
* Data about how the creature will behave when in idle state
*/
public class IdleData {
//the animation that plays when the creature is idle
String idleAnimation;
//the animation that plays when the creature idles in first person
String firstPersonIdleAnimation;
/**
* the animation that plays when the creature is idle
* @return
*/
public String getIdleAnimation(){
return idleAnimation;
}
/**
* the animation that plays when the creature idles in first person
* @return
*/
public String getFirstPersonIdleAnimation(){
return firstPersonIdleAnimation;
}
}

View File

@ -0,0 +1,54 @@
package electrosphere.game.data.creature.type;
/**
* Data about the first person view model for this creature type
*/
public class ViewModelData {
//How far from the origin of the creature to place the viewmodel
double heightFromOrigin;
//How far to pull the view model below the camera
double cameraViewDirOffsetY;
//How far to pull the view model behind the camera
double cameraViewDirOffsetZ;
//the actual model
String firstPersonModelPath;
/**
* How far from the origin of the creature to place the viewmodel
* @return
*/
public double getHeightFromOrigin(){
return heightFromOrigin;
}
/**
* How far to pull the view model below the camera
* @return
*/
public double getCameraViewDirOffsetY(){
return cameraViewDirOffsetY;
}
/**
* How far to pull the view model behind the camera
* @return
*/
public double getCameraViewDirOffsetZ(){
return cameraViewDirOffsetZ;
}
/**
* the actual model
* @return
*/
public String getFirstPersonModelPath(){
return firstPersonModelPath;
}
}

View File

@ -1,15 +1,14 @@
package electrosphere.game.data.creature.type.attack; package electrosphere.game.data.creature.type.attack;
import java.util.List; import electrosphere.game.data.creature.type.Animation;
/** /**
* * Data about a single attack move this creature is capable of
* @author amaterasu
*/ */
public class AttackMove { public class AttackMove {
/* /*
Base data
*/ */
String attackMoveId; String attackMoveId;
String type; String type;
@ -21,6 +20,10 @@ public class AttackMove {
String holdAnimationName; String holdAnimationName;
String attackAnimationName; String attackAnimationName;
Animation animationFirstPersonWindup;
Animation animationFirstPersonHold;
Animation animationFirstPersonAttack;
/* /*
Damage stuff Damage stuff
*/ */
@ -45,66 +48,154 @@ public class AttackMove {
int driftFrameStart; //when do we start drifting int driftFrameStart; //when do we start drifting
int driftFrameEnd; //when do we stop drifting int driftFrameEnd; //when do we stop drifting
/**
* Gets the id of the attack move
* @return the id of the attack move
*/
public String getAttackMoveId(){ public String getAttackMoveId(){
return attackMoveId; return attackMoveId;
} }
/**
* Gets the type of attack move
* @return the attack move type
*/
public String getType() { public String getType() {
return type; return type;
} }
/**
* Gets the name of the animation to play in 3rd person for the windup
* @return the animation name
*/
public String getWindupAnimationName() { public String getWindupAnimationName() {
return windupAnimationName; return windupAnimationName;
} }
/**
* Gets the name of the animation to play in 3rd person for the hold
* @return the animation name
*/
public String getHoldAnimationName() { public String getHoldAnimationName() {
return holdAnimationName; return holdAnimationName;
} }
/**
* Gets the name of the animation to play in 3rd person for the attack
* @return the animation name
*/
public String getAttackAnimationName() { public String getAttackAnimationName() {
return attackAnimationName; return attackAnimationName;
} }
/**
* Gets the animation data for the 1st person windup
* @return the animation data
*/
public Animation getAnimationFirstPersonWindup(){
return animationFirstPersonWindup;
}
/**
* Gets the animation data for the 1st person hold
* @return the animation data
*/
public Animation getAnimationFirstPersonHold(){
return animationFirstPersonHold;
}
/**
* Gets the animation data for the 1st person attack
* @return the animation data
*/
public Animation getAnimationFirstPersonAttack(){
return animationFirstPersonAttack;
}
/**
* Gets the number of frames to windup for
* @return the number of frames
*/
public int getWindupFrames() { public int getWindupFrames() {
return windupFrames; return windupFrames;
} }
/**
* Gets the number of frames to attack for
* @return the number of frames
*/
public int getAttackFrames() { public int getAttackFrames() {
return attackFrames; return attackFrames;
} }
/**
* Gets the number of frames to cooldown for
* @return the number of frames
*/
public int getCooldownFrames(){ public int getCooldownFrames(){
return cooldownFrames; return cooldownFrames;
} }
/**
* Gets the id of the next attack move
* @return the id of the next attack move
*/
public String getNextMoveId() { public String getNextMoveId() {
return nextMoveId; return nextMoveId;
} }
/**
* Gets the frame number where the window to chain the next attack starts
* @return the frame number
*/
public int getMoveChainWindowStart(){ public int getMoveChainWindowStart(){
return moveChainWindowStart; return moveChainWindowStart;
} }
/**
* Gets the frame number where the window to chain the next attack ends
* @return the frame number
*/
public int getMoveChainWindowEnd(){ public int getMoveChainWindowEnd(){
return moveChainWindowEnd; return moveChainWindowEnd;
} }
/**
* Gets the amount we want the animation to push the creature forward
* @return the amount to push forward
*/
public float getDriftGoal(){ public float getDriftGoal(){
return driftGoal; return driftGoal;
} }
/**
* Gets the frame number where the drift starts
* @return the frame number
*/
public int getDriftFrameStart(){ public int getDriftFrameStart(){
return driftFrameStart; return driftFrameStart;
} }
/**
* Gets the frame number where the drift starts
* @return the frame number
*/
public int getDriftFrameEnd(){ public int getDriftFrameEnd(){
return driftFrameEnd; return driftFrameEnd;
} }
/**
* Returns if the move is the initial move in the attack chain
* @return true if the initial move, false otherwise
*/
public boolean isInitialMove(){ public boolean isInitialMove(){
return initialMove; return initialMove;
} }
/**
* Returns if it fires a projectile
* @return true if it fires a projectile, false otherwise
*/
public boolean getFiresProjectile(){ public boolean getFiresProjectile(){
return firesProjectile; return firesProjectile;
} }

View File

@ -2,30 +2,68 @@ package electrosphere.game.data.creature.type.equip;
import java.util.List; import java.util.List;
/**
* A portion of the creature that can have an item attached to it
*/
public class EquipPoint { public class EquipPoint {
//the id of the equip point
String equipPointId; String equipPointId;
//the bone that can have the item attached to it (may not be defined depending on the type of equip point (think legs))
String bone; String bone;
//the bone to attach items to for the first person viewmodel (may not be defined based on the viewmodel)
String firstPersonBone;
//the offset to apply to items that are attached to the bone
List<Float> offsetVector; List<Float> offsetVector;
//the rotation to apply to the items that are attached to the bone
List<Float> offsetRotation; List<Float> offsetRotation;
//the equip classes that are whitelisted for this equip point
List<String> equipClassWhitelist; List<String> equipClassWhitelist;
/**
* Gets the equip point id
* @return the id of the equip point
*/
public String getEquipPointId(){ public String getEquipPointId(){
return equipPointId; return equipPointId;
} }
/**
* Gets the bone that can have the item attached to it (may not be defined depending on the type of equip point (think legs))
* @return the bone
*/
public String getBone(){ public String getBone(){
return bone; return bone;
} }
/**
* Gets the bone to attach items to for the first person viewmodel (may not be defined based on the viewmodel)
* @return the bone
*/
public String getFirstPersonBone(){
return firstPersonBone;
}
/**
* Gets the offset to apply to items that are attached to the bone
* @return the offset
*/
public List<Float> getOffsetVector(){ public List<Float> getOffsetVector(){
return offsetVector; return offsetVector;
} }
/**
* Gets the rotation to apply to the items that are attached to the bone
* @return the rotation
*/
public List<Float> getOffsetRotation(){ public List<Float> getOffsetRotation(){
return offsetRotation; return offsetRotation;
} }
/**
* Gets the equip classes that are whitelisted for this equip point
* @return the classes
*/
public List<String> getEquipClassWhitelist(){ public List<String> getEquipClassWhitelist(){
return equipClassWhitelist; return equipClassWhitelist;
} }

View File

@ -2,23 +2,55 @@ package electrosphere.game.data.creature.type.movement;
import electrosphere.game.data.creature.type.Animation; import electrosphere.game.data.creature.type.Animation;
/**
* Data about a falling movement system
*/
public class FallMovementSystem implements MovementSystem { public class FallMovementSystem implements MovementSystem {
public static final String FALL_MOVEMENT_SYSTEM = "FALL"; public static final String FALL_MOVEMENT_SYSTEM = "FALL";
String type; String type;
//Fall data
Animation animationFall; Animation animationFall;
Animation animationLand; Animation animationFirstPersonFall;
//landing data
Animation animationLand;
Animation animationFirstPersonLand;
/**
* Gets the animation to play in 3rd person when the creature is falling
* @return the animation data
*/
public Animation getAnimationFall(){ public Animation getAnimationFall(){
return animationFall; return animationFall;
} }
/**
* Gets the animation to play in 1st person when the creature is falling
* @return the animation data
*/
public Animation getAnimationFirstPersonFall(){
return animationFirstPersonFall;
}
/**
* Gets the animation to play in 3rd person when the creature is landing
* @return the animation data
*/
public Animation getAnimationLand(){ public Animation getAnimationLand(){
return animationLand; return animationLand;
} }
/**
* Gets the animation to play in 1st person when the creature is landing
* @return the animation data
*/
public Animation getAnimationFirstPersonLand(){
return animationFirstPersonLand;
}
@Override @Override
public String getType() { public String getType() {
return type; return type;

View File

@ -3,40 +3,105 @@ package electrosphere.game.data.creature.type.movement;
import electrosphere.game.data.creature.type.Animation; import electrosphere.game.data.creature.type.Animation;
import electrosphere.game.data.creature.type.SprintSystem; import electrosphere.game.data.creature.type.SprintSystem;
/**
* A ground movement system's data
*/
public class GroundMovementSystem implements MovementSystem { public class GroundMovementSystem implements MovementSystem {
//move system type string
public static final String GROUND_MOVEMENT_SYSTEM = "GROUND"; public static final String GROUND_MOVEMENT_SYSTEM = "GROUND";
//type of move system
String type; String type;
//core physics numbers
float acceleration; float acceleration;
float maxVelocity; float maxVelocity;
//startup data
Animation animationStartup; Animation animationStartup;
Animation animationFirstPersonStartup;
//loop data
Animation animationLoop; Animation animationLoop;
Animation animationFirstPersonLoop;
//wind down data
Animation animationWindDown; Animation animationWindDown;
Animation animationFirstPersonWindDown;
//sprint data
SprintSystem sprintSystem; SprintSystem sprintSystem;
/**
* Gets the acceleration factor for this creature
* @return the acceleration factor
*/
public float getAcceleration() { public float getAcceleration() {
return acceleration; return acceleration;
} }
/**
* Gets the maximum velocity the creature can move at with this system
* @return the max velocity
*/
public float getMaxVelocity() { public float getMaxVelocity() {
return maxVelocity; return maxVelocity;
} }
/**
* Gets the animation to play in 3rd person for startup
* @return The animation data
*/
public Animation getAnimationStartup() { public Animation getAnimationStartup() {
return animationStartup; return animationStartup;
} }
/**
* Gets the animation to play in 1st person for startup
* @return The animation data
*/
public Animation getAnimationFirstPersonStartup(){
return animationFirstPersonStartup;
}
/**
* Gets the animation to loop in 3rd person
* @return The animation data
*/
public Animation getAnimationLoop() { public Animation getAnimationLoop() {
return animationLoop; return animationLoop;
} }
/**
* Gets the animation to loop in 1st person
* @return The animation data
*/
public Animation getAnimationFirstPersonLoop(){
return animationFirstPersonLoop;
}
/**
* Gets the animation to play in 3rd person to wind down
* @return The animation data
*/
public Animation getAnimationWindDown() { public Animation getAnimationWindDown() {
return animationWindDown; return animationWindDown;
} }
/**
* Gets the animation to play in 1st person to wind down
* @return The animation data
*/
public Animation getAnimationFirstPersonWindDown(){
return animationFirstPersonWindDown;
}
/**
* Gets the sprint system data
* @return The sprint system data
*/
public SprintSystem getSprintSystem() { public SprintSystem getSprintSystem() {
return sprintSystem; return sprintSystem;
} }

View File

@ -9,7 +9,8 @@ public class JumpMovementSystem implements MovementSystem {
String type; String type;
Animation animationJump; Animation animationJump;
Animation animationFirstPersonJump;
int jumpFrames; int jumpFrames;
float jumpForce; float jumpForce;
@ -25,6 +26,10 @@ public class JumpMovementSystem implements MovementSystem {
return animationJump; return animationJump;
} }
public Animation getAnimationFirstPersonJump(){
return animationFirstPersonJump;
}
@Override @Override
public String getType() { public String getType() {
return type; return type;

View File

@ -99,6 +99,12 @@ public class TreeModel {
//The maximum scalar of a branch to generate a sway behavior tree //The maximum scalar of a branch to generate a sway behavior tree
float maximumScalarToGenerateSwayTree; float maximumScalarToGenerateSwayTree;
//The model for the trunk of the tree
String trunkModelPath;
//the model for a leaf blob
String leafModelPath;
/** /**
* how quickly do the limbs shrink * how quickly do the limbs shrink
* @return * @return
@ -332,4 +338,20 @@ public class TreeModel {
return this.physicsBody; return this.physicsBody;
} }
/**
* The model for the trunk of the tree
* @return
*/
public String getTrunkModelPath(){
return trunkModelPath;
}
/**
* the model for a leaf blob
* @return
*/
public String getLeafModelPath(){
return leafModelPath;
}
} }

View File

@ -26,7 +26,7 @@ public class LoggerInterface {
*/ */
public static void initLoggers(){ public static void initLoggers(){
loggerStartup = new Logger(LogLevel.WARNING); loggerStartup = new Logger(LogLevel.WARNING);
loggerNetworking = new Logger(LogLevel.DEBUG); loggerNetworking = new Logger(LogLevel.WARNING);
loggerFileIO = new Logger(LogLevel.WARNING); loggerFileIO = new Logger(LogLevel.WARNING);
loggerGameLogic = new Logger(LogLevel.WARNING); loggerGameLogic = new Logger(LogLevel.WARNING);
loggerRenderer = new Logger(LogLevel.WARNING); loggerRenderer = new Logger(LogLevel.WARNING);

View File

@ -6,15 +6,20 @@ import org.joml.Vector3d;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils; import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity; import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils; import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.attack.ClientAttackTree; import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.attack.ServerAttackTree; import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.creature.CreatureTemplate; import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.ViewModelData;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.util.Utilities; import electrosphere.util.Utilities;
@ -101,19 +106,7 @@ public class EntityProtocol {
case SETPROPERTY: { case SETPROPERTY: {
if(Globals.clientSceneWrapper.serverToClientMapContainsId(message.getentityID())){ if(Globals.clientSceneWrapper.serverToClientMapContainsId(message.getentityID())){
if(message.getpropertyType() == 0){ if(message.getpropertyType() == 0){
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID()); setPlayerEntity(message);
if(target != null){
CreatureUtils.setControllerPlayerId(target, message.getpropertyValue());
if(Globals.clientPlayer != null && message.getpropertyValue() == Globals.clientPlayer.getId()){
Globals.clientCharacterID = message.getentityID();
Globals.playerEntity = target;
if(Globals.controlHandler.cameraIsThirdPerson()){
Globals.playerEntity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
} else {
Globals.playerEntity.putData(EntityDataStrings.DATA_STRING_DRAW, false);
}
}
}
} }
} else { } else {
//TODO: bounce message //TODO: bounce message
@ -168,4 +161,33 @@ public class EntityProtocol {
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
} }
/**
* Sets the player's entity
* @param message the network message to parse
*/
static void setPlayerEntity(EntityMessage message){
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
if(target != null){
CreatureUtils.setControllerPlayerId(target, message.getpropertyValue());
String creatureTypeRaw = CreatureUtils.getType(target);
CreatureType creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(creatureTypeRaw);
ViewModelData viewModelData = creatureType.getViewModelData();
if(Globals.clientPlayer != null && message.getpropertyValue() == Globals.clientPlayer.getId()){
Globals.clientCharacterID = message.getentityID();
Globals.playerEntity = target;
if(Globals.controlHandler.cameraIsThirdPerson()){
Globals.playerEntity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
} else {
Globals.playerEntity.putData(EntityDataStrings.DATA_STRING_DRAW, false);
if(viewModelData != null && viewModelData.getFirstPersonModelPath() != null){
Globals.firstPersonEntity = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(Globals.firstPersonEntity, viewModelData.getFirstPersonModelPath());
FirstPersonTree.attachTree(Globals.firstPersonEntity, viewModelData.getHeightFromOrigin(), viewModelData.getCameraViewDirOffsetY(), viewModelData.getCameraViewDirOffsetZ());
Globals.clientSceneWrapper.getScene().removeEntityFromTag(Globals.firstPersonEntity,EntityTags.DRAWABLE);
}
}
}
}
}
} }

View File

@ -103,6 +103,7 @@ import electrosphere.renderer.light.LightManager;
import electrosphere.renderer.model.Model; import electrosphere.renderer.model.Model;
import electrosphere.renderer.pipelines.CompositePipeline; import electrosphere.renderer.pipelines.CompositePipeline;
import electrosphere.renderer.pipelines.DebugContentPipeline; import electrosphere.renderer.pipelines.DebugContentPipeline;
import electrosphere.renderer.pipelines.FirstPersonItemsPipeline;
import electrosphere.renderer.pipelines.MainContentNoOITPipeline; import electrosphere.renderer.pipelines.MainContentNoOITPipeline;
import electrosphere.renderer.pipelines.MainContentPipeline; import electrosphere.renderer.pipelines.MainContentPipeline;
import electrosphere.renderer.pipelines.NormalsForOutlinePipeline; import electrosphere.renderer.pipelines.NormalsForOutlinePipeline;
@ -244,6 +245,7 @@ public class RenderingEngine {
MainContentPipeline mainContentPipeline = new MainContentPipeline(); MainContentPipeline mainContentPipeline = new MainContentPipeline();
MainContentNoOITPipeline mainContentNoOITPipeline = new MainContentNoOITPipeline(); MainContentNoOITPipeline mainContentNoOITPipeline = new MainContentNoOITPipeline();
DebugContentPipeline debugContentPipeline = new DebugContentPipeline(); DebugContentPipeline debugContentPipeline = new DebugContentPipeline();
FirstPersonItemsPipeline firstPersonItemsPipeline = new FirstPersonItemsPipeline();
ShadowMapPipeline shadowMapPipeline = new ShadowMapPipeline(); ShadowMapPipeline shadowMapPipeline = new ShadowMapPipeline();
VolumeBufferPipeline volumeBufferPipeline = new VolumeBufferPipeline(); VolumeBufferPipeline volumeBufferPipeline = new VolumeBufferPipeline();
NormalsForOutlinePipeline normalsForOutlinePipeline = new NormalsForOutlinePipeline(); NormalsForOutlinePipeline normalsForOutlinePipeline = new NormalsForOutlinePipeline();
@ -448,6 +450,12 @@ public class RenderingEngine {
// fogColor.put(1.0f); // fogColor.put(1.0f);
// fogColor.flip(); // fogColor.flip();
// GL11.glFogfv(GL_FOG_COLOR, fogColor); // GL11.glFogfv(GL_FOG_COLOR, fogColor);
//
//Init pipelines
//
firstPersonItemsPipeline.init();
compositePipeline.setFirstPersonPipeline(firstPersonItemsPipeline);
// //
// Projection and View matrix creation // Projection and View matrix creation
@ -496,6 +504,7 @@ public class RenderingEngine {
} }
debugContentPipeline.render(openGLState, renderPipelineState); debugContentPipeline.render(openGLState, renderPipelineState);
normalsForOutlinePipeline.render(openGLState, renderPipelineState); normalsForOutlinePipeline.render(openGLState, renderPipelineState);
firstPersonItemsPipeline.render(openGLState, renderPipelineState);
postProcessingPipeline.render(openGLState, renderPipelineState); postProcessingPipeline.render(openGLState, renderPipelineState);
compositePipeline.render(openGLState, renderPipelineState); compositePipeline.render(openGLState, renderPipelineState);
} }

View File

@ -336,14 +336,31 @@ public class Actor {
return meshMask; return meshMask;
} }
/**
* Masks a shader with another shader
* @param mesh The mesh to apply the mask on
* @param vertexShader the vertex shader to apply
* @param fragmentShader the fragment shader to apply
*/
public void maskShader(String mesh, String vertexShader, String fragmentShader){ public void maskShader(String mesh, String vertexShader, String fragmentShader){
shaderMasks.add(new ActorShaderMask(this.modelPath, mesh, vertexShader, null, fragmentShader)); shaderMasks.add(new ActorShaderMask(this.modelPath, mesh, vertexShader, null, fragmentShader));
} }
/**
* Masks a shader with another shader
* @param mesh the mesh to apply the mask on
* @param vertexShader the vertex shader to apply
* @param geometryShader the geometry shader to apply
* @param fragmentShader the fragment shader to apply
*/
public void maskShader(String mesh, String vertexShader, String geometryShader, String fragmentShader){ public void maskShader(String mesh, String vertexShader, String geometryShader, String fragmentShader){
shaderMasks.add(new ActorShaderMask(this.modelPath, mesh, vertexShader, geometryShader, fragmentShader)); shaderMasks.add(new ActorShaderMask(this.modelPath, mesh, vertexShader, geometryShader, fragmentShader));
} }
/**
* Unmasks a shader
* @param mesh the mesh to unmask
*/
public void unmaskShader(String mesh){ public void unmaskShader(String mesh){
throw new UnsupportedOperationException("Not implemented yet"); throw new UnsupportedOperationException("Not implemented yet");
} }

View File

@ -1,13 +1,29 @@
package electrosphere.renderer.actor; package electrosphere.renderer.actor;
/**
* Masks a shader on a mesh with another shader
*/
public class ActorShaderMask { public class ActorShaderMask {
//the model name
String modelName; String modelName;
//the mesh name
String meshName; String meshName;
//the vertex shader
String vertexShaderPath; String vertexShaderPath;
//the geometry shader
String geometryShaderPath; String geometryShaderPath;
//the fragment shader
String fragmentShaderPath; String fragmentShaderPath;
/**
* Constructor
* @param modelName
* @param meshName
* @param vertexShaderPath
* @param geometryShaderPath
* @param fragmentShaderPath
*/
public ActorShaderMask(String modelName, String meshName, String vertexShaderPath, String geometryShaderPath, String fragmentShaderPath){ public ActorShaderMask(String modelName, String meshName, String vertexShaderPath, String geometryShaderPath, String fragmentShaderPath){
this.modelName = modelName; this.modelName = modelName;
this.meshName = meshName; this.meshName = meshName;
@ -16,22 +32,42 @@ public class ActorShaderMask {
this.fragmentShaderPath = fragmentShaderPath; this.fragmentShaderPath = fragmentShaderPath;
} }
/**
* Gets the model name
* @return the model name
*/
public String getModelName(){ public String getModelName(){
return modelName; return modelName;
} }
/**
* Gets the mesh name
* @return the mesh name
*/
public String getMeshName(){ public String getMeshName(){
return meshName; return meshName;
} }
/**
* Gets the vertex shader path
* @return the vertex shader path
*/
public String getVertexShaderPath(){ public String getVertexShaderPath(){
return vertexShaderPath; return vertexShaderPath;
} }
/**
* Gets the geometry shader path
* @return the geometry shader path
*/
public String getGeometryShaderPath(){ public String getGeometryShaderPath(){
return geometryShaderPath; return geometryShaderPath;
} }
/**
* Gets the fragment shader path
* @return the fragment shader path
*/
public String getFragmentShaderPath(){ public String getFragmentShaderPath(){
return fragmentShaderPath; return fragmentShaderPath;
} }

View File

@ -58,8 +58,7 @@ import static org.lwjgl.opengl.GL30.glRenderbufferStorage;
import static org.lwjgl.system.MemoryUtil.NULL; import static org.lwjgl.system.MemoryUtil.NULL;
/** /**
* * Utilities for framebuffer creation
* @author amaterasu
*/ */
public class FramebufferUtils { public class FramebufferUtils {

View File

@ -436,17 +436,17 @@ public class Model {
* Describes the model at a high level * Describes the model at a high level
*/ */
public void describeHighLevel(){ public void describeHighLevel(){
LoggerInterface.loggerRenderer.DEBUG("Meshes: "); LoggerInterface.loggerRenderer.WARNING("Meshes: ");
for(Mesh mesh : meshes){ for(Mesh mesh : meshes){
LoggerInterface.loggerRenderer.DEBUG(mesh.getMeshName()); LoggerInterface.loggerRenderer.WARNING(mesh.getMeshName());
} }
LoggerInterface.loggerRenderer.DEBUG("Animations: "); LoggerInterface.loggerRenderer.WARNING("Animations: ");
for(Animation anim : animations){ for(Animation anim : animations){
LoggerInterface.loggerRenderer.DEBUG(anim.name); LoggerInterface.loggerRenderer.WARNING(anim.name);
} }
LoggerInterface.loggerRenderer.DEBUG("Bones:"); LoggerInterface.loggerRenderer.WARNING("Bones:");
for(Bone bone : bones){ for(Bone bone : bones){
LoggerInterface.loggerRenderer.DEBUG(bone.boneID); LoggerInterface.loggerRenderer.WARNING(bone.boneID);
} }
} }

View File

@ -9,6 +9,9 @@ import electrosphere.renderer.RenderingEngine;
public class CompositePipeline implements RenderPipeline { public class CompositePipeline implements RenderPipeline {
//the pipeline for the first person render items
FirstPersonItemsPipeline firstPersonItemsPipeline;
@Override @Override
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
Globals.profiler.beginCpuSample("CompositePipeline.render"); Globals.profiler.beginCpuSample("CompositePipeline.render");
@ -60,12 +63,55 @@ public class CompositePipeline implements RenderPipeline {
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyAccumulatorTexture.getTexturePointer()); openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyAccumulatorTexture.getTexturePointer());
openGLState.glActiveTexture(GL40.GL_TEXTURE1); openGLState.glActiveTexture(GL40.GL_TEXTURE1);
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyRevealageTexture.getTexturePointer()); openGLState.glBindTexture(GL40.GL_TEXTURE_2D, RenderingEngine.transparencyRevealageTexture.getTexturePointer());
openGLState.glActiveTexture(GL40.GL_TEXTURE2);
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, firstPersonItemsPipeline.getFramebuffer().getTexturePointer());
GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6); GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6);
//
//Draw the first person texture on top of the other textures
//
openGLState.setActiveShader(renderPipelineState, RenderingEngine.screenTextureShaders);
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
openGLState.glActiveTexture(GL40.GL_TEXTURE1);
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
openGLState.glActiveTexture(GL40.GL_TEXTURE2);
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
openGLState.glActiveTexture(GL40.GL_TEXTURE3);
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, 0);
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
openGLState.glBindTexture(GL40.GL_TEXTURE_2D, firstPersonItemsPipeline.getFramebuffer().getTexturePointer());
openGLState.glActiveTexture(GL40.GL_TEXTURE1);
GL40.glDrawArrays(GL40.GL_TRIANGLES, 0, 6);
//
//Close down pipeline
//
GL40.glBindVertexArray(0); GL40.glBindVertexArray(0);
Globals.profiler.endCpuSample(); Globals.profiler.endCpuSample();
} }
/**
* Get the first person pipeline
* @param firstPersonItemsPipeline the first person pipeline
*/
public void setFirstPersonPipeline(FirstPersonItemsPipeline firstPersonItemsPipeline){
this.firstPersonItemsPipeline = firstPersonItemsPipeline;
}
} }

View File

@ -1,13 +1,119 @@
package electrosphere.renderer.pipelines; package electrosphere.renderer.pipelines;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
import org.joml.Matrix4d;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4d;
import org.lwjgl.opengl.GL40;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.RenderPipelineState;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.framebuffer.Framebuffer;
import electrosphere.renderer.framebuffer.FramebufferUtils;
/**
* Renders content that should only be rendered in first person (ie the view model/hands/whatever)
*/
public class FirstPersonItemsPipeline implements RenderPipeline { public class FirstPersonItemsPipeline implements RenderPipeline {
//framebuffer to store what is rendered in this pass
Framebuffer firstPersonFramebuffer;
//internal model matrix
Matrix4d modelTransformMatrix = new Matrix4d();
/**
* Initializes the pipeline
*/
public void init(){
this.firstPersonFramebuffer = FramebufferUtils.generateTextureFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
}
@Override @Override
public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) { public void render(OpenGLState openGLState, RenderPipelineState renderPipelineState) {
//todo, render hands to a screenbuffer
//update logic
updateFirstPersonModelPosition(Globals.firstPersonEntity);
//setup opengl state
this.firstPersonFramebuffer.bind();
renderPipelineState.setUseBones(true);
renderPipelineState.setUseLight(false);
renderPipelineState.setUseMaterial(true);
renderPipelineState.setUseMeshShader(true);
renderPipelineState.setUseShadowMap(false);
renderPipelineState.setBufferStandardUniforms(true);
renderPipelineState.setFrustumCheck(false);
openGLState.glDepthTest(true);
openGLState.glDepthFunc(GL40.GL_LESS);
GL40.glDepthMask(true);
//clear
GL40.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL40.glClear(GL40.GL_COLOR_BUFFER_BIT);
GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT);
//render
if(
!Globals.controlHandler.cameraIsThirdPerson() &&
Globals.firstPersonEntity != null
){
Vector3d position = EntityUtils.getPosition(Globals.firstPersonEntity);
Actor actor = EntityUtils.getActor(Globals.firstPersonEntity);
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
//calculate and apply model transform
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(Globals.firstPersonEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(Globals.firstPersonEntity)));
actor.applySpatialData(modelTransformMatrix,position);
//draw
actor.draw(renderPipelineState, openGLState);
}
//finish up
openGLState.glBindFramebuffer(GL_FRAMEBUFFER,0);
}
/**
* Gets the framebuffer of the pipeline
* @return the framebuffer
*/
public Framebuffer getFramebuffer(){
return this.firstPersonFramebuffer;
}
/**
* Updates the position and rotation of the first person model
*/
private void updateFirstPersonModelPosition(Entity target){
FirstPersonTree tree = FirstPersonTree.getTree(target);
Quaternionf quatRaw = CameraEntityUtils.getYawQuat(Globals.playerCamera).mul(CameraEntityUtils.getPitchQuat(Globals.playerCamera));
Quaterniond quatd = new Quaterniond(quatRaw).normalize();
EntityUtils.getRotation(Globals.firstPersonEntity).set(quatd);
Matrix4d rotationMat = new Matrix4d().rotate(quatd);
Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity);
Vector4d behindCameraOffsetRaw = rotationMat.transform(new Vector4d(0,tree.getCameraViewDirOffsetY(),tree.getCameraViewDirOffsetZ(),1)); //pushes the model behind the camera
Vector3d behindCameraOffset = new Vector3d(behindCameraOffsetRaw.x,behindCameraOffsetRaw.y,behindCameraOffsetRaw.z);
EntityUtils.getPosition(Globals.firstPersonEntity).set(playerPos).add(0.0f,tree.getHeightFromOrigin(),0.0f).add(behindCameraOffset);
} }
} }

View File

@ -58,6 +58,15 @@ public class MicroSimulation {
currentActor.incrementAnimationTime(Globals.timekeeper.getSimFrameTime() / Main.targetFrameRate); currentActor.incrementAnimationTime(Globals.timekeeper.getSimFrameTime() / Main.targetFrameRate);
} }
} }
//update first person model animations
if(Globals.firstPersonEntity != null){
//fetch actor
Actor currentActor = EntityUtils.getActor(Globals.firstPersonEntity);
//increment animations
if(currentActor.isPlayingAnimation()){
currentActor.incrementAnimationTime(Globals.timekeeper.getSimFrameTime() / Main.targetFrameRate);
}
}
//make items play idle animation //make items play idle animation
for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){ for(Entity item : dataCell.getScene().getEntitiesWithTag(EntityTags.ITEM)){
ItemUtils.updateItemActorAnimation(item); ItemUtils.updateItemActorAnimation(item);

View File

@ -12,6 +12,9 @@ import electrosphere.server.terrain.manager.ServerTerrainChunk;
* Provides utilities for editing terrain (particularly brushes, etc) * Provides utilities for editing terrain (particularly brushes, etc)
*/ */
public class TerrainEditing { public class TerrainEditing {
//the minimum value before hard setting to 0
static final float MINIMUM_FULL_VALUE = 0.01f;
/** /**
* Performs a terrain chunk edit. Basically has a sphere around the provided position that it attempts to add value to. * Performs a terrain chunk edit. Basically has a sphere around the provided position that it attempts to add value to.
@ -62,7 +65,10 @@ public class TerrainEditing {
){ ){
float current = data.getWeights()[voxelPos.x][voxelPos.y][voxelPos.z]; float current = data.getWeights()[voxelPos.x][voxelPos.y][voxelPos.z];
//hard clamp so it doesn't go over 1 //hard clamp so it doesn't go over 1
float finalValue = Math.max(Math.min(current + weight * distance,1),-1); float finalValue = Math.max(Math.min(current + weight / distance,1),-1);
if(finalValue < MINIMUM_FULL_VALUE && current > MINIMUM_FULL_VALUE){
finalValue = -1;
}
voxelCellManager.editChunk(chunkPos, voxelPos, finalValue, type); voxelCellManager.editChunk(chunkPos, voxelPos, finalValue, type);
} }
} }