multiple hitboxes per bone + data fixes
This commit is contained in:
parent
06b068643e
commit
0b2086a1d4
@ -15,22 +15,32 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Leg.L",
|
"bone": "Forearm.L",
|
||||||
"radius": 0.04
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hurt",
|
|
||||||
"bone": "Leg.R",
|
|
||||||
"radius": 0.04
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hurt",
|
|
||||||
"bone": "Shoulder.L",
|
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Shoulder.R",
|
"bone": "Forearm.R",
|
||||||
|
"radius": 0.06
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hurt",
|
||||||
|
"bone": "Leg.L",
|
||||||
|
"radius": 0.06
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hurt",
|
||||||
|
"bone": "Leg.R",
|
||||||
|
"radius": 0.06
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hurt",
|
||||||
|
"bone": "LowerLeg.L",
|
||||||
|
"radius": 0.06
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hurt",
|
||||||
|
"bone": "LowerLeg.R",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -38,16 +48,11 @@
|
|||||||
"bone": "Neck",
|
"bone": "Neck",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "hurt",
|
|
||||||
"bone": "Bone",
|
|
||||||
"radius": 0.08
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Head",
|
"bone": "Head",
|
||||||
"radius": 0.06,
|
"radius": 0.07,
|
||||||
"offset": [0.0,3.0,0.0]
|
"offset": [0.0,0.13,0.0]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tokens" : [
|
"tokens" : [
|
||||||
|
|||||||
@ -69,6 +69,11 @@
|
|||||||
"bone": "Blade2",
|
"bone": "Blade2",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "hit_connected",
|
||||||
|
"bone": "Blade3",
|
||||||
|
"radius": 0.04
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "hit_connected",
|
"type": "hit_connected",
|
||||||
"bone": "Blade3",
|
"bone": "Blade3",
|
||||||
|
|||||||
@ -551,6 +551,7 @@ Movement tweaks
|
|||||||
|
|
||||||
(08/13/2024)
|
(08/13/2024)
|
||||||
Hitbox support offsets now
|
Hitbox support offsets now
|
||||||
|
Multiple hitboxes per bone
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
package electrosphere.entity.state.hitbox;
|
package electrosphere.entity.state.hitbox;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
@ -64,8 +64,10 @@ public class HitboxCollectionState {
|
|||||||
|
|
||||||
//the list of all geoms in the collection state
|
//the list of all geoms in the collection state
|
||||||
List<DGeom> geoms = new LinkedList<DGeom>();
|
List<DGeom> geoms = new LinkedList<DGeom>();
|
||||||
//the map of bone -> hitbox shape in ode4j
|
//the map of bone -> list of states of individual shapes attached to that bone
|
||||||
Map<String,DGeom> hitboxGeomMap = new HashMap<String,DGeom>();
|
Map<String,List<HitboxState>> boneHitboxMap = new HashMap<String,List<HitboxState>>();
|
||||||
|
//map of hitbox state -> geometry
|
||||||
|
Map<HitboxState,DGeom> stateGeomMap = new HashMap<HitboxState,DGeom>();
|
||||||
//the map of geometry -> hitbox shape status, useful for finding data about a given hitbox during collision
|
//the map of geometry -> hitbox shape status, useful for finding data about a given hitbox during collision
|
||||||
Map<DGeom,HitboxState> geomStateMap = new HashMap<DGeom,HitboxState>();
|
Map<DGeom,HitboxState> geomStateMap = new HashMap<DGeom,HitboxState>();
|
||||||
|
|
||||||
@ -154,11 +156,16 @@ public class HitboxCollectionState {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//create the state for the individual shape
|
||||||
|
HitboxState state = new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, subType, shapeType, false);
|
||||||
|
|
||||||
|
//add to structures
|
||||||
if(hitboxDataRaw.getBone() != null){
|
if(hitboxDataRaw.getBone() != null){
|
||||||
rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom);
|
rVal.addHitbox(hitboxDataRaw.getBone(),state);
|
||||||
|
} else {
|
||||||
|
LoggerInterface.loggerEngine.WARNING("Trying to attach hitbox to bone where bone cannot be found: " + hitboxDataRaw.getBone());
|
||||||
}
|
}
|
||||||
rVal.geoms.add(geom);
|
rVal.registerGeom(geom,state);
|
||||||
rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, subType, shapeType, false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//create body with all the shapes
|
//create body with all the shapes
|
||||||
@ -189,28 +196,34 @@ public class HitboxCollectionState {
|
|||||||
* @return The hitbox state that has been attached to the entity
|
* @return The hitbox state that has been attached to the entity
|
||||||
*/
|
*/
|
||||||
public static HitboxCollectionState attachHitboxStateWithCallback(HitboxManager manager, CollisionEngine collisionEngine, Entity entity, HitboxData data, HitboxPositionCallback callback){
|
public static HitboxCollectionState attachHitboxStateWithCallback(HitboxManager manager, CollisionEngine collisionEngine, Entity entity, HitboxData data, HitboxPositionCallback callback){
|
||||||
HitboxCollectionState rVal = new HitboxCollectionState();
|
throw new UnsupportedOperationException("Not yet implemented!");
|
||||||
|
// HitboxCollectionState rVal = new HitboxCollectionState();
|
||||||
|
|
||||||
//create the shapes
|
// //create the shapes
|
||||||
rVal.hitboxGeomMap.put(data.getBone(),CollisionBodyCreation.createShapeSphere(collisionEngine, data.getRadius(), Collidable.TYPE_OBJECT_BIT));
|
// DGeom geom = CollisionBodyCreation.createShapeSphere(collisionEngine, data.getRadius(), Collidable.TYPE_OBJECT_BIT);
|
||||||
|
|
||||||
//create body with all the shapes
|
// //create the state for the individual shape
|
||||||
DGeom[] geomArray = rVal.hitboxGeomMap.values().toArray(new DGeom[rVal.hitboxGeomMap.values().size()]);
|
// HitboxState state = new HitboxState(data.getBone(), data, getType(data), getSubType(data), getShapeType(data), false);
|
||||||
rVal.body = CollisionBodyCreation.createBodyWithShapes(collisionEngine, geomArray);
|
// rVal.addHitbox(data.getBone(), state);
|
||||||
|
// rVal.registerGeom(geom,state);
|
||||||
|
|
||||||
//register collidable with collision engine
|
// //create body with all the shapes
|
||||||
Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
// DGeom[] geomArray = rVal.geoms.toArray(new DGeom[rVal.geoms.size()]);
|
||||||
collisionEngine.registerCollisionObject(rVal.body, collidable);
|
// rVal.body = CollisionBodyCreation.createBodyWithShapes(collisionEngine, geomArray);
|
||||||
|
|
||||||
//attach
|
// //register collidable with collision engine
|
||||||
entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
// Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
||||||
rVal.parent = entity;
|
// collisionEngine.registerCollisionObject(rVal.body, collidable);
|
||||||
|
|
||||||
//register
|
// //attach
|
||||||
manager.registerHitbox(rVal);
|
// entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
||||||
rVal.manager = manager;
|
// rVal.parent = entity;
|
||||||
|
|
||||||
return rVal;
|
// //register
|
||||||
|
// manager.registerHitbox(rVal);
|
||||||
|
// rVal.manager = manager;
|
||||||
|
|
||||||
|
// return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,22 +241,24 @@ public class HitboxCollectionState {
|
|||||||
*/
|
*/
|
||||||
public void updateHitboxPositions(CollisionEngine collisionEngine){
|
public void updateHitboxPositions(CollisionEngine collisionEngine){
|
||||||
if(parent != null && !isServer && EntityUtils.getActor(parent) != null){
|
if(parent != null && !isServer && EntityUtils.getActor(parent) != null){
|
||||||
if(!this.hitboxGeomMap.isEmpty()){
|
if(!this.geoms.isEmpty()){
|
||||||
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||||
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
||||||
for(String boneName : this.hitboxGeomMap.keySet()){
|
for(String boneName : this.boneHitboxMap.keySet()){
|
||||||
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
||||||
DGeom geom = this.hitboxGeomMap.get(boneName);
|
for(HitboxState state : this.boneHitboxMap.get(boneName)){
|
||||||
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
DGeom geom = this.stateGeomMap.get(state);
|
||||||
switch(shapeStatus.shapeType){
|
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||||
case SPHERE: {
|
switch(shapeStatus.shapeType){
|
||||||
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
case SPHERE: {
|
||||||
} break;
|
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||||
case CAPSULE: {
|
} break;
|
||||||
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
case CAPSULE: {
|
||||||
} break;
|
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||||
case STATIC_CAPSULE: {
|
} break;
|
||||||
} break;
|
case STATIC_CAPSULE: {
|
||||||
|
} break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(positionCallback != null){
|
} else if(positionCallback != null){
|
||||||
@ -254,22 +269,24 @@ public class HitboxCollectionState {
|
|||||||
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
}
|
}
|
||||||
} else if(parent != null && isServer && EntityUtils.getPoseActor(parent) != null){
|
} else if(parent != null && isServer && EntityUtils.getPoseActor(parent) != null){
|
||||||
if(!this.hitboxGeomMap.isEmpty()){
|
if(!this.geoms.isEmpty()){
|
||||||
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||||
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
||||||
for(String boneName : this.hitboxGeomMap.keySet()){
|
for(String boneName : this.boneHitboxMap.keySet()){
|
||||||
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
|
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
|
||||||
DGeom geom = this.hitboxGeomMap.get(boneName);
|
for(HitboxState state : this.boneHitboxMap.get(boneName)){
|
||||||
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
DGeom geom = this.stateGeomMap.get(state);
|
||||||
switch(shapeStatus.shapeType){
|
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||||
case SPHERE: {
|
switch(shapeStatus.shapeType){
|
||||||
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
case SPHERE: {
|
||||||
} break;
|
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||||
case CAPSULE: {
|
} break;
|
||||||
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
case CAPSULE: {
|
||||||
} break;
|
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||||
case STATIC_CAPSULE: {
|
} break;
|
||||||
} break;
|
case STATIC_CAPSULE: {
|
||||||
|
} break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(positionCallback != null){
|
} else if(positionCallback != null){
|
||||||
@ -313,7 +330,7 @@ public class HitboxCollectionState {
|
|||||||
* @param bonePosition the position of the bone
|
* @param bonePosition the position of the bone
|
||||||
*/
|
*/
|
||||||
private void updateSphereShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3f bonePosition){
|
private void updateSphereShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3f bonePosition){
|
||||||
DGeom geom = this.hitboxGeomMap.get(boneName);
|
DGeom geom = this.stateGeomMap.get(hitboxState);
|
||||||
|
|
||||||
//get offset's transform
|
//get offset's transform
|
||||||
Vector3d offsetPosition = DataFormatUtil.getDoubleListAsVector(hitboxState.getHitboxData().getOffset());
|
Vector3d offsetPosition = DataFormatUtil.getDoubleListAsVector(hitboxState.getHitboxData().getOffset());
|
||||||
@ -344,7 +361,7 @@ public class HitboxCollectionState {
|
|||||||
private void updateCapsuleShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3f bonePosition){
|
private void updateCapsuleShapePosition(CollisionEngine collisionEngine, String boneName, HitboxState hitboxState, Vector3f bonePosition){
|
||||||
|
|
||||||
//get data about the hitbox
|
//get data about the hitbox
|
||||||
DGeom geom = this.hitboxGeomMap.get(boneName);
|
DGeom geom = this.stateGeomMap.get(hitboxState);
|
||||||
Vector3d previousWorldPos = hitboxState.getPreviousWorldPos();
|
Vector3d previousWorldPos = hitboxState.getPreviousWorldPos();
|
||||||
double length = hitboxState.getHitboxData().getRadius();
|
double length = hitboxState.getHitboxData().getRadius();
|
||||||
|
|
||||||
@ -418,7 +435,7 @@ public class HitboxCollectionState {
|
|||||||
CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom);
|
CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom);
|
||||||
}
|
}
|
||||||
//update maps and other variables for next frame
|
//update maps and other variables for next frame
|
||||||
this.hitboxGeomMap.put(boneName,geom);
|
this.stateGeomMap.put(hitboxState,geom);
|
||||||
this.geomStateMap.put(geom,hitboxState);
|
this.geomStateMap.put(geom,hitboxState);
|
||||||
this.geoms.add(geom);
|
this.geoms.add(geom);
|
||||||
hitboxState.setPreviousWorldPos(worldPosition);
|
hitboxState.setPreviousWorldPos(worldPosition);
|
||||||
@ -514,20 +531,115 @@ public class HitboxCollectionState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the set of bone names in the state data
|
* Gets the hitboxes associated with a bone
|
||||||
* @return The set of bone names in the state data
|
* @param bone The bone
|
||||||
|
* @return The list of hitboxes if at least one is present, null otherwise
|
||||||
*/
|
*/
|
||||||
public Set<String> getBones(){
|
private List<HitboxState> getHitboxes(String bone){
|
||||||
return this.hitboxGeomMap.keySet();
|
return this.boneHitboxMap.get(bone);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets geometry on a single hitbox based on its bone name
|
* Adds a hitbox to a bone
|
||||||
* @param boneName the bone name
|
* @param bone The bone
|
||||||
* @return the hitbox geometry
|
* @param state The hitbox
|
||||||
*/
|
*/
|
||||||
public DGeom getGeometry(String boneName){
|
private void addHitbox(String bone, HitboxState state){
|
||||||
return this.hitboxGeomMap.get(boneName);
|
if(this.boneHitboxMap.containsKey(bone)){
|
||||||
|
this.boneHitboxMap.get(bone).add(state);
|
||||||
|
} else {
|
||||||
|
List<HitboxState> states = new LinkedList<HitboxState>();
|
||||||
|
states.add(state);
|
||||||
|
this.boneHitboxMap.put(bone,states);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a geometry
|
||||||
|
* @param geom The geom
|
||||||
|
* @param state The state associated with the geom
|
||||||
|
*/
|
||||||
|
private void registerGeom(DGeom geom, HitboxState state){
|
||||||
|
this.geoms.add(geom);
|
||||||
|
this.geomStateMap.put(geom,state);
|
||||||
|
this.stateGeomMap.put(state,geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox type of a given hitbox data
|
||||||
|
* @param data The data
|
||||||
|
* @return The type of hitbox
|
||||||
|
*/
|
||||||
|
private static HitboxType getType(HitboxData data){
|
||||||
|
switch(data.getType()){
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT: {
|
||||||
|
return HitboxType.HIT;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT: {
|
||||||
|
return HitboxType.HURT;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
|
||||||
|
return HitboxType.HIT;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
|
return HitboxType.HURT;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_TYPE_STATIC_CAPSULE: {
|
||||||
|
return HitboxType.HURT;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Trying to parse undefined hitbox type " + data.getType()));
|
||||||
|
return HitboxType.HIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the shape type of a hitbox data object
|
||||||
|
* @param data The data
|
||||||
|
* @return The shape type
|
||||||
|
*/
|
||||||
|
private static HitboxShapeType getShapeType(HitboxData data){
|
||||||
|
switch(data.getType()){
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT:
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT: {
|
||||||
|
return HitboxShapeType.SPHERE;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT_CONNECTED:
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
|
return HitboxShapeType.CAPSULE;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_TYPE_STATIC_CAPSULE: {
|
||||||
|
return HitboxShapeType.STATIC_CAPSULE;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Trying to parse undefined hitbox shape type " + data.getType()));
|
||||||
|
return HitboxShapeType.SPHERE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox subtype
|
||||||
|
* @param data The data
|
||||||
|
* @return The subtype
|
||||||
|
*/
|
||||||
|
private static HitboxSubtype getSubType(HitboxData data){
|
||||||
|
switch(data.getSubType()){
|
||||||
|
case HitboxData.HITBOX_SUBTYPE_SWEET: {
|
||||||
|
return HitboxSubtype.SWEET;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_SUBTYPE_REUGLAR: {
|
||||||
|
return HitboxSubtype.REGULAR;
|
||||||
|
}
|
||||||
|
case HitboxData.HITBOX_SUBTYPE_SOUR: {
|
||||||
|
return HitboxSubtype.SOUR;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
LoggerInterface.loggerEngine.ERROR(new IllegalArgumentException("Trying to parse undefined hitbox subtype " + data.getSubType()));
|
||||||
|
return HitboxSubtype.REGULAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user