Model global pretransforms + physics work
This commit is contained in:
parent
f248bf4e2d
commit
dc0a61c0dc
@ -103,6 +103,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.2,
|
||||
"dimension3" : 0.1,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.2,
|
||||
"offsetZ" : 0
|
||||
@ -159,6 +163,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.45,
|
||||
"dimension3" : 0.1,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.45,
|
||||
"offsetZ" : 0
|
||||
@ -208,6 +216,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.2,
|
||||
"dimension3" : 0.1,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.2,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -269,6 +269,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.45,
|
||||
"dimension3" : 0.1,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.45,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -269,6 +269,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.9,
|
||||
"dimension3" : 0.1,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.45,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -75,6 +75,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.45,
|
||||
"dimension3" : 0.1,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.45,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -76,6 +76,10 @@
|
||||
"dimension1" : 0.5,
|
||||
"dimension2" : 3,
|
||||
"dimension3" : 0.5,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 1.5,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -41,6 +41,10 @@
|
||||
"dimension1" : 0.03,
|
||||
"dimension2" : 0.03,
|
||||
"dimension3" : 0.2,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0.0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0.0
|
||||
@ -67,6 +71,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
@ -87,6 +95,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
@ -120,6 +132,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
@ -151,6 +167,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
@ -188,6 +208,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -13,6 +13,10 @@
|
||||
"dimension1" : 0.1,
|
||||
"dimension2" : 0.1,
|
||||
"dimension3" : 0.35,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : 0.05,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -13,6 +13,10 @@
|
||||
"dimension1" : 1.7,
|
||||
"dimension2" : 1.7,
|
||||
"dimension3" : 1.7,
|
||||
"rotX": 0,
|
||||
"rotY": 0,
|
||||
"rotZ": 0,
|
||||
"rotW": 1,
|
||||
"offsetX" : 0,
|
||||
"offsetY" : -1.7,
|
||||
"offsetZ" : 0
|
||||
|
||||
@ -54,6 +54,16 @@
|
||||
"scale" : [1.0, 1.0, 1.0]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"path" : "Models/baseman5.fbx",
|
||||
"globalTransform": {
|
||||
"rotation" : [0,0,0,1],
|
||||
"offset" : [0.0, 0.0, 0.0],
|
||||
"scale" : [0.005, 0.005, 0.005]
|
||||
},
|
||||
"meshes" : [
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -25,6 +25,7 @@ The big case for this engine is the main physics system. The goal is to provide
|
||||
## Major Usage Notes
|
||||
|
||||
- All geometries are aligned along z by default in the library (ie your cylinders will be on their sides)
|
||||
- All functions that transform the scale of a DBody only transform the first shape within the rigid body. This should likely eventually be updated to support multiple shapes in a body.
|
||||
|
||||
|
||||
|
||||
|
||||
79
docs/src/resources/modelLoading.md
Normal file
79
docs/src/resources/modelLoading.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Model Loading
|
||||
|
||||
TODO
|
||||
|
||||
|
||||
## High Level Overview
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Major Usage Notes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Main Classes
|
||||
|
||||
[CollisionEngine.java](@ref #electrosphere.collision.CollisionEngine) - Represents a specific collision system. It may be helpful to think of it as viewing the world through a specific lens. Keeps track of all entities that do its type of collisions and fires callbacks on collision. Should be updated each tick.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Library Explanation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Code Organization and Best Practices
|
||||
|
||||
#### Startup
|
||||
|
||||
|
||||
#### Usage
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Terminology
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Future Goals
|
||||
@ -16,9 +16,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.ode4j.math.DMatrix3;
|
||||
import org.ode4j.math.DVector3;
|
||||
import org.ode4j.math.DVector4;
|
||||
@ -356,13 +359,17 @@ public class CollisionEngine {
|
||||
*/
|
||||
public void updateDynamicObjectTransforms(){
|
||||
for(Collidable collidable : collidableList){
|
||||
Entity physicsEntity = collidable.getParent();
|
||||
DBody rigidBody = (DBody)physicsEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
||||
Vector3d offset = (Vector3d)physicsEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET);
|
||||
Vector3d newPosition = PhysicsUtils.getRigidBodyPosition(rigidBody).sub(offset);
|
||||
Quaterniond newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody);
|
||||
EntityUtils.getPosition(physicsEntity).set(newPosition);
|
||||
EntityUtils.getRotation(physicsEntity).set(newRotation);
|
||||
if(collidable.getParentTracksCollidable()){
|
||||
Entity physicsEntity = collidable.getParent();
|
||||
DBody rigidBody = (DBody)physicsEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
||||
Matrix4d transform = PhysicsEntityUtils.getEntityCollidableTransform(physicsEntity);
|
||||
Matrix4d inverseTransform = transform.invert();
|
||||
Vector4d rawPos = inverseTransform.transform(new Vector4d(PhysicsUtils.getRigidBodyPosition(rigidBody),1));
|
||||
Vector3d newPosition = new Vector3d(rawPos.x,rawPos.y,rawPos.z);
|
||||
Quaterniond newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody);
|
||||
EntityUtils.getPosition(physicsEntity).set(newPosition);
|
||||
EntityUtils.getRotation(physicsEntity).set(newRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -633,6 +640,28 @@ public class CollisionEngine {
|
||||
spaceLock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transform on a body
|
||||
* @param body The body
|
||||
* @param position The position
|
||||
* @param rotation The rotation
|
||||
* @param scale The scale
|
||||
*/
|
||||
protected void setBodyTransform(DBody body, Vector3d position, Quaterniond rotation, Vector3d scale){
|
||||
spaceLock.acquireUninterruptibly();
|
||||
body.setPosition(position.x, position.y, position.z);
|
||||
body.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
|
||||
DGeom firstGeom = body.getFirstGeom();
|
||||
if(firstGeom instanceof DCylinder){
|
||||
((DCylinder)firstGeom).setParams(scale.x,scale.y);
|
||||
} else if(firstGeom instanceof DBox){
|
||||
((DBox)firstGeom).setLengths(scale.x,scale.y,scale.z);
|
||||
} else if(firstGeom instanceof DCapsule){
|
||||
((DCapsule)firstGeom).setParams(scale.x,scale.y);
|
||||
}
|
||||
spaceLock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the position of the body in a thread-safe way
|
||||
* @param body The body to get the position of
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package electrosphere.collision;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
@ -45,7 +46,13 @@ public class PhysicsEntityUtils {
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
|
||||
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
|
||||
@ -71,7 +78,13 @@ public class PhysicsEntityUtils {
|
||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
|
||||
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
|
||||
Matrix4d offsetTransform = new Matrix4d().translationRotateScale(
|
||||
physicsTemplate.getOffsetX(), physicsTemplate.getOffsetY(), physicsTemplate.getOffsetZ(), //translate
|
||||
physicsTemplate.getRotX(), physicsTemplate.getRotY(), physicsTemplate.getRotZ(), physicsTemplate.getRotW(), //rotate
|
||||
1, 1, 1 //scale
|
||||
);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
|
||||
@ -266,5 +279,14 @@ public class PhysicsEntityUtils {
|
||||
|
||||
return terrainBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transform from parent entity position to rigid body
|
||||
* @param entity The entity
|
||||
* @return The transform
|
||||
*/
|
||||
public static Matrix4d getEntityCollidableTransform(Entity entity){
|
||||
return (Matrix4d) entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -68,6 +68,18 @@ public class PhysicsUtils {
|
||||
collisionEngine.setBodyTransform(body, position, rotation);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the position + rotation + scale of a body
|
||||
* @param position The position
|
||||
* @param rotation The rotation
|
||||
* @param scale The scale
|
||||
* @param body The body
|
||||
*/
|
||||
public static void setRigidBodyTransform(CollisionEngine collisionEngine, Vector3d position, Quaterniond rotation, Vector3d scale, DBody body){
|
||||
collisionEngine.setBodyTransform(body, position, rotation, scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mass in the physics space from the body and mass value input
|
||||
* @param collisionEngine The collision engine to create the mass in
|
||||
|
||||
@ -15,9 +15,15 @@ import org.joml.Vector3f;
|
||||
*/
|
||||
public class Collidable {
|
||||
|
||||
//The entity this collidable is attached to
|
||||
Entity parent;
|
||||
//The type of collidable
|
||||
String type;
|
||||
|
||||
//If true, once impulses are applied to the collidable, have the parent entity resynchronize its position with the collidable
|
||||
boolean parentTracksCollidable = true;
|
||||
|
||||
//The impulses to be applied to this collidable
|
||||
List<Impulse> impulses = new CopyOnWriteArrayList<Impulse>();
|
||||
|
||||
public static final String TYPE_TERRAIN = "terrain";
|
||||
@ -49,6 +55,14 @@ public class Collidable {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the parent tracks the collidable's position
|
||||
* @return True if the parent tracks the collidable's position, false otherwise
|
||||
*/
|
||||
public boolean getParentTracksCollidable(){
|
||||
return parentTracksCollidable;
|
||||
}
|
||||
|
||||
public void overrideType(String type){
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@ -242,10 +242,10 @@ public class ClientLoading {
|
||||
});
|
||||
|
||||
Random rand = new Random(0);
|
||||
{
|
||||
Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", rand.nextLong());
|
||||
EntityUtils.getPosition(tree).set(5,0,5);
|
||||
}
|
||||
// {
|
||||
// Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", rand.nextLong());
|
||||
// EntityUtils.getPosition(tree).set(5,0,5);
|
||||
// }
|
||||
// for(int i = 0; i < 6; i++){
|
||||
// Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", rand.nextLong());
|
||||
// // EntityUtils.getPosition(tree).set(5,0,5);
|
||||
@ -258,6 +258,7 @@ public class ClientLoading {
|
||||
for(int z = 0; z < 5; z++){
|
||||
Entity tree = ProceduralTree.clientGenerateProceduralTree("oak", rand.nextLong());
|
||||
ClientEntityUtils.initiallyPositionEntity(tree, new Vector3d(5 + x * 5,0,5 + z * 5));
|
||||
EntityUtils.getScale(tree).set(0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -118,6 +118,7 @@ public class EntityDataStrings {
|
||||
*/
|
||||
public static final String PHYSICS_COLLISION_BODY = "physicsRigidBody";
|
||||
public static final String PHYSICS_COLLISION_BODY_OFFSET = "physicsRigidBodyOffset";
|
||||
public static final String PHYSICS_COLLISION_BODY_TRANSFORM = "physicsRigidBodyTransform"; // the transform matrix from origin of entity to origin of physics body
|
||||
public static final String PHYSICS_COLLIDABLE = "physicsCollidable";
|
||||
public static final String PHYSICS_MODEL_TEMPLATE = "physicsModelTemplate";
|
||||
public static final String PHYSICS_MASS = "physicsMass";
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package electrosphere.entity.state.collidable;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.ode4j.ode.DBody;
|
||||
|
||||
import electrosphere.collision.PhysicsEntityUtils;
|
||||
import electrosphere.collision.PhysicsUtils;
|
||||
import electrosphere.collision.collidable.Collidable;
|
||||
import electrosphere.engine.Globals;
|
||||
@ -201,10 +204,26 @@ public class ClientCollidableTree implements BehaviorTree {
|
||||
|
||||
//update collision engine of this thing's position
|
||||
CollidableTemplate template = (CollidableTemplate)parent.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);
|
||||
Matrix4d physicsBodyTransform = PhysicsEntityUtils.getEntityCollidableTransform(parent);
|
||||
Vector3f parentScale = EntityUtils.getScale(parent);
|
||||
Matrix4d parentTransform = new Matrix4d();
|
||||
// calculate new transform for current entity
|
||||
parentTransform.identity()
|
||||
.translate(position)
|
||||
.rotate(rotation)
|
||||
.scale(parentScale.x,parentScale.y,parentScale.z)
|
||||
.mul(physicsBodyTransform);
|
||||
//transform bone space
|
||||
Vector4d rigidBodyPositionRaw = parentTransform.transform(new Vector4d(0,0,0,1));
|
||||
Vector3d rigidBodyPosition = new Vector3d(rigidBodyPositionRaw.x,rigidBodyPositionRaw.y,rigidBodyPositionRaw.z);
|
||||
Quaterniond rigidBodyRotation = parentTransform.getUnnormalizedRotation(new Quaterniond()).normalize();
|
||||
Vector3d rigidBodyScaleRaw = parentTransform.getScale(new Vector3d());
|
||||
Vector3d rigidBodyScale = new Vector3d(rigidBodyScaleRaw.x,rigidBodyScaleRaw.y,rigidBodyScaleRaw.z);
|
||||
PhysicsUtils.setRigidBodyTransform(
|
||||
Globals.clientSceneWrapper.getCollisionEngine(),
|
||||
new Vector3d(position.x + template.getOffsetX(),position.y + template.getOffsetY(),position.z + template.getOffsetZ()),
|
||||
rotation,
|
||||
rigidBodyPosition,
|
||||
rigidBodyRotation,
|
||||
rigidBodyScale,
|
||||
body
|
||||
);
|
||||
}
|
||||
|
||||
@ -10,6 +10,11 @@ public class CollidableTemplate {
|
||||
float dimension1;
|
||||
float dimension2;
|
||||
float dimension3;
|
||||
|
||||
float rotX;
|
||||
float rotY;
|
||||
float rotZ;
|
||||
float rotW;
|
||||
|
||||
float offsetX;
|
||||
float offsetY;
|
||||
@ -31,6 +36,22 @@ public class CollidableTemplate {
|
||||
return dimension3;
|
||||
}
|
||||
|
||||
public float getRotX(){
|
||||
return rotX;
|
||||
}
|
||||
|
||||
public float getRotY(){
|
||||
return rotY;
|
||||
}
|
||||
|
||||
public float getRotZ(){
|
||||
return rotZ;
|
||||
}
|
||||
|
||||
public float getRotW(){
|
||||
return rotW;
|
||||
}
|
||||
|
||||
public float getOffsetX() {
|
||||
return offsetX;
|
||||
}
|
||||
|
||||
@ -44,7 +44,6 @@ public class EntityProtocol {
|
||||
LoggerInterface.loggerNetworking.DEBUG("Spawn Creature " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
|
||||
CreatureTemplate template = Utilities.deserialize(message.getcreatureTemplate(), CreatureTemplate.class);
|
||||
newlySpawnedEntity = CreatureUtils.clientSpawnBasicCreature(template.getCreatureType(),template);
|
||||
EntityUtils.getScale(newlySpawnedEntity).set(0.005f);
|
||||
EntityUtils.getPosition(newlySpawnedEntity).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
|
||||
break;
|
||||
|
||||
@ -7,6 +7,8 @@ import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.assimp.AIBone;
|
||||
|
||||
import electrosphere.renderer.loading.ModelPretransforms;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
@ -15,22 +17,22 @@ public class Bone {
|
||||
public String boneID;
|
||||
int numWeights;
|
||||
HashMap<Integer,Float> weights;
|
||||
public Matrix4f inverseBindPoseMatrix;
|
||||
public Matrix4d inverseBindPoseMatrix;
|
||||
public Matrix4d deform;
|
||||
public Matrix4f transform;
|
||||
public Matrix4f final_transform;
|
||||
public Matrix4d transform;
|
||||
public Matrix4d final_transform;
|
||||
public AIBone raw_data;
|
||||
public Bone(){
|
||||
transform = new Matrix4f();
|
||||
transform = new Matrix4d();
|
||||
deform = new Matrix4d();
|
||||
final_transform = new Matrix4f();
|
||||
final_transform = new Matrix4d();
|
||||
}
|
||||
public Bone(AIBone raw_data){
|
||||
transform = new Matrix4f();
|
||||
transform = new Matrix4d();
|
||||
deform = new Matrix4d();
|
||||
final_transform = new Matrix4f();
|
||||
final_transform = new Matrix4d();
|
||||
boneID = raw_data.mName().dataString();
|
||||
inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrix(raw_data.mOffsetMatrix());
|
||||
inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrixd(raw_data.mOffsetMatrix());
|
||||
this.raw_data = raw_data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.Map;
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.lwjgl.BufferUtils;
|
||||
@ -161,8 +162,6 @@ public class Mesh {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Matrix4d vertexPretransform = new Matrix4d().identity();
|
||||
if(metadata != null){
|
||||
System.out.println("Pretransforming");
|
||||
@ -199,6 +198,7 @@ public class Mesh {
|
||||
minZ = maxZ = z;
|
||||
}
|
||||
Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0));
|
||||
transformedVertex.w = 1.0;
|
||||
temp[0] = (float)transformedVertex.x;
|
||||
temp[1] = (float)transformedVertex.y;
|
||||
temp[2] = (float)transformedVertex.z;
|
||||
@ -313,7 +313,7 @@ public class Mesh {
|
||||
// System.out.println("Num weights: " + currentBoneData.mNumWeights());
|
||||
Bone currentBone = new Bone();
|
||||
currentBone.boneID = currentBoneData.mName().dataString();
|
||||
currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrix(currentBoneData.mOffsetMatrix());
|
||||
currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrixd(currentBoneData.mOffsetMatrix());
|
||||
currentBone.numWeights = currentBoneData.mNumWeights();
|
||||
currentBone.weights = new HashMap<Integer,Float>();
|
||||
Iterator<AIVertexWeight> weightIterator = currentBoneData.mWeights().iterator();
|
||||
|
||||
@ -65,7 +65,7 @@ public class Model {
|
||||
public ArrayList<Material> materials;
|
||||
public Matrix4d modelMatrix = new Matrix4d();
|
||||
ShaderProgram program;
|
||||
Matrix4f globalInverseTransform;
|
||||
Matrix4d globalInverseTransform;
|
||||
|
||||
AnimNode root_anim_node;
|
||||
ActorMeshMask meshMask;
|
||||
@ -80,6 +80,10 @@ public class Model {
|
||||
rVal.scene = s;
|
||||
|
||||
ModelPretransforms.ModelMetadata modelMetadata = Globals.modelPretransforms.getModel(path);
|
||||
ModelPretransforms.GlobalTransform globalTransform = null;
|
||||
if(modelMetadata != null){
|
||||
globalTransform = modelMetadata.getGlobalTransform();
|
||||
}
|
||||
|
||||
//
|
||||
//load meshes
|
||||
@ -146,7 +150,10 @@ public class Model {
|
||||
//parse animation nodes and form hierarchy
|
||||
//
|
||||
AINode rootNode = s.mRootNode();
|
||||
rVal.globalInverseTransform = electrosphere.util.Utilities.convertAIMatrix(rootNode.mTransformation());
|
||||
rVal.globalInverseTransform = electrosphere.util.Utilities.convertAIMatrixd(rootNode.mTransformation());
|
||||
if(globalTransform != null){
|
||||
rVal.globalInverseTransform.scale(globalTransform.getScale());
|
||||
}
|
||||
// System.out.println("Global inverse transform");
|
||||
// System.out.println(globalInverseTransform);
|
||||
rVal.root_anim_node = rVal.build_anim_node_map(s.mRootNode(),null);
|
||||
@ -406,18 +413,24 @@ public class Model {
|
||||
boneMatrix = new Matrix4f(rootTransformation).mul(boneMatrix);
|
||||
frame.setMatrix(j, boneMatrix);
|
||||
*/
|
||||
//
|
||||
//bone rotators (turrets, hair, etc)
|
||||
Bone target_bone = boneMap.get(n.id);
|
||||
n.transform = n.transform.mul(target_bone.deform);
|
||||
if(boneRotators.containsKey(target_bone.boneID)){
|
||||
n.transform.rotate(boneRotators.get(target_bone.boneID).getRotation());
|
||||
}
|
||||
Matrix4f bone_matrix = new Matrix4f(n.transform);
|
||||
//
|
||||
//static morph (changing nose size, eye distance, etc)
|
||||
Matrix4d bone_matrix = new Matrix4d(n.transform);
|
||||
if(staticMorph != null && staticMorph.getBoneTransforms(n.id) != null){
|
||||
bone_matrix.mul(staticMorph.getBoneTransforms(n.id).getTransform());
|
||||
n.transform.mul(staticMorph.getBoneTransforms(n.id).getTransform());
|
||||
}
|
||||
//
|
||||
//Calculate final offset from initial bone
|
||||
bone_matrix.mul(target_bone.inverseBindPoseMatrix);
|
||||
bone_matrix = new Matrix4f(globalInverseTransform).mul(bone_matrix);
|
||||
bone_matrix = new Matrix4d(globalInverseTransform).mul(bone_matrix);
|
||||
target_bone.final_transform = bone_matrix;
|
||||
// if(!toggled){
|
||||
// System.out.println(n.id);
|
||||
|
||||
@ -18,6 +18,7 @@ import org.joml.Matrix4f;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
/**
|
||||
@ -247,11 +248,11 @@ public class Actor {
|
||||
// model.updateNodeTransform();
|
||||
Bone currentBone = model.boneMap.get(boneName);
|
||||
if(currentBone != null){
|
||||
Vector4f result = currentBone.final_transform.transform(new Matrix4f(currentBone.inverseBindPoseMatrix).invert().transform(new Vector4f(rVal.x,rVal.y,rVal.z,1)));
|
||||
Vector4d result = currentBone.final_transform.transform(new Matrix4d(currentBone.inverseBindPoseMatrix).invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1)));
|
||||
// currentBone.inverseBindPoseMatrix
|
||||
rVal.x = result.x;
|
||||
rVal.y = result.y;
|
||||
rVal.z = result.z;
|
||||
rVal.x = (float)result.x;
|
||||
rVal.y = (float)result.y;
|
||||
rVal.z = (float)result.z;
|
||||
}
|
||||
// }
|
||||
}
|
||||
@ -270,7 +271,7 @@ public class Actor {
|
||||
Bone currentBone = model.boneMap.get(boneName);
|
||||
if(currentBone != null){
|
||||
AxisAngle4f axisAngle = new AxisAngle4f();
|
||||
currentBone.final_transform.getRotation(axisAngle);
|
||||
new Matrix4f(currentBone.final_transform).getRotation(axisAngle);
|
||||
Quaterniond rotation = new Quaterniond(axisAngle);
|
||||
rVal.set(rotation);
|
||||
}
|
||||
@ -279,8 +280,8 @@ public class Actor {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public Matrix4f getBoneTransform(String boneName){
|
||||
Matrix4f rVal = new Matrix4f();
|
||||
public Matrix4d getBoneTransform(String boneName){
|
||||
Matrix4d rVal = new Matrix4d();
|
||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||
if(model != null){
|
||||
applyAnimationMasks(model);
|
||||
|
||||
@ -25,7 +25,6 @@ public class ActorUtils {
|
||||
public static void applyBlenderTransformer(Entity actorEntity){
|
||||
Actor entityActor = EntityUtils.getActor(actorEntity);
|
||||
entityActor.setAnimationScalar(60f); //should be the value of the fps i think
|
||||
EntityUtils.getScale(actorEntity).set(0.005f);
|
||||
}
|
||||
|
||||
public static void applyBlenderRotation(Entity actorEntity){
|
||||
|
||||
@ -6,9 +6,11 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIAnimation;
|
||||
import org.lwjgl.assimp.AIMeshAnim;
|
||||
@ -17,6 +19,8 @@ import org.lwjgl.assimp.AINodeAnim;
|
||||
import org.lwjgl.assimp.AIQuatKey;
|
||||
import org.lwjgl.assimp.AIVectorKey;
|
||||
|
||||
import electrosphere.renderer.loading.ModelPretransforms;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
@ -69,22 +73,19 @@ public class Animation {
|
||||
// System.out.println("Ticks per second: " + ticksPerSecond);
|
||||
// System.out.println("Anim sizeof: " + animData.sizeof());
|
||||
// System.out.println("Duration: " + duration);
|
||||
|
||||
|
||||
//
|
||||
//Read in anim channels (bone modifications)
|
||||
//
|
||||
int channelCount = animData.mNumChannels();
|
||||
channels = new ArrayList<AnimChannel>();
|
||||
if(channelCount > 0){
|
||||
// System.out.println("Channel count: " + channelCount);
|
||||
for(int i = 0; i < channelCount; i++){
|
||||
AINodeAnim currentChannelData = AINodeAnim.create(animData.mChannels().get(i));
|
||||
// System.out.println("Channel[" + (i + 1) + "]: " + currentChannelData.mNodeName().dataString());
|
||||
|
||||
//Create channel
|
||||
AnimChannel currentChannel = new AnimChannel(duration);
|
||||
// currentChannel.positionFrame = new ArrayList();
|
||||
// currentChannel.rotationFrame = new ArrayList();
|
||||
// currentChannel.scaleFrame = new ArrayList();
|
||||
currentChannel.nodeID = currentChannelData.mNodeName().dataString();
|
||||
channels.add(currentChannel);
|
||||
|
||||
@ -95,20 +96,17 @@ public class Animation {
|
||||
|
||||
if(currentChannelData.mNumPositionKeys() > 0){
|
||||
org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mPositionKeys();
|
||||
// Iterator<AIVectorKey> keyIterator = buff.iterator();
|
||||
// while (keyIterator.hasNext()) {
|
||||
// AIVectorKey key = keyIterator.next();
|
||||
// Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
// currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
// currentChannel.positionFrame.add(currentFrame);
|
||||
// }
|
||||
if(buff != null && buff.hasRemaining()){
|
||||
// System.out.println("Position vectors: ");
|
||||
AIVectorKey key = buff.get();
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
Vector4d positionRaw = new Vector4d(
|
||||
key.mValue().x(),
|
||||
key.mValue().y(),
|
||||
key.mValue().z(),
|
||||
1
|
||||
);
|
||||
currentFrame.position = new Vector3f((float)positionRaw.x,(float)positionRaw.y,(float)positionRaw.z);
|
||||
currentChannel.addPositionFrame(key.mTime(),currentFrame);
|
||||
// System.out.println(currentFrame.position);
|
||||
currentChannel.startingPosition = currentFrame.position;
|
||||
|
||||
Keyframe previousFrame;
|
||||
@ -116,10 +114,14 @@ public class Animation {
|
||||
previousFrame = currentFrame;
|
||||
key = buff.get();
|
||||
currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
// System.out.println(currentFrame.position);
|
||||
positionRaw = new Vector4d(
|
||||
key.mValue().x(),
|
||||
key.mValue().y(),
|
||||
key.mValue().z(),
|
||||
1
|
||||
);
|
||||
currentFrame.position = new Vector3f((float)positionRaw.x,(float)positionRaw.y,(float)positionRaw.z);
|
||||
//check if duplicate
|
||||
// Keyframe previousFrame = currentChannel.positionFrame.get(currentChannel.positionFrame.size() - 1);
|
||||
if( previousFrame.position.x == currentFrame.position.x &&
|
||||
previousFrame.position.y == currentFrame.position.y &&
|
||||
previousFrame.position.z == currentFrame.position.z
|
||||
@ -138,7 +140,6 @@ public class Animation {
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.rotation = new Quaterniond();
|
||||
currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w());
|
||||
// currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w());
|
||||
currentChannel.addRotationFrame(key.mTime(),currentFrame);
|
||||
|
||||
currentChannel.startingRotation = currentFrame.rotation;
|
||||
@ -150,9 +151,7 @@ public class Animation {
|
||||
currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.rotation = new Quaterniond();
|
||||
currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w());
|
||||
// currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w());
|
||||
//check for duplicate
|
||||
// Keyframe previousFrame = currentChannel.rotationFrame.get(currentChannel.rotationFrame.size() - 1);
|
||||
if( previousFrame.rotation.w == currentFrame.rotation.w &&
|
||||
previousFrame.rotation.x == currentFrame.rotation.x &&
|
||||
previousFrame.rotation.y == currentFrame.rotation.y &&
|
||||
@ -163,35 +162,29 @@ public class Animation {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Iterator<AIQuatKey> keyIterator = buff.iterator();
|
||||
// while(keyIterator.hasNext()){
|
||||
// AIQuatKey key = keyIterator.next();
|
||||
// Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
// currentFrame.rotation = new Quaternionf(key.mValue().w(),key.mValue().x(),key.mValue().y(),key.mValue().z());
|
||||
// currentChannel.rotationFrame.add(currentFrame);
|
||||
// }
|
||||
}
|
||||
|
||||
if(currentChannelData.mNumScalingKeys() > 0){
|
||||
org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mScalingKeys();
|
||||
// Iterator<AIVectorKey> keyIterator = buff.iterator();
|
||||
// while (keyIterator.hasNext()) {
|
||||
// AIVectorKey key = keyIterator.next();
|
||||
// Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
// currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
// currentChannel.scaleFrame.add(currentFrame);
|
||||
// }
|
||||
if(buff != null && buff.hasRemaining()){
|
||||
AIVectorKey key = buff.get();
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
currentFrame.scale = new Vector3f(
|
||||
(float)(key.mValue().x()),
|
||||
(float)(key.mValue().y()),
|
||||
(float)(key.mValue().z())
|
||||
);
|
||||
currentChannel.addScaleFrame(key.mTime(),currentFrame);
|
||||
Keyframe previousFrame;
|
||||
while(buff.hasRemaining()){
|
||||
previousFrame = currentFrame;
|
||||
key = buff.get();
|
||||
currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
currentFrame.scale = new Vector3f(
|
||||
(float)(key.mValue().x()),
|
||||
(float)(key.mValue().y()),
|
||||
(float)(key.mValue().z())
|
||||
);
|
||||
if( currentFrame.scale.x == previousFrame.scale.x &&
|
||||
currentFrame.scale.y == previousFrame.scale.y &&
|
||||
currentFrame.scale.z == previousFrame.scale.z
|
||||
@ -204,33 +197,8 @@ public class Animation {
|
||||
}
|
||||
|
||||
|
||||
// System.out.println("end times");
|
||||
// for(int j = 0; j < currentChannelData.mNumPositionKeys(); j++){
|
||||
// org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mPositionKeys();
|
||||
// Iterator<AIVectorKey> keyIterator = buff.iterator();
|
||||
// AIVectorKey posKey = currentChannelData.mPositionKeys().get(i);
|
||||
// Keyframe currentFrame = new Keyframe(posKey.mTime());
|
||||
// currentFrame.position = new Vector3f(posKey.mValue().x(),posKey.mValue().y(),posKey.mValue().z());
|
||||
// }
|
||||
// for(int j = 0; j < currentChannelData.mNumRotationKeys(); j++){
|
||||
// AIQuatKey rotKey = currentChannelData.mRotationKeys().get(i);
|
||||
// HashMap test = new HashMap();
|
||||
// System.out.println(new Quaternionf(rotKey.mValue().w(),rotKey.mValue().x(),rotKey.mValue().y(),rotKey.mValue().z()));
|
||||
// }
|
||||
// for(int j = 0; j < currentChannelData.mNumScalingKeys(); j++){
|
||||
// AIVectorKey scaleKey = currentChannelData.mScalingKeys().get(i);
|
||||
//// scaleKey.mValue().
|
||||
// System.out.println(new Vector3f(scaleKey.mValue().x(),scaleKey.mValue().y(),scaleKey.mValue().z()));
|
||||
// }
|
||||
}
|
||||
}
|
||||
// int meshChannelCount = animData.mNumMeshChannels();
|
||||
// meshChannelData = new ArrayList();
|
||||
// if(meshChannelCount > 0){
|
||||
// for(int i = 0; i < meshChannelCount; i++){
|
||||
// AIMeshAnim test = AIMeshAnim.create(animData.mMeshChannels().get(i));
|
||||
// }
|
||||
// }
|
||||
//gotta free things
|
||||
nodeChannelData = null;
|
||||
meshChannelData = null;
|
||||
|
||||
@ -38,7 +38,9 @@ public class ModelLoader {
|
||||
aiProcess_JoinIdenticalVertices |
|
||||
aiProcess_Triangulate |
|
||||
aiProcess_FixInfacingNormals |
|
||||
aiProcess_LimitBoneWeights);
|
||||
aiProcess_LimitBoneWeights |
|
||||
aiProcess_GlobalScale
|
||||
);
|
||||
if(rVal == null){
|
||||
throw new IllegalStateException(aiGetErrorString());
|
||||
}
|
||||
|
||||
@ -49,6 +49,8 @@ public class ModelPretransforms {
|
||||
List<MeshMetadata> meshes;
|
||||
//Map relating path->mesh metadata
|
||||
Map<String,MeshMetadata> meshDataMap;
|
||||
//Optional global transform
|
||||
GlobalTransform globalTransform;
|
||||
|
||||
/**
|
||||
* Initializes the ModelMetadata object
|
||||
@ -76,6 +78,14 @@ public class ModelPretransforms {
|
||||
public String getPath(){
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the global transform metadata
|
||||
* @return The global transform metadata
|
||||
*/
|
||||
public GlobalTransform getGlobalTransform(){
|
||||
return globalTransform;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,4 +132,50 @@ public class ModelPretransforms {
|
||||
return new Vector3d(scale.get(0),scale.get(1),scale.get(2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds metadata for pretransforming all meshes and potentially all animations
|
||||
*/
|
||||
public class GlobalTransform {
|
||||
List<Double> rotation;
|
||||
List<Double> offset;
|
||||
List<Double> scale;
|
||||
boolean applyToAnimations;
|
||||
|
||||
/**
|
||||
* gets the rotation of the transform as a JOML Quaterniond
|
||||
* !!WARNING!! unsafe: If there aren't at least 4 doubles in the array it out of bounds
|
||||
* @return The rotation of the transform
|
||||
*/
|
||||
public Quaterniond getRotation(){
|
||||
return new Quaterniond(rotation.get(0),rotation.get(1),rotation.get(2),rotation.get(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the offset of the transform as a JOML vector3d
|
||||
* !!WARNING!! unsafe: If there aren't at least 3 doubles in the array it out of bounds
|
||||
* @return The offset of the transform
|
||||
*/
|
||||
public Vector3d getOffset(){
|
||||
return new Vector3d(offset.get(0),offset.get(1),offset.get(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the scale of the transform as a JOML vector3d
|
||||
* !!WARNING!! unsafe: If there aren't at least 3 doubles in the array it out of bounds
|
||||
* @return The scale of the transform
|
||||
*/
|
||||
public Vector3d getScale(){
|
||||
return new Vector3d(scale.get(0),scale.get(1),scale.get(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the global transform should be applied to animations
|
||||
* @return True if should apply to animations, false otherwise
|
||||
*/
|
||||
public boolean getApplyToAnimations(){
|
||||
return applyToAnimations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,9 +7,11 @@ import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
import org.joml.AxisAngle4f;
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaterniond;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4d;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
@ -243,7 +245,7 @@ public class PoseActor {
|
||||
Bone currentBone = model.boneMap.get(boneName);
|
||||
if(currentBone != null){
|
||||
AxisAngle4f axisAngle = new AxisAngle4f();
|
||||
currentBone.final_transform.getRotation(axisAngle);
|
||||
new Matrix4f(currentBone.final_transform).getRotation(axisAngle);
|
||||
Quaterniond rotation = new Quaterniond(axisAngle);
|
||||
rVal.set(rotation);
|
||||
}
|
||||
@ -268,11 +270,11 @@ public class PoseActor {
|
||||
// model.updateNodeTransform();
|
||||
Bone currentBone = model.boneMap.get(boneName);
|
||||
if(currentBone != null){
|
||||
Vector4f result = currentBone.final_transform.transform(new Matrix4f(currentBone.inverseBindPoseMatrix).invert().transform(new Vector4f(rVal.x,rVal.y,rVal.z,1)));
|
||||
Vector4d result = currentBone.final_transform.transform(new Matrix4d(currentBone.inverseBindPoseMatrix).invert().transform(new Vector4d(rVal.x,rVal.y,rVal.z,1)));
|
||||
// currentBone.inverseBindPoseMatrix
|
||||
rVal.x = result.x;
|
||||
rVal.y = result.y;
|
||||
rVal.z = result.z;
|
||||
rVal.x = (float)result.x;
|
||||
rVal.y = (float)result.y;
|
||||
rVal.z = (float)result.z;
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
@ -9,7 +9,6 @@ public class PoseActorUtils {
|
||||
public static void applyBlenderTransformer(Entity actorEntity){
|
||||
PoseActor entityActor = EntityUtils.getPoseActor(actorEntity);
|
||||
entityActor.setAnimationScalar(60f); //should be the value of the fps i think
|
||||
EntityUtils.getScale(actorEntity).set(0.005f);
|
||||
}
|
||||
|
||||
public static void applyBlenderRotation(Entity actorEntity){
|
||||
|
||||
@ -33,7 +33,7 @@ public class PoseModel {
|
||||
|
||||
List<Bone> bones;
|
||||
Map<String,Bone> boneMap;
|
||||
Matrix4f globalInverseTransform;
|
||||
Matrix4d globalInverseTransform;
|
||||
Map<String,AnimNode> nodeMap;
|
||||
AnimNode rootAnimNode;
|
||||
List<Animation> animations;
|
||||
@ -47,6 +47,10 @@ public class PoseModel {
|
||||
*/
|
||||
public PoseModel(String path, AIScene scene){
|
||||
ModelPretransforms.ModelMetadata modelMetadata = Globals.modelPretransforms.getModel(path);
|
||||
ModelPretransforms.GlobalTransform globalTransform = null;
|
||||
if(modelMetadata != null){
|
||||
globalTransform = modelMetadata.getGlobalTransform();
|
||||
}
|
||||
|
||||
bones = new ArrayList<Bone>();
|
||||
boneMap = new HashMap<String, Bone>();
|
||||
@ -77,7 +81,10 @@ public class PoseModel {
|
||||
//parse animation nodes and form hierarchy
|
||||
//
|
||||
AINode rootNode = scene.mRootNode();
|
||||
globalInverseTransform = electrosphere.util.Utilities.convertAIMatrix(rootNode.mTransformation());
|
||||
globalInverseTransform = electrosphere.util.Utilities.convertAIMatrixd(rootNode.mTransformation());
|
||||
if(globalTransform != null){
|
||||
globalInverseTransform.scale(globalTransform.getScale());
|
||||
}
|
||||
rootAnimNode = buildAnimNodeMap(scene.mRootNode(),null);
|
||||
|
||||
//
|
||||
@ -173,13 +180,13 @@ public class PoseModel {
|
||||
if(boneRotators.containsKey(target_bone.boneID)){
|
||||
n.transform.rotate(boneRotators.get(target_bone.boneID).getRotation());
|
||||
}
|
||||
Matrix4f bone_matrix = new Matrix4f(n.transform);
|
||||
Matrix4d bone_matrix = new Matrix4d(n.transform);
|
||||
if(staticMorph != null && staticMorph.getBoneTransforms(n.id) != null){
|
||||
bone_matrix.mul(staticMorph.getBoneTransforms(n.id).getTransform());
|
||||
n.transform.mul(staticMorph.getBoneTransforms(n.id).getTransform());
|
||||
}
|
||||
bone_matrix.mul(target_bone.inverseBindPoseMatrix);
|
||||
bone_matrix = new Matrix4f(globalInverseTransform).mul(bone_matrix);
|
||||
bone_matrix = new Matrix4d(globalInverseTransform).mul(bone_matrix);
|
||||
target_bone.final_transform = bone_matrix;
|
||||
} else {
|
||||
//not a bone, so use transform directly from data
|
||||
|
||||
@ -25,6 +25,8 @@ import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.joml.Matrix4d;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
@ -84,6 +86,47 @@ public class Utilities {
|
||||
rVal.m33(mat.d4());
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static Matrix4d convertAIMatrixd(AIMatrix4x4 mat){
|
||||
Matrix4d rVal = new Matrix4d();
|
||||
//Old, wrong approach:
|
||||
// mat.set(
|
||||
// mat.a1(),
|
||||
// mat.b1(),
|
||||
// mat.c1(),
|
||||
// mat.d1(),
|
||||
// mat.a2(),
|
||||
// mat.b2(),
|
||||
// mat.c2(),
|
||||
// mat.d2(),
|
||||
// mat.a3(),
|
||||
// mat.b3(),
|
||||
// mat.c3(),
|
||||
// mat.d3(),
|
||||
// mat.a4(),
|
||||
// mat.b4(),
|
||||
// mat.c4(),
|
||||
// mat.d4()
|
||||
// );
|
||||
//as demo'd in https://github.com/lwjglgamedev/lwjglbook/blob/master/chapter27/c27-p2/src/main/java/org/lwjglb/engine/loaders/assimp/AnimMeshesLoader.java
|
||||
rVal.m00(mat.a1());
|
||||
rVal.m10(mat.a2());
|
||||
rVal.m20(mat.a3());
|
||||
rVal.m30(mat.a4());
|
||||
rVal.m01(mat.b1());
|
||||
rVal.m11(mat.b2());
|
||||
rVal.m21(mat.b3());
|
||||
rVal.m31(mat.b4());
|
||||
rVal.m02(mat.c1());
|
||||
rVal.m12(mat.c2());
|
||||
rVal.m22(mat.c3());
|
||||
rVal.m32(mat.c4());
|
||||
rVal.m03(mat.d1());
|
||||
rVal.m13(mat.d2());
|
||||
rVal.m23(mat.d3());
|
||||
rVal.m33(mat.d4());
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user