multiple hitboxes per bone + data fixes
This commit is contained in:
parent
06b068643e
commit
0b2086a1d4
@ -15,22 +15,32 @@
|
||||
},
|
||||
{
|
||||
"type": "hurt",
|
||||
"bone": "Leg.L",
|
||||
"radius": 0.04
|
||||
},
|
||||
{
|
||||
"type": "hurt",
|
||||
"bone": "Leg.R",
|
||||
"radius": 0.04
|
||||
},
|
||||
{
|
||||
"type": "hurt",
|
||||
"bone": "Shoulder.L",
|
||||
"bone": "Forearm.L",
|
||||
"radius": 0.06
|
||||
},
|
||||
{
|
||||
"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
|
||||
},
|
||||
{
|
||||
@ -38,16 +48,11 @@
|
||||
"bone": "Neck",
|
||||
"radius": 0.06
|
||||
},
|
||||
{
|
||||
"type": "hurt",
|
||||
"bone": "Bone",
|
||||
"radius": 0.08
|
||||
},
|
||||
{
|
||||
"type": "hurt",
|
||||
"bone": "Head",
|
||||
"radius": 0.06,
|
||||
"offset": [0.0,3.0,0.0]
|
||||
"radius": 0.07,
|
||||
"offset": [0.0,0.13,0.0]
|
||||
}
|
||||
],
|
||||
"tokens" : [
|
||||
|
||||
@ -69,6 +69,11 @@
|
||||
"bone": "Blade2",
|
||||
"radius": 0.04
|
||||
},
|
||||
{
|
||||
"type": "hit_connected",
|
||||
"bone": "Blade3",
|
||||
"radius": 0.04
|
||||
},
|
||||
{
|
||||
"type": "hit_connected",
|
||||
"bone": "Blade3",
|
||||
|
||||
@ -551,6 +551,7 @@ Movement tweaks
|
||||
|
||||
(08/13/2024)
|
||||
Hitbox support offsets now
|
||||
Multiple hitboxes per bone
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package electrosphere.entity.state.hitbox;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
@ -64,8 +64,10 @@ public class HitboxCollectionState {
|
||||
|
||||
//the list of all geoms in the collection state
|
||||
List<DGeom> geoms = new LinkedList<DGeom>();
|
||||
//the map of bone -> hitbox shape in ode4j
|
||||
Map<String,DGeom> hitboxGeomMap = new HashMap<String,DGeom>();
|
||||
//the map of bone -> list of states of individual shapes attached to that bone
|
||||
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
|
||||
Map<DGeom,HitboxState> geomStateMap = new HashMap<DGeom,HitboxState>();
|
||||
|
||||
@ -154,11 +156,16 @@ public class HitboxCollectionState {
|
||||
} 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){
|
||||
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.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, subType, shapeType, false));
|
||||
rVal.registerGeom(geom,state);
|
||||
}
|
||||
|
||||
//create body with all the shapes
|
||||
@ -189,28 +196,34 @@ public class HitboxCollectionState {
|
||||
* @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){
|
||||
HitboxCollectionState rVal = new HitboxCollectionState();
|
||||
throw new UnsupportedOperationException("Not yet implemented!");
|
||||
// HitboxCollectionState rVal = new HitboxCollectionState();
|
||||
|
||||
//create the shapes
|
||||
rVal.hitboxGeomMap.put(data.getBone(),CollisionBodyCreation.createShapeSphere(collisionEngine, data.getRadius(), Collidable.TYPE_OBJECT_BIT));
|
||||
// //create the shapes
|
||||
// DGeom geom = CollisionBodyCreation.createShapeSphere(collisionEngine, data.getRadius(), Collidable.TYPE_OBJECT_BIT);
|
||||
|
||||
//create body with all the shapes
|
||||
DGeom[] geomArray = rVal.hitboxGeomMap.values().toArray(new DGeom[rVal.hitboxGeomMap.values().size()]);
|
||||
rVal.body = CollisionBodyCreation.createBodyWithShapes(collisionEngine, geomArray);
|
||||
// //create the state for the individual shape
|
||||
// HitboxState state = new HitboxState(data.getBone(), data, getType(data), getSubType(data), getShapeType(data), false);
|
||||
// rVal.addHitbox(data.getBone(), state);
|
||||
// rVal.registerGeom(geom,state);
|
||||
|
||||
//register collidable with collision engine
|
||||
Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
||||
collisionEngine.registerCollisionObject(rVal.body, collidable);
|
||||
// //create body with all the shapes
|
||||
// DGeom[] geomArray = rVal.geoms.toArray(new DGeom[rVal.geoms.size()]);
|
||||
// rVal.body = CollisionBodyCreation.createBodyWithShapes(collisionEngine, geomArray);
|
||||
|
||||
//attach
|
||||
entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
||||
rVal.parent = entity;
|
||||
// //register collidable with collision engine
|
||||
// Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
||||
// collisionEngine.registerCollisionObject(rVal.body, collidable);
|
||||
|
||||
//register
|
||||
manager.registerHitbox(rVal);
|
||||
rVal.manager = manager;
|
||||
// //attach
|
||||
// entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
||||
// 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){
|
||||
if(parent != null && !isServer && EntityUtils.getActor(parent) != null){
|
||||
if(!this.hitboxGeomMap.isEmpty()){
|
||||
if(!this.geoms.isEmpty()){
|
||||
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||
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);
|
||||
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||
switch(shapeStatus.shapeType){
|
||||
case SPHERE: {
|
||||
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case CAPSULE: {
|
||||
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case STATIC_CAPSULE: {
|
||||
} break;
|
||||
for(HitboxState state : this.boneHitboxMap.get(boneName)){
|
||||
DGeom geom = this.stateGeomMap.get(state);
|
||||
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||
switch(shapeStatus.shapeType){
|
||||
case SPHERE: {
|
||||
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case CAPSULE: {
|
||||
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case STATIC_CAPSULE: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(positionCallback != null){
|
||||
@ -254,22 +269,24 @@ public class HitboxCollectionState {
|
||||
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||
}
|
||||
} else if(parent != null && isServer && EntityUtils.getPoseActor(parent) != null){
|
||||
if(!this.hitboxGeomMap.isEmpty()){
|
||||
if(!this.geoms.isEmpty()){
|
||||
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||
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);
|
||||
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||
switch(shapeStatus.shapeType){
|
||||
case SPHERE: {
|
||||
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case CAPSULE: {
|
||||
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case STATIC_CAPSULE: {
|
||||
} break;
|
||||
for(HitboxState state : this.boneHitboxMap.get(boneName)){
|
||||
DGeom geom = this.stateGeomMap.get(state);
|
||||
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||
switch(shapeStatus.shapeType){
|
||||
case SPHERE: {
|
||||
this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case CAPSULE: {
|
||||
this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition);
|
||||
} break;
|
||||
case STATIC_CAPSULE: {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(positionCallback != null){
|
||||
@ -313,7 +330,7 @@ public class HitboxCollectionState {
|
||||
* @param bonePosition the position of the bone
|
||||
*/
|
||||
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
|
||||
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){
|
||||
|
||||
//get data about the hitbox
|
||||
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||
DGeom geom = this.stateGeomMap.get(hitboxState);
|
||||
Vector3d previousWorldPos = hitboxState.getPreviousWorldPos();
|
||||
double length = hitboxState.getHitboxData().getRadius();
|
||||
|
||||
@ -418,7 +435,7 @@ public class HitboxCollectionState {
|
||||
CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom);
|
||||
}
|
||||
//update maps and other variables for next frame
|
||||
this.hitboxGeomMap.put(boneName,geom);
|
||||
this.stateGeomMap.put(hitboxState,geom);
|
||||
this.geomStateMap.put(geom,hitboxState);
|
||||
this.geoms.add(geom);
|
||||
hitboxState.setPreviousWorldPos(worldPosition);
|
||||
@ -514,20 +531,115 @@ public class HitboxCollectionState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of bone names in the state data
|
||||
* @return The set of bone names in the state data
|
||||
* Gets the hitboxes associated with a bone
|
||||
* @param bone The bone
|
||||
* @return The list of hitboxes if at least one is present, null otherwise
|
||||
*/
|
||||
public Set<String> getBones(){
|
||||
return this.hitboxGeomMap.keySet();
|
||||
private List<HitboxState> getHitboxes(String bone){
|
||||
return this.boneHitboxMap.get(bone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets geometry on a single hitbox based on its bone name
|
||||
* @param boneName the bone name
|
||||
* @return the hitbox geometry
|
||||
* Adds a hitbox to a bone
|
||||
* @param bone The bone
|
||||
* @param state The hitbox
|
||||
*/
|
||||
public DGeom getGeometry(String boneName){
|
||||
return this.hitboxGeomMap.get(boneName);
|
||||
private void addHitbox(String bone, HitboxState state){
|
||||
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