diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 2f256c04..46425cb9 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -46,7 +46,8 @@ { "type": "hurt", "bone": "Head", - "radius": 0.06 + "radius": 0.06, + "offset": [0.0,3.0,0.0] } ], "tokens" : [ diff --git a/assets/Data/items.json b/assets/Data/items.json index a9439edb..41da1f73 100644 --- a/assets/Data/items.json +++ b/assets/Data/items.json @@ -72,7 +72,8 @@ { "type": "hit_connected", "bone": "Blade3", - "radius": 0.04 + "radius": 0.04, + "offset": [0, 0, 0.15] } ] }, diff --git a/docs/src/highlevel-design/locations/biomesindex.md b/docs/src/highlevel-design/locations/biomesindex.md index 6b2cc65d..4d4bbeb3 100644 --- a/docs/src/highlevel-design/locations/biomesindex.md +++ b/docs/src/highlevel-design/locations/biomesindex.md @@ -5,4 +5,5 @@ - @subpage largelocationideas - @subpage macrolocationideas - @subpage smalllocations - - @subpage minidungeons \ No newline at end of file + - @subpage minidungeons + - @subpage zones \ No newline at end of file diff --git a/docs/src/highlevel-design/locations/zones.md b/docs/src/highlevel-design/locations/zones.md new file mode 100644 index 00000000..816e432e --- /dev/null +++ b/docs/src/highlevel-design/locations/zones.md @@ -0,0 +1 @@ +@page zones Zones \ No newline at end of file diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 42cac7dc..54f55ebd 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -549,6 +549,9 @@ Always upright tree Fix upright tree clearing linear force/velocity Movement tweaks +(08/13/2024) +Hitbox support offsets now + # TODO diff --git a/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java b/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java index 4eb0fb68..7d8d0efe 100644 --- a/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java +++ b/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java @@ -3,16 +3,13 @@ package electrosphere.collision.hitbox; import electrosphere.collision.collidable.Collidable; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; -import electrosphere.entity.EntityUtils; import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.state.hitbox.HitboxCollectionState; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxType; import electrosphere.game.data.collidable.HitboxData; -import org.joml.Quaterniond; import org.joml.Vector3d; -import org.joml.Vector3f; import org.ode4j.ode.DContactGeom; import org.ode4j.ode.DGeom; @@ -21,211 +18,6 @@ import org.ode4j.ode.DGeom; */ public class HitboxUtils { - // /** - // * Spawns a hitbox entity on the client - // * @param parent The parent entity to attach the hitbox to - // * @param bone The bone on the parent to attach to - // * @param size The radius of the hitsphere - // * @return The hitbox entity - // */ - // public static Entity clientSpawnRegularHitbox(Entity parent, String bone, float size){ - // Entity rVal = EntityCreationUtils.createClientSpatialEntity(); - // HitboxData data = new HitboxData(); - // data.setActive(false); - // data.setBone(bone); - // data.setRadius(size); - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT); - // rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent); - // rVal.putData(EntityDataStrings.HITBOX_DATA, data); - // rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0)); - // rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); - // Globals.clientHitboxManager.registerHitbox(rVal); - // return rVal; - // } - - // /** - // * Spawns a hitbox entity on the server - // * @param parent The parent entity to attach the hitbox to - // * @param bone The bone to attach to the hitbox to - // * @param size The radius of the hitsphere - // * @return The hitbox entity - // */ - // public static Entity serverSpawnRegularHitbox(Entity parent, String bone, float size){ - // Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0)); - // HitboxData data = new HitboxData(); - // data.setActive(false); - // data.setBone(bone); - // data.setRadius(size); - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT); - // rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent); - // rVal.putData(EntityDataStrings.HITBOX_DATA, data); - // rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0)); - // rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); - // Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal); - // return rVal; - // } - - - // /** - // * Spawns a hurtbox on the client - // * @param parent The parent entity of the hurtbox - // * @param bone The bone on the parent to attach the hurtbox to - // * @param size The radius of the hurtsphere - // * @return The hurtbox entity - // */ - // public static Entity clientSpawnRegularHurtbox(Entity parent, String bone, float size){ - // Entity rVal = EntityCreationUtils.createClientSpatialEntity(); - // HitboxData data = new HitboxData(); - // data.setActive(true); - // data.setBone(bone); - // data.setRadius(size); - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT); - // rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent); - // rVal.putData(EntityDataStrings.HITBOX_DATA, data); - // rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0)); - // rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); - // Globals.clientHitboxManager.registerHitbox(rVal); - // return rVal; - // } - - // /** - // * Spawns a hurtbox on the server - // * @param parent The parent entity of the hurtbox - // * @param bone The bone on the parent to attach the hurtbox to - // * @param size The radius of the hurtsphere - // * @return The hurtbox entity - // */ - // public static Entity serverSpawnRegularHurtbox(Entity parent, String bone, float size){ - // Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0)); - // HitboxData data = new HitboxData(); - // data.setActive(true); - // data.setBone(bone); - // data.setRadius(size); - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT); - // rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent); - // rVal.putData(EntityDataStrings.HITBOX_DATA, data); - // rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0)); - // rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); - // Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal); - // return rVal; - // } - - // /** - // * More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone - // * @param parent The parent entity of the hitbox - // * @param positionCallback The position callback for keeping hitbox entity position up to date - // * @param size The size of the hitbox - // * @param hurtbox If true, it will instead be a hurtbox - // * @param filter an optional list of parent entities to not colide with - // * @return The hitbox entity - // */ - // public static Entity clientSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List filter){ - // Entity rVal = EntityCreationUtils.createClientSpatialEntity(); - // HitboxData data = new HitboxData(); - // data.setActive(true); - // data.setPositionCallback(positionCallback); - // data.setRadius(size); - // data.setEntityFilter(filter); - // if(hurtbox){ - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT); - // } else { - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT); - // } - // rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent); - // rVal.putData(EntityDataStrings.HITBOX_DATA, data); - // rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0)); - // rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); - // Globals.clientHitboxManager.registerHitbox(rVal); - // return rVal; - // } - - - // /** - // * More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone - // * @param parent The parent entity of the hitbox - // * @param positionCallback The position callback for keeping hitbox entity position up to date - // * @param size The size of the hitbox - // * @param hurtbox If true, it will instead be a hurtbox - // * @param filter an optional list of parent entities to not colide with - // * @return The hitbox entity - // */ - // public static Entity serverSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List filter){ - // Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0)); - // HitboxData data = new HitboxData(); - // data.setActive(true); - // data.setPositionCallback(positionCallback); - // data.setRadius(size); - // data.setEntityFilter(filter); - // if(hurtbox){ - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT); - // } else { - // data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT); - // } - // rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent); - // rVal.putData(EntityDataStrings.HITBOX_DATA, data); - // rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0)); - // rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true); - // Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal); - // return rVal; - // } - - public static void clientUpdatePosition(Entity hitbox){ - Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT)); - HitboxData hitboxData = getHitboxData(hitbox); - String boneName = hitboxData.getBone(); - if(boneName != null){ - Quaterniond parentRotation = EntityUtils.getRotation(parent); - Vector3f positionScale = EntityUtils.getScale(parent); - Vector3d worldPosition = new Vector3d(); - Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName); - Vector3d parentPos = EntityUtils.getPosition(parent); - worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z); - Quaterniond rotation = new Quaterniond(parentRotation); - - worldPosition = worldPosition.mul(positionScale); - - worldPosition = worldPosition.rotate(rotation); - - - worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z)); - - EntityUtils.getPosition(hitbox).set(worldPosition); - } else { - HitboxPositionCallback positionCallback = hitboxData.getPositionCallback(); - EntityUtils.getPosition(hitbox).set(positionCallback.getPosition()); - } - } - - /** - * Updates the position of a hitbox - * @param hitbox the hitbox to update - */ - public static void serverUpdatePosition(Entity hitbox){ - Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT)); - HitboxData hitboxData = getHitboxData(hitbox); - String boneName = hitboxData.getBone(); - if(boneName != null){ - Quaterniond parentRotation = EntityUtils.getRotation(parent); - Vector3f positionScale = EntityUtils.getScale(parent); - Vector3d worldPosition = new Vector3d(); - Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName); - Vector3d parentPos = EntityUtils.getPosition(parent); - worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z); - Quaterniond rotation = new Quaterniond(parentRotation); - - worldPosition = worldPosition.mul(positionScale); - - worldPosition = worldPosition.rotate(rotation); - - - worldPosition.add(new Vector3d(parentPos.x,parentPos.y,parentPos.z)); - - EntityUtils.getPosition(hitbox).set(worldPosition); - } else { - HitboxPositionCallback positionCallback = hitboxData.getPositionCallback(); - EntityUtils.getPosition(hitbox).set(positionCallback.getPosition()); - } - } /** * Handles a damage collision on the client diff --git a/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java b/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java index a1f99da4..27f29ca5 100644 --- a/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java +++ b/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java @@ -23,7 +23,9 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState.HitboxShapeType; +import electrosphere.entity.types.attach.AttachUtils; import electrosphere.game.data.collidable.HitboxData; +import electrosphere.game.data.utils.DataFormatUtil; import electrosphere.logger.LoggerInterface; import electrosphere.util.math.MathUtils; @@ -235,10 +237,10 @@ public class HitboxCollectionState { HitboxState shapeStatus = this.geomStateMap.get(geom); switch(shapeStatus.shapeType){ case SPHERE: { - this.updateSphereShapePosition(collisionEngine,boneName,bonePosition); + this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition); } break; case CAPSULE: { - this.updateCapsuleShapePosition(collisionEngine,boneName,bonePosition); + this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition); } break; case STATIC_CAPSULE: { } break; @@ -261,10 +263,10 @@ public class HitboxCollectionState { HitboxState shapeStatus = this.geomStateMap.get(geom); switch(shapeStatus.shapeType){ case SPHERE: { - this.updateSphereShapePosition(collisionEngine,boneName,bonePosition); + this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition); } break; case CAPSULE: { - this.updateCapsuleShapePosition(collisionEngine,boneName,bonePosition); + this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition); } break; case STATIC_CAPSULE: { } break; @@ -310,21 +312,27 @@ public class HitboxCollectionState { * @param boneName The name of the bone * @param bonePosition the position of the bone */ - private void updateSphereShapePosition(CollisionEngine collisionEngine, String boneName, Vector3f bonePosition){ + private void updateSphereShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3f bonePosition){ DGeom geom = this.hitboxGeomMap.get(boneName); + + //get offset's transform + Vector3d offsetPosition = DataFormatUtil.getDoubleListAsVector(hitboxState.getHitboxData().getOffset()); + Quaterniond offsetRotation = new Quaterniond(); + + //the bone's transform + Vector3d bonePositionD = new Vector3d(bonePosition); + Quaterniond boneRotation = new Quaterniond(); + + //the parent's transform + Vector3d parentPosition = EntityUtils.getPosition(parent); Quaterniond parentRotation = EntityUtils.getRotation(parent); - Vector3f positionScale = EntityUtils.getScale(parent); - Vector3d worldPosition = new Vector3d(); - Vector3d parentPos = EntityUtils.getPosition(parent); - Quaterniond rotation = new Quaterniond(parentRotation); + Vector3d parentScale = new Vector3d(EntityUtils.getScale(parent)); - //calculate new world pos - worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z); - worldPosition = worldPosition.mul(positionScale); - worldPosition = worldPosition.rotate(rotation); - worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z)); + //calculate + Vector3d hitboxPos = AttachUtils.calculateBoneAttachmentPosition(offsetPosition, offsetRotation, bonePositionD, boneRotation, parentPosition, parentRotation, parentScale); - PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation); + + PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, hitboxPos, new Quaterniond()); } /** @@ -333,23 +341,30 @@ public class HitboxCollectionState { * @param boneName * @param bonePosition */ - private void updateCapsuleShapePosition(CollisionEngine collisionEngine, String boneName, Vector3f bonePosition){ - DGeom geom = this.hitboxGeomMap.get(boneName); - HitboxState shapeStatus = this.geomStateMap.get(geom); - Quaterniond parentRotation = EntityUtils.getRotation(parent); - Vector3f positionScale = EntityUtils.getScale(parent); - Vector3d worldPosition = new Vector3d(); - Vector3d parentPos = EntityUtils.getPosition(parent); - Quaterniond rotation = new Quaterniond(parentRotation); - Vector3d previousWorldPos = shapeStatus.getPreviousWorldPos(); + private void updateCapsuleShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3f bonePosition){ - //calculate new world pos - worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z); - worldPosition = worldPosition.mul(positionScale); - worldPosition = worldPosition.rotate(rotation); - worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z)); - double length = shapeStatus.getHitboxData().getRadius(); - // double radius = shapeStatus.getHitboxData().getRadius(); + //get data about the hitbox + DGeom geom = this.hitboxGeomMap.get(boneName); + Vector3d previousWorldPos = hitboxState.getPreviousWorldPos(); + double length = hitboxState.getHitboxData().getRadius(); + + + //get offset's transform + Vector3d offsetPosition = DataFormatUtil.getDoubleListAsVector(hitboxState.getHitboxData().getOffset()); + Quaterniond offsetRotation = new Quaterniond(); + + //the bone's transform + Vector3d bonePositionD = new Vector3d(bonePosition); + Quaterniond boneRotation = new Quaterniond(); + + //the parent's transform + Vector3d parentPosition = EntityUtils.getPosition(parent); + Quaterniond parentRotation = EntityUtils.getRotation(parent); + Vector3d parentScale = new Vector3d(EntityUtils.getScale(parent)); + + //calculate + Vector3d worldPosition = AttachUtils.calculateBoneAttachmentPosition(offsetPosition, offsetRotation, bonePositionD, boneRotation, parentPosition, parentRotation, parentScale); + Quaterniond worldRotation = new Quaterniond(); if(previousWorldPos != null){ //called all subsequent updates to hitbox position @@ -366,7 +381,7 @@ public class HitboxCollectionState { //the second quaternion is a rotation along the x axis. This is used to put the hitbox rotation into ode's space //ode is Z-axis-up if(previousWorldPos.distance(worldPosition) > 0.0){ - rotation = MathUtils.calculateRotationFromPointToPoint(previousWorldPos,worldPosition).mul(new Quaterniond(0,0.707,0,0.707)); + worldRotation = MathUtils.calculateRotationFromPointToPoint(previousWorldPos,worldPosition).mul(new Quaterniond(0,0.707,0,0.707)); } //create new capsule @@ -389,9 +404,9 @@ public class HitboxCollectionState { } length = 0.1; } - geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), shapeStatus.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT); + geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxState.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT); CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom); - PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, bodyPosition, rotation); + PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, bodyPosition, worldRotation); } else { //called first time the hitbox updates position this.geomStateMap.remove(geom); @@ -399,14 +414,14 @@ public class HitboxCollectionState { CollisionBodyCreation.destroyShape(collisionEngine, geom); //create new capsule - geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), shapeStatus.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT); + geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxState.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT); CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom); } //update maps and other variables for next frame this.hitboxGeomMap.put(boneName,geom); - this.geomStateMap.put(geom,shapeStatus); + this.geomStateMap.put(geom,hitboxState); this.geoms.add(geom); - shapeStatus.setPreviousWorldPos(worldPosition); + hitboxState.setPreviousWorldPos(worldPosition); } /** diff --git a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java index 506f71df..a50beb38 100644 --- a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java +++ b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java @@ -289,6 +289,58 @@ public class AttachUtils { Vector3d bonePosition, Quaterniond boneRotation, + //parent transforms + Vector3d parentPosition, + Quaterniond parentRotation, + Vector3d parentScale + ){ + //transform bone space + Vector3d position = AttachUtils.calculateBoneAttachmentPosition( + offsetVector, + offsetRotation, + bonePosition, + boneRotation, + parentPosition, + parentRotation, + parentScale + ); + //set + EntityUtils.getPosition(child).set(position); + + + //calculate and apply rotation + Quaterniond rotation = AttachUtils.calculateBoneAttachmentRotation( + offsetVector, + offsetRotation, + bonePosition, + boneRotation, + parentPosition, + parentRotation, + parentScale + ); + EntityUtils.getRotation(child).set(rotation); + } + + /** + * Calculates the position of an entity attached to a bone + * @param offsetVector The offset position + * @param offsetRotation The offset rotation + * @param bonePosition The bone's position + * @param boneRotation The bone's rotation + * @param parentPosition The parent's position + * @param parentRotation The parent's rotation + * @param parentScale The parent's scale + * @return The position of the attached/child entity + */ + public static Vector3d calculateBoneAttachmentPosition( + //optional offsets + Vector3d offsetVector, + Quaterniond offsetRotation, + + //current bone transform + Vector3d bonePosition, + Quaterniond boneRotation, + //parent transforms Vector3d parentPosition, Quaterniond parentRotation, @@ -302,11 +354,36 @@ public class AttachUtils { position = position.rotate(new Quaterniond(parentRotation)); //transform worldspace position.add(parentPosition); - //set - EntityUtils.getPosition(child).set(position); - //calculate rotation of model - EntityUtils.getRotation(child) - .identity() + + return position; + } + + /** + * Calculates the rotation of a child that is attached to a bone on an entity + * @param offsetVector The offset vector + * @param offsetRotation The offset rotation + * @param bonePosition The position of the bone + * @param boneRotation The rotation of the bone + * @param parentPosition The position of the parent + * @param parentRotation The rotation of the parent + * @param parentScale The scale of the parent + * @return The rotation of the child + */ + public static Quaterniond calculateBoneAttachmentRotation( + //optional offsets + Vector3d offsetVector, + Quaterniond offsetRotation, + + //current bone transform + Vector3d bonePosition, + Quaterniond boneRotation, + + //parent transforms + Vector3d parentPosition, + Quaterniond parentRotation, + Vector3d parentScale + ){ + return new Quaterniond() .mul(parentRotation) .mul(boneRotation) .mul(offsetRotation) @@ -649,7 +726,6 @@ public class AttachUtils { * @param parentEntity * @return The list of entities that are attached to this parent entity, or null if undefined */ - @SuppressWarnings("unchecked") //as long as we only ever access this value via the getters and setters in this class, this assumption should always be correct public static List getChildrenList(Entity parentEntity){ return (List)parentEntity.getData(EntityDataStrings.ATTACH_CHILDREN_LIST); } diff --git a/src/main/java/electrosphere/game/data/collidable/HitboxData.java b/src/main/java/electrosphere/game/data/collidable/HitboxData.java index 06623c1d..775ab876 100644 --- a/src/main/java/electrosphere/game/data/collidable/HitboxData.java +++ b/src/main/java/electrosphere/game/data/collidable/HitboxData.java @@ -59,6 +59,9 @@ public class HitboxData { //used to filter this hitbox to hitting only certain parent entities List filter; + //The offset from the bone + List offset; + /** * Gets the type of hitbox * @return the type of hitbox @@ -194,6 +197,22 @@ public class HitboxData { public List getEntityFilter(){ return filter; } + + /** + * Gets the offset for the hitbox + * @return The offset + */ + public List getOffset(){ + return this.offset; + } + + /** + * Sets the offset for the hitbox + * @param offset The offset + */ + public void setOffset(List offset){ + this.offset = offset; + } } diff --git a/src/main/java/electrosphere/game/data/utils/DataFormatUtil.java b/src/main/java/electrosphere/game/data/utils/DataFormatUtil.java new file mode 100644 index 00000000..1ce0cea7 --- /dev/null +++ b/src/main/java/electrosphere/game/data/utils/DataFormatUtil.java @@ -0,0 +1,64 @@ +package electrosphere.game.data.utils; + +import java.util.Arrays; +import java.util.List; + +import org.joml.Quaterniond; +import org.joml.Vector3d; + +/** + * Converts data structures between formats saved to disk vs formats used in engine + */ +public class DataFormatUtil { + + /** + * Gets the rotation in quaterniond form + * @param values The list of raw float values + * @return The quaterniond containing those values or an identity quaterniond if no such values exist + */ + public static Quaterniond getDoubleListAsQuaternion(List values){ + if(values == null){ + return new Quaterniond(); + } + if(values.size() > 0){ + return new Quaterniond(values.get(0),values.get(1),values.get(2),values.get(3)); + } else { + return new Quaterniond(); + } + } + + /** + * Gets a quaterniond as a list of doubles + * @param quat The quaternion + * @return The list of doubles + */ + public static List getQuatAsDoubleList(Quaterniond quat){ + return Arrays.asList((Double)quat.x,(Double)quat.y,(Double)quat.z,(Double)quat.w); + } + + /** + * Gets the vector in vector3d form + * @param values The list of raw float values + * @return The vector containing those values or an identity vector if no such values exist + */ + public static Vector3d getDoubleListAsVector(List values){ + if(values == null){ + return new Vector3d(); + } + if(values.size() > 0){ + return new Vector3d(values.get(0),values.get(1),values.get(2)); + } else { + return new Vector3d(); + } + } + + /** + * Gets a vector as a list of doubles + * @param vec The vector + * @return The list of doubles + */ + public static List getVectorAsDoubleList(Vector3d vec){ + return Arrays.asList((Double)vec.x,(Double)vec.y,(Double)vec.z); + } + +}