physics fixes
This commit is contained in:
parent
ff0c3c099a
commit
ace8a9b27b
@ -2103,6 +2103,13 @@ ServerGroundMovementTree geom work
|
|||||||
ServerLODComponent replaces bodies with geometries instead of just destroying the geometries
|
ServerLODComponent replaces bodies with geometries instead of just destroying the geometries
|
||||||
|
|
||||||
|
|
||||||
|
(06/04/2025)
|
||||||
|
Fix rebase world origin routine
|
||||||
|
Non-rigid-body collidables behave as expected
|
||||||
|
Fix physics performance issues
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -99,11 +99,6 @@ public class CollisionEngine {
|
|||||||
* Distance from current floating point origin to trigger a rebase
|
* Distance from current floating point origin to trigger a rebase
|
||||||
*/
|
*/
|
||||||
private static final double REBASE_TRIGGER_DISTANCE = 16;
|
private static final double REBASE_TRIGGER_DISTANCE = 16;
|
||||||
|
|
||||||
/**
|
|
||||||
* Maximum expected distance from local origin
|
|
||||||
*/
|
|
||||||
private static final double MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN = 3000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* world data that the collision engine leverages for position correction and the like
|
* world data that the collision engine leverages for position correction and the like
|
||||||
@ -267,19 +262,19 @@ public class CollisionEngine {
|
|||||||
*/
|
*/
|
||||||
public static void resolveCollision(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
public static void resolveCollision(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
||||||
switch(receiver.getType()){
|
switch(receiver.getType()){
|
||||||
case Collidable.TYPE_CREATURE:
|
case Collidable.TYPE_CREATURE: {
|
||||||
switch(impactor.getType()){
|
switch(impactor.getType()){
|
||||||
case Collidable.TYPE_STATIC:
|
case Collidable.TYPE_STATIC: {
|
||||||
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude * 2, Collidable.TYPE_STATIC));
|
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude * 2, Collidable.TYPE_STATIC));
|
||||||
break;
|
} break;
|
||||||
case Collidable.TYPE_CREATURE:
|
case Collidable.TYPE_CREATURE: {
|
||||||
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_CREATURE));
|
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_CREATURE));
|
||||||
break;
|
} break;
|
||||||
case Collidable.TYPE_OBJECT:
|
case Collidable.TYPE_OBJECT: {
|
||||||
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_OBJECT));
|
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_OBJECT));
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,12 +324,6 @@ public class CollisionEngine {
|
|||||||
){
|
){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// //
|
|
||||||
// // are we below the terrain?
|
|
||||||
// //
|
|
||||||
// if(w.getElevationAtPoint(positionToCheck) > positionToCheck.y){
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,18 +700,7 @@ public class CollisionEngine {
|
|||||||
newRotation.mul(new Quaterniond(template.getRotX(),template.getRotY(),template.getRotZ(),template.getRotW()).invert());
|
newRotation.mul(new Quaterniond(template.getRotX(),template.getRotY(),template.getRotZ(),template.getRotW()).invert());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if(rigidBody != null && suggestedPosition.distance(0,0,0) < 100){
|
EntityUtils.setPosition(physicsEntity, suggestedPosition);
|
||||||
// String message = "\n" +
|
|
||||||
// "this.floatingOrigin: " + this.floatingOrigin + "\n" +
|
|
||||||
// "calculatedPosition: " + calculatedPosition + "\n" +
|
|
||||||
// "suggestedPosition: " + suggestedPosition + "\n" +
|
|
||||||
// "rawPos: " + rawPos + "\n" +
|
|
||||||
// (rigidBody != null ? "body: " + rigidBody.getPosition() + "\n" : "\n") +
|
|
||||||
// (geom != null ? "geom: " + geom.getPosition() + "\n" : "\n") +
|
|
||||||
// "";
|
|
||||||
// throw new Error(message);
|
|
||||||
// }
|
|
||||||
EntityUtils.getPosition(physicsEntity).set(suggestedPosition);
|
|
||||||
EntityUtils.getRotation(physicsEntity).set(newRotation);
|
EntityUtils.getRotation(physicsEntity).set(newRotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -741,16 +719,13 @@ public class CollisionEngine {
|
|||||||
int collected = 0;
|
int collected = 0;
|
||||||
Vector3d newOrigin = new Vector3d();
|
Vector3d newOrigin = new Vector3d();
|
||||||
//calculate new origin
|
//calculate new origin
|
||||||
|
//only reference the rigid bodies because the rebase is principally concerned with physics sim
|
||||||
|
//pure colliders (no rigid body) don't do physics sim in ode so don't need to worry about being quite as close to 0,0,0
|
||||||
for(Collidable collidable : collidableList){
|
for(Collidable collidable : collidableList){
|
||||||
Entity physicsEntity = collidable.getParent();
|
Entity physicsEntity = collidable.getParent();
|
||||||
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
|
DBody rigidBody = PhysicsEntityUtils.getDBody(physicsEntity);
|
||||||
if(rigidBody != null){
|
if(rigidBody != null){
|
||||||
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition());
|
Vector3d currentBodyOffset = PhysicsUtils.odeVecToJomlVec(rigidBody.getPosition());
|
||||||
// if(this.bodies.size() > 1 && currentBodyOffset.distance(0,0,0) > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN && this.hasRebased){
|
|
||||||
// String message = "Body far outside expected range! " + currentBodyOffset + "\n";
|
|
||||||
// message = message + this.getDebugStatus();
|
|
||||||
// throw new Error(message);
|
|
||||||
// }
|
|
||||||
currentBodyOffset.add(this.floatingOrigin);
|
currentBodyOffset.add(this.floatingOrigin);
|
||||||
if(collected == 0){
|
if(collected == 0){
|
||||||
newOrigin.set(currentBodyOffset);
|
newOrigin.set(currentBodyOffset);
|
||||||
@ -771,18 +746,18 @@ public class CollisionEngine {
|
|||||||
//only perform rebase if sufficiently far away
|
//only perform rebase if sufficiently far away
|
||||||
if(delta.length() > REBASE_TRIGGER_DISTANCE){
|
if(delta.length() > REBASE_TRIGGER_DISTANCE){
|
||||||
//error checking
|
//error checking
|
||||||
if(collected > 1 && delta.length() > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN){
|
// if(collected > 1 && delta.length() > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN){
|
||||||
System.out.println("newOrigin: " + newOrigin);
|
// System.out.println("newOrigin: " + newOrigin);
|
||||||
System.out.println("delta: " + delta);
|
// System.out.println("delta: " + delta);
|
||||||
throw new Error(this.getDebugStatus());
|
// throw new Error(this.getDebugStatus());
|
||||||
}
|
// }
|
||||||
System.out.println("REbase");
|
// System.out.println("REbase");
|
||||||
System.out.println(this.getStatus());
|
// System.out.println(this.getStatus());
|
||||||
System.out.println("newOrigin: " + newOrigin);
|
// System.out.println("newOrigin: " + newOrigin);
|
||||||
System.out.println("delta: " + delta);
|
// System.out.println("delta: " + delta);
|
||||||
if(delta.y > 100 || delta.y < -100){
|
// if(delta.y > 100 || delta.y < -100){
|
||||||
throw new Error(this.getDebugStatus());
|
// throw new Error(this.getDebugStatus());
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
this.floatingOrigin = newOrigin;
|
this.floatingOrigin = newOrigin;
|
||||||
@ -826,30 +801,12 @@ public class CollisionEngine {
|
|||||||
throw new Error("Collidable is null!");
|
throw new Error("Collidable is null!");
|
||||||
}
|
}
|
||||||
spaceLock.lock();
|
spaceLock.lock();
|
||||||
// if(this.name.equals("serverPhysics") && position.distance(0,0,0) < 100){
|
|
||||||
// throw new Error("Invalid position " + position);
|
|
||||||
// }
|
|
||||||
// if(this.name.equals("serverPhysics") && this.hasRebased && this.bodies.size() > 1 && position.distance(this.floatingOrigin) > MAX_EXPECTED_DIST_FROM_LOCAL_ORIGIN){
|
|
||||||
// String message = "Position invalid!\n" +
|
|
||||||
// "position: " + position.x + "," + position.y + "," + position.z + "\n" +
|
|
||||||
// "floating origin: " + this.floatingOrigin.x + "," + this.floatingOrigin.y + "," + this.floatingOrigin.z + "\n" +
|
|
||||||
// "dist: " + position.distance(this.floatingOrigin) + "\n" +
|
|
||||||
// "ent pos: " + EntityUtils.getPosition(collidable.getParent()) + "\n" +
|
|
||||||
// this.getDebugStatus() +
|
|
||||||
// "";
|
|
||||||
// throw new Error(message);
|
|
||||||
// }
|
|
||||||
// if(this.name.equals("serverPhysics")){
|
|
||||||
// System.out.println("Register collidable at " + position);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//Body transform needs to be set before the body is added to the collidable list
|
//Body transform needs to be set before the body is added to the collidable list
|
||||||
//this makes sure that dynamic update transforms and floating origin work correctly
|
//this makes sure that dynamic update transforms and floating origin work correctly
|
||||||
this.setBodyTransform(body, new Vector3d(position), new Quaterniond());
|
this.setBodyTransform(body, new Vector3d(position), new Quaterniond());
|
||||||
|
|
||||||
// if(this.name.equals("serverPhysics") && (body.getPosition().get0() != position.x || body.getPosition().get1() != position.y || body.getPosition().get2() != position.z)){
|
//actually attach to tracking structures
|
||||||
// System.out.println("Transform not set properly! " + body.getPosition() + " " + position);
|
|
||||||
// }
|
|
||||||
this.registerPhysicsObject(body);
|
this.registerPhysicsObject(body);
|
||||||
bodyPointerMap.put(body,collidable);
|
bodyPointerMap.put(body,collidable);
|
||||||
collidableList.add(collidable);
|
collidableList.add(collidable);
|
||||||
@ -861,11 +818,16 @@ public class CollisionEngine {
|
|||||||
* @param geom The geom
|
* @param geom The geom
|
||||||
* @param collidable The corresponding collidable
|
* @param collidable The corresponding collidable
|
||||||
*/
|
*/
|
||||||
public void registerCollisionObject(DGeom geom, Collidable collidable){
|
public void registerCollisionObject(DGeom geom, Collidable collidable, Vector3d position){
|
||||||
if(collidable == null){
|
if(collidable == null){
|
||||||
throw new Error("Collidable is null!");
|
throw new Error("Collidable is null!");
|
||||||
}
|
}
|
||||||
spaceLock.lock();
|
spaceLock.lock();
|
||||||
|
|
||||||
|
//Body transform needs to be set before the body is added to the collidable list
|
||||||
|
//this makes sure that dynamic update transforms and floating origin work correctly
|
||||||
|
this.setGeomTransform(geom, position, new Quaterniond());
|
||||||
|
|
||||||
geomPointerMap.put(geom,collidable);
|
geomPointerMap.put(geom,collidable);
|
||||||
collidableList.add(collidable);
|
collidableList.add(collidable);
|
||||||
spaceLock.unlock();
|
spaceLock.unlock();
|
||||||
@ -876,12 +838,16 @@ public class CollisionEngine {
|
|||||||
* @param geoms The list of geoms
|
* @param geoms The list of geoms
|
||||||
* @param collidable The corresponding collidable
|
* @param collidable The corresponding collidable
|
||||||
*/
|
*/
|
||||||
public void registerCollisionObject(List<DGeom> geoms, Collidable collidable){
|
public void registerCollisionObject(List<DGeom> geoms, Collidable collidable, Vector3d position){
|
||||||
if(collidable == null){
|
if(collidable == null){
|
||||||
throw new Error("Collidable is null!");
|
throw new Error("Collidable is null!");
|
||||||
}
|
}
|
||||||
spaceLock.lock();
|
spaceLock.lock();
|
||||||
for(DGeom geom : geoms){
|
for(DGeom geom : geoms){
|
||||||
|
//Body transform needs to be set before the body is added to the collidable list
|
||||||
|
//this makes sure that dynamic update transforms and floating origin work correctly
|
||||||
|
this.setGeomTransform(geom, position, new Quaterniond());
|
||||||
|
|
||||||
geomPointerMap.put(geom,collidable);
|
geomPointerMap.put(geom,collidable);
|
||||||
}
|
}
|
||||||
collidableList.add(collidable);
|
collidableList.add(collidable);
|
||||||
|
|||||||
@ -106,7 +106,7 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
|
|
||||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||||
engine.registerCollisionObject(geom, collidable);
|
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||||
} break;
|
} break;
|
||||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||||
//
|
//
|
||||||
@ -134,7 +134,7 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
|
|
||||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||||
engine.registerCollisionObject(geom, collidable);
|
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||||
} break;
|
} break;
|
||||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||||
//
|
//
|
||||||
@ -161,11 +161,10 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
|
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||||
|
|
||||||
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
Globals.clientState.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
|
||||||
engine.registerCollisionObject(geom, collidable);
|
engine.registerCollisionObject(geom, collidable, EntityUtils.getPosition(rVal));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -231,7 +230,6 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
|
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
|
||||||
|
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||||
|
|
||||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||||
@ -295,7 +293,6 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
|
rVal.putData(EntityDataStrings.CLIENT_COLLIDABLE_TREE, tree);
|
||||||
|
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||||
|
|
||||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable, EntityUtils.getPosition(rVal));
|
||||||
@ -399,7 +396,7 @@ public class PhysicsEntityUtils {
|
|||||||
}
|
}
|
||||||
CollisionEngine.lockOde();
|
CollisionEngine.lockOde();
|
||||||
if(physicsTemplate.getKinematic()){
|
if(physicsTemplate.getKinematic()){
|
||||||
PhysicsEntityUtils.serverAttachGeom(realm,rVal,physicsTemplate);
|
PhysicsEntityUtils.serverAttachGeom(realm,rVal,physicsTemplate,position);
|
||||||
} else {
|
} else {
|
||||||
DBody rigidBody = null;
|
DBody rigidBody = null;
|
||||||
switch(physicsTemplate.getType()){
|
switch(physicsTemplate.getType()){
|
||||||
@ -619,7 +616,7 @@ public class PhysicsEntityUtils {
|
|||||||
* @param physicsTemplate The collidable template
|
* @param physicsTemplate The collidable template
|
||||||
* @return The geometry object
|
* @return The geometry object
|
||||||
*/
|
*/
|
||||||
public static DGeom serverAttachGeom(Realm realm, Entity rVal, CollidableTemplate physicsTemplate){
|
public static DGeom serverAttachGeom(Realm realm, Entity rVal, CollidableTemplate physicsTemplate, Vector3d position){
|
||||||
if(physicsTemplate == null){
|
if(physicsTemplate == null){
|
||||||
throw new Error("Physics template is null!");
|
throw new Error("Physics template is null!");
|
||||||
}
|
}
|
||||||
@ -646,6 +643,7 @@ public class PhysicsEntityUtils {
|
|||||||
//
|
//
|
||||||
//create collidable and attach tracking
|
//create collidable and attach tracking
|
||||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||||
|
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,geom);
|
||||||
PhysicsEntityUtils.setDGeom(rVal, geom);
|
PhysicsEntityUtils.setDGeom(rVal, geom);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -658,11 +656,11 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
|
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||||
|
|
||||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||||
realm.getCollisionEngine().registerCollisionObject(geom, collidable);
|
realm.getCollisionEngine().registerCollisionObject(geom, collidable, position);
|
||||||
} break;
|
} break;
|
||||||
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
case CollidableTemplate.COLLIDABLE_TYPE_CUBE: {
|
||||||
//
|
//
|
||||||
@ -676,6 +674,7 @@ public class PhysicsEntityUtils {
|
|||||||
//
|
//
|
||||||
//create collidable and attach tracking
|
//create collidable and attach tracking
|
||||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||||
|
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,geom);
|
||||||
PhysicsEntityUtils.setDGeom(rVal, geom);
|
PhysicsEntityUtils.setDGeom(rVal, geom);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -688,11 +687,11 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
|
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||||
|
|
||||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||||
realm.getCollisionEngine().registerCollisionObject(geom, collidable);
|
realm.getCollisionEngine().registerCollisionObject(geom, collidable, position);
|
||||||
} break;
|
} break;
|
||||||
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
case CollidableTemplate.COLLIDABLE_TYPE_CAPSULE: {
|
||||||
//
|
//
|
||||||
@ -707,6 +706,7 @@ public class PhysicsEntityUtils {
|
|||||||
//
|
//
|
||||||
//create collidable and attach tracking
|
//create collidable and attach tracking
|
||||||
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE, true);
|
||||||
|
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,geom);
|
||||||
PhysicsEntityUtils.setDGeom(rVal, geom);
|
PhysicsEntityUtils.setDGeom(rVal, geom);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -719,11 +719,11 @@ public class PhysicsEntityUtils {
|
|||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_TRANSFORM, offsetTransform);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
rVal.putData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE, physicsTemplate);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
rVal.putData(EntityDataStrings.PHYSICS_COLLIDABLE, collidable);
|
||||||
|
rVal.putData(EntityDataStrings.SERVER_COLLIDABLE_TREE, tree);
|
||||||
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
rVal.putData(EntityDataStrings.PHYSICS_MASS, mass);
|
||||||
|
|
||||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
|
||||||
realm.getCollisionEngine().registerCollisionObject(geom, collidable);
|
realm.getCollisionEngine().registerCollisionObject(geom, collidable, position);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
CollisionEngine.unlockOde();
|
CollisionEngine.unlockOde();
|
||||||
@ -759,7 +759,7 @@ public class PhysicsEntityUtils {
|
|||||||
DGeom terrainGeom = CollisionBodyCreation.generateGeomFromTerrainData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
|
DGeom terrainGeom = CollisionBodyCreation.generateGeomFromTerrainData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
|
||||||
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, true);
|
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, true);
|
||||||
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
||||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainGeom, collidable);
|
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainGeom, collidable, EntityUtils.getPosition(terrain));
|
||||||
CollisionEngine.unlockOde();
|
CollisionEngine.unlockOde();
|
||||||
PhysicsEntityUtils.setDGeom(terrain,terrainGeom);
|
PhysicsEntityUtils.setDGeom(terrain,terrainGeom);
|
||||||
}
|
}
|
||||||
@ -789,7 +789,7 @@ public class PhysicsEntityUtils {
|
|||||||
DGeom terrainBody = CollisionBodyCreation.generateColliderFromMultiShapeMeshData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
|
DGeom terrainBody = CollisionBodyCreation.generateColliderFromMultiShapeMeshData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), data, Collidable.TYPE_STATIC_BIT);
|
||||||
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false);
|
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false);
|
||||||
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
||||||
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable);
|
Globals.clientState.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, collidable, EntityUtils.getPosition(terrain));
|
||||||
PhysicsEntityUtils.setDGeom(terrain,terrainBody);
|
PhysicsEntityUtils.setDGeom(terrain,terrainBody);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +823,7 @@ public class PhysicsEntityUtils {
|
|||||||
|
|
||||||
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, true);
|
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, true);
|
||||||
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
||||||
realm.getCollisionEngine().registerCollisionObject(terrainCollider, collidable);
|
realm.getCollisionEngine().registerCollisionObject(terrainCollider, collidable, EntityUtils.getPosition(terrain));
|
||||||
PhysicsEntityUtils.setDGeom(terrain,terrainCollider);
|
PhysicsEntityUtils.setDGeom(terrain,terrainCollider);
|
||||||
|
|
||||||
return terrainCollider;
|
return terrainCollider;
|
||||||
@ -858,7 +858,7 @@ public class PhysicsEntityUtils {
|
|||||||
|
|
||||||
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false);
|
Collidable collidable = new Collidable(terrain,Collidable.TYPE_STATIC, false);
|
||||||
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
PhysicsEntityUtils.setCollidable(terrain, collidable);
|
||||||
realm.getCollisionEngine().registerCollisionObject(terrainBody, collidable);
|
realm.getCollisionEngine().registerCollisionObject(terrainBody, collidable, EntityUtils.getPosition(terrain));
|
||||||
PhysicsEntityUtils.setDGeom(terrain,terrainBody);
|
PhysicsEntityUtils.setDGeom(terrain,terrainBody);
|
||||||
|
|
||||||
return terrainBody;
|
return terrainBody;
|
||||||
@ -882,6 +882,10 @@ public class PhysicsEntityUtils {
|
|||||||
if(body != null && body.isEnabled() && !body.isKinematic()){
|
if(body != null && body.isEnabled() && !body.isKinematic()){
|
||||||
toReposition.add(entity);
|
toReposition.add(entity);
|
||||||
}
|
}
|
||||||
|
DGeom geom = PhysicsEntityUtils.getDGeom(entity);
|
||||||
|
if(geom != null && geom.getCategoryBits() != Collidable.TYPE_STATIC_BIT){
|
||||||
|
toReposition.add(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ServerWorldData worldDat = realm.getServerWorldData();
|
ServerWorldData worldDat = realm.getServerWorldData();
|
||||||
for(Entity parent : toReposition){
|
for(Entity parent : toReposition){
|
||||||
|
|||||||
@ -280,7 +280,7 @@ public class ClientLoading {
|
|||||||
DrawableUtils.disableCulling(skybox);
|
DrawableUtils.disableCulling(skybox);
|
||||||
EntityUtils.getScale(skybox).mul(SKYSPHERE_SCALE);
|
EntityUtils.getScale(skybox).mul(SKYSPHERE_SCALE);
|
||||||
Globals.clientState.clientScene.registerBehaviorTree(() -> {
|
Globals.clientState.clientScene.registerBehaviorTree(() -> {
|
||||||
EntityUtils.getPosition(skybox).set(EntityUtils.getPosition(Globals.clientState.playerEntity));
|
EntityUtils.setPosition(skybox, EntityUtils.getPosition(Globals.clientState.playerEntity));
|
||||||
});
|
});
|
||||||
Globals.assetManager.queueOverrideMeshShader(EntityUtils.getActor(skybox).getBaseModelPath(), GeometryMeshGen.SPHERE_MESH_NAME, AssetDataStrings.SHADER_SKYBOX_VERT, AssetDataStrings.SHADER_SKYBOX_FRAG);
|
Globals.assetManager.queueOverrideMeshShader(EntityUtils.getActor(skybox).getBaseModelPath(), GeometryMeshGen.SPHERE_MESH_NAME, AssetDataStrings.SHADER_SKYBOX_VERT, AssetDataStrings.SHADER_SKYBOX_FRAG);
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public class ClientEntityUtils {
|
|||||||
public static void repositionEntity(Entity entity, Vector3d position, Quaterniond rotation){
|
public static void repositionEntity(Entity entity, Vector3d position, Quaterniond rotation){
|
||||||
//reposition entity
|
//reposition entity
|
||||||
CollisionObjUtils.clientPositionCharacter(entity, position, rotation);
|
CollisionObjUtils.clientPositionCharacter(entity, position, rotation);
|
||||||
EntityUtils.getPosition(entity).set(position);
|
EntityUtils.setPosition(entity, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -16,8 +16,22 @@ import org.joml.Vector3f;
|
|||||||
*/
|
*/
|
||||||
public class EntityUtils {
|
public class EntityUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position of the entity
|
||||||
|
* @param e The entity
|
||||||
|
* @return The position of the entity
|
||||||
|
*/
|
||||||
public static Vector3d getPosition(Entity e){
|
public static Vector3d getPosition(Entity e){
|
||||||
return (Vector3d)e.getData(EntityDataStrings.DATA_STRING_POSITION);
|
return new Vector3d((Vector3d)e.getData(EntityDataStrings.DATA_STRING_POSITION));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of the entity
|
||||||
|
* @param e The entity
|
||||||
|
* @param newVec The new position
|
||||||
|
*/
|
||||||
|
public static void setPosition(Entity e, Vector3d newVec){
|
||||||
|
((Vector3d)e.getData(EntityDataStrings.DATA_STRING_POSITION)).set(newVec);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Quaterniond getRotation(Entity e){
|
public static Quaterniond getRotation(Entity e){
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import electrosphere.entity.state.gravity.ServerGravityTree;
|
|||||||
import electrosphere.entity.state.movement.fall.ServerFallTree;
|
import electrosphere.entity.state.movement.fall.ServerFallTree;
|
||||||
|
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server collidable tree
|
* Server collidable tree
|
||||||
@ -41,6 +42,17 @@ public class ServerCollidableTree implements BehaviorTree {
|
|||||||
this.collidable = collidable;
|
this.collidable = collidable;
|
||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param e The entity
|
||||||
|
* @param collidable The collidable
|
||||||
|
* @param geom The Geom
|
||||||
|
*/
|
||||||
|
public ServerCollidableTree(Entity e, Collidable collidable, DGeom geom){
|
||||||
|
parent = e;
|
||||||
|
this.collidable = collidable;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulates the collidable tree
|
* Simulates the collidable tree
|
||||||
|
|||||||
@ -79,7 +79,7 @@ public class ServerLODComponent implements BehaviorTree {
|
|||||||
if(CreatureUtils.hasControllerPlayerId(parent)){
|
if(CreatureUtils.hasControllerPlayerId(parent)){
|
||||||
throw new Error("Should not be attaching a geometry to a player entity!");
|
throw new Error("Should not be attaching a geometry to a player entity!");
|
||||||
}
|
}
|
||||||
PhysicsEntityUtils.serverAttachGeom(realm, parent, type.getCollidable());
|
PhysicsEntityUtils.serverAttachGeom(realm, parent, type.getCollidable(), EntityUtils.getPosition(parent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -282,7 +282,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
//this should only fire on the client, we don't want the server snap updating due to client position reporting
|
//this should only fire on the client, we don't want the server snap updating due to client position reporting
|
||||||
lastServerPosition = new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
lastServerPosition = new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||||
if(position.distance(lastServerPosition) > STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD){
|
if(position.distance(lastServerPosition) > STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD){
|
||||||
EntityUtils.getPosition(parent).set(lastServerPosition);
|
EntityUtils.setPosition(parent, lastServerPosition);
|
||||||
} else if(position.distance(lastServerPosition) > STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD){
|
} else if(position.distance(lastServerPosition) > STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD){
|
||||||
EntityUtils.getPosition(parent).lerp(lastServerPosition,SOFT_UPDATE_MULTIPLIER);
|
EntityUtils.getPosition(parent).lerp(lastServerPosition,SOFT_UPDATE_MULTIPLIER);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ public class ClientPhysicsSyncTree implements BehaviorTree {
|
|||||||
|
|
||||||
//
|
//
|
||||||
//Synchronize data
|
//Synchronize data
|
||||||
EntityUtils.getPosition(parent).set(position);
|
EntityUtils.setPosition(parent, position);
|
||||||
EntityUtils.getRotation(parent).set(rotationFromServer);
|
EntityUtils.getRotation(parent).set(rotationFromServer);
|
||||||
PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, rotationFromServer, linearVelocity, angularVelocity, linearForce, angularForce, enabled);
|
PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, rotationFromServer, linearVelocity, angularVelocity, linearForce, angularForce, enabled);
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ public class ClientAlwaysUprightTree implements BehaviorTree {
|
|||||||
//make sure rotation is vertical
|
//make sure rotation is vertical
|
||||||
// sourceRotation = sourceRotation.mul(0.001, 1, 0.001, 1).normalize();
|
// sourceRotation = sourceRotation.mul(0.001, 1, 0.001, 1).normalize();
|
||||||
|
|
||||||
EntityUtils.getPosition(parent).set(position);
|
EntityUtils.setPosition(parent, position);
|
||||||
EntityUtils.getRotation(parent).set(sourceRotation);
|
EntityUtils.getRotation(parent).set(sourceRotation);
|
||||||
PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce);
|
PhysicsUtils.synchronizeData(Globals.clientState.clientSceneWrapper.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ public class ServerAlwaysUprightTree implements BehaviorTree {
|
|||||||
sourceRotation = new Quaterniond().rotationTo(SpatialMathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
sourceRotation = new Quaterniond().rotationTo(SpatialMathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityUtils.getPosition(parent).set(position);
|
EntityUtils.setPosition(parent, position);
|
||||||
EntityUtils.getRotation(parent).set(sourceRotation);
|
EntityUtils.getRotation(parent).set(sourceRotation);
|
||||||
PhysicsUtils.synchronizeData(realm.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce);
|
PhysicsUtils.synchronizeData(realm.getCollisionEngine(), body, position, sourceRotation, linearVelocity, angularVelocity, linearForce, angularForce);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -77,8 +77,8 @@ public class CollisionObjUtils {
|
|||||||
double startX = position.x;
|
double startX = position.x;
|
||||||
double startY = position.y;
|
double startY = position.y;
|
||||||
double startZ = position.z;
|
double startZ = position.z;
|
||||||
|
EntityUtils.setPosition(e, position);
|
||||||
Vector3d entPos = EntityUtils.getPosition(e);
|
Vector3d entPos = EntityUtils.getPosition(e);
|
||||||
entPos.set(position);
|
|
||||||
if(startX != entPos.x || startX != entPos.x || startX != entPos.x){
|
if(startX != entPos.x || startX != entPos.x || startX != entPos.x){
|
||||||
throw new Error("Failed to position entity! " + startX + "," + startY + "," + startZ + " " + entPos.x + "," + entPos.y + "," + entPos.z);
|
throw new Error("Failed to position entity! " + startX + "," + startY + "," + startZ + " " + entPos.x + "," + entPos.y + "," + entPos.z);
|
||||||
}
|
}
|
||||||
@ -107,12 +107,12 @@ public class CollisionObjUtils {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vector3d finalRef = EntityUtils.getPosition(e);
|
// Vector3d finalRef = EntityUtils.getPosition(e);
|
||||||
if(finalRef != entPos){
|
// if(finalRef != entPos){
|
||||||
throw new Error("Reference changed while positioning character! " + entPos + " " + finalRef);
|
// throw new Error("Reference changed while positioning character! " + entPos.x + "," + entPos.y + "," + entPos.z + " " + finalRef.x + "," + finalRef.y + "," + finalRef.z);
|
||||||
}
|
// }
|
||||||
if(startX != entPos.x || startX != entPos.x || startX != entPos.x){
|
if(startX != entPos.x || startX != entPos.x || startX != entPos.x){
|
||||||
throw new Error("Position not preserved while positioning entity! " + startX + "," + startY + "," + startZ + " " + entPos.x + "," + entPos.y + "," + entPos.z + " " + position);
|
throw new Error("Position not preserved while positioning entity! " + startX + "," + startY + "," + startZ + " " + entPos.x + "," + entPos.y + "," + entPos.z + " " + position.x + "," + position.y + "," + position.z);
|
||||||
}
|
}
|
||||||
CollisionEngine.unlockOde();
|
CollisionEngine.unlockOde();
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ public class CollisionObjUtils {
|
|||||||
* @param rotation The rotation
|
* @param rotation The rotation
|
||||||
*/
|
*/
|
||||||
public static void clientPositionCharacter(Entity e, Vector3d position, Quaterniond rotation){
|
public static void clientPositionCharacter(Entity e, Vector3d position, Quaterniond rotation){
|
||||||
EntityUtils.getPosition(e).set(position);
|
EntityUtils.setPosition(e, position);
|
||||||
DBody body = PhysicsEntityUtils.getDBody(e);
|
DBody body = PhysicsEntityUtils.getDBody(e);
|
||||||
if(body != null){
|
if(body != null){
|
||||||
PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, rotation, body);
|
PhysicsUtils.setRigidBodyTransform(Globals.clientState.clientSceneWrapper.getCollisionEngine(), position, rotation, body);
|
||||||
|
|||||||
@ -519,7 +519,7 @@ public class CommonEntityUtils {
|
|||||||
if(Globals.serverState.lodEmitterService.isFullLod(position)){
|
if(Globals.serverState.lodEmitterService.isFullLod(position)){
|
||||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, entity, physicsTemplate,position);
|
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, entity, physicsTemplate,position);
|
||||||
} else {
|
} else {
|
||||||
PhysicsEntityUtils.serverAttachGeom(realm, entity, physicsTemplate);
|
PhysicsEntityUtils.serverAttachGeom(realm, entity, physicsTemplate, position);
|
||||||
}
|
}
|
||||||
ServerLODComponent.attachTree(entity);
|
ServerLODComponent.attachTree(entity);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,7 @@ public class CollisionEngineStaticSpaceTests extends EntityTestTemplate {
|
|||||||
CollisionEngine collisionEngine = realm.getCollisionEngine();
|
CollisionEngine collisionEngine = realm.getCollisionEngine();
|
||||||
|
|
||||||
Entity ent1 = EntityCreationUtils.createServerEntity(realm, new Vector3d(0));
|
Entity ent1 = EntityCreationUtils.createServerEntity(realm, new Vector3d(0));
|
||||||
PhysicsEntityUtils.serverAttachGeom(realm, ent1, CollidableTemplate.getBoxTemplate(new Vector3d(1,1,1)));
|
PhysicsEntityUtils.serverAttachGeom(realm, ent1, CollidableTemplate.getBoxTemplate(new Vector3d(1,1,1)), new Vector3d(0));
|
||||||
|
|
||||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, ent1, CollidableTemplate.getBoxTemplate(new Vector3d(1,1,1)), new Vector3d(0));
|
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, ent1, CollidableTemplate.getBoxTemplate(new Vector3d(1,1,1)), new Vector3d(0));
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user