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