hitbox offsets
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
902680ad16
commit
06b068643e
@ -46,7 +46,8 @@
|
||||
{
|
||||
"type": "hurt",
|
||||
"bone": "Head",
|
||||
"radius": 0.06
|
||||
"radius": 0.06,
|
||||
"offset": [0.0,3.0,0.0]
|
||||
}
|
||||
],
|
||||
"tokens" : [
|
||||
|
||||
@ -72,7 +72,8 @@
|
||||
{
|
||||
"type": "hit_connected",
|
||||
"bone": "Blade3",
|
||||
"radius": 0.04
|
||||
"radius": 0.04,
|
||||
"offset": [0, 0, 0.15]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -5,4 +5,5 @@
|
||||
- @subpage largelocationideas
|
||||
- @subpage macrolocationideas
|
||||
- @subpage smalllocations
|
||||
- @subpage minidungeons
|
||||
- @subpage minidungeons
|
||||
- @subpage zones
|
||||
1
docs/src/highlevel-design/locations/zones.md
Normal file
1
docs/src/highlevel-design/locations/zones.md
Normal file
@ -0,0 +1 @@
|
||||
@page zones Zones
|
||||
@ -549,6 +549,9 @@ Always upright tree
|
||||
Fix upright tree clearing linear force/velocity
|
||||
Movement tweaks
|
||||
|
||||
(08/13/2024)
|
||||
Hitbox support offsets now
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
|
||||
@ -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<Entity> 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<Entity> 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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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<Entity> getChildrenList(Entity parentEntity){
|
||||
return (List<Entity>)parentEntity.getData(EntityDataStrings.ATTACH_CHILDREN_LIST);
|
||||
}
|
||||
|
||||
@ -59,6 +59,9 @@ public class HitboxData {
|
||||
//used to filter this hitbox to hitting only certain parent entities
|
||||
List<Entity> filter;
|
||||
|
||||
//The offset from the bone
|
||||
List<Double> offset;
|
||||
|
||||
/**
|
||||
* Gets the type of hitbox
|
||||
* @return the type of hitbox
|
||||
@ -194,6 +197,22 @@ public class HitboxData {
|
||||
public List<Entity> getEntityFilter(){
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the offset for the hitbox
|
||||
* @return The offset
|
||||
*/
|
||||
public List<Double> getOffset(){
|
||||
return this.offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the offset for the hitbox
|
||||
* @param offset The offset
|
||||
*/
|
||||
public void setOffset(List<Double> offset){
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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<Double> 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<Double> 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<Double> 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<Double> getVectorAsDoubleList(Vector3d vec){
|
||||
return Arrays.asList((Double)vec.x,(Double)vec.y,(Double)vec.z);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user