diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 33a6b7d0..5715a477 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -263,10 +263,10 @@ "equipPointId" : "handsCombined", "bone" : "Hand.R", "firstPersonBone" : "hand.R", - "offsetVectorFirstPerson" : [-0.01,-0.05,-0.10], "offsetVectorThirdPerson" : [0.02,-0.06,0], - "offsetRotationThirdPerson" : [-0.334,0.145,-0.28,0.89], - "offsetRotationFirstPerson" : [0.02,-0.977,-0.211,-0.005], + "offsetVectorFirstPerson" : [0.04,-0.08,0.016], + "offsetRotationThirdPerson" : [0.665,-0.462,0.176,-0.56], + "offsetRotationFirstPerson" : [0.35,-0.775,-0.012,-0.53], "canBlock" : true, "equipClassWhitelist" : [ "tool", diff --git a/assets/Models/basic/geometry/unitvector.glb b/assets/Models/basic/geometry/unitvector.glb new file mode 100644 index 00000000..1a403629 Binary files /dev/null and b/assets/Models/basic/geometry/unitvector.glb differ diff --git a/assets/Models/creatures/person2/person2_1.glb b/assets/Models/creatures/person2/person2_1.glb index e1a86e6b..a938faaa 100644 Binary files a/assets/Models/creatures/person2/person2_1.glb and b/assets/Models/creatures/person2/person2_1.glb differ diff --git a/assets/Models/creatures/viewmodel.glb b/assets/Models/creatures/viewmodel.glb index 91f5103b..7d049610 100644 Binary files a/assets/Models/creatures/viewmodel.glb and b/assets/Models/creatures/viewmodel.glb differ diff --git a/docs/src/progress/currenttarget.md b/docs/src/progress/currenttarget.md index df2ae8a5..c64c69e9 100644 --- a/docs/src/progress/currenttarget.md +++ b/docs/src/progress/currenttarget.md @@ -13,11 +13,10 @@ Things that feel bad: Attack animation feels slow - No audio Short movement bursts feel jittery Part of this may be cylinder collidable instead of capsule + Hitboxes between server and client feel wayyyy off Sound effect on block Allow block hotboxes to block damage -Server packet on damage collision diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index bfeeb090..ed83ba76 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -516,8 +516,15 @@ Sound effects on footstep New sound effects for movement Jump sound effects Don't play walking audio when entity is jumping +Server alert client on collision Sound effect on sword hit +(08/09/2024) +Math overhaul + - Engine defined origin, up, and left vectors + - Redo math for camera calculations +Rotate player models to face correct direction + # TODO diff --git a/src/main/java/electrosphere/client/sim/ClientSimulation.java b/src/main/java/electrosphere/client/sim/ClientSimulation.java index 0a34ff10..d2842e17 100644 --- a/src/main/java/electrosphere/client/sim/ClientSimulation.java +++ b/src/main/java/electrosphere/client/sim/ClientSimulation.java @@ -163,8 +163,7 @@ public class ClientSimulation { Globals.profiler.beginCpuSample("updateFirstPersonAttachments"); //update the facing vector when camera moves in first person if(!Globals.controlHandler.cameraIsThirdPerson() && Globals.playerCamera != null && Globals.playerEntity != null){ - Vector3f cameraEyeVec = CameraEntityUtils.getCameraEye(Globals.playerCamera); - CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(cameraEyeVec.x,0,cameraEyeVec.z).normalize()); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); //flush equipped item state if(ClientEquipState.hasEquipState(Globals.playerEntity)){ ClientEquipState equipState = ClientEquipState.getClientEquipState(Globals.playerEntity); diff --git a/src/main/java/electrosphere/controls/CameraHandler.java b/src/main/java/electrosphere/controls/CameraHandler.java index 5fc13d1d..e7575e24 100644 --- a/src/main/java/electrosphere/controls/CameraHandler.java +++ b/src/main/java/electrosphere/controls/CameraHandler.java @@ -49,7 +49,7 @@ public class CameraHandler { if(Globals.controlHandler != null && !Globals.controlHandler.isMouseVisible()){ yaw = yaw + event.getDeltaX() * mouseSensitivityHorizontal; - pitch = pitch - event.getDeltaY() * mouseSensitivityVertical; + pitch = pitch + event.getDeltaY() * mouseSensitivityVertical; if (pitch >= 89.9f) { pitch = 89.9f; @@ -105,8 +105,8 @@ public class CameraHandler { // CameraEntityUtils.setCameraCenter(Globals.playerCamera, new Vector3f((float)charPos.x,(float)charPos.y,(float)charPos.z)); // } - Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(1,0,0), -pitch); - Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(0,1,0), -yaw); + Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(MathUtils.getLeftVectorf(), -pitch); + Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(MathUtils.getUpVectorf(), -yaw); // float yawRad = yaw / 180.0f * (float)Math.PI; // float pitchRad = pitch / 180.0f * (float)Math.PI; // float rollRad = 0.0f; @@ -140,15 +140,17 @@ public class CameraHandler { if(Globals.controlHandler.cameraIsThirdPerson()){ perspectiveVal = CameraHandler.CAMERA_PERSPECTIVE_THIRD; } - Globals.clientConnection.queueOutgoingMessage( - EntityMessage.constructupdateEntityViewDirMessage( - Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()), - Globals.timekeeper.getNumberOfSimFramesElapsed(), - perspectiveVal, - yaw, - pitch - ) - ); + if(Globals.cameraHandler.getTrackPlayerEntity()){ + Globals.clientConnection.queueOutgoingMessage( + EntityMessage.constructupdateEntityViewDirMessage( + Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()), + Globals.timekeeper.getNumberOfSimFramesElapsed(), + perspectiveVal, + yaw, + pitch + ) + ); + } //the view matrix Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera); diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index 982ff09a..24e797da 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -522,18 +522,14 @@ public class ControlHandler { BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity); if(movementTree instanceof ClientGroundMovementTree){ ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; - Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); 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(); - CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.FORWARD_LEFT); } 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(); - CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.FORWARD_RIGHT); } else { - Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize(); - CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.FORWARD); } } @@ -544,18 +540,14 @@ public class ControlHandler { BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity); if(movementTree instanceof ClientGroundMovementTree){ ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; - Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); 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(); - CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.FORWARD_LEFT); } 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(); - CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.FORWARD_RIGHT); } else { - Vector3d newFacingVector = new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize(); - CreatureUtils.setFacingVector(Globals.playerEntity, newFacingVector); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.FORWARD); } } @@ -587,7 +579,7 @@ public class ControlHandler { CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(5.0/4.0*Math.PI).normalize()); groundTree.start(MovementRelativeFacing.BACKWARD_RIGHT); } else { - CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.BACKWARD); } } @@ -606,7 +598,7 @@ public class ControlHandler { CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).rotateY(5.0/4.0*Math.PI).normalize()); groundTree.start(MovementRelativeFacing.BACKWARD_RIGHT); } else { - CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); groundTree.start(MovementRelativeFacing.BACKWARD); } } @@ -729,8 +721,7 @@ public class ControlHandler { BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity); if(movementTree instanceof ClientGroundMovementTree){ ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; - Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); - CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z)); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); if( (groundTree.getState()==MovementTreeState.IDLE || groundTree.getState()==MovementTreeState.SLOWDOWN) && (controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).isIsKey() && !Globals.controlCallback.getKey(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).getKeyValue())) && @@ -746,8 +737,7 @@ public class ControlHandler { BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity); if(movementTree instanceof ClientGroundMovementTree){ ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; - Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); - CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z)); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); if( (groundTree.getState()==MovementTreeState.IDLE || groundTree.getState()==MovementTreeState.SLOWDOWN) && (controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).isIsKey() && !Globals.controlCallback.getKey(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).getKeyValue())) && @@ -776,8 +766,7 @@ public class ControlHandler { BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity); if(movementTree instanceof ClientGroundMovementTree){ ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; - Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); - CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z)); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); if( (groundTree.getState()==MovementTreeState.IDLE || groundTree.getState()==MovementTreeState.SLOWDOWN) && (controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).isIsKey() && !Globals.controlCallback.getKey(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).getKeyValue())) && @@ -793,8 +782,7 @@ public class ControlHandler { BehaviorTree movementTree = CreatureUtils.clientGetEntityMovementTree(Globals.playerEntity); if(movementTree instanceof ClientGroundMovementTree){ ClientGroundMovementTree groundTree = (ClientGroundMovementTree) movementTree; - Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); - CreatureUtils.setFacingVector(Globals.playerEntity, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z)); + CreatureUtils.setFacingVector(Globals.playerEntity, CameraEntityUtils.getFacingVec(Globals.playerCamera)); if( (groundTree.getState()==MovementTreeState.IDLE || groundTree.getState()==MovementTreeState.SLOWDOWN) && (controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).isIsKey() && !Globals.controlCallback.getKey(controls.get(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD).getKeyValue())) && diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java index d083d6fd..6373163f 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java @@ -238,7 +238,7 @@ public class ClientGroundMovementTree implements BehaviorTree { break; } } - Quaterniond movementQuaternion = new Quaterniond().rotationTo(MathUtils.getOriginVector(), new Vector3d(movementVector.x,0,movementVector.z)).normalize(); + Quaterniond movementQuaternion = new Quaterniond().rotationTo(MathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize(); Quaterniond rotation = EntityUtils.getRotation(parent); rotation.set(movementQuaternion); diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java index 4afbdec5..bfd0d4f5 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java @@ -214,7 +214,7 @@ public class ServerGroundMovementTree implements BehaviorTree { break; } } - Quaterniond movementQuaternion = new Quaterniond().rotationTo(MathUtils.getOriginVector(), new Vector3d(movementVector.x,0,movementVector.z)).normalize(); + Quaterniond movementQuaternion = new Quaterniond().rotationTo(MathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize(); Quaterniond rotation = EntityUtils.getRotation(parent); rotation.set(movementQuaternion); //TODO: optimize away and document (I know for the moment if this exception isn't here it will bite me in the ass later) diff --git a/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java b/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java index 7b9143b1..e8aa8b84 100644 --- a/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java +++ b/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java @@ -120,9 +120,9 @@ public class CameraEntityUtils { } //create if(Globals.controlHandler.cameraIsThirdPerson()){ - Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraEntity(new Vector3f(1,0,1), MathUtils.getOriginVectorf()); + Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraEntity(new Vector3f(0,0,0), MathUtils.getOriginVectorf()); } else { - Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(1,0,1), MathUtils.getOriginVectorf()); + Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(0,0,0), MathUtils.getOriginVectorf()); } } @@ -184,7 +184,7 @@ public class CameraEntityUtils { * @return The quaternion */ public static Quaternionf getPitchQuat(double pitch){ - Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(1,0,0), -(float)pitch); + Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(MathUtils.getLeftVectorf(), -(float)pitch); return pitchQuat; } @@ -194,7 +194,7 @@ public class CameraEntityUtils { * @return The quaternion */ public static Quaternionf getYawQuat(double yaw){ - Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(0,1,0), -(float)yaw); + Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(MathUtils.getUpVectorf(), -(float)yaw); return yawQuat; } @@ -207,7 +207,7 @@ public class CameraEntityUtils { public static Matrix4f getCameraViewMatrix(Entity camera){ Vector3f cameraCenter = new Vector3f(0,0,0);//getViewMatrixCenterOffset(camera); Vector3f cameraEye = new Vector3f(cameraCenter).add(getCameraEye(camera)); - Vector3f cameraUp = new Vector3f(0,1.0f,0); + Vector3f cameraUp = MathUtils.getUpVectorf(); //!!before you make the same mistake I made, cameraEye is NOT NECESSARILY normalized/unit vector //the orbital distance and offset are included in this vector //TODO: refactor this to some other matrix of transforms or something?? @@ -231,9 +231,9 @@ public class CameraEntityUtils { public static Quaterniond getRotationQuat(Entity entity){ double yaw = CameraEntityUtils.getCameraYaw(entity); double pitch = CameraEntityUtils.getCameraPitch(entity); - Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)); + //quaternion is multiplied by pi because we want to point away from the eye of the camera, NOT towards it + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)).mul(new Quaternionf().rotateY((float)Math.PI)); Quaterniond quatd = new Quaterniond(quatRaw).normalize(); - return quatd; } @@ -244,9 +244,9 @@ public class CameraEntityUtils { * @return The rotation quaternion */ public static Quaterniond getRotationQuat(double yaw, double pitch){ - Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)); + //quaternion is multiplied by pi because we want to point away from the eye of the camera, NOT towards it + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)).mul(new Quaternionf().rotateY((float)Math.PI)); Quaterniond quatd = new Quaterniond(quatRaw).normalize(); - return quatd; } @@ -257,14 +257,30 @@ public class CameraEntityUtils { * @return The rotation matrix */ public static Matrix4d getRotationMat(double yaw, double pitch){ - Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)); + //quaternion is multiplied by pi because we want to point away from the eye of the camera, NOT towards it + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)).mul(new Quaternionf().rotateY((float)Math.PI)); Quaterniond quatd = new Quaterniond(quatRaw).normalize(); - Matrix4d rotationMat = new Matrix4d().rotate(quatd); - return rotationMat; } + /** + * Gets the facing vector from the camera angles + * @param cameraEntity The camera entity + * @return The facing vector + */ + public static Vector3d getFacingVec(Entity cameraEntity){ + float yaw = CameraEntityUtils.getCameraYaw(cameraEntity); + float pitch = CameraEntityUtils.getCameraPitch(cameraEntity); + //quaternion is multiplied by pi because we want to point away from the eye of the camera, NOT towards it + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)).mul(new Quaternionf().rotateY((float)Math.PI)); + Quaterniond quatd = new Quaterniond(quatRaw).normalize(); + Matrix4d rotationMat = new Matrix4d().rotate(quatd); + Vector4d rotationVecRaw = MathUtils.getOriginVector4(); + rotationVecRaw = rotationMat.transform(rotationVecRaw); + return new Vector3d(rotationVecRaw.x,0,rotationVecRaw.z); + } + /** * Gets the facing vector from the camera angles * @param yaw The yaw of the camera @@ -272,14 +288,13 @@ public class CameraEntityUtils { * @return The facing vector */ public static Vector3d getFacingVec(double yaw, double pitch){ - Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)); + //quaternion is multiplied by pi because we want to point away from the eye of the camera, NOT towards it + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)).mul(new Quaternionf().rotateY((float)Math.PI)); Quaterniond quatd = new Quaterniond(quatRaw).normalize(); - Matrix4d rotationMat = new Matrix4d().rotate(quatd); Vector4d rotationVecRaw = MathUtils.getOriginVector4(); rotationVecRaw = rotationMat.transform(rotationVecRaw); - - return new Vector3d(-rotationVecRaw.x,0,-rotationVecRaw.z); + return new Vector3d(rotationVecRaw.x,0,rotationVecRaw.z); } /** @@ -289,11 +304,12 @@ public class CameraEntityUtils { * @return The rotation matrix */ public static Matrix4d getRotationMat(Entity entity){ - Quaternionf quatRaw = CameraEntityUtils.getYawQuat(CameraEntityUtils.getCameraYaw(entity)).mul(CameraEntityUtils.getPitchQuat(CameraEntityUtils.getCameraPitch(entity))); + float yaw = CameraEntityUtils.getCameraYaw(entity); + float pitch = CameraEntityUtils.getCameraPitch(entity); + //quaternion is multiplied by pi because we want to point away from the eye of the camera, NOT towards it + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)).mul(new Quaternionf().rotateY((float)Math.PI)); Quaterniond quatd = new Quaterniond(quatRaw).normalize(); - Matrix4d rotationMat = new Matrix4d().rotate(quatd); - return rotationMat; } diff --git a/src/main/java/electrosphere/entity/types/debug/DebugVisualizerUtils.java b/src/main/java/electrosphere/entity/types/debug/DebugVisualizerUtils.java index b8d9ac62..25311a4b 100644 --- a/src/main/java/electrosphere/entity/types/debug/DebugVisualizerUtils.java +++ b/src/main/java/electrosphere/entity/types/debug/DebugVisualizerUtils.java @@ -1,31 +1,68 @@ package electrosphere.entity.types.debug; +import java.util.function.Consumer; + +import org.joml.Quaterniond; import org.joml.Vector3d; +import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityCreationUtils; import electrosphere.entity.EntityUtils; +import electrosphere.entity.btree.BehaviorTree; +import electrosphere.util.math.MathUtils; +/** + * Debug tools for visualizing things in the game engine + */ public class DebugVisualizerUtils { - public static Entity clientSpawnVectorVisualizer(Vector3d position, Vector3d direction){ + /** + * Spawns an entity that visualizes a vector + * @param position The position to start the vector + * @param rotation The rotation of the vector + * @param scale The scale of the vector + * @return The entity that visualizes the vector + */ + public static Entity clientSpawnVectorVisualizer(Vector3d position, Quaterniond rotation, Vector3d scale){ Entity rVal = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(rVal, "Models/unitcube.fbx"); - Vector3d pos = new Vector3d(position).add(new Vector3d(direction).normalize().mul(0.3)); + EntityCreationUtils.makeEntityDrawable(rVal, "Models/basic/geometry/unitvector.glb"); + Vector3d pos = new Vector3d(position); EntityUtils.getPosition(rVal).set(pos); - EntityUtils.getScale(rVal).set(0.05f,0.3f,0.05f); - EntityUtils.getRotation(rVal).rotateTo(new Vector3d(0,1,0), new Vector3d(direction.x,direction.y,direction.z)); + EntityUtils.getScale(rVal).set(scale); + EntityUtils.getRotation(rVal).set(rotation); return rVal; } - public static Entity clientSpawnUpdatingVectorVisualizer(Vector3d position, Vector3d direction){ + /** + * Spawns a vector that visualizes the distance between two points + * @param point1 The first point + * @param point2 The second point + * @return The entity that visualizes the vector + */ + public static Entity clientSpawnVectorVisualizer(Vector3d point1, Vector3d point2){ + Vector3d position = point1; + Quaterniond rotation = MathUtils.calculateRotationFromPointToPoint(point1, point2); + Vector3d scale = new Vector3d(point1.distance(point2)); + return clientSpawnVectorVisualizer(position, rotation, scale); + } + + /** + * Spawns an entity that visualizes a vector. It's transform is constantly updated by a provided callback. + * @param callback The callback which should update the transforms of the vector + * @return The entity that visualizes the vector + */ + public static Entity clientSpawnVectorVisualizer(Consumer callback){ Entity rVal = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(rVal, "Models/unitcube.fbx"); - Vector3d pos = new Vector3d(position).add(new Vector3d(direction).normalize().mul(0.3)); - EntityUtils.getPosition(rVal).set(pos); - EntityUtils.getScale(rVal).set(0.05f,0.3f,0.05f); - EntityUtils.getRotation(rVal).rotateTo(new Vector3d(0,1,0), new Vector3d(direction.x,direction.y,direction.z)); + EntityCreationUtils.makeEntityDrawable(rVal, "Models/basic/geometry/unitvector.glb"); + BehaviorTree updateTree = new BehaviorTree() { + @Override + public void simulate(float deltaTime) { + callback.accept(rVal); + } + }; + Globals.clientSceneWrapper.getScene().registerBehaviorTree(updateTree); return rVal; } diff --git a/src/main/java/electrosphere/menu/debug/ImGuiEntityMacros.java b/src/main/java/electrosphere/menu/debug/ImGuiEntityMacros.java index 8c3ff877..14f56afb 100644 --- a/src/main/java/electrosphere/menu/debug/ImGuiEntityMacros.java +++ b/src/main/java/electrosphere/menu/debug/ImGuiEntityMacros.java @@ -12,8 +12,10 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.equip.ClientEquipState; +import electrosphere.entity.state.server.ServerPlayerViewDirTree; import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.entity.types.debug.DebugVisualizerUtils; import electrosphere.entity.types.foliage.FoliageUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.creature.type.equip.EquipPoint; @@ -28,6 +30,7 @@ import electrosphere.renderer.model.Mesh; import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; +import electrosphere.server.datacell.utils.EntityLookupUtils; import imgui.ImGui; /** @@ -48,6 +51,7 @@ public class ImGuiEntityMacros { private static boolean showEquipStateTab = false; //actor details private static boolean showFirstPersonTab = false; //first person tab private static boolean showLinkedEntitiesTab = false;//show linked entities + private static boolean showServerViewDirTab = false; //show server view dir /** * Creates the windows in this file @@ -116,6 +120,9 @@ public class ImGuiEntityMacros { ){ showLinkedEntitiesTab = !showLinkedEntitiesTab; } + if(ServerPlayerViewDirTree.hasTree(detailViewEntity) && ImGui.checkbox("Server View Dir", showServerViewDirTab)){ + showServerViewDirTab = !showServerViewDirTab; + } ImGui.treePop(); } ImGui.nextColumn(); @@ -123,6 +130,7 @@ public class ImGuiEntityMacros { drawEquipState(); drawFirstPersonView(); drawLinkedEntities(); + drawServerViewDir(); } }); clientEntityDetailWindow.setOpen(false); @@ -234,6 +242,22 @@ public class ImGuiEntityMacros { if(showFirstPersonTab && ImGui.collapsingHeader("First Person Tree")){ ImGui.indent(); // FirstPersonTree firstPersonTree = FirstPersonTree.getTree(detailViewEntity); + if(ImGui.button("Visualize facing vectors")){ + DebugVisualizerUtils.clientSpawnVectorVisualizer((Entity vector) -> { + EntityUtils.getPosition(vector).set(EntityUtils.getPosition(Globals.firstPersonEntity)); + EntityUtils.getRotation(vector).set(EntityUtils.getRotation(Globals.firstPersonEntity)); + }); + DebugVisualizerUtils.clientSpawnVectorVisualizer((Entity vector) -> { + EntityUtils.getPosition(vector).set(EntityUtils.getPosition(Globals.playerEntity)); + EntityUtils.getRotation(vector).set(EntityUtils.getRotation(Globals.playerEntity)); + }); + DebugVisualizerUtils.clientSpawnVectorVisualizer((Entity vector) -> { + int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()); + Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); + EntityUtils.getPosition(vector).set(EntityUtils.getPosition(serverPlayerEntity)); + EntityUtils.getRotation(vector).set(EntityUtils.getRotation(serverPlayerEntity)); + }); + } ImGui.unindent(); } } @@ -329,6 +353,12 @@ public class ImGuiEntityMacros { AttachUtils.setRotationOffset(equippedEntity, AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationFirstPerson())); } } + if(ImGui.button("Print transforms")){ + LoggerInterface.loggerEngine.WARNING("Third person Offset: " + AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorThirdPerson())); + LoggerInterface.loggerEngine.WARNING("First person Offset: " + AttachUtils.getEquipPointVectorOffset(point.getOffsetVectorFirstPerson())); + LoggerInterface.loggerEngine.WARNING("Third person Rotation: " + AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationThirdPerson())); + LoggerInterface.loggerEngine.WARNING("First person Rotation: " + AttachUtils.getEquipPointRotationOffset(point.getOffsetRotationFirstPerson())); + } } } } @@ -373,6 +403,21 @@ public class ImGuiEntityMacros { } } + /** + * Server view dir + */ + protected static void drawServerViewDir(){ + if(showServerViewDirTab && ImGui.collapsingHeader("Server View Dir")){ + ImGui.indent(); + if(ServerPlayerViewDirTree.hasTree(detailViewEntity)){ + ServerPlayerViewDirTree viewDirTree = ServerPlayerViewDirTree.getTree(detailViewEntity); + ImGui.text("Yaw: " + viewDirTree.getYaw()); + ImGui.text("Pitch: " + viewDirTree.getPitch()); + } + ImGui.unindent(); + } + } + /** * Gets the displayed name of an entity (ie creature type, foliage type, terrain, etc) * @param entity diff --git a/src/main/java/electrosphere/menu/debug/ImGuiPlayerEntity.java b/src/main/java/electrosphere/menu/debug/ImGuiPlayerEntity.java new file mode 100644 index 00000000..d84050e8 --- /dev/null +++ b/src/main/java/electrosphere/menu/debug/ImGuiPlayerEntity.java @@ -0,0 +1,140 @@ +package electrosphere.menu.debug; + +import org.ode4j.ode.DBody; + +import electrosphere.collision.PhysicsEntityUtils; +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.attack.ClientAttackTree; +import electrosphere.entity.state.server.ServerPlayerViewDirTree; +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.renderer.ui.imgui.ImGuiWindow; +import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; +import electrosphere.server.datacell.utils.EntityLookupUtils; +import imgui.ImGui; + +/** + * Menus for player entity in particular + */ +public class ImGuiPlayerEntity { + + //player entity details + public static ImGuiWindow playerEntityWindow; + + /** + * Create player entity debug menu + */ + public static void createPlayerEntityDebugWindow(){ + playerEntityWindow = new ImGuiWindow("Player Entity"); + playerEntityWindow.setCallback(new ImGuiWindowCallback() { + @Override + public void exec() { + //player entity details + ImGui.text("Player Entity Details"); + + //data about player entity + if(Globals.playerEntity != null){ + ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity)); + ImGui.text("Rotation: " + EntityUtils.getRotation(Globals.playerEntity)); + + //physics on client + if(ImGui.collapsingHeader("Physics Data")){ + drawPhysicsData(); + } + + //sync data + if(ImGui.collapsingHeader("Synchronization Data")){ + drawSynchronizationData(); + } + + //camera details + if(ImGui.collapsingHeader("Camera Data")){ + drawCameraData(); + } + + } + + // + //Camera controls + if(ImGui.button("Toggle Player Camera Lock")){ + Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity()); + } + if(ImGui.button("Toggle 1st/3rd Person")){ + Globals.controlHandler.setIsThirdPerson(!Globals.controlHandler.cameraIsThirdPerson()); + } + + // + //quick launch entity details + if(ImGui.button("Client Details")){ + ImGuiEntityMacros.showEntity(Globals.playerEntity); + } + ImGui.sameLine(); + if(ImGui.button("1st Person Details")){ + ImGuiEntityMacros.showEntity(Globals.firstPersonEntity); + } + ImGui.sameLine(); + if(ImGui.button("Server Details")){ + int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()); + Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); + ImGuiEntityMacros.showEntity(serverPlayerEntity); + } + + + } + }); + playerEntityWindow.setOpen(false); + Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(playerEntityWindow); + } + + /** + * Draws data about physics for client entity + */ + private static void drawPhysicsData(){ + //client-side tree stuff + DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity); + ClientAttackTree attackTree = ClientAttackTree.getClientAttackTree(Globals.playerEntity); + if(body != null){ + ImGui.text("Velocity: " + body.getLinearVel()); + ImGui.text("Force: " + body.getForce()); + ImGui.text("Angular Velocity: " + body.getAngularVel()); + ImGui.text("Torque: " + body.getTorque()); + ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(Globals.playerEntity)); + if(attackTree != null){ + ImGui.text("Attack Tree State: " + attackTree.getState()); + } + } + } + + /** + * Draws data on server side for synchronization comparison + */ + private static void drawSynchronizationData(){ + //server pos + int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()); + Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); + ImGui.text("Position (Server): " + EntityUtils.getPosition(serverPlayerEntity)); + ImGui.text("Rotation (Server): " + EntityUtils.getRotation(serverPlayerEntity)); + + //server-side physics stuff + DBody serverBody = PhysicsEntityUtils.getDBody(serverPlayerEntity); + if(serverBody != null){ + ImGui.text("Velocity (Server): " + serverBody.getLinearVel()); + ImGui.text("Force (Server): " + serverBody.getForce()); + ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverPlayerEntity)); + ImGui.text("Velocity (Server): " + CreatureUtils.getVelocity(serverPlayerEntity)); + } + ImGui.text("View yaw (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getYaw()); + ImGui.text("View pitch (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getPitch()); + } + + /** + * Draws camera data + */ + private static void drawCameraData(){ + ImGui.text("Yaw: " + CameraEntityUtils.getCameraYaw(Globals.playerCamera)); + ImGui.text("Pitch: " + CameraEntityUtils.getCameraPitch(Globals.playerCamera)); + } + +} diff --git a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java index dbb32c4c..2e5f8bfc 100644 --- a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java +++ b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java @@ -3,21 +3,12 @@ package electrosphere.menu.debug; import java.util.HashMap; import java.util.Map; -import org.ode4j.ode.DBody; - -import electrosphere.collision.PhysicsEntityUtils; import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; -import electrosphere.entity.Entity; -import electrosphere.entity.EntityUtils; -import electrosphere.entity.state.attack.ClientAttackTree; -import electrosphere.entity.state.server.ServerPlayerViewDirTree; -import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.renderer.ui.imgui.ImGuiLinePlot; import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; -import electrosphere.server.datacell.utils.EntityLookupUtils; import electrosphere.server.fluid.manager.ServerFluidManager; import imgui.ImGui; @@ -36,9 +27,6 @@ public class ImGuiWindowMacros { private static ImGuiLinePlot globalFrametimePlot; private static Map globalFrametimeDatasets; - //player entity details - private static ImGuiWindow playerEntityWindow; - //fluid details private static ImGuiWindow fluidWindow; @@ -48,7 +36,7 @@ public class ImGuiWindowMacros { public static void initImGuiWindows(){ createMainDebugMenu(); createFramerateGraph(); - createPlayerEntityDebugWindow(); + ImGuiPlayerEntity.createPlayerEntityDebugWindow(); createFluidDebugWindow(); ImGuiEntityMacros.createClientEntityWindows(); ImGuiUIFramework.createUIFrameworkWindows(); @@ -108,64 +96,6 @@ public class ImGuiWindowMacros { } } - - /** - * Create player entity debug menu - */ - private static void createPlayerEntityDebugWindow(){ - playerEntityWindow = new ImGuiWindow("Player Entity"); - playerEntityWindow.setCallback(new ImGuiWindowCallback() { - @Override - public void exec() { - //player entity details - ImGui.text("Player Entity Details"); - if(Globals.playerEntity != null){ - ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity)); - ImGui.text("Rotation: " + EntityUtils.getRotation(Globals.playerEntity)); - - //server pos - int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()); - Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity); - ImGui.text("Position (Server): " + EntityUtils.getPosition(serverPlayerEntity)); - ImGui.text("Rotation (Server): " + EntityUtils.getRotation(serverPlayerEntity)); - - //client-side tree stuff - DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity); - ClientAttackTree attackTree = ClientAttackTree.getClientAttackTree(Globals.playerEntity); - if(body != null){ - ImGui.text("Velocity: " + body.getLinearVel()); - ImGui.text("Force: " + body.getForce()); - ImGui.text("Angular Velocity: " + body.getAngularVel()); - ImGui.text("Torque: " + body.getTorque()); - ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(Globals.playerEntity)); - if(attackTree != null){ - ImGui.text("Attack Tree State: " + attackTree.getState()); - } - } - - //server-side tree stuff - DBody serverBody = PhysicsEntityUtils.getDBody(serverPlayerEntity); - if(body != null){ - ImGui.text("Velocity (Server): " + serverBody.getLinearVel()); - ImGui.text("Force (Server): " + serverBody.getForce()); - ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverPlayerEntity)); - ImGui.text("Velocity (Server): " + CreatureUtils.getVelocity(serverPlayerEntity)); - } - ImGui.text("View yaw (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getYaw()); - ImGui.text("View pitch (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getPitch()); - } - if(ImGui.button("Toggle Player Camera Lock")){ - Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity()); - } - if(ImGui.button("Toggle 1st/3rd Person")){ - Globals.controlHandler.setIsThirdPerson(!Globals.controlHandler.cameraIsThirdPerson()); - } - } - }); - playerEntityWindow.setOpen(false); - Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(playerEntityWindow); - } - /** * Create fluid debug menu */ @@ -205,7 +135,7 @@ public class ImGuiWindowMacros { } //show audio debug if(ImGui.button("Show Player Entity Debug Menu")){ - playerEntityWindow.setOpen(true); + ImGuiPlayerEntity.playerEntityWindow.setOpen(true); } //show fluids debug if(ImGui.button("Show Fluids Debug Menu")){ diff --git a/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java b/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java index 1d63c53c..e091df56 100644 --- a/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java @@ -1,6 +1,7 @@ package electrosphere.renderer.pipelines; import org.joml.Matrix4d; +import org.joml.Quaterniond; import org.joml.Vector3d; import org.joml.Vector3f; import org.joml.Vector4d; @@ -76,7 +77,7 @@ public class FirstPersonItemsPipeline implements RenderPipeline { //calculate and apply model transform modelTransformMatrix.identity(); modelTransformMatrix.translate(cameraModifiedPosition); - modelTransformMatrix.rotate(EntityUtils.getRotation(child)); + modelTransformMatrix.rotate(new Quaterniond(EntityUtils.getRotation(child))); modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(child))); actor.applySpatialData(modelTransformMatrix,position); //draw diff --git a/src/main/java/electrosphere/util/math/MathUtils.java b/src/main/java/electrosphere/util/math/MathUtils.java index ae42b5bb..391d0c7b 100644 --- a/src/main/java/electrosphere/util/math/MathUtils.java +++ b/src/main/java/electrosphere/util/math/MathUtils.java @@ -16,7 +16,7 @@ public class MathUtils { * @return The origin vector */ public static Vector3d getOriginVector(){ - return new Vector3d(0,0,1); + return new Vector3d(1,0,0); } /** @@ -24,7 +24,7 @@ public class MathUtils { * @return The origin vector */ public static Vector4d getOriginVector4(){ - return new Vector4d(0,0,1,1); + return new Vector4d(1,0,0,1); } /** @@ -32,6 +32,54 @@ public class MathUtils { * @return The origin vector */ public static Vector3f getOriginVectorf(){ + return new Vector3f(1,0,0); + } + + /** + * Gets the origin vector of the engine + * @return The origin vector + */ + public static Vector3d getUpVector(){ + return new Vector3d(0,1,0); + } + + /** + * Gets the origin vector of the engine + * @return The origin vector + */ + public static Vector4d getUpVector4(){ + return new Vector4d(0,1,0,1); + } + + /** + * Gets the origin vector of the engine, in Vector3f format + * @return The origin vector + */ + public static Vector3f getUpVectorf(){ + return new Vector3f(0,1,0); + } + + /** + * Gets the origin vector of the engine + * @return The origin vector + */ + public static Vector3d getLeftVector(){ + return new Vector3d(0,0,1); + } + + /** + * Gets the origin vector of the engine + * @return The origin vector + */ + public static Vector4d getLeftVector4(){ + return new Vector4d(0,0,1,1); + } + + /** + * Gets the origin vector of the engine, in Vector3f format + * @return The origin vector + */ + public static Vector3f getLeftVectorf(){ return new Vector3f(0,0,1); } @@ -43,7 +91,7 @@ public class MathUtils { * @return The quaternion */ public static Quaterniond calculateRotationFromPointToPoint(Vector3d originPoint, Vector3d destinationPoint){ - return getOriginVector().rotationTo(new Vector3d(originPoint).sub(destinationPoint).normalize(), new Quaterniond()); + return getOriginVector().rotationTo(new Vector3d(destinationPoint).sub(originPoint).normalize(), new Quaterniond()); }