diff --git a/net/entity.json b/net/entity.json index e2dec0ac..8e64d34e 100644 --- a/net/entity.json +++ b/net/entity.json @@ -49,6 +49,14 @@ "name" : "rotationW", "type" : "FIXED_DOUBLE" }, + { + "name" : "yaw", + "type" : "FIXED_DOUBLE" + }, + { + "name" : "pitch", + "type" : "FIXED_DOUBLE" + }, { "name" : "velocity", "type" : "FIXED_DOUBLE" @@ -251,9 +259,9 @@ "data" : [ "entityID", "time", - "positionX", - "positionY", - "positionZ" + "propertyType", + "yaw", + "pitch" ] } diff --git a/pom.xml b/pom.xml index 059e8b38..06a7989a 100644 --- a/pom.xml +++ b/pom.xml @@ -305,7 +305,7 @@ exec - ${basedir}/assets/scripts/compiler/get_typescript.sh + ${basedir}/Assets/Scripts/compiler/get_typescript.sh @@ -350,7 +350,7 @@ exec - ${basedir}/assets/scripts/compiler/get_typescript.sh + ${basedir}/Assets/Scripts/compiler/get_typescript.sh diff --git a/src/main/java/electrosphere/controls/CameraHandler.java b/src/main/java/electrosphere/controls/CameraHandler.java index 6f5f9cfe..62393c28 100644 --- a/src/main/java/electrosphere/controls/CameraHandler.java +++ b/src/main/java/electrosphere/controls/CameraHandler.java @@ -18,6 +18,11 @@ import electrosphere.util.MathUtils; * Handler for camera-related events and controls */ public class CameraHandler { + + //The first person camera perspective + public static final int CAMERA_PERSPECTIVE_FIRST = 1; + //The third person camera perspective + public static final int CAMERA_PERSPECTIVE_THIRD = 3; //the horizontal mouse sensitivity float mouseSensitivityHorizontal = .1f; @@ -130,14 +135,18 @@ public class CameraHandler { cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera)); CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector); - //tell the server that we changed where we're looking + //tell the server that we changed where we're looking, if we're in first person + int perspectiveVal = CameraHandler.CAMERA_PERSPECTIVE_FIRST; + if(Globals.controlHandler.cameraIsThirdPerson()){ + perspectiveVal = CameraHandler.CAMERA_PERSPECTIVE_THIRD; + } Globals.clientConnection.queueOutgoingMessage( EntityMessage.constructupdateEntityViewDirMessage( Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()), Globals.timekeeper.getNumberOfSimFramesElapsed(), - cameraRotationVector.x, - cameraRotationVector.y, - cameraRotationVector.z + perspectiveVal, + yaw, + pitch ) ); 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 e2b47339..1ec83556 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ServerGroundMovementTree.java @@ -12,6 +12,7 @@ import electrosphere.entity.state.gravity.GravityUtils; import electrosphere.collision.PhysicsEntityUtils; import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; +import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; @@ -26,6 +27,7 @@ import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState; import electrosphere.entity.state.movement.jump.ServerJumpTree; +import electrosphere.entity.state.server.ServerPlayerViewDirTree; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.synchronization.annotation.SyncedField; import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; @@ -165,8 +167,11 @@ public class ServerGroundMovementTree implements BehaviorTree { acceleration = CreatureUtils.getAcceleration(parent); maxNaturalVelocity = sprintTree != null && sprintTree.getState() == SprintTreeState.SPRINTING ? sprintTree.getMaxVelocity() : CreatureUtils.getMaxNaturalVelocity(parent); } + if(ServerPlayerViewDirTree.hasTree(parent)){ + ServerPlayerViewDirTree serverViewTree =ServerPlayerViewDirTree.getTree(parent); + CreatureUtils.setFacingVector(parent, CameraEntityUtils.getFacingVec(serverViewTree.getYaw(), serverViewTree.getPitch())); + } PoseActor poseActor = EntityUtils.getPoseActor(parent); -// Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent)); Vector3d position = EntityUtils.getPosition(parent); Vector3d facingVector = CreatureUtils.getFacingVector(parent); DBody body = PhysicsEntityUtils.getDBody(parent); diff --git a/src/main/java/electrosphere/entity/state/server/ServerPlayerViewDirTree.java b/src/main/java/electrosphere/entity/state/server/ServerPlayerViewDirTree.java index 10f9fab7..b5f6cae5 100644 --- a/src/main/java/electrosphere/entity/state/server/ServerPlayerViewDirTree.java +++ b/src/main/java/electrosphere/entity/state/server/ServerPlayerViewDirTree.java @@ -1,10 +1,11 @@ package electrosphere.entity.state.server; -import org.joml.Vector3d; - +import electrosphere.controls.CameraHandler; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; +import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.entity.types.creature.CreatureUtils; @@ -13,12 +14,15 @@ import electrosphere.entity.types.creature.CreatureUtils; */ public class ServerPlayerViewDirTree implements BehaviorTree { - //the direction of the view - Vector3d playerViewDir = new Vector3d(); - //the last time this value was updated long lastUpdateTime = 0; + //The yaw for the camera + double yaw; + + //The pitch for the camera + double pitch; + //the parent entity Entity parent; @@ -63,22 +67,39 @@ public class ServerPlayerViewDirTree implements BehaviorTree { } /** - * Gets the player view dir - * @return The player view dir + * Gets the yaw + * @return The yaw */ - public Vector3d getPlayerViewDir(){ - return playerViewDir; + public double getYaw(){ + return yaw; + } + + /** + * Gets the pitch + * @return The pitch + */ + public double getPitch(){ + return pitch; } /** * Sets the player view dir vector * @param playerViewDir The player view dir vector */ - public void setPlayerViewDir(Vector3d playerViewDir, long time){ + public void setPlayerViewDir(int perspective, double yaw, double pitch, long time){ if(time > lastUpdateTime){ - this.playerViewDir = playerViewDir; + //set initial values + this.yaw = yaw; + this.pitch = pitch; + + //if first person, set facing angle + if(perspective == CameraHandler.CAMERA_PERSPECTIVE_FIRST){ + CreatureUtils.setFacingVector(parent, CameraEntityUtils.getFacingVec(yaw, pitch)); + EntityUtils.getRotation(parent).set(CameraEntityUtils.getRotationQuat(yaw,pitch)); + } + + this.lastUpdateTime = time; - CreatureUtils.setFacingVector(parent, new Vector3d(-playerViewDir.x,0,-playerViewDir.z)); } } diff --git a/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java b/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java index 025ea664..77094ea7 100644 --- a/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java +++ b/src/main/java/electrosphere/entity/types/camera/CameraEntityUtils.java @@ -8,10 +8,13 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; import electrosphere.util.MathUtils; +import org.joml.Matrix4d; import org.joml.Matrix4f; +import org.joml.Quaterniond; import org.joml.Quaternionf; import org.joml.Vector3d; import org.joml.Vector3f; +import org.joml.Vector4d; /** * Camera entity utility functions @@ -177,21 +180,21 @@ public class CameraEntityUtils { /** * Gets the quaternion containing the camera pitch - * @param camera - * @return + * @param camera The pitch of the camera + * @return The quaternion */ - public static Quaternionf getPitchQuat(Entity camera){ - Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(1,0,0), -getCameraPitch(camera)); + public static Quaternionf getPitchQuat(double pitch){ + Quaternionf pitchQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(1,0,0), -(float)pitch); return pitchQuat; } /** * Gets the quaternion containing the camera yaw - * @param camera - * @return + * @param yaw The yaw of the camera + * @return The quaternion */ - public static Quaternionf getYawQuat(Entity camera){ - Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(0,1,0), -getCameraYaw(camera)); + public static Quaternionf getYawQuat(double yaw){ + Quaternionf yawQuat = new Quaternionf().fromAxisAngleDeg(new Vector3f(0,1,0), -(float)yaw); return yawQuat; } @@ -219,5 +222,79 @@ public class CameraEntityUtils { ).scale(1.0f, 1.0f, 1.0f); return rVal; } + + /** + * Gets the rotation quaternion from a camera entity + * @param entity The entity + * @return The rotation quaternion + */ + 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)); + Quaterniond quatd = new Quaterniond(quatRaw).normalize(); + + return quatd; + } + + /** + * Gets the rotation quaternion from a yaw and pitch + * @param yaw The yaw + * @param pitch The pitch + * @return The rotation quaternion + */ + public static Quaterniond getRotationQuat(double yaw, double pitch){ + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)); + Quaterniond quatd = new Quaterniond(quatRaw).normalize(); + + return quatd; + } + + /** + * Gets the rotation matrix from a yaw and pitch + * @param yaw The yaw + * @param pitch The pitch + * @return The rotation matrix + */ + public static Matrix4d getRotationMat(double yaw, double pitch){ + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)); + Quaterniond quatd = new Quaterniond(quatRaw).normalize(); + + Matrix4d rotationMat = new Matrix4d().rotate(quatd); + + return rotationMat; + } + + /** + * Gets the facing vector from the camera angles + * @param yaw The yaw of the camera + * @param pitch The pitch of the camera + * @return The facing vector + */ + public static Vector3d getFacingVec(double yaw, double pitch){ + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(yaw).mul(CameraEntityUtils.getPitchQuat(pitch)); + 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 rotation matrix from a yaw and pitch + * @param yaw The yaw + * @param pitch The pitch + * @return The rotation matrix + */ + public static Matrix4d getRotationMat(Entity entity){ + Quaternionf quatRaw = CameraEntityUtils.getYawQuat(CameraEntityUtils.getCameraYaw(entity)).mul(CameraEntityUtils.getPitchQuat(CameraEntityUtils.getCameraPitch(entity))); + Quaterniond quatd = new Quaterniond(quatRaw).normalize(); + + Matrix4d rotationMat = new Matrix4d().rotate(quatd); + + return rotationMat; + } } diff --git a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java index 344f8748..42687fbd 100644 --- a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java +++ b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java @@ -216,7 +216,8 @@ public class ImGuiWindowMacros { ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverPlayerEntity)); ImGui.text("Velocity (Server): " + CreatureUtils.getVelocity(serverPlayerEntity)); } - ImGui.text("View dir (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getPlayerViewDir()); + 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()); diff --git a/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java b/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java index f836c0ab..f1491dce 100644 --- a/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/EntityMessage.java @@ -35,6 +35,8 @@ public class EntityMessage extends NetworkMessage { double rotationY; double rotationZ; double rotationW; + double yaw; + double pitch; double velocity; int treeState; int propertyType; @@ -149,6 +151,22 @@ public class EntityMessage extends NetworkMessage { this.rotationW = rotationW; } + public double getyaw() { + return yaw; + } + + public void setyaw(double yaw) { + this.yaw = yaw; + } + + public double getpitch() { + return pitch; + } + + public void setpitch(double pitch) { + this.pitch = pitch; + } + public double getvelocity() { return velocity; } @@ -794,19 +812,19 @@ public class EntityMessage extends NetworkMessage { stripPacketHeader(byteBuffer); rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer)); - rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); - rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); - rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpropertyType(ByteStreamUtils.popIntFromByteQueue(byteBuffer)); + rVal.setyaw(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setpitch(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); return rVal; } - public static EntityMessage constructupdateEntityViewDirMessage(int entityID,long time,double positionX,double positionY,double positionZ){ + public static EntityMessage constructupdateEntityViewDirMessage(int entityID,long time,int propertyType,double yaw,double pitch){ EntityMessage rVal = new EntityMessage(EntityMessageType.UPDATEENTITYVIEWDIR); rVal.setentityID(entityID); rVal.settime(time); - rVal.setpositionX(positionX); - rVal.setpositionY(positionY); - rVal.setpositionZ(positionZ); + rVal.setpropertyType(propertyType); + rVal.setyaw(yaw); + rVal.setpitch(pitch); rVal.serialize(); return rVal; } @@ -1161,7 +1179,7 @@ public class EntityMessage extends NetworkMessage { } break; case UPDATEENTITYVIEWDIR: - rawBytes = new byte[2+4+8+8+8+8]; + rawBytes = new byte[2+4+8+4+8+8]; //message header rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY; //entity messaage header @@ -1174,17 +1192,17 @@ public class EntityMessage extends NetworkMessage { for(int i = 0; i < 8; i++){ rawBytes[6+i] = intValues[i]; } - intValues = ByteStreamUtils.serializeDoubleToBytes(positionX); - for(int i = 0; i < 8; i++){ + intValues = ByteStreamUtils.serializeIntToBytes(propertyType); + for(int i = 0; i < 4; i++){ rawBytes[14+i] = intValues[i]; } - intValues = ByteStreamUtils.serializeDoubleToBytes(positionY); + intValues = ByteStreamUtils.serializeDoubleToBytes(yaw); for(int i = 0; i < 8; i++){ - rawBytes[22+i] = intValues[i]; + rawBytes[18+i] = intValues[i]; } - intValues = ByteStreamUtils.serializeDoubleToBytes(positionZ); + intValues = ByteStreamUtils.serializeDoubleToBytes(pitch); for(int i = 0; i < 8; i++){ - rawBytes[30+i] = intValues[i]; + rawBytes[26+i] = intValues[i]; } break; } diff --git a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java index cb66d03a..d9243c79 100644 --- a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java +++ b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java @@ -39,7 +39,7 @@ Message categories public static final byte ENTITY_MESSAGE_TYPE_KILL_SIZE = 14; public static final byte ENTITY_MESSAGE_TYPE_DESTROY_SIZE = 6; public static final byte ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE = 22; - public static final byte ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR_SIZE = 38; + public static final byte ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR_SIZE = 34; /* Lore subcategories */ diff --git a/src/main/java/electrosphere/net/server/protocol/EntityProtocol.java b/src/main/java/electrosphere/net/server/protocol/EntityProtocol.java index dcc95812..da435919 100644 --- a/src/main/java/electrosphere/net/server/protocol/EntityProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/EntityProtocol.java @@ -1,7 +1,5 @@ package electrosphere.net.server.protocol; -import org.joml.Vector3d; - import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.state.attack.ServerAttackTree; @@ -54,7 +52,7 @@ public class EntityProtocol implements ServerProtocolTemplate { case UPDATEENTITYVIEWDIR: { targetEntity = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId()); if(targetEntity != null && ServerPlayerViewDirTree.hasTree(targetEntity)){ - ServerPlayerViewDirTree.getTree(targetEntity).setPlayerViewDir(new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()),message.gettime()); + ServerPlayerViewDirTree.getTree(targetEntity).setPlayerViewDir(message.getpropertyType(), message.getyaw(),message.getpitch(),message.gettime()); } } break; //ignore stack diff --git a/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java b/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java index 45188bad..e884fb40 100644 --- a/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/FirstPersonItemsPipeline.java @@ -1,8 +1,6 @@ package electrosphere.renderer.pipelines; import org.joml.Matrix4d; -import org.joml.Quaterniond; -import org.joml.Quaternionf; import org.joml.Vector3d; import org.joml.Vector3f; import org.joml.Vector4d; @@ -96,11 +94,8 @@ public class FirstPersonItemsPipeline implements RenderPipeline { 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); + Matrix4d rotationMat = CameraEntityUtils.getRotationMat(Globals.playerCamera); + EntityUtils.getRotation(Globals.firstPersonEntity).set(CameraEntityUtils.getRotationQuat(Globals.playerCamera)); Vector3d playerPos = EntityUtils.getPosition(Globals.playerEntity); Vector4d behindCameraOffsetRaw = rotationMat.transform(new Vector4d(0,tree.getCameraViewDirOffsetY(),tree.getCameraViewDirOffsetZ(),1)); //pushes the model behind the camera diff --git a/src/main/java/electrosphere/util/MathUtils.java b/src/main/java/electrosphere/util/MathUtils.java index 079cf2f2..ff07dc0c 100644 --- a/src/main/java/electrosphere/util/MathUtils.java +++ b/src/main/java/electrosphere/util/MathUtils.java @@ -3,6 +3,7 @@ package electrosphere.util; import org.joml.Quaterniond; import org.joml.Vector3d; import org.joml.Vector3f; +import org.joml.Vector4d; /** * Utility functions for doing math @@ -18,6 +19,14 @@ public class MathUtils { return new Vector3d(0,0,1); } + /** + * Gets the origin vector of the engine + * @return The origin vector + */ + public static Vector4d getOriginVector4(){ + return new Vector4d(0,0,1,1); + } + /** * Gets the origin vector of the engine, in Vector3f format * @return The origin vector