Ray casting

This commit is contained in:
austin 2023-06-06 00:12:18 -04:00
parent 8f06a025f0
commit 3434edebf0
71 changed files with 1675 additions and 1645 deletions

View File

@ -267,7 +267,7 @@
"collidable" : {
"type" : "CYLINDER",
"dimension1" : 0.1,
"dimension2" : 0.45,
"dimension2" : 0.9,
"dimension3" : 0.1,
"offsetX" : 0,
"offsetY" : 0.45,

26
pom.xml
View File

@ -130,22 +130,13 @@
<version>2.8.6</version>
</dependency>
<!--jBulletFork-->
<!--License: ZLIB-->
<!--
manual: http://www.cs.kent.edu/~ruttan/GameEngines/lectures/Bullet_User_Manual
because their docs ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/CylinderShape.html ) suck
source: https://github.com/jbullet-maven/jbullet/tree/master/src/main/java/com/bulletphysics
-->
<dependency>
<groupId>electrosphere</groupId>
<artifactId>jBulletFork</artifactId>
<version>0.1</version>
</dependency>
<!--Ode4J-->
<!--License: Dual LGPL 2.1 OR BSD 3-clause-->
<!--https://github.com/tzaeschke/ode4j-->
<!--https://tzaeschke.github.io/ode4j-old/ode4j-doc.html -->
<!--http://ode.org/wikiold/htmlfile1.html -->
<!--http://ode.org/wiki/index.php/Main_Page -->
<!--https://github.com/tzaeschke/ode4j/tree/master/demo/src/main/java/org/ode4j/demo -->
<dependency>
<groupId>org.ode4j</groupId>
<artifactId>core</artifactId>
@ -194,15 +185,6 @@
<version>1.9.0</version>
</dependency>
<!--Vecmath explicit import-->
<!--License: TBD-->
<!--https://mvnrepository.com/artifact/javax.vecmath/vecmath-->
<dependency>
<groupId>javax.vecmath</groupId>
<artifactId>vecmath</artifactId>
<version>1.5.2</version>
</dependency>
</dependencies>

View File

@ -8,8 +8,9 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Quaterniond;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -121,11 +122,11 @@ public class ClientFoliageManager {
*/
public void update(){
if(ready){
Matrix4f modelMatrix = new Matrix4f();
Matrix4d modelMatrix = new Matrix4d();
Vector3f cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
for(Entity grassEntity : grassEntities){
Vector3d grassPosition = EntityUtils.getPosition(grassEntity);
Quaternionf grassRotation = EntityUtils.getRotation(grassEntity);
Quaterniond grassRotation = EntityUtils.getRotation(grassEntity);
Vector3d playerPosition = EntityUtils.getPosition(Globals.playerEntity);
InstancedActor instancedActor = InstancedActor.getInstancedActor(grassEntity);
//update position
@ -137,8 +138,8 @@ public class ClientFoliageManager {
modelMatrix = modelMatrix.identity();
Vector3f cameraModifiedPosition = new Vector3f((float)grassPosition.x,(float)grassPosition.y,(float)grassPosition.z).sub(cameraCenter);
modelMatrix.translate(cameraModifiedPosition);
modelMatrix.rotate(grassRotation);
modelMatrix.scale(EntityUtils.getScale(grassEntity));
modelMatrix.rotate(new Quaterniond(grassRotation));
modelMatrix.scale(new Vector3d(EntityUtils.getScale(grassEntity)));
instancedActor.setAttribute(modelMatrixAttribute, modelMatrix);
@ -167,8 +168,8 @@ public class ClientFoliageManager {
* Gets a new rotation for a blade of grass
* @return The rotation
*/
protected Quaternionf getNewRotation(){
return new Quaternionf().rotationX(-(float)Math.PI / 2.0f).rotateLocalY((float)Math.PI * placementRandomizer.nextFloat());
protected Quaterniond getNewRotation(){
return new Quaterniond().rotationX(-Math.PI / 2.0f).rotateLocalY(Math.PI * placementRandomizer.nextFloat());
}
@ -180,7 +181,7 @@ public class ClientFoliageManager {
public static void makeEntityInstancedFoliage(Entity entity, String modelPath, int capacity){
entity.putData(EntityDataStrings.INSTANCED_ACTOR, Globals.clientInstanceManager.createInstancedActor(modelPath, vertexPath, fragmentPath, attributes, capacity));
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
Globals.clientScene.registerEntity(entity);

View File

@ -3,9 +3,9 @@ package electrosphere.client.scene;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import electrosphere.collision.CollisionEngine;
import electrosphere.entity.Entity;
import electrosphere.entity.Scene;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.logger.LoggerInterface;
/**

View File

@ -2,8 +2,8 @@ package electrosphere.client.terrain.cells;
import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.client.terrain.manager.ClientTerrainManager;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
@ -11,8 +11,6 @@ import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.terrain.TerrainChunk;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.terrain.processing.TerrainInterpolator;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.Mesh;
@ -31,6 +29,7 @@ import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.ode4j.ode.DBody;
/**
*
@ -46,7 +45,7 @@ public class DrawCell {
ShaderProgram program;
CollisionObject physicsObject;
DBody physicsObject;
static Texture groundTextureOne = new Texture("/Textures/Ground/Dirt1.png");
static Texture groundTextureTwo = new Texture("/Textures/Ground/Dirt1.png");

View File

@ -0,0 +1,708 @@
package electrosphere.collision;
import electrosphere.collision.collidable.Collidable;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.types.hitbox.HitboxData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Semaphore;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.ode4j.math.DMatrix3;
import org.ode4j.math.DVector3;
import org.ode4j.math.DVector4;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DBox;
import org.ode4j.ode.DContact;
import org.ode4j.ode.DContactBuffer;
import org.ode4j.ode.DContactJoint;
import org.ode4j.ode.DCylinder;
import org.ode4j.ode.DGeom;
import org.ode4j.ode.DJoint;
import org.ode4j.ode.DJointGroup;
import org.ode4j.ode.DRay;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DTriMesh;
import org.ode4j.ode.DTriMeshData;
import org.ode4j.ode.DWorld;
import org.ode4j.ode.OdeHelper;
import org.ode4j.ode.DGeom.DNearCallback;
import static org.ode4j.ode.OdeHelper.*;
import static org.ode4j.ode.OdeMath.*;
/**
*
* TODO: https://stackoverflow.com/questions/32445679/3d-java-collision-detection-with-jbullet
*/
public class CollisionEngine {
public static final float ENGINE_STEP_SIZE = 1000.0f / 120.0f;
//world data that the collision engine leverages for position correction and the like
CollisionWorldData collisionWorldData;
private DWorld world;
private DSpace space;
private Semaphore spaceLock = new Semaphore(1);
private DJointGroup contactgroup;
private static final int MAX_CONTACTS = 1; // maximum number of contact points per body
List<Entity> collisionEntities = new ArrayList<Entity>();
List<Entity> physicsEntities = new ArrayList<Entity>();
List<Entity> dynamicPhysicsEntities = new ArrayList<Entity>();
List<Entity> structurePhysicsEntities = new ArrayList<Entity>();
List<DBody> bodies = new ArrayList<DBody>();
Map<DBody,Collidable> bodyPointerMap = new HashMap<DBody,Collidable>();
List<Collidable> collidableList = new ArrayList<Collidable>();
//callbacks for collision check
RayCastCallback rayCastCallback = new RayCastCallback();
static final float linearDamping = 0.02f;
public CollisionEngine(){
world = OdeHelper.createWorld();
space = OdeHelper.createHashSpace();
contactgroup = OdeHelper.createJointGroup();
// callback = new InternalTickCallback(){
// @Override
// public void internalTick(DynamicsWorld dw, float f) {
// Dispatcher dispatcher = dw.getDispatcher();
// int manifoldCount = dispatcher.getNumManifolds();
// for (int i = 0; i < manifoldCount; i++) {
// PersistentManifold manifold = dispatcher.getManifoldByIndexInternal(i);
// // The following two lines are optional.
// CollisionObject object1 = (CollisionObject)manifold.getBody0();
// CollisionObject object2 = (CollisionObject)manifold.getBody1();
// Collidable physicsObject1 = (Collidable)object1.getUserPointer();
// Collidable physicsObject2 = (Collidable)object2.getUserPointer();
// boolean hit = false;
// Vector3d normal = null;
// Vector3d localPosition1 = null;
// Vector3d localPosition2 = null;
// Vector3d worldPosA = null;
// Vector3d worldPosB = null;
// float magnitude = 0.0f;
// for (int j = 0; j < manifold.getNumContacts(); j++) {
// ManifoldPoint contactPoint = manifold.getContactPoint(j);
// if (contactPoint.getDistance() < 0.0f) {
// magnitude = -contactPoint.getDistance();
// //linear dampen
// // magnitude = magnitude;// * (float)Math.pow(1.0f - linearDamping,deltaTime * 2);
// hit = true;
// // System.out.println(contactPoint.positionWorldOnA + " " + contactPoint.positionWorldOnB);
// normal = new Vector3d(contactPoint.normalWorldOnB.x,contactPoint.normalWorldOnB.y,contactPoint.normalWorldOnB.z);
// localPosition1 = new Vector3d(contactPoint.localPointA.x,contactPoint.localPointA.y,contactPoint.localPointA.z);
// localPosition2 = new Vector3d(contactPoint.localPointB.x,contactPoint.localPointB.y,contactPoint.localPointB.z);
// worldPosA = new Vector3d(contactPoint.positionWorldOnA.x,contactPoint.positionWorldOnA.y,contactPoint.positionWorldOnA.z);
// worldPosB = new Vector3d(contactPoint.positionWorldOnB.x,contactPoint.positionWorldOnB.y,contactPoint.positionWorldOnB.z);
// break;
// }
// }
// if (hit) {
// resolveCollision(physicsObject1,physicsObject2, new Vector3d(normal).mul(-1.0), localPosition1, worldPosA, magnitude);
// resolveCollision(physicsObject2,physicsObject1, normal, localPosition2, worldPosB, magnitude);
// // System.out.println("HIT + " + normal);
// // Collision happened between physicsObject1 and physicsObject2. Collision normal is in variable 'normal'.
// }
// }
// }
// };
// world.setInternalTickCallback(callback, world);
//https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=11507
//https://www.google.com/search?client=firefox-b-1-d&q=bullet+set+position+and+check+if+collision
//https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=11399
}
public static void resolveCollision(Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
switch(receiver.getType()){
case Collidable.TYPE_CREATURE:
switch(impactor.getType()){
case Collidable.TYPE_TERRAIN:
// System.out.println(EntityUtils.getPosition(impactor.getParent()) + " " + EntityUtils.getPosition(receiver.getParent()));
// System.out.println();
// System.out.println("Terrain-creature collision: " + normal + " mag:" + magnitude);
// if(normal.y > normal.x + normal.z){
// normal.x = 0;
// normal.z = 0;
// }
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude * 2, Collidable.TYPE_TERRAIN));
break;
case Collidable.TYPE_CREATURE:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_CREATURE));
break;
case Collidable.TYPE_STRUCTURE:
// float realMag = 1f/(float)Math.pow(0.1, magnitude);
// System.out.println(normal + " - " + realMag);
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_STRUCTURE));
// System.out.println("Structure-creature collision");
break;
case Collidable.TYPE_ITEM:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_ITEM));
break;
case Collidable.TYPE_OBJECT:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_OBJECT));
break;
}
break;
case Collidable.TYPE_ITEM:
switch(impactor.getType()){
case Collidable.TYPE_TERRAIN:
// System.out.println(EntityUtils.getPosition(impactor.getParent()) + " " + EntityUtils.getPosition(receiver.getParent()));
// System.out.println();
// System.out.println("Terrain-item collision: " + normal + " mag:" + magnitude);
// if(normal.y > normal.x + normal.z){
// normal.x = 0;
// normal.z = 0;
// }
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude * 2, Collidable.TYPE_TERRAIN));
break;
case Collidable.TYPE_CREATURE:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_CREATURE));
break;
case Collidable.TYPE_STRUCTURE:
// float realMag = 1f/(float)Math.pow(0.1, magnitude);
// System.out.println(normal + " - " + realMag);
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_STRUCTURE));
// System.out.println("Structure-creature collision");
break;
case Collidable.TYPE_ITEM:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_ITEM));
break;
case Collidable.TYPE_OBJECT:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_OBJECT));
break;
}
break;
}
}
public void clearCollidableImpulseLists(){
for(Collidable collidable : collidableList){
collidable.clear();
}
}
/**
*
* @param e the entity that wants to move
* @param positionToCheck the position that it wants to move to
* @return true if it can occupy that position, false otherwise
*/
public boolean checkCanOccupyPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){
boolean rVal = true;
//
// check world bounds
//
if(
positionToCheck.x < collisionWorldData.getWorldBoundMin().x ||
positionToCheck.z < collisionWorldData.getWorldBoundMin().z ||
positionToCheck.x > collisionWorldData.getWorldBoundMax().x ||
positionToCheck.z > collisionWorldData.getWorldBoundMax().z
){
return false;
}
// //
// // are we below the terrain?
// //
// if(w.getElevationAtPoint(positionToCheck) > positionToCheck.y){
// return false;
// }
return rVal;
}
/**
* Performs the collision and simulation phases for this collision engine
* @param time The time to increment the physics simulation by
*/
public void simulatePhysics(float time){
spaceLock.acquireUninterruptibly();
space.collide(0,nearCallback);
// space.collide2(space, collisionWorldData, nearCallback);
// world.quickStep(ENGINE_STEP_SIZE);
// remove all contact joints
contactgroup.empty();
spaceLock.release();
}
/**
* Callback for any near collisions in the broadphase of the collision check
*/
private DNearCallback nearCallback = new DNearCallback() {
@Override
public void call(Object data, DGeom o1, DGeom o2) {
nearCallback( data, o1, o2);
}
};
//buffer for collisions
DContactBuffer contacts = null;
// this is called by dSpaceCollide when two objects in space are
// potentially colliding.
private void nearCallback (Object data, DGeom o1, DGeom o2) {
// if (o1->body && o2->body) return;
// exit without doing anything if the two bodies are connected by a joint
DBody b1 = o1.getBody();
DBody b2 = o2.getBody();
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return;
//creates a buffer to store potential collisions
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
for (int i=0; i<MAX_CONTACTS; i++) {
DContact contact = contacts.get(i);
contact.surface.mode = dContactBounce | dContactSoftCFM;
contact.surface.mu = dInfinity;
contact.surface.mu2 = 0;
contact.surface.bounce = 0.1;
contact.surface.bounce_vel = 0.1;
contact.surface.soft_cfm = 0.01;
}
if(!(bodyPointerMap.get(b1).getType() == Collidable.TYPE_TERRAIN && bodyPointerMap.get(b2).getType() == Collidable.TYPE_TERRAIN)){
//calculate collisions
int numc = OdeHelper.collide(o1,o2,MAX_CONTACTS,contacts.getGeomBuffer());
//create DContacts based on each collision that occurs
if (numc != 0) {
DMatrix3 RI = new DMatrix3();
RI.setIdentity ();
for (int i=0; i<numc; i++) {
DContact contact = contacts.get(i);
//special code for ray casting
if (o1 instanceof DRay || o2 instanceof DRay){
DMatrix3 Rotation = new DMatrix3();
Rotation.setIdentity();
// dsDrawSphere(contact.geom.pos, Rotation, (0.01));
DVector3 End = new DVector3();
End.eqSum( contact.geom.pos, contact.geom.normal, contact.geom.depth );
// dsDrawLine(contact.geom.pos, End);
continue;
}
// contact.geom.pos
resolveCollision(
bodyPointerMap.get(o1.getBody()),
bodyPointerMap.get(o2.getBody()),
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
(float)contact.geom.depth
);
resolveCollision(
bodyPointerMap.get(o2.getBody()),
bodyPointerMap.get(o1.getBody()),
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
(float)contact.geom.depth
);
//add contact to contact group
DJoint c = OdeHelper.createContactJoint (world,contactgroup,contact );
c.attach (b1,b2);
}
}
}
}
/**
*
* @param e the entity that's trying to move
* @param positionToCheck the position the entity wants to be at
* @return the position the engine recommends it move to instead (this is
* guaranteed to be a valid position)
*/
public Vector3d suggestMovementPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){
Vector3d suggestedPosition = new Vector3d(positionToCheck);
//
// adjust for minimum height (Terrain)
//
// float heightMapBias = 0.00001f;
// if(w.getElevationAtPoint(positionToCheck) > positionToCheck.y){
// suggestedPosition.y = w.getElevationAtPoint(positionToCheck) + heightMapBias;
// }
//
// adjust for world bounds
//
if(suggestedPosition.x < collisionWorldData.getWorldBoundMin().x){
suggestedPosition.x = collisionWorldData.getWorldBoundMin().x;
}
if(suggestedPosition.z < collisionWorldData.getWorldBoundMin().z){
suggestedPosition.z = collisionWorldData.getWorldBoundMin().z;
}
if(suggestedPosition.x > collisionWorldData.getWorldBoundMax().x){
suggestedPosition.x = collisionWorldData.getWorldBoundMax().x;
}
if(suggestedPosition.z > collisionWorldData.getWorldBoundMax().z){
suggestedPosition.z = collisionWorldData.getWorldBoundMax().z;
}
return suggestedPosition;
}
public void registerCollidableEntity(Entity collidable){
collisionEntities.add(collidable);
}
public List<Entity> getCollisionEntities(){
return collisionEntities;
}
/**
* Sets the collision world data
* @param collisionWorldData The collision world data
*/
public void setCollisionWorldData(CollisionWorldData collisionWorldData){
this.collisionWorldData = collisionWorldData;
}
public boolean collisionSphereCheck(Entity hitbox1, HitboxData hitbox1data, Entity hitbox2, HitboxData hitbox2data){
Vector3d position1 = EntityUtils.getPosition(hitbox1);
Vector3d position2 = EntityUtils.getPosition(hitbox2);
float radius1 = hitbox1data.getRadius();
float radius2 = hitbox2data.getRadius();
double distance = position1.distance(position2);
if(distance < radius1 + radius2){
return true;
} else {
return false;
}
}
public void registerPhysicsEntity(Entity physicsEntity){
physicsEntities.add(physicsEntity);
}
public List<Entity> getPhysicsEntities(){
return physicsEntities;
}
public void deregisterPhysicsEntity(Entity physicsEntity){
physicsEntities.remove(physicsEntity);
}
public void registerDynamicPhysicsEntity(Entity dynamicEntity){
dynamicPhysicsEntities.add(dynamicEntity);
}
public void deregisterDynamicPhysicsEntity(Entity dynamicEntity){
dynamicPhysicsEntities.remove(dynamicEntity);
}
public List<Entity> getDynamicPhysicsEntities(){
return dynamicPhysicsEntities;
}
public void registerStructurePhysicsEntity(Entity structureEntity){
structurePhysicsEntities.add(structureEntity);
}
public List<Entity> getStructurePhysicsEntities(){
return structurePhysicsEntities;
}
public void updateDynamicObjectTransforms(){
for(Entity dynamicEntity : dynamicPhysicsEntities){
DBody rigidBody = (DBody)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Vector3d offset = (Vector3d)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET);
Vector3d newPosition = PhysicsUtils.getRigidBodyPosition(rigidBody).sub(offset);
Quaterniond newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody);
// System.out.println(rigidBody + " position " + newPosition);
// System.out.println("Linear velocity: " + rigidBody.getLinearVelocity(new javax.vecmath.Vector3f()));
EntityUtils.getPosition(dynamicEntity).set(newPosition);
EntityUtils.getRotation(dynamicEntity).set(newRotation);
}
}
public void registerCollisionObject(DBody body, Collidable collidable){
registerPhysicsObject(body);
bodyPointerMap.put(body,collidable);
collidableList.add(collidable);
}
public void listBodyPositions(){
for(DBody body : bodies){
System.out.println(body);
System.out.println(PhysicsUtils.getRigidBodyPosition(body));
}
}
/*
Check if the entity is being accelerated by gravity
*/
// public boolean gravityCheck(CommonWorldData w, Entity e){
// double worldHeight = w.getElevationAtPoint(EntityUtils.getPosition(e));
// double entityHeight = EntityUtils.getPosition(e).y;
// return entityHeight > worldHeight + 0.1f;
// }
public float sweepTest(DBody body, Vector3f startPos, Vector3f endPos){
// space.collide2(body.getFirstGeom(), endPos, nearCallback);
// SphereShape sphere = new SphereShape(0.1f);
// // CollisionObject collider = new CollisionObject();
// // collider.setCollisionShape(sphere);
// ClosestConvexResultCallbackImpl callback = new ClosestConvexResultCallbackImpl(startPos,endPos,object,dispatcher,world.getPairCache());
// callback.collisionFilterGroup = 1;
// callback.collisionFilterMask = 1;
// world.convexSweepTest(sphere, PhysicsUtils.jomlVecToTransform(startPos), PhysicsUtils.jomlVecToTransform(endPos), callback);
// // callback.hasHit()
// if(callback.hasHit()){
// return callback.closestHitFraction;
// } else {
// return -1.0f;
// }
return -1.0f;
}
boolean RaycastQuery(DSpace space, DVector3 start, DVector3 end) {
// Calculate direction
DVector3 direction = new DVector3();
dSubtractVectors3(direction, end, start);
// Get length
double length = dCalcVectorLengthSquare3(direction);
double inverseLength = dRecip(length);
// Normalize
direction.scale(inverseLength);
// Create ray
DRay ray = OdeHelper.createRay(space, length);
ray.set(start.get0(), start.get1(), start.get2(), direction.get0(), direction.get1(), direction.get2());
// Check collisions
DVector4 hitPosition = new DVector4();
hitPosition.set3(dInfinity);
space.collide2(ray, null, nearCallback);
// Cleanup
ray.destroy();
// Check for hit
if(hitPosition.get3() != dInfinity) {
end.set0(hitPosition.get0());
end.set1(hitPosition.get1());
end.set2(hitPosition.get2());
return true;
}
return false;
}
// private static class ClosestConvexResultCallbackImpl extends ClosestConvexResultCallback {
// CollisionObject me;
// private OverlappingPairCache pairCache;
// private Dispatcher dispatcher;
// public ClosestConvexResultCallbackImpl(Vector3f startPos, Vector3f endPos, CollisionObject me, Dispatcher dispatcher, OverlappingPairCache pairCache){
// super(PhysicsUtils.jomlToVecmathVector3f(startPos),PhysicsUtils.jomlToVecmathVector3f(endPos));
// this.me = me;
// this.pairCache = pairCache;
// this.dispatcher = dispatcher;
// }
// @Override
// public float addSingleResult(LocalConvexResult convexResult, boolean normalInWorldSpace) {
// if (convexResult.hitCollisionObject == me) {
// return 1f;
// }
// Vector3f linVelA = new Vector3f(), linVelB = new Vector3f();
// linVelA.sub(PhysicsUtils.vecmathToJomlVector3f(convexToWorld), PhysicsUtils.vecmathToJomlVector3f(convexFromWorld));
// linVelB.set(0f, 0f, 0f);//toB.getOrigin()-fromB.getOrigin();
// Vector3f relativeVelocity = new Vector3f();
// relativeVelocity.sub(linVelA, linVelB);
// // don't report time of impact for motion away from the contact normal (or causes minor penetration)
// if (convexResult.hitNormalLocal.dot(PhysicsUtils.jomlToVecmathVector3f(relativeVelocity)) >= -0f) {
// return 1f;
// }
// return super.addSingleResult(convexResult, normalInWorldSpace);
// }
// @Override
// public boolean needsCollision(BroadphaseProxy proxy0) {
// // don't collide with itself
// if (proxy0.clientObject == me) {
// return false;
// }
// // don't do CCD when the collision filters are not matching
// if (!super.needsCollision(proxy0)) {
// return false;
// }
// CollisionObject otherObj = (CollisionObject)proxy0.clientObject;
// // call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
// if (dispatcher.needsResponse(me, otherObj)) {
// // don't do CCD when there are already contact points (touching contact/penetration)
// ObjectArrayList<PersistentManifold> manifoldArray = new ObjectArrayList<PersistentManifold>();
// BroadphasePair collisionPair = pairCache.findPair(me.getBroadphaseHandle(), proxy0);
// if (collisionPair != null) {
// if (collisionPair.algorithm != null) {
// //manifoldArray.resize(0);
// collisionPair.algorithm.getAllContactManifolds(manifoldArray);
// for (int j=0; j<manifoldArray.size(); j++) {
// PersistentManifold manifold = manifoldArray.getQuick(j);
// if (manifold.getNumContacts() > 0) {
// return false;
// }
// }
// }
// }
// }
// return true;
// }
// }
public void registerPhysicsObject(DBody body){
if(!bodies.contains(body)){
bodies.add(body);
OdeHelper.createBody(world);
}
}
public void deregisterPhysicsObject(DBody body){
if(bodies.contains(body)){
bodies.remove(body);
}
body.destroy();
}
public void deregisterRigidBody(DBody body){
if(bodies.contains(body)){
bodies.remove(body);
}
if((body) != null){
body.destroy();
// world.removeRigidBody(body);
}
}
public void deregisterCollidableEntity(Entity e){
if(collisionEntities.contains(e)){
collisionEntities.remove(e);
}
if(physicsEntities.contains(e)){
physicsEntities.remove(e);
}
if(dynamicPhysicsEntities.contains(e)){
dynamicPhysicsEntities.remove(e);
}
if(structurePhysicsEntities.contains(e)){
structurePhysicsEntities.remove(e);
}
}
public void destroyEntityThatHasPhysics(Entity e){
//make uncollidable
if(e.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && e.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
DBody rigidBody = (DBody)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
deregisterPhysicsObject(rigidBody);
}
deregisterCollidableEntity(e);
}
/**
* Returns the Ode DSpace
* @return The DSpace
*/
public DSpace getSpace(){
return space;
}
/**
* Gets the DWorld for this collision engine
* @return The DWorld
*/
public DWorld getDWorld(){
return world;
}
/**
* Creates a trimesh from a given set of vertices and indices
* @param verts The vertices
* @param indices The indices
* @return The DTriMesh
*/
protected DTriMesh createTrimeshGeom(float[] verts, int[] indices){
spaceLock.acquireUninterruptibly();
DTriMeshData data = OdeHelper.createTriMeshData();
data.build(verts, indices);
DTriMesh rVal = OdeHelper.createTriMesh(getSpace(), data);
spaceLock.release();
return rVal;
}
/**
* Creates a cube dbody. Dimensions vector control the total length of the x, y, and z dimensions respectively.
* @param dimensions The dimensions of the box
* @return The DBody
*/
protected DBody createCubeGeom(Vector3d dimensions){
spaceLock.acquireUninterruptibly();
DBody body = OdeHelper.createBody(world);
DBox boxGeom = OdeHelper.createBox(space, dimensions.x, dimensions.y, dimensions.z);
boxGeom.setBody(body);
spaceLock.release();
return body;
}
/**
* Creates a cylinder dbody
* @param dimensions The dimensions of the cylinder. X is the radius, y is the total height.
* @return The Dbody
*/
protected DBody createCylinderGeom(Vector3d dimensions){
spaceLock.acquireUninterruptibly();
DBody body = OdeHelper.createBody(world);
System.out.println(dimensions.y);
DCylinder cylinderGeom = OdeHelper.createCylinder(space, dimensions.x, dimensions.y);
cylinderGeom.setBody(body);
spaceLock.release();
return body;
}
/**
* Sets the transform on a body
* @param body The body
* @param position The position
* @param rotation The rotation
*/
protected void setBodyTransform(DBody body, Vector3d position, Quaterniond rotation){
spaceLock.acquireUninterruptibly();
body.setPosition(position.x, position.y, position.z);
body.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
spaceLock.release();
}
}

View File

@ -1,4 +1,4 @@
package electrosphere.game.collision;
package electrosphere.collision;
import electrosphere.client.scene.ClientWorldData;
import electrosphere.client.terrain.manager.ClientTerrainManager;

View File

@ -0,0 +1,366 @@
package electrosphere.collision;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.server.datacell.Realm;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.types.terrain.TerrainChunkData;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.lwjgl.PointerBuffer;
import org.lwjgl.assimp.AIFace;
import org.lwjgl.assimp.AIMesh;
import org.lwjgl.assimp.AIScene;
import org.lwjgl.assimp.AIVector3D;
import org.ode4j.math.DQuaternion;
import org.ode4j.math.DQuaternionC;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DBox;
import org.ode4j.ode.DCylinder;
import org.ode4j.ode.DGeom;
import org.ode4j.ode.DJointGroup;
import org.ode4j.ode.DPlane;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DTriMesh;
import org.ode4j.ode.DTriMeshData;
import org.ode4j.ode.DWorld;
import org.ode4j.ode.OdeHelper;
/**
*
* @author amaterasu
*/
public class PhysicsUtils {
/**
* Attaches a heightmap dbody to an entity
* @param terrain The terrain entity
* @param heightfield The heightfield values
* @return The DBody created
*/
public static DBody clientAttachTerrainRigidBody(Entity terrain, CollisionEngine collisionEngine, float[][] heightfield){
Vector3d position = EntityUtils.getPosition(terrain);
int arrayLength = heightfield.length;
int arrayWidth = heightfield[0].length;
float collisionMargin = 0.08f;
/*
Traditional buffer code not working for some reason
the approach of
https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
works much better
IDK why
*/
int numberTriangles = (arrayLength - 1) * (arrayWidth - 1) * 2;
int triangleStride = 0;
int numberVertices = arrayLength * arrayWidth;
int vertexStride = 0;
float[] vertices = new float[numberVertices * 3];
int vertexInserterPos = 0;
int[] indices = new int[numberTriangles * 3];
int indexInserterPos = 0;
for(int x = 0; x < arrayLength; x++){
for(int y = 0; y < arrayWidth; y++){
vertices[vertexInserterPos] = x;
vertexInserterPos++;
vertices[vertexInserterPos] = heightfield[x][y] - collisionMargin;
vertexInserterPos++;
vertices[vertexInserterPos] = y;
vertexInserterPos++;
if(x < arrayLength - 1 && y < arrayWidth - 1){
//if we should also add a triangle index
/*
as copied from ModelUtil's terrain mesh generation function
faces.put((x / stride + 0) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 1));
*/
indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 0);
indexInserterPos++;
indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1);
indexInserterPos++;
indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0);
indexInserterPos++;
indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0);
indexInserterPos++;
indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1);
indexInserterPos++;
indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 1);
indexInserterPos++;
}
}
}
DBody body = OdeHelper.createBody(null);
DTriMesh triMesh = collisionEngine.createTrimeshGeom(vertices,indices);
triMesh.setBody(body);
// terrainRigidBody.setFriction(1f);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(body, new Collidable(terrain,Collidable.TYPE_TERRAIN));
// terrainRigidBody.getAabb(aabbMin, aabbMax);
//
// System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax);
terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, body);
return body;
}
public static DBody clientAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){
Vector3d position = EntityUtils.getPosition(terrain);
DBody terrainBody = generateBodyFromTerrainData(Globals.clientSceneWrapper.getCollisionEngine(), data);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainBody);
return terrainBody;
}
public static DBody serverAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){
Vector3d position = EntityUtils.getPosition(terrain);
Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain);
DBody terrainBody = generateBodyFromTerrainData(terrainRealm.getCollisionEngine(),data);
terrainRealm.getCollisionEngine().registerCollisionObject(terrainBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainBody);
return terrainBody;
}
/**
* Creates an ode DBody from a terrain chunk data object
* @param data The terrain data
* @return The DBody
*/
private static DBody generateBodyFromTerrainData(CollisionEngine collisionEngine, TerrainChunkData data){
//create body
DBody body = OdeHelper.createBody(collisionEngine.getDWorld());
//create data
int numberTriangles = data.getFaceElements().size() / 3;
int numberVertices = data.getVertices().size() / 3;
float[] vertices = new float[numberVertices * 3];
int vertexInserterPos = 0;
int[] indices = new int[numberTriangles * 3];
int indexInserterPos = 0;
for(float vertexValue : data.getVertices()){
vertices[vertexInserterPos] = vertexValue;
vertexInserterPos++;
}
for(int element : data.getFaceElements()){
indices[indexInserterPos] = element;
indexInserterPos++;
}
//create trimesh
if(vertices.length > 0){
DTriMesh triMesh = collisionEngine.createTrimeshGeom(vertices,indices);
triMesh.setBody(body);
}
return body;
}
/**
* Generates a body from an AIScene
* @param scene The AIScene to generate a rigid body off of
* @return A rigid body based on the AIScene
*/
public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene){
DBody body = OdeHelper.createBody(collisionEngine.getDWorld());
PointerBuffer meshesBuffer = scene.mMeshes();
while(meshesBuffer.hasRemaining()){
float[] verts;
int numVertices;
int[] indices;
int numTriangles;
AIMesh aiMesh = AIMesh.create(meshesBuffer.get());
//allocate array for vertices
numVertices = aiMesh.mNumVertices();
verts = new float[numVertices * 3];
//read vertices
AIVector3D.Buffer vertexBuffer = aiMesh.mVertices();
int vertPos = 0;
while(vertexBuffer.hasRemaining()){
AIVector3D vector = vertexBuffer.get();
verts[vertPos+0] = vector.x();
verts[vertPos+1] = vector.y();
verts[vertPos+2] = vector.z();
vertPos = vertPos + 3;
}
numTriangles = aiMesh.mNumFaces();
indices = new int[numTriangles * 3];
int indicesPos = 0;
//read faces
AIFace.Buffer faceBuffer = aiMesh.mFaces();
while(faceBuffer.hasRemaining()){
AIFace currentFace = faceBuffer.get();
IntBuffer indexBuffer = currentFace.mIndices();
while(indexBuffer.hasRemaining()){
int index = indexBuffer.get();
indices[indicesPos] = index;
indicesPos++;
}
}
DTriMesh meshGeom = collisionEngine.createTrimeshGeom(verts, indices);
meshGeom.setBody(body);
}
return body;
}
/**
* Adds a test plane body to the engine scene
* @param engine The engine
*/
public static void addTestPlaneRigidBody(CollisionEngine engine){
DPlane plane = OdeHelper.createPlane(engine.getSpace(), 0, 1, 0, 0);
}
/**
* Gets the current position of a rigid body as a joml vector
* @param body The dbody
* @return The position
*/
public static Vector3d getRigidBodyPosition(DBody body){
return odeVecToJomlVec(body.getPosition());
}
/**
* Gets the rotation of an ode body as a joml quaternion
* @param body
* @return
*/
public static Quaterniond getRigidBodyRotation(DBody body){
return odeQuatToJomlQuat(body.getQuaternion());
}
/**
* Converts an Ode vector to a joml vector
* @param vector Ode vector
* @return joml vector
*/
public static Vector3d odeVecToJomlVec(org.ode4j.math.DVector3C vector){
return new Vector3d(vector.get0(),vector.get1(),vector.get2());
}
/**
* Converts an Ode quaternion to a joml quaternion
* @param quaternion Ode quat
* @return joml quat
*/
public static Quaterniond odeQuatToJomlQuat(DQuaternionC quaternion){
return new Quaterniond(quaternion.get1(), quaternion.get2(), quaternion.get3(), quaternion.get0());
}
/**
* Converts a joml quat to an ode quat
* @param quaternion The joml quat
* @return The ode quata
*/
public static DQuaternion jomlQuatToOdeQuat(Quaterniond quaternion){
return new DQuaternion(quaternion.w, quaternion.x, quaternion.y, quaternion.z);
}
/**
* Sets the position + rotation of a body
* @param position The position
* @param rotation The rotation
* @param body The body
*/
public static void setRigidBodyTransform(CollisionEngine collisionEngine, Vector3d position, Quaterniond rotation, DBody body){
collisionEngine.setBodyTransform(body, position, rotation);
}
// public static RigidBody getUnitCylinderRigidBody(float mass){
// CylinderShape cylinderShape = new CylinderShape(jomlToVecmathVector3f(new Vector3f(1.0f,1.0f,1.0f)));
// DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,1,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f)));
// RigidBodyConstructionInfo cylinderRigidBodyCI = new RigidBodyConstructionInfo(mass, defaultMotionState, cylinderShape);
// RigidBody cylinderRigidBody = new RigidBody(cylinderRigidBodyCI);
//// cylinderRigidBody.setMassProps(mass, PhysicsUtils.jomlToVecmathVector3f(new Vector3f(1.0f,1.0f,1.0f)));
// cylinderRigidBody.clearForces();
// return cylinderRigidBody;
// }
//The width of a plane rigid body
//It's really a box under the hood
static final double PLANE_WIDTH = 0.3;
/**
* Creates a plane DBody. Dimensions x and z control the length and width of the plane;
* @param dimensions The dimensions of the plane
* @return The DBody
*/
public static DBody createPlaneGeom(CollisionEngine collisionEngine, Vector3d dimensions){
return collisionEngine.createCubeGeom(new Vector3d(dimensions.x,PLANE_WIDTH,dimensions.z));
}
/**
* Creates a cube DBody. Dimensions controlled by the dimensions vector.
* @param collisionEngine The collision engine to create the body inside of
* @param dimensions The dimensions of the cube
* @return The DBody
*/
public static DBody createCubeGeom(CollisionEngine collisionEngine, Vector3d dimensions){
return collisionEngine.createCubeGeom(dimensions);
}
/**
* Creates a cylinder DBody. Dimensions controlled by the dimensions vector.
* @param collisionEngine The collision engine to create the body inside of
* @param dimensions The dimensions of the cube
* @return The DBody
*/
public static DBody createCylinderGeom(CollisionEngine collisionEngine, Vector3d dimensions){
return collisionEngine.createCylinderGeom(dimensions);
}
}

View File

@ -0,0 +1,113 @@
package electrosphere.collision;
import org.ode4j.math.DMatrix3;
import org.ode4j.math.DVector3;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DBox;
import org.ode4j.ode.DContact;
import org.ode4j.ode.DContactBuffer;
import org.ode4j.ode.DContactJoint;
import org.ode4j.ode.DCylinder;
import org.ode4j.ode.DGeom;
import org.ode4j.ode.DJoint;
import org.ode4j.ode.DJointGroup;
import org.ode4j.ode.DRay;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DTriMesh;
import org.ode4j.ode.DTriMeshData;
import org.ode4j.ode.DWorld;
import org.ode4j.ode.OdeHelper;
import org.ode4j.ode.DGeom.DNearCallback;
import electrosphere.collision.collidable.Collidable;
import static org.ode4j.ode.OdeHelper.*;
import static org.ode4j.ode.OdeMath.*;
public class RayCastCallback implements DNearCallback {
static final int MAX_CONTACTS = 5;
/**
* // Check ray collision against a space
void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) {
dReal *HitPosition = (dReal *)Data;
// Check collisions
dContact Contacts[MAX_CONTACTS];
int Count = dCollide(Geometry1, Geometry2, MAX_CONTACTS, &Contacts[0].geom, sizeof(dContact));
for(int i = 0; i < Count; i++) {
// Check depth against current closest hit
if(Contacts[i].geom.depth < HitPosition[3]) {
dCopyVector3(HitPosition, Contacts[i].geom.pos);
HitPosition[3] = Contacts[i].geom.depth;
}
}
}
*/
@Override
public void call(Object data, DGeom o1, DGeom o2) {
// if (o1->body && o2->body) return;
// exit without doing anything if the two bodies are connected by a joint
DBody b1 = o1.getBody();
DBody b2 = o2.getBody();
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return;
//creates a buffer to store potential collisions
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
for (int i=0; i<MAX_CONTACTS; i++) {
DContact contact = contacts.get(i);
contact.surface.mode = dContactBounce | dContactSoftCFM;
contact.surface.mu = dInfinity;
contact.surface.mu2 = 0;
contact.surface.bounce = 0.1;
contact.surface.bounce_vel = 0.1;
contact.surface.soft_cfm = 0.01;
}
if(!(bodyPointerMap.get(b1).getType() == Collidable.TYPE_TERRAIN && bodyPointerMap.get(b2).getType() == Collidable.TYPE_TERRAIN)){
//calculate collisions
int numc = OdeHelper.collide(o1,o2,MAX_CONTACTS,contacts.getGeomBuffer());
//create DContacts based on each collision that occurs
if (numc != 0) {
DMatrix3 RI = new DMatrix3();
RI.setIdentity ();
for (int i=0; i<numc; i++) {
DContact contact = contacts.get(i);
//special code for ray casting
if (o1 instanceof DRay || o2 instanceof DRay){
DMatrix3 Rotation = new DMatrix3();
Rotation.setIdentity();
// dsDrawSphere(contact.geom.pos, Rotation, (0.01));
DVector3 End = new DVector3();
End.eqSum( contact.geom.pos, contact.geom.normal, contact.geom.depth );
// dsDrawLine(contact.geom.pos, End);
continue;
}
// contact.geom.pos
resolveCollision(
bodyPointerMap.get(o1.getBody()),
bodyPointerMap.get(o2.getBody()),
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
(float)contact.geom.depth
);
resolveCollision(
bodyPointerMap.get(o2.getBody()),
bodyPointerMap.get(o1.getBody()),
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
(float)contact.geom.depth
);
}
}
}
}
}

View File

@ -1,7 +1,5 @@
package electrosphere.game.collision.collidable;
package electrosphere.collision.collidable;
import electrosphere.collision.shapes.CollisionShape;
import electrosphere.dynamics.RigidBody;
import electrosphere.entity.Entity;
import electrosphere.entity.state.collidable.Impulse;
import java.util.LinkedList;

View File

@ -19,7 +19,8 @@ import electrosphere.client.scene.ClientWorldData;
import electrosphere.client.sim.ClientSimulation;
import electrosphere.client.terrain.cells.DrawCellManager;
import electrosphere.client.terrain.manager.ClientTerrainManager;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.CollisionWorldData;
import electrosphere.controls.CameraHandler;
import electrosphere.controls.ControlCallback;
import electrosphere.controls.ControlHandler;
@ -30,8 +31,6 @@ import electrosphere.engine.loadingthreads.LoadingThread;
import electrosphere.entity.Entity;
import electrosphere.entity.Scene;
import electrosphere.entity.types.hitbox.HitboxManager;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.game.collision.CollisionWorldData;
import electrosphere.game.config.UserSettings;
import electrosphere.game.server.structure.virtual.StructureManager;
import electrosphere.game.server.world.MacroData;

View File

@ -6,6 +6,8 @@ import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import java.util.concurrent.TimeUnit;
import org.ode4j.ode.OdeHelper;
import electrosphere.audio.AudioEngine;
import electrosphere.client.sim.ClientFunctions;
import electrosphere.controls.ControlHandler;
@ -80,6 +82,9 @@ public class Main {
//init global variables
Globals.initGlobals();
//init ODE
OdeHelper.initODE();
// if(1==1){
// SaveUtils.loadSave("arena");
// Globals.authenticationManager = new AuthenticationManager();
@ -328,6 +333,8 @@ public class Main {
if(Globals.netMonitor != null){
Globals.netMonitor.close();
}
//shutdown ode
OdeHelper.closeODE();
}
public static long getCurrentFrame(){

View File

@ -1,8 +1,8 @@
package electrosphere.engine.assetmanager;
import electrosphere.audio.AudioBuffer;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils;
import electrosphere.renderer.Mesh;
import electrosphere.renderer.Model;
import electrosphere.renderer.ShaderProgram;
@ -21,6 +21,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.lwjgl.assimp.AIScene;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DWorld;
/**
*
@ -41,8 +43,8 @@ public class AssetManager {
Map<String,ShaderProgram> shadersLoadedIntoMemory = new ConcurrentHashMap<String,ShaderProgram>();
List<ActorShaderMask> shadersInQueue = new CopyOnWriteArrayList<ActorShaderMask>();
Map<String,CollisionObject> physicsMeshesLoadedIntoMemory = new ConcurrentHashMap<String,CollisionObject>();
List<String> physicsMeshesToLoad = new CopyOnWriteArrayList<String>();
Map<String,DBody> physicsMeshesLoadedIntoMemory = new ConcurrentHashMap<String,DBody>();
List<PhysicsMeshQueueItem> physicsMeshesToLoad = new CopyOnWriteArrayList<PhysicsMeshQueueItem>();
Map<String,PoseModel> poseModelsLoadedIntoMemory = new ConcurrentHashMap<String,PoseModel>();
List<String> poseModelsInQueue = new CopyOnWriteArrayList<String>();
@ -67,12 +69,17 @@ public class AssetManager {
//models
for(String currentPath : modelsInQueue){
modelsInQueue.remove(currentPath);
AIScene scene = ModelLoader.loadAIScene(currentPath);
modelsLoadedIntoMemory.put(currentPath, ModelLoader.createModelFromAiScene(scene,currentPath));
if(physicsMeshesToLoad.contains(currentPath)){
//create physics
physicsMeshesToLoad.remove(currentPath);
physicsMeshesLoadedIntoMemory.put(currentPath,PhysicsUtils.generateRigidBodyFromAIScene(scene));
AIScene aiScene = ModelLoader.loadAIScene(currentPath);
modelsLoadedIntoMemory.put(currentPath, ModelLoader.createModelFromAiScene(aiScene,currentPath));
for(PhysicsMeshQueueItem physicsMeshQueueItem : physicsMeshesToLoad){
if(physicsMeshQueueItem.modelPath.contains(currentPath)){
//create physics
physicsMeshesToLoad.remove(physicsMeshQueueItem);
physicsMeshesLoadedIntoMemory.put(
getCollisionMeshMapKey(physicsMeshQueueItem.collisionEngine,currentPath),
PhysicsUtils.generateRigidBodyFromAIScene(physicsMeshQueueItem.collisionEngine,aiScene)
);
}
}
}
//textures from disk to gpu
@ -345,14 +352,29 @@ public class AssetManager {
//
//COLLISION MESH
//
public void addCollisionMeshToQueue(String path){
if(!physicsMeshesToLoad.contains(path) && !physicsMeshesLoadedIntoMemory.containsKey(path)){
physicsMeshesToLoad.add(path);
public void addCollisionMeshToQueue(PhysicsMeshQueueItem physicsMeshQueueItem){
if(
!physicsMeshesToLoad.contains(physicsMeshQueueItem) &&
!physicsMeshesLoadedIntoMemory.containsKey(getCollisionMeshMapKey(
physicsMeshQueueItem.collisionEngine,
physicsMeshQueueItem.modelPath
))){
physicsMeshesToLoad.add(physicsMeshQueueItem);
}
}
public CollisionObject fetchCollisionObject(String path){
return physicsMeshesLoadedIntoMemory.get(path);
public DBody fetchCollisionObject(CollisionEngine collisionEngine, String path){
return physicsMeshesLoadedIntoMemory.get(getCollisionMeshMapKey(collisionEngine,path));
}
/**
* Gets a key based on collision engine object hash and path of model
* @param collisionEngine collision engine
* @param path The path
* @return The key
*/
private String getCollisionMeshMapKey(CollisionEngine collisionEngine, String path){
return collisionEngine + path;
}

View File

@ -0,0 +1,26 @@
package electrosphere.engine.assetmanager;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DWorld;
import electrosphere.collision.CollisionEngine;
/**
* Item in a queue of physics meshes to be loaded from disk. Relates world to model path.
*/
public class PhysicsMeshQueueItem {
CollisionEngine collisionEngine;
String modelPath;
/**
* Constructor
* @param collisionEngine The collision engine
* @param modelPath The path to the model
*/
public PhysicsMeshQueueItem(CollisionEngine collisionEngine, String modelPath){
this.collisionEngine = collisionEngine;
this.modelPath = modelPath;
}
}

View File

@ -2,6 +2,7 @@ package electrosphere.engine.loadingthreads;
import java.util.concurrent.TimeUnit;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@ -202,7 +203,7 @@ public class ClientLoading {
EntityCreationUtils.makeEntityDrawable(cloudRing, "Models/cloudRing.fbx");
EntityUtils.getRotation(cloudRing).rotateX((float)(-Math.PI/2.0f));
EntityUtils.getScale(cloudRing).mul(1000.0f);
Globals.clientScene.registerBehaviorTree(new ApplyRotationTree(cloudRing,new Quaternionf().rotationZ(0.0001f)));
Globals.clientScene.registerBehaviorTree(new ApplyRotationTree(cloudRing,new Quaterniond().rotationZ(0.0001)));
Globals.assetManager.queueOverrideMeshShader("Models/cloudRing.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs");
}

View File

@ -13,6 +13,7 @@ import org.joml.Vector3i;
import electrosphere.auth.AuthenticationManager;
import electrosphere.client.terrain.cells.DrawCellManager;
import electrosphere.collision.CollisionWorldData;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
@ -20,7 +21,6 @@ import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.movement.ApplyRotationTree;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.collision.CollisionWorldData;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.game.server.town.Town;

View File

@ -18,7 +18,7 @@ public class ClientEntityUtils {
*/
public static void initiallyPositionEntity(Entity entity, Vector3d position){
//reposition entity
CollisionObjUtils.positionCharacter(entity, position);
CollisionObjUtils.clientPositionCharacter(entity, position);
}

View File

@ -1,5 +1,6 @@
package electrosphere.entity;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -80,7 +81,7 @@ public class EntityCreationUtils {
public static void makeEntityPoseable(Entity entity, String modelPath){
entity.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(modelPath));
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
@ -95,7 +96,7 @@ public class EntityCreationUtils {
public static void makeEntityDrawable(Entity entity, String modelPath){
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
@ -111,7 +112,7 @@ public class EntityCreationUtils {
public static void makeEntityDrawablePreexistingModel(Entity entity, String modelPath){
entity.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(modelPath));
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);

View File

@ -19,6 +19,7 @@ import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.poseactor.PoseActor;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -33,8 +34,8 @@ public class EntityUtils {
return (Vector3d)e.getData(EntityDataStrings.DATA_STRING_POSITION);
}
public static Quaternionf getRotation(Entity e){
return (Quaternionf)e.getData(EntityDataStrings.DATA_STRING_ROTATION);
public static Quaterniond getRotation(Entity e){
return (Quaterniond)e.getData(EntityDataStrings.DATA_STRING_ROTATION);
}
public static Vector3f getScale(Entity e){
@ -55,7 +56,7 @@ public class EntityUtils {
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
@ -73,7 +74,7 @@ public class EntityUtils {
Entity rVal = new Entity();
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(modelPath));
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().rotateAxis((float)0, new Vector3f(1,0,0)));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().rotateAxis(0, new Vector3d(1,0,0)));
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
@ -92,7 +93,7 @@ public class EntityUtils {
rVal.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(modelPath));
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
@ -103,7 +104,7 @@ public class EntityUtils {
Entity rVal = new Entity();
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().rotateAxis((float)0, new Vector3f(1,0,0)));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().rotateAxis(0, new Vector3d(1,0,0)));
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_UI_ELEMENT, true);
Globals.clientScene.registerEntity(rVal);
@ -119,7 +120,7 @@ public class EntityUtils {
Entity rVal = new Entity();
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
EntityLookupUtils.registerServerEntity(rVal);
return rVal;

View File

@ -33,7 +33,7 @@ public class ServerEntityUtils {
realm.initializeServerSideEntity(entity, cell);
}
//reposition entity
CollisionObjUtils.positionCharacter(entity, position);
CollisionObjUtils.serverPositionCharacter(entity, position);
}
/**
@ -66,7 +66,7 @@ public class ServerEntityUtils {
// Globals.drawCellManager.setCellY(Globals.clientPlayerData.getWorldPos().z);
// }
//reposition entity
CollisionObjUtils.positionCharacter(entity, Globals.spawnPoint);
CollisionObjUtils.serverPositionCharacter(entity, Globals.spawnPoint);
}
}

View File

@ -1,5 +1,6 @@
package electrosphere.entity.state.attack;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
@ -17,7 +18,6 @@ import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.projectile.ProjectileUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.attack.AttackMove;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.net.parser.net.message.EntityMessage;
@ -128,7 +128,7 @@ public class AttackTree implements BehaviorTree {
}
}
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z));
EntityUtils.getRotation(parent).rotationTo(new Vector3d(0,0,1), new Vector3d(movementVector.x,movementVector.y,movementVector.z));
//set initial stuff
state = AttackTreeState.WINDUP;
frameCurrent = 0;
@ -297,7 +297,7 @@ public class AttackTree implements BehaviorTree {
//spawn projectile
//TODO: solve spawnPosition, initialVector
Vector3d spawnPosition = new Vector3d(0,0,0);
Quaternionf arrowRotation = new Quaternionf();
Quaterniond arrowRotation = new Quaterniond();
String targetBone = null;
EquipState equipState = EquipState.getEquipState(parent);
EquipPoint weaponPoint = null;
@ -309,7 +309,7 @@ public class AttackTree implements BehaviorTree {
//transform bone space
spawnPosition = new Vector3d(parentActor.getBonePosition(targetBone));
spawnPosition = spawnPosition.mul(((Vector3f)EntityUtils.getScale(parent)));
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
spawnPosition = spawnPosition.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w));
//transform worldspace
spawnPosition.add(new Vector3d(EntityUtils.getPosition(parent)));

View File

@ -1,5 +1,6 @@
package electrosphere.entity.state.attack;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
@ -19,7 +20,6 @@ import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.types.projectile.ProjectileUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.attack.AttackMove;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.net.parser.net.message.EntityMessage;
@ -131,7 +131,7 @@ public class ServerAttackTree implements BehaviorTree {
}
}
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z));
EntityUtils.getRotation(parent).rotationTo(new Vector3d(0,0,1), new Vector3d(movementVector.x,movementVector.y,movementVector.z));
//set initial stuff
state = AttackTreeState.WINDUP;
frameCurrent = 0;
@ -298,7 +298,7 @@ public class ServerAttackTree implements BehaviorTree {
//spawn projectile
//TODO: solve spawnPosition, initialVector
Vector3d spawnPosition = new Vector3d(0,0,0);
Quaternionf arrowRotation = new Quaternionf();
Quaterniond arrowRotation = new Quaterniond();
String targetBone = null;
EquipState equipState = EquipState.getEquipState(parent);
EquipPoint weaponPoint = null;
@ -310,7 +310,7 @@ public class ServerAttackTree implements BehaviorTree {
//transform bone space
spawnPosition = new Vector3d(parentActor.getBonePosition(targetBone));
spawnPosition = spawnPosition.mul(((Vector3f)EntityUtils.getScale(parent)));
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
spawnPosition = spawnPosition.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w));
//transform worldspace
spawnPosition.add(new Vector3d(EntityUtils.getPosition(parent)));

View File

@ -1,18 +1,17 @@
package electrosphere.entity.state.collidable;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.debug.DebugVisualizerUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate;
import org.joml.Matrix4f;
@ -22,6 +21,7 @@ import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4d;
import org.joml.Vector4f;
import org.ode4j.ode.DBody;
/**
*
@ -30,22 +30,23 @@ import org.joml.Vector4f;
public class ClientCollidableTree implements BehaviorTree {
Entity parent;
CollisionObject body;
//the ode body for this collidable tree
DBody body;
Collidable collidable;
Quaternionf angularVelocity = new Quaternionf(0,0,0,0);
Quaterniond angularVelocity = new Quaterniond(0,0,0,0);
Vector4d cumulativeTorque = new Vector4d(0,0,0,0);
boolean applyImpulses = true;
static final float DELTA_T = 0.01f;
public ClientCollidableTree(Entity e, Collidable collidable, CollisionObject body){
public ClientCollidableTree(Entity e, Collidable collidable, DBody body){
parent = e;
this.collidable = collidable;
this.body = body;
}
public ClientCollidableTree(Entity e, Collidable collidable, CollisionObject body, boolean applyImpulses){
public ClientCollidableTree(Entity e, Collidable collidable, DBody body, boolean applyImpulses){
parent = e;
this.collidable = collidable;
this.body = body;
@ -56,11 +57,10 @@ public class ClientCollidableTree implements BehaviorTree {
public void simulate(float deltaTime){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Matrix4f inverseInertiaTensor = CollisionObjUtils.getInverseInertiaTensor(parent);
Vector3d offsetVector = new Vector3d();
Vector3d newPosition = new Vector3d(position);
javax.vecmath.Matrix4f bodyTransformMatrix;
//have we hit a terrain impulse?
boolean hitTerrain = false;
//handle impulses
@ -74,13 +74,13 @@ public class ClientCollidableTree implements BehaviorTree {
}
if(impulse.type.matches(Collidable.TYPE_ITEM)){
if(parent.containsKey(EntityDataStrings.CLIENT_GRAVITY_TREE)){
((GravityTree)parent.getData(EntityDataStrings.CLIENT_GRAVITY_TREE)).start();
((ClientGravityTree)parent.getData(EntityDataStrings.CLIENT_GRAVITY_TREE)).start();
}
}
if(impulse.type.matches(Collidable.TYPE_CREATURE)){
// System.out.println(System.currentTimeMillis() + " creature hit!");
if(parent.containsKey(EntityDataStrings.CLIENT_GRAVITY_TREE)){
((GravityTree)parent.getData(EntityDataStrings.CLIENT_GRAVITY_TREE)).start();
((ClientGravityTree)parent.getData(EntityDataStrings.CLIENT_GRAVITY_TREE)).start();
}
}
if(
@ -132,7 +132,7 @@ public class ClientCollidableTree implements BehaviorTree {
// if(CreatureUtils.isCreature(parent) && forceDir.y < 0.5){
// System.out.println(collisionPoint + " x " + forceDir + " => " + torqueVec + " " + torqueMag);
// }
Quaternionf impulseRotation = new Quaternionf().rotationAxis((float)torqueMag * DELTA_T,new Vector3f((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z));
Quaterniond impulseRotation = new Quaterniond().rotationAxis(torqueMag * DELTA_T,torqueVec.x,torqueVec.y,torqueVec.z);
if(angularVelocity.lengthSquared() > 0.001){
angularVelocity.mul(impulseRotation);
} else {
@ -148,7 +148,7 @@ public class ClientCollidableTree implements BehaviorTree {
// }
//friction
if(angularVelocity.lengthSquared() > 0.001){
angularVelocity.slerp(new Quaternionf(0,0,0,1), 0.03f);
angularVelocity.slerp(new Quaterniond(0,0,0,1), 0.03);
// angularVelocity.scale((float)(Math.sqrt(angularVelocity.lengthSquared()) * 0.9));
// System.out.println(angularVelocity);
}
@ -163,7 +163,7 @@ public class ClientCollidableTree implements BehaviorTree {
// }
if(angularVelocity.lengthSquared() > 0.001){
// System.out.println("-" + rotation);
Quaternionf newRotation = new Quaternionf(rotation).mul(angularVelocity).normalize();
Quaterniond newRotation = new Quaterniond(rotation).mul(angularVelocity).normalize();
// if(new Quaternionf(newRotation).add(new Quaternionf(rotation).conjugate()).lengthSquared() > 0.2){
// newRotation.w = Math.copySign(newRotation.w, rotation.w);
// newRotation.x = Math.copySign(newRotation.x, rotation.x);
@ -206,21 +206,21 @@ public class ClientCollidableTree implements BehaviorTree {
//update collision engine of this thing's position
CollidableTemplate template = (CollidableTemplate)parent.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);
bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)position.x + template.getOffsetX(),(float)position.y + template.getOffsetY(),(float)position.z + template.getOffsetZ())),1.0f);
body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
// bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)newPosition.x,(float)newPosition.y,(float)newPosition.z)),1.0f);
// body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
body.setPosition(position.x + template.getOffsetX(),position.y + template.getOffsetY(),position.z + template.getOffsetZ());
body.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
}
public void setCollisionObject(CollisionObject body, Collidable collidable){
/**
* Sets the structures backing this collidable tree
* @param body The ode body
* @param collidable The collidable
*/
public void setCollisionObject(DBody body, Collidable collidable){
this.body = body;
this.collidable = collidable;
}
public float getAngularVelocityMagnitude(){
public double getAngularVelocityMagnitude(){
return angularVelocity.lengthSquared();
}

View File

@ -1,19 +1,17 @@
package electrosphere.entity.state.collidable;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.debug.DebugVisualizerUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.server.datacell.Realm;
@ -24,6 +22,7 @@ import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector4d;
import org.joml.Vector4f;
import org.ode4j.ode.DBody;
/**
*
@ -32,22 +31,22 @@ import org.joml.Vector4f;
public class ServerCollidableTree implements BehaviorTree {
Entity parent;
CollisionObject body;
DBody body;
Collidable collidable;
Quaternionf angularVelocity = new Quaternionf(0,0,0,0);
Quaterniond angularVelocity = new Quaterniond(0,0,0,0);
Vector4d cumulativeTorque = new Vector4d(0,0,0,0);
boolean applyImpulses = true;
static final float DELTA_T = 0.01f;
public ServerCollidableTree(Entity e, Collidable collidable, CollisionObject body){
public ServerCollidableTree(Entity e, Collidable collidable, DBody body){
parent = e;
this.collidable = collidable;
this.body = body;
}
public ServerCollidableTree(Entity e, Collidable collidable, CollisionObject body, boolean applyImpulses){
public ServerCollidableTree(Entity e, Collidable collidable, DBody body, boolean applyImpulses){
parent = e;
this.collidable = collidable;
this.body = body;
@ -58,11 +57,10 @@ public class ServerCollidableTree implements BehaviorTree {
public void simulate(float deltaTime){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Matrix4f inverseInertiaTensor = CollisionObjUtils.getInverseInertiaTensor(parent);
Vector3d offsetVector = new Vector3d();
Vector3d newPosition = new Vector3d(position);
javax.vecmath.Matrix4f bodyTransformMatrix;
//have we hit a terrain impulse?
boolean hitTerrain = false;
//handle impulses
@ -134,7 +132,7 @@ public class ServerCollidableTree implements BehaviorTree {
// if(CreatureUtils.isCreature(parent) && forceDir.y < 0.5){
// System.out.println(collisionPoint + " x " + forceDir + " => " + torqueVec + " " + torqueMag);
// }
Quaternionf impulseRotation = new Quaternionf().rotationAxis((float)torqueMag * DELTA_T,new Vector3f((float)torqueVec.x,(float)torqueVec.y,(float)torqueVec.z));
Quaterniond impulseRotation = new Quaterniond().rotationAxis(torqueMag * DELTA_T,torqueVec.x,torqueVec.y,torqueVec.z);
if(angularVelocity.lengthSquared() > 0.001){
angularVelocity.mul(impulseRotation);
} else {
@ -150,7 +148,7 @@ public class ServerCollidableTree implements BehaviorTree {
// }
//friction
if(angularVelocity.lengthSquared() > 0.001){
angularVelocity.slerp(new Quaternionf(0,0,0,1), 0.03f);
angularVelocity.slerp(new Quaterniond(0,0,0,1), 0.03);
// angularVelocity.scale((float)(Math.sqrt(angularVelocity.lengthSquared()) * 0.9));
// System.out.println(angularVelocity);
}
@ -165,7 +163,7 @@ public class ServerCollidableTree implements BehaviorTree {
// }
if(angularVelocity.lengthSquared() > 0.001){
// System.out.println("-" + rotation);
Quaternionf newRotation = new Quaternionf(rotation).mul(angularVelocity).normalize();
Quaterniond newRotation = new Quaterniond(rotation).mul(angularVelocity).normalize();
// if(new Quaternionf(newRotation).add(new Quaternionf(rotation).conjugate()).lengthSquared() > 0.2){
// newRotation.w = Math.copySign(newRotation.w, rotation.w);
// newRotation.x = Math.copySign(newRotation.x, rotation.x);
@ -209,21 +207,23 @@ public class ServerCollidableTree implements BehaviorTree {
//update collision engine of this thing's position
CollidableTemplate template = (CollidableTemplate)parent.getData(EntityDataStrings.PHYSICS_MODEL_TEMPLATE);
bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)position.x + template.getOffsetX(),(float)position.y + template.getOffsetY(),(float)position.z + template.getOffsetZ())),1.0f);
body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
// bodyTransformMatrix = new javax.vecmath.Matrix4f(PhysicsUtils.jomlToVecmathQuaternionf(rotation),PhysicsUtils.jomlToVecmathVector3f(new Vector3f((float)newPosition.x,(float)newPosition.y,(float)newPosition.z)),1.0f);
// body.setWorldTransform(new electrosphere.linearmath.Transform(bodyTransformMatrix));
body.setPosition(position.x + template.getOffsetX(),position.y + template.getOffsetY(),position.z + template.getOffsetZ());
body.setQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
}
public void setCollisionObject(CollisionObject body, Collidable collidable){
/**
* Sets the structures backing this collidable tree
* @param body The ode body
* @param collidable The collidable
*/
public void setCollisionObject(DBody body, Collidable collidable){
this.body = body;
this.collidable = collidable;
}
public float getAngularVelocityMagnitude(){
public double getAngularVelocityMagnitude(){
return angularVelocity.lengthSquared();
}

View File

@ -6,10 +6,10 @@ import java.util.List;
import java.util.Map;
import org.joml.Vector3d;
import org.ode4j.ode.DBody;
import electrosphere.client.targeting.crosshair.Crosshair;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
@ -22,7 +22,6 @@ import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.game.data.item.type.EquipWhitelist;
import electrosphere.net.parser.net.message.InventoryMessage;
@ -117,7 +116,7 @@ public class EquipState {
AttachUtils.serverAttachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
//make uncollidable
if(inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)inWorldItem.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
DBody rigidBody = (DBody)inWorldItem.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Realm inWorldRealm = Globals.realmManager.getEntityRealm(inWorldItem);
inWorldRealm.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
@ -133,7 +132,7 @@ public class EquipState {
equipMap.put(point.getEquipPointId(),inWorldItem);
AttachUtils.serverAttachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
if(inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)inWorldItem.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
DBody rigidBody = (DBody)inWorldItem.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Realm inWorldRealm = Globals.realmManager.getEntityRealm(inWorldItem);
inWorldRealm.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
@ -215,7 +214,7 @@ public class EquipState {
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
//make uncollidable
if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
//hide toEquip actor
@ -230,7 +229,7 @@ public class EquipState {
equipMap.put(point.getEquipPointId(),toEquip);
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody);
}
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE);

View File

@ -3,11 +3,13 @@ package electrosphere.entity.state.gravity;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.ode4j.ode.DBody;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
@ -16,14 +18,13 @@ import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.movement.FallTree;
import electrosphere.entity.state.movement.JumpTree;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.parser.net.message.EntityMessage;
/**
*
* @author amaterasu
*/
public class GravityTree implements BehaviorTree {
public class ClientGravityTree implements BehaviorTree {
public static enum GravityTreeState {
ACTIVE,
@ -40,12 +41,12 @@ public class GravityTree implements BehaviorTree {
float gravityVelocity = 0;
float gravityAccel = 0.0007f;
CollisionObject body;
DBody body;
Collidable collidable;
List<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
public GravityTree(Entity e, Collidable collidable, CollisionObject body, int fallFrame){
public ClientGravityTree(Entity e, Collidable collidable, DBody body, int fallFrame){
state = GravityTreeState.ACTIVE;
parent = e;
this.body = body;
@ -88,9 +89,8 @@ public class GravityTree implements BehaviorTree {
// Actor entityActor = EntityUtils.getActor(parent);
Vector3d position = EntityUtils.getPosition(parent);
// Vector3f movementVector = CreatureUtils.getMovementVector(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Vector3f newPosition;
javax.vecmath.Matrix4f bodyTransformMatrix;
ClientCollidableTree collidableTree = null;
if(ClientCollidableTree.hasClientCollidableTree(parent)){
collidableTree = ClientCollidableTree.getClientCollidableTree(parent);

View File

@ -7,7 +7,7 @@ public class GravityUtils {
public static void clientAttemptActivateGravity(Entity target){
if(target.containsKey(EntityDataStrings.GRAVITY_ENTITY)){
GravityTree tree = (GravityTree)target.getData(EntityDataStrings.CLIENT_GRAVITY_TREE);
ClientGravityTree tree = (ClientGravityTree)target.getData(EntityDataStrings.CLIENT_GRAVITY_TREE);
tree.start();
}
}
@ -21,7 +21,7 @@ public class GravityUtils {
public static void clientAttemptDeactivateGravity(Entity target){
if(target.containsKey(EntityDataStrings.GRAVITY_ENTITY)){
GravityTree tree = (GravityTree)target.getData(EntityDataStrings.CLIENT_GRAVITY_TREE);
ClientGravityTree tree = (ClientGravityTree)target.getData(EntityDataStrings.CLIENT_GRAVITY_TREE);
tree.stop();
}
}

View File

@ -3,11 +3,13 @@ package electrosphere.entity.state.gravity;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.ode4j.ode.DBody;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
@ -16,7 +18,6 @@ import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.movement.ServerFallTree;
import electrosphere.entity.state.movement.ServerJumpTree;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.server.datacell.Realm;
@ -41,12 +42,12 @@ public class ServerGravityTree implements BehaviorTree {
float gravityVelocity = 0;
float gravityAccel = 0.0007f;
CollisionObject body;
DBody body;
Collidable collidable;
List<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
public ServerGravityTree(Entity e, Collidable collidable, CollisionObject body, int fallFrame){
public ServerGravityTree(Entity e, Collidable collidable, DBody body, int fallFrame){
state = GravityTreeState.ACTIVE;
parent = e;
this.body = body;
@ -89,9 +90,8 @@ public class ServerGravityTree implements BehaviorTree {
// Actor entityActor = EntityUtils.getActor(parent);
Vector3d position = EntityUtils.getPosition(parent);
// Vector3f movementVector = CreatureUtils.getMovementVector(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Vector3f newPosition;
javax.vecmath.Matrix4f bodyTransformMatrix;
ServerCollidableTree collidableTree = null;
if(ServerCollidableTree.hasServerCollidableTree(parent)){
collidableTree = ServerCollidableTree.getServerCollidableTree(parent);

View File

@ -2,10 +2,12 @@ package electrosphere.entity.state.movement;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
@ -14,7 +16,6 @@ import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.anim.Animation;
@ -81,8 +82,8 @@ public class AirplaneMovementTree implements BehaviorTree {
Actor entityActor = EntityUtils.getActor(parent);
Vector3d position = EntityUtils.getPosition(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
Quaternionf movementQuaternion = new Quaternionf().rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingVector.x,0,(float)facingVector.z)).normalize();
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
Quaterniond rotation = EntityUtils.getRotation(parent);
//
//handle network messages
//
@ -181,7 +182,7 @@ public class AirplaneMovementTree implements BehaviorTree {
* @param rotation Rotation quaternion
* @param rotationVector Rotation vector
*/
void updateRotation(Quaternionf rotation, Vector3d rotationVector){
void updateRotation(Quaterniond rotation, Vector3d rotationVector){
if(Globals.RUN_CLIENT && this.parent == Globals.playerEntity){
Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
float pitch = CameraEntityUtils.getCameraPitch(Globals.playerCamera) / 180 * (float)Math.PI;
@ -198,16 +199,16 @@ public class AirplaneMovementTree implements BehaviorTree {
}
Quaternionf yawQuat = new Quaternionf().fromAxisAngleRad(new Vector3f(0,1,0), yaw);
Quaternionf pitchQuat = new Quaternionf().fromAxisAngleRad(new Vector3f(1,0,0), pitch);
Quaternionf rollQuat = new Quaternionf().fromAxisAngleRad(new Vector3f(0,0,1), rollVal);
Quaterniond yawQuat = new Quaterniond().fromAxisAngleRad(new Vector3d(0,1,0), yaw);
Quaterniond pitchQuat = new Quaterniond().fromAxisAngleRad(new Vector3d(1,0,0), pitch);
Quaterniond rollQuat = new Quaterniond().fromAxisAngleRad(new Vector3d(0,0,1), rollVal);
rotation.slerp(yawQuat.mul(pitchQuat).mul(rollQuat),0.1f);
rotation.slerp(yawQuat.mul(pitchQuat).mul(rollQuat),0.1);
//rotate thrust vector
rotationVector.set(rotation.transform(new Vector3f(0,0,1)));
rotationVector.set(rotation.transform(new Vector3d(0,0,1)));
// rotationVector.set(new Vector3f((float)rotationVector.x,(float)rotationVector.y,(float)rotationVector.z).mul(1.0f - this.maxRotationSpeed).add(new Vector3f(cameraEyeVector).mul(-this.maxRotationSpeed)));
@ -222,9 +223,9 @@ public class AirplaneMovementTree implements BehaviorTree {
* @param facingVector The current facing vector
* @param collidable The collidable of the entity
*/
void addMovementForce(float velocity, Quaternionf rotation, Collidable collidable){
Vector3f impulseDir = rotation.transform(new Vector3f(0,0,1));
collidable.addImpulse(new Impulse(new Vector3d(impulseDir.x,impulseDir.y,impulseDir.z), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Main.deltaFrames, "movement"));
void addMovementForce(float velocity, Quaterniond rotation, Collidable collidable){
Vector3d impulseDir = rotation.transform(new Vector3d(0,0,1));
collidable.addImpulse(new Impulse(new Vector3d(impulseDir), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Main.deltaFrames, "movement"));
}
/**
@ -233,7 +234,7 @@ public class AirplaneMovementTree implements BehaviorTree {
* @param facingVector The facing vector of the airplane
* @param velocity The velocity of the airplane
*/
void serverUpdateTree(Vector3d position, Quaternionf rotation, float velocity){
void serverUpdateTree(Vector3d position, Quaterniond rotation, float velocity){
if(Globals.RUN_SERVER){
int stateNumber = 0;
switch(this.state){

View File

@ -15,11 +15,11 @@ public class ApplyRotationTree implements BehaviorTree {
}
Quaternionf rotationToApply;
Quaterniond rotationToApply;
Entity parent;
ApplyRotationTreeState state = ApplyRotationTreeState.ROTATE;
public ApplyRotationTree(Entity parent, Quaternionf rotationToApply){
public ApplyRotationTree(Entity parent, Quaterniond rotationToApply){
this.parent = parent;
this.rotationToApply = rotationToApply;
}

View File

@ -1,10 +1,11 @@
package electrosphere.entity.state.movement;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.types.camera.CameraEntityUtils;
@ -16,9 +17,6 @@ import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.attack.AttackTree;
import electrosphere.entity.state.attack.AttackTree.AttackTreeState;
import electrosphere.entity.state.movement.SprintTree.SprintTreeState;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.anim.Animation;
@ -29,6 +27,8 @@ import electrosphere.renderer.actor.Actor;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -101,7 +101,7 @@ public class GroundMovementTree implements BehaviorTree {
//if we aren't the server, alert the server we intend to walk forward
if(!Globals.RUN_SERVER){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
float velocity = CreatureUtils.getVelocity(parent);
Globals.clientConnection.queueOutgoingMessage(
@ -133,7 +133,7 @@ public class GroundMovementTree implements BehaviorTree {
//if we aren't the server, alert the server we intend to slow down
if(!Globals.RUN_SERVER){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
float velocity = CreatureUtils.getVelocity(parent);
Globals.clientConnection.queueOutgoingMessage(
@ -192,8 +192,8 @@ public class GroundMovementTree implements BehaviorTree {
break;
}
// float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera);
Quaternionf movementQuaternion = new Quaternionf().rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingVector.x,0,(float)facingVector.z)).normalize();
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
Quaterniond rotation = EntityUtils.getRotation(parent);
//parse attached network messages
for(EntityMessage message : networkMessageQueue){

View File

@ -2,6 +2,7 @@ package electrosphere.entity.state.movement;
import org.joml.Vector3d;
import electrosphere.collision.collidable.Collidable;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
@ -9,7 +10,6 @@ import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.renderer.actor.Actor;
public class JumpTree implements BehaviorTree {

View File

@ -1,10 +1,10 @@
package electrosphere.entity.state.movement;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.types.camera.CameraEntityUtils;
@ -16,9 +16,6 @@ import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.attack.ServerAttackTree.AttackTreeState;
import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.net.NetUtils;
import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.renderer.anim.Animation;
@ -30,6 +27,8 @@ import electrosphere.renderer.actor.Actor;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -102,7 +101,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
//if we aren't the server, alert the server we intend to walk forward
if(!Globals.RUN_SERVER){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
float velocity = CreatureUtils.getVelocity(parent);
Globals.clientConnection.queueOutgoingMessage(
@ -134,7 +133,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
//if we aren't the server, alert the server we intend to slow down
if(!Globals.RUN_SERVER){
Vector3d position = EntityUtils.getPosition(parent);
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
float velocity = CreatureUtils.getVelocity(parent);
Globals.clientConnection.queueOutgoingMessage(
@ -193,8 +192,8 @@ public class ServerGroundMovementTree implements BehaviorTree {
break;
}
// float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera);
Quaternionf movementQuaternion = new Quaternionf().rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingVector.x,0,(float)facingVector.z)).normalize();
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
Quaterniond rotation = EntityUtils.getRotation(parent);
//parse attached network messages
for(EntityMessage message : networkMessageQueue){

View File

@ -2,6 +2,7 @@ package electrosphere.entity.state.movement;
import org.joml.Vector3d;
import electrosphere.collision.collidable.Collidable;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
@ -9,7 +10,6 @@ import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.renderer.actor.Actor;
public class ServerJumpTree implements BehaviorTree {

View File

@ -3,6 +3,7 @@ package electrosphere.entity.state.rotator;
import java.util.LinkedList;
import java.util.List;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -60,7 +61,7 @@ public class RotatorTree implements BehaviorTree{
public void applyRotatorNode(RotatorHierarchyNode node){
//apply
String nodeBoneName = node.getBone();
Quaternionf currentRotation = entityActor.getBoneRotation(nodeBoneName);
Quaterniond currentRotation = entityActor.getBoneRotation(nodeBoneName);
for(RotatorConstraint constraint : node.getRotatorContraints()){
float allowedMarginPitch = constraint.getAllowedMarginPitch();
float allowedMarginYaw = constraint.getAllowedMarginYaw();
@ -68,7 +69,7 @@ public class RotatorTree implements BehaviorTree{
boolean followsView = constraint.getFollowsView();
if(followsBone){
String parentBone = constraint.getParentBone();
Quaternionf parentBoneRotation = entityActor.getBoneRotation(parentBone);
Quaterniond parentBoneRotation = entityActor.getBoneRotation(parentBone);
// currentRotation.
}
if(followsView){

View File

@ -3,6 +3,7 @@ package electrosphere.entity.state.rotator;
import java.util.LinkedList;
import java.util.List;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -61,7 +62,7 @@ public class ServerRotatorTree implements BehaviorTree{
public void applyRotatorNode(RotatorHierarchyNode node){
//apply
String nodeBoneName = node.getBone();
Quaternionf currentRotation = entityPoseActor.getBoneRotation(nodeBoneName);
Quaterniond currentRotation = entityPoseActor.getBoneRotation(nodeBoneName);
for(RotatorConstraint constraint : node.getRotatorContraints()){
float allowedMarginPitch = constraint.getAllowedMarginPitch();
float allowedMarginYaw = constraint.getAllowedMarginYaw();
@ -69,7 +70,7 @@ public class ServerRotatorTree implements BehaviorTree{
boolean followsView = constraint.getFollowsView();
if(followsBone){
String parentBone = constraint.getParentBone();
Quaternionf parentBoneRotation = entityPoseActor.getBoneRotation(parentBone);
Quaterniond parentBoneRotation = entityPoseActor.getBoneRotation(parentBone);
// currentRotation.
}
if(followsView){

View File

@ -26,7 +26,7 @@ import org.joml.Vector3f;
public class AttachUtils {
public static void serverAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaternionf rotation){
public static void serverAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaterniond rotation){
ServerEntityTagUtils.attachTagToEntity(toAttach, EntityTags.BONE_ATTACHED);
toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true);
toAttach.putData(EntityDataStrings.ATTACH_PARENT, parent);
@ -42,7 +42,7 @@ public class AttachUtils {
}
public static void clientAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaternionf rotation){
public static void clientAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaterniond rotation){
Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED);
toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true);
toAttach.putData(EntityDataStrings.ATTACH_PARENT, parent);
@ -65,11 +65,11 @@ public class AttachUtils {
if((targetBone = (String)currentEntity.getData(EntityDataStrings.ATTACH_TARGET_BONE))!=null){
Actor parentActor = EntityUtils.getActor(parent);
//get offset rotation
Quaternionf offsetRotation = getRotationOffset(currentEntity);
Quaterniond offsetRotation = getRotationOffset(currentEntity);
//transform bone space
Vector3d position = new Vector3d(parentActor.getBonePosition(targetBone));
position = position.mul(((Vector3f)EntityUtils.getScale(parent)));
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
position = position.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w));
//transform worldspace
position.add(new Vector3d(EntityUtils.getPosition(parent)));
@ -81,7 +81,7 @@ public class AttachUtils {
Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
//calculate rotation of model
EntityUtils.getRotation(currentEntity)
.rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z))
.rotationTo(new Vector3d(0,0,1), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z))
.mul(parentActor.getBoneRotation(targetBone))
.mul(offsetRotation)
.normalize();
@ -98,11 +98,11 @@ public class AttachUtils {
if((targetBone = (String)currentEntity.getData(EntityDataStrings.ATTACH_TARGET_BONE))!=null){
Actor parentActor = EntityUtils.getActor(parent);
//get offset rotation
Quaternionf offsetRotation = getRotationOffset(currentEntity);
Quaterniond offsetRotation = getRotationOffset(currentEntity);
//transform bone space
Vector3d position = new Vector3d(parentActor.getBonePosition(targetBone));
position = position.mul(((Vector3f)EntityUtils.getScale(parent)));
Quaternionf rotation = EntityUtils.getRotation(parent);
Quaterniond rotation = EntityUtils.getRotation(parent);
position = position.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w));
//transform worldspace
position.add(new Vector3d(EntityUtils.getPosition(parent)));
@ -114,7 +114,7 @@ public class AttachUtils {
Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
//calculate rotation of model
EntityUtils.getRotation(currentEntity)
.rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z))
.rotationTo(new Vector3d(0,0,1), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z))
.mul(parentActor.getBoneRotation(targetBone))
.mul(offsetRotation)
.normalize();
@ -155,8 +155,8 @@ public class AttachUtils {
return (Entity)e.getData(EntityDataStrings.ATTACH_PARENT);
}
protected static Quaternionf getRotationOffset(Entity e){
return (Quaternionf)e.getData(EntityDataStrings.ATTACH_ROTATION_OFFSET);
protected static Quaterniond getRotationOffset(Entity e){
return (Quaterniond)e.getData(EntityDataStrings.ATTACH_ROTATION_OFFSET);
}
public static boolean hasChildren(Entity e){
@ -179,8 +179,8 @@ public class AttachUtils {
}
}
public static Quaternionf getEquipPointRotationOffset(List<Float> values){
return new Quaternionf(values.get(0),values.get(1),values.get(2),values.get(3));
public static Quaterniond getEquipPointRotationOffset(List<Float> values){
return new Quaterniond(values.get(0),values.get(1),values.get(2),values.get(3));
}
}

View File

@ -1,21 +1,25 @@
package electrosphere.entity.types.collision;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.shapes.CylinderShape;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import org.joml.Matrix4f;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DWorld;
/**
*
@ -23,17 +27,13 @@ import org.joml.Vector3f;
*/
public class CollisionObjUtils {
public static Entity clientSpawnCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation){
public static Entity clientSpawnCollisionPlane(Vector3f scale, Vector3d position, Quaterniond rotation){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
float mass = 1.0f;
CollisionObject planeObject = PhysicsUtils.getPlaneObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
planeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
DBody planeObject = PhysicsUtils.createPlaneGeom(Globals.clientSceneWrapper.getCollisionEngine(),new Vector3d(scale));
PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, planeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(planeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
@ -54,17 +54,13 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity serverSpawnCollisionPlane(Realm realm, Vector3f scale, Vector3f position, Quaternionf rotation){
public static Entity serverSpawnCollisionPlane(Realm realm, Vector3f scale, Vector3d position, Quaterniond rotation){
Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position));
float mass = 1.0f;
CollisionObject planeObject = PhysicsUtils.getPlaneObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
planeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
DBody planeObject = PhysicsUtils.createPlaneGeom(realm.getCollisionEngine(),new Vector3d(scale));
PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, planeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(planeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
@ -86,17 +82,13 @@ public class CollisionObjUtils {
}
public static Entity clientSpawnCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation){
public static Entity clientSpawnCollisionCube(Vector3f scale, Vector3d position, Quaterniond rotation){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
float mass = 1.0f;
CollisionObject cubeObject = PhysicsUtils.getCubeObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
DBody cubeObject = PhysicsUtils.createCubeGeom(Globals.clientSceneWrapper.getCollisionEngine(),new Vector3d(scale));
PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
@ -117,17 +109,13 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity serverSpawnCollisionCube(Realm realm, Vector3f scale, Vector3f position, Quaternionf rotation){
public static Entity serverSpawnCollisionCube(Realm realm, Vector3f scale, Vector3d position, Quaterniond rotation){
Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position));
float mass = 1.0f;
CollisionObject cubeObject = PhysicsUtils.getCubeObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
DBody cubeObject = PhysicsUtils.createCubeGeom(realm.getCollisionEngine(),new Vector3d(scale));
PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
@ -148,17 +136,12 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity clientSpawnCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation){
public static Entity clientSpawnCollisionCylinder(Vector3f scale, Vector3d position, Quaterniond rotation){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
float mass = 1.0f;
CollisionObject cubeObject = PhysicsUtils.getCylinderObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
DBody cubeObject = PhysicsUtils.createCylinderGeom(Globals.clientSceneWrapper.getCollisionEngine(),new Vector3d(scale));
PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
Globals.clientSceneWrapper.getCollisionEngine().registerStructurePhysicsEntity(rVal);
@ -182,17 +165,12 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity serverSpawnCollisionCylinder(Realm realm, Vector3f scale, Vector3f position, Quaternionf rotation){
public static Entity serverSpawnCollisionCylinder(Realm realm, Vector3f scale, Vector3d position, Quaterniond rotation){
Entity rVal = EntityCreationUtils.createServerEntity(realm, new Vector3d(position));
float mass = 1.0f;
CollisionObject cubeObject = PhysicsUtils.getCylinderObject(scale);
javax.vecmath.Matrix4f planeTransform = new javax.vecmath.Matrix4f(
PhysicsUtils.jomlToVecmathQuaternionf(rotation),
PhysicsUtils.jomlToVecmathVector3f(position),
1.0f);
cubeObject.setWorldTransform(new electrosphere.linearmath.Transform(planeTransform));
DBody cubeObject = PhysicsUtils.createCylinderGeom(realm.getCollisionEngine(),new Vector3d(scale));
PhysicsUtils.setRigidBodyTransform(realm.getCollisionEngine(), position, rotation, cubeObject);
Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
realm.getCollisionEngine().registerCollisionObject(cubeObject, collidable);
realm.getCollisionEngine().registerStructurePhysicsEntity(rVal);
@ -217,7 +195,7 @@ public class CollisionObjUtils {
}
public static Entity clientAttachCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
public static Entity clientAttachCollisionPlane(Vector3f scale, Vector3d position, Quaterniond rotation, Entity parent){
Entity rVal = clientSpawnCollisionPlane(scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
@ -232,7 +210,7 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity serverAttachCollisionPlane(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
public static Entity serverAttachCollisionPlane(Vector3f scale, Vector3d position, Quaterniond rotation, Entity parent){
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
Entity rVal = serverSpawnCollisionPlane(parentRealm, scale, position, rotation);
@ -248,7 +226,7 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity clientAttachCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
public static Entity clientAttachCollisionCube(Vector3f scale, Vector3d position, Quaterniond rotation, Entity parent){
Entity rVal = clientSpawnCollisionCube(scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
@ -263,7 +241,7 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity serverAttachCollisionCube(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
public static Entity serverAttachCollisionCube(Vector3f scale, Vector3d position, Quaterniond rotation, Entity parent){
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
Entity rVal = serverSpawnCollisionCube(parentRealm, scale, position, rotation);
@ -279,7 +257,7 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity clientAttachCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
public static Entity clientAttachCollisionCylinder(Vector3f scale, Vector3d position, Quaterniond rotation, Entity parent){
Entity rVal = clientSpawnCollisionCylinder(scale, position, rotation);
AttachUtils.attachEntityToEntity(parent, rVal);
@ -297,7 +275,7 @@ public class CollisionObjUtils {
return rVal;
}
public static Entity serverAttachCollisionCylinder(Vector3f scale, Vector3f position, Quaternionf rotation, Entity parent){
public static Entity serverAttachCollisionCylinder(Vector3f scale, Vector3d position, Quaterniond rotation, Entity parent){
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
Entity rVal = serverSpawnCollisionCylinder(parentRealm, scale, position, rotation);
@ -323,7 +301,7 @@ public class CollisionObjUtils {
* @param mass The mass of the collidable
* @param collidableType The type of collidable we are attaching. For instance, "Terrain", "Creature", "Item", etc. Refer to Collidable class for options.
*/
public static void clientAttachCollisionObjectToEntity(Entity entity, CollisionObject collisionObject, float mass, String collidableType){
public static void clientAttachCollisionObjectToEntity(Entity entity, DBody collisionObject, float mass, String collidableType){
Vector3d position = EntityUtils.getPosition(entity);
Vector3f scale = EntityUtils.getScale(entity);
Collidable collidable = new Collidable(entity, collidableType);
@ -333,7 +311,7 @@ public class CollisionObjUtils {
entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject);
//update world transform of collision object
positionCharacter(entity,position);
clientPositionCharacter(entity,position);
entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, collisionObject);
entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
@ -354,7 +332,7 @@ public class CollisionObjUtils {
* @param mass The mass of the collidable
* @param collidableType The type of collidable we are attaching. For instance, "Terrain", "Creature", "Item", etc. Refer to Collidable class for options.
*/
public static void serverAttachCollisionObjectToEntity(Entity entity, CollisionObject collisionObject, float mass, String collidableType){
public static void serverAttachCollisionObjectToEntity(Entity entity, DBody collisionObject, float mass, String collidableType){
Vector3d position = EntityUtils.getPosition(entity);
Vector3f scale = EntityUtils.getScale(entity);
Collidable collidable = new Collidable(entity, collidableType);
@ -365,7 +343,7 @@ public class CollisionObjUtils {
entity.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, collisionObject);
//update world transform of collision object
positionCharacter(entity,position);
serverPositionCharacter(entity,position);
entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLISION_OBJECT, collisionObject);
entity.putData(EntityDataStrings.COLLISION_ENTITY_COLLIDABLE, collidable);
@ -379,16 +357,26 @@ public class CollisionObjUtils {
entity.putData(EntityDataStrings.PHYSICS_INVERSE_INERTIA_TENSOR, inertiaTensor.invert());
}
public static CollisionObject getCollisionBody(Entity e){
return (CollisionObject)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
public static DBody getCollisionBody(Entity e){
return (DBody)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
}
public static void positionCharacter(Entity e, Vector3d position){
public static void serverPositionCharacter(Entity e, Vector3d position){
EntityUtils.getPosition(e).set(position);
Quaternionf rotation = EntityUtils.getRotation(e);
CollisionObject body = getCollisionBody(e);
Quaterniond rotation = EntityUtils.getRotation(e);
DBody body = getCollisionBody(e);
CollisionEngine collisionEngine = Globals.realmManager.getEntityRealm(e).getCollisionEngine();
if(body != null){
PhysicsUtils.setRigidBodyTransform(new Vector3f((float)position.x,(float)position.y,(float)position.z), rotation, body);
PhysicsUtils.setRigidBodyTransform(collisionEngine, position, rotation, body);
}
}
public static void clientPositionCharacter(Entity e, Vector3d position){
EntityUtils.getPosition(e).set(position);
Quaterniond rotation = EntityUtils.getRotation(e);
DBody body = getCollisionBody(e);
if(body != null){
PhysicsUtils.setRigidBodyTransform(Globals.clientSceneWrapper.getCollisionEngine(), position, rotation, body);
}
}

View File

@ -1,7 +1,7 @@
package electrosphere.entity.types.creature;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
@ -28,7 +28,7 @@ import electrosphere.entity.state.attack.ShooterTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.equip.EquipState;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.state.inventory.InventoryState;
@ -42,8 +42,6 @@ import electrosphere.entity.state.movement.SprintTree;
import electrosphere.entity.state.rotator.RotatorHierarchyNode;
import electrosphere.entity.state.rotator.RotatorTree;
import electrosphere.entity.state.rotator.ServerRotatorTree;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.game.data.creature.type.SprintSystem;
import electrosphere.game.data.creature.type.attack.AttackMove;
@ -87,6 +85,9 @@ import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DWorld;
/**
*
@ -167,14 +168,17 @@ public class CreatureUtils {
}
if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable();
CollisionObject rigidBody;
DBody rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER": {
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCylinderGeom(
Globals.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())
);
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
@ -199,7 +203,10 @@ public class CreatureUtils {
Globals.clientScene.registerEntityToTag(rVal, EntityTags.COLLIDABLE);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCubeGeom(
Globals.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())
);
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
ClientCollidableTree tree = new ClientCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
@ -365,8 +372,8 @@ public class CreatureUtils {
} break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
GravityTree gravityTree = new GravityTree(rVal,collidable,collisionObject,30);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ClientGravityTree gravityTree = new ClientGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.CLIENT_GRAVITY_TREE, gravityTree);
@ -518,14 +525,14 @@ public class CreatureUtils {
}
if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable();
CollisionObject rigidBody;
DBody rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER": {
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCylinderGeom(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
@ -550,7 +557,7 @@ public class CreatureUtils {
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCubeGeom(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_CREATURE);
ServerCollidableTree tree = new ServerCollidableTree(rVal,collidable,rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
@ -716,7 +723,7 @@ public class CreatureUtils {
} break;
case "GRAVITY": {
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ServerGravityTree gravityTree = new ServerGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);

View File

@ -16,7 +16,7 @@ public class DebugVisualizerUtils {
Vector3d pos = new Vector3d(position).add(new Vector3d(direction).normalize().mul(0.3));
EntityUtils.getPosition(rVal).set(pos);
EntityUtils.getScale(rVal).set(0.05f,0.3f,0.05f);
EntityUtils.getRotation(rVal).rotateTo(new Vector3f(0,1,0), new Vector3f((float)direction.x,(float)direction.y,(float)direction.z));
EntityUtils.getRotation(rVal).rotateTo(new Vector3d(0,1,0), new Vector3d(direction.x,direction.y,direction.z));
return rVal;
}
@ -26,7 +26,7 @@ public class DebugVisualizerUtils {
Vector3d pos = new Vector3d(position).add(new Vector3d(direction).normalize().mul(0.3));
EntityUtils.getPosition(rVal).set(pos);
EntityUtils.getScale(rVal).set(0.05f,0.3f,0.05f);
EntityUtils.getRotation(rVal).rotateTo(new Vector3f(0,1,0), new Vector3f((float)direction.x,(float)direction.y,(float)direction.z));
EntityUtils.getRotation(rVal).rotateTo(new Vector3d(0,1,0), new Vector3d(direction.x,direction.y,direction.z));
return rVal;
}

View File

@ -1,6 +1,7 @@
package electrosphere.entity.types.foliage;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
@ -8,8 +9,6 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.foliage.type.FoliageType;
import electrosphere.game.data.foliage.type.PhysicsObject;
import electrosphere.renderer.actor.ActorUtils;

View File

@ -18,6 +18,7 @@ import electrosphere.server.datacell.Realm;
import java.util.List;
import org.joml.Matrix4f;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -182,13 +183,13 @@ public class HitboxUtils {
HitboxData hitboxData = getHitboxData(hitbox);
String boneName = hitboxData.getBone();
if(boneName != null){
Quaternionf parentRotation = EntityUtils.getRotation(parent);
Quaterniond parentRotation = EntityUtils.getRotation(parent);
Vector3f positionScale = EntityUtils.getScale(parent);
Vector3f worldPosition = new Vector3f();
Vector3d worldPosition = new Vector3d();
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
Vector3d parentPos = EntityUtils.getPosition(parent);
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
Quaternionf rotation = new Quaternionf(parentRotation);
Quaterniond rotation = new Quaterniond(parentRotation);
worldPosition = worldPosition.mul(positionScale);
@ -209,20 +210,20 @@ public class HitboxUtils {
HitboxData hitboxData = getHitboxData(hitbox);
String boneName = hitboxData.getBone();
if(boneName != null){
Quaternionf parentRotation = EntityUtils.getRotation(parent);
Quaterniond parentRotation = EntityUtils.getRotation(parent);
Vector3f positionScale = EntityUtils.getScale(parent);
Vector3f worldPosition = new Vector3f();
Vector3d worldPosition = new Vector3d();
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
Vector3d parentPos = EntityUtils.getPosition(parent);
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
Quaternionf rotation = new Quaternionf(parentRotation);
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));
worldPosition.add(new Vector3d(parentPos.x,parentPos.y,parentPos.z));
EntityUtils.getPosition(hitbox).set(worldPosition);
} else {

View File

@ -1,6 +1,7 @@
package electrosphere.entity.types.item;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
@ -9,15 +10,13 @@ import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.movement.GroundMovementTree;
import electrosphere.entity.types.attach.AttachUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.entity.types.hitbox.HitboxUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.game.data.creature.type.CreatureType;
import electrosphere.game.data.item.type.EquipWhitelist;
@ -40,6 +39,9 @@ import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DWorld;
/**
*
@ -70,14 +72,19 @@ public class ItemUtils {
}
if(item.getCollidable() != null){
CollidableTemplate physicsTemplate = item.getCollidable();
CollisionObject rigidBody;
DBody rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
DWorld dWorld = Globals.clientSceneWrapper.getCollisionEngine().getDWorld();
DSpace dSpace = Globals.clientSceneWrapper.getCollisionEngine().getSpace();
switch(physicsTemplate.getType()){
case "CYLINDER":
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCylinderGeom(
Globals.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())
);
collidable = new Collidable(rVal, Collidable.TYPE_ITEM);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -101,7 +108,10 @@ public class ItemUtils {
Globals.clientSceneWrapper.getScene().registerEntityToTag(rVal, EntityTags.COLLIDABLE);
break;
case "CUBE":
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCubeGeom(
Globals.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())
);
collidable = new Collidable(rVal, Collidable.TYPE_ITEM);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -130,8 +140,8 @@ public class ItemUtils {
break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
GravityTree gravityTree = new GravityTree(rVal,collidable,collisionObject,30);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ClientGravityTree gravityTree = new ClientGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.CLIENT_GRAVITY_TREE, gravityTree);
@ -192,14 +202,14 @@ public class ItemUtils {
}
if(item.getCollidable() != null){
CollidableTemplate physicsTemplate = item.getCollidable();
CollisionObject rigidBody;
DBody rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER":
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCylinderGeom(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_ITEM);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -223,7 +233,7 @@ public class ItemUtils {
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.COLLIDABLE);
break;
case "CUBE":
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCubeGeom(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_ITEM);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -252,7 +262,7 @@ public class ItemUtils {
break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ServerGravityTree gravityTree = new ServerGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);

View File

@ -3,9 +3,14 @@ package electrosphere.entity.types.object;
import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.ode4j.ode.DBody;
import org.ode4j.ode.DSpace;
import org.ode4j.ode.DWorld;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.PhysicsMeshQueueItem;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
@ -14,7 +19,7 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.BehaviorTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.state.inventory.InventoryState;
@ -23,8 +28,6 @@ import electrosphere.entity.state.inventory.ServerInventoryState;
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.state.life.LifeState;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.creature.type.CollidableTemplate;
import electrosphere.game.data.object.type.ObjectData;
import electrosphere.renderer.actor.Actor;
@ -51,9 +54,9 @@ public class ObjectUtils {
collisionMakeDynamic = false;
} break;
case "GENERATE_COLLISION_OBJECT": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(Globals.clientSceneWrapper.getCollisionEngine(),rawType.getModelPath()));
Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
DBody collisionObject = Globals.assetManager.fetchCollisionObject(Globals.clientSceneWrapper.getCollisionEngine(),rawType.getModelPath());
if(collisionObject != null){
Globals.clientSceneWrapper.getScene().deregisterBehaviorTree(this);
CollisionObjUtils.clientAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_OBJECT);
@ -61,9 +64,9 @@ public class ObjectUtils {
}});
} break;
case "GENERATE_COLLISION_TERRAIN": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(Globals.clientSceneWrapper.getCollisionEngine(),rawType.getModelPath()));
Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
DBody collisionObject = Globals.assetManager.fetchCollisionObject(Globals.clientSceneWrapper.getCollisionEngine(),rawType.getModelPath());
if(collisionObject != null){
Globals.clientSceneWrapper.getScene().deregisterBehaviorTree(this);
CollisionObjUtils.clientAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_TERRAIN);
@ -75,14 +78,17 @@ public class ObjectUtils {
//main entity construction
if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable();
CollisionObject rigidBody;
DBody rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER": {
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCylinderGeom(
Globals.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())
);
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -106,7 +112,10 @@ public class ObjectUtils {
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCubeGeom(
Globals.clientSceneWrapper.getCollisionEngine(),
new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3())
);
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -137,8 +146,8 @@ public class ObjectUtils {
break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
GravityTree gravityTree = new GravityTree(rVal,collidable,collisionObject,30);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ClientGravityTree gravityTree = new ClientGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);
rVal.putData(EntityDataStrings.CLIENT_GRAVITY_TREE, gravityTree);
@ -189,7 +198,6 @@ public class ObjectUtils {
//enable behavior tree tracking
ServerBehaviorTreeUtils.registerEntity(rVal);
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
//forward-searching tokens
boolean collisionMakeDynamic = true;
@ -199,9 +207,9 @@ public class ObjectUtils {
collisionMakeDynamic = false;
} break;
case "GENERATE_COLLISION_OBJECT": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(realm.getCollisionEngine(),rawType.getModelPath()));
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
DBody collisionObject = Globals.assetManager.fetchCollisionObject(realm.getCollisionEngine(),rawType.getModelPath());
if(collisionObject != null){
ServerBehaviorTreeUtils.detatchBTreeFromEntity(rVal, this);
CollisionObjUtils.serverAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_OBJECT);
@ -209,9 +217,9 @@ public class ObjectUtils {
}});
} break;
case "GENERATE_COLLISION_TERRAIN": {
Globals.assetManager.addCollisionMeshToQueue(rawType.getModelPath());
Globals.assetManager.addCollisionMeshToQueue(new PhysicsMeshQueueItem(realm.getCollisionEngine(),rawType.getModelPath()));
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, new BehaviorTree() {public void simulate(float deltaTime) {
CollisionObject collisionObject = Globals.assetManager.fetchCollisionObject(rawType.getModelPath());
DBody collisionObject = Globals.assetManager.fetchCollisionObject(realm.getCollisionEngine(),rawType.getModelPath());
if(collisionObject != null){
ServerBehaviorTreeUtils.detatchBTreeFromEntity(rVal, this);
CollisionObjUtils.serverAttachCollisionObjectToEntity(rVal, collisionObject, 0, Collidable.TYPE_TERRAIN);
@ -223,14 +231,14 @@ public class ObjectUtils {
//main entity construction
if(rawType.getCollidable() != null){
CollidableTemplate physicsTemplate = rawType.getCollidable();
CollisionObject rigidBody;
DBody rigidBody;
Collidable collidable;
float mass = 1.0f;
Matrix4f inertiaTensor;
Vector3f scale;
switch(physicsTemplate.getType()){
case "CYLINDER": {
rigidBody = PhysicsUtils.getCylinderObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCylinderGeom(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -254,7 +262,7 @@ public class ObjectUtils {
realm.getCollisionEngine().registerCollisionObject(rigidBody, collidable);
} break;
case "CUBE": {
rigidBody = PhysicsUtils.getCubeObject(new Vector3f(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
rigidBody = PhysicsUtils.createCubeGeom(realm.getCollisionEngine(),new Vector3d(physicsTemplate.getDimension1(),physicsTemplate.getDimension2(),physicsTemplate.getDimension3()));
collidable = new Collidable(rVal, Collidable.TYPE_OBJECT);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, rigidBody);
rVal.putData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET, new Vector3f(physicsTemplate.getOffsetX(),physicsTemplate.getOffsetY(),physicsTemplate.getOffsetZ()));
@ -285,7 +293,7 @@ public class ObjectUtils {
break;
case "GRAVITY":
Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE);
CollisionObject collisionObject = (CollisionObject)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
DBody collisionObject = (DBody)rVal.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
ServerGravityTree gravityTree = new ServerGravityTree(rVal,collidable,collisionObject,30);
// gravityTree.setCollisionObject(collisionObject, collidable);
rVal.putData(EntityDataStrings.GRAVITY_ENTITY, true);

View File

@ -32,13 +32,13 @@ public class ProjectileUtils {
* @param velocity The velocity
* @return The projectile entity
*/
public static Entity clientSpawnBasicProjectile(String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){
public static Entity clientSpawnBasicProjectile(String model, Vector3d initialPosition, Quaterniond rotation, int maxLife, Vector3f initialVector, float velocity){
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, model);
Globals.assetManager.addModelPathToQueue(model);
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
EntityUtils.getPosition(rVal).set(initialPosition);
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree);
return rVal;
}
@ -53,13 +53,13 @@ public class ProjectileUtils {
* @param velocity The velocity
* @return The projectile entity
*/
public static Entity serverSpawnBasicProjectile(Realm realm, String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){
public static Entity serverSpawnBasicProjectile(Realm realm, String model, Vector3d initialPosition, Quaterniond rotation, int maxLife, Vector3f initialVector, float velocity){
Entity rVal = EntityCreationUtils.createServerEntity(realm, initialPosition);
Globals.assetManager.addModelPathToQueue(model);
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
EntityUtils.getPosition(rVal).set(initialPosition);
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
// ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true);
// rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree);
// rVal.putData(EntityDataStrings.IS_PARTICLE, true);
@ -81,7 +81,7 @@ public class ProjectileUtils {
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
//initial coordinates
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
EntityUtils.getPosition(rVal).set(initialPosition);
//projectile behavior tree
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
@ -112,7 +112,7 @@ public class ProjectileUtils {
ProjectileType rawType = Globals.gameConfigCurrent.getProjectileMap().getType(projectileType);
Entity rVal = EntityCreationUtils.createServerEntity(realm, initialPosition);
//initial coordinates
EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize();
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
EntityUtils.getPosition(rVal).set(initialPosition);
//projectile behavior tree
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());

View File

@ -1,12 +1,12 @@
package electrosphere.entity.types.structure;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.types.collision.CollisionObjUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.data.structure.type.model.CollisionObjectTemplate;
import electrosphere.game.data.structure.type.model.StructureType;
import electrosphere.net.parser.net.message.EntityMessage;
@ -15,6 +15,7 @@ import electrosphere.net.server.player.Player;
import electrosphere.server.datacell.Realm;
import org.joml.Matrix4f;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -38,8 +39,8 @@ public class StructureUtils {
case CollisionObjectTemplate.TYPE_CUBE:
Matrix4f rotationTransform = new Matrix4f().rotate(rotation);
Vector4f rotatedPosition = rotationTransform.transform(new Vector4f(template.getPositionX(),template.getPositionY(),template.getPositionZ(),1.0f));
Vector3f cubePosition = new Vector3f(position).add(rotatedPosition.x,rotatedPosition.y,rotatedPosition.z);
Quaternionf cubeRotation = new Quaternionf(rotation).mul(new Quaternionf(template.getRotationX(),template.getRotationY(),template.getRotationZ(),template.getRotationW())).normalize();
Vector3d cubePosition = new Vector3d(position).add(rotatedPosition.x,rotatedPosition.y,rotatedPosition.z);
Quaterniond cubeRotation = new Quaterniond(rotation).mul(new Quaterniond(template.getRotationX(),template.getRotationY(),template.getRotationZ(),template.getRotationW())).normalize();
CollisionObjUtils.clientAttachCollisionCube(new Vector3f(template.getScaleX(),template.getScaleY(),template.getScaleZ()), cubePosition, cubeRotation, rVal);
// Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
// Globals.collisionEngine.registerPhysicsEntity(rVal);
@ -65,8 +66,8 @@ public class StructureUtils {
case CollisionObjectTemplate.TYPE_CUBE:
Matrix4f rotationTransform = new Matrix4f().rotate(rotation);
Vector4f rotatedPosition = rotationTransform.transform(new Vector4f(template.getPositionX(),template.getPositionY(),template.getPositionZ(),1.0f));
Vector3f cubePosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(rotatedPosition.x,rotatedPosition.y,rotatedPosition.z);
Quaternionf cubeRotation = new Quaternionf(rotation).mul(new Quaternionf(template.getRotationX(),template.getRotationY(),template.getRotationZ(),template.getRotationW())).normalize();
Vector3d cubePosition = new Vector3d((float)position.x,(float)position.y,(float)position.z).add(rotatedPosition.x,rotatedPosition.y,rotatedPosition.z);
Quaterniond cubeRotation = new Quaterniond(rotation).mul(new Quaterniond(template.getRotationX(),template.getRotationY(),template.getRotationZ(),template.getRotationW())).normalize();
CollisionObjUtils.serverAttachCollisionCube(new Vector3f(template.getScaleX(),template.getScaleY(),template.getScaleZ()), cubePosition, cubeRotation, rVal);
// Collidable collidable = new Collidable(rVal, Collidable.TYPE_STRUCTURE);
// Globals.collisionEngine.registerPhysicsEntity(rVal);

View File

@ -3,11 +3,11 @@ package electrosphere.entity.types.terrain;
import org.joml.Vector3d;
import electrosphere.client.terrain.manager.ClientTerrainManager;
import electrosphere.collision.PhysicsUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.renderer.meshgen.TerrainChunkModelGeneration;
import electrosphere.server.datacell.Realm;

View File

@ -1,515 +0,0 @@
package electrosphere.game.collision;
import electrosphere.collision.dispatch.CollisionWorld.ClosestConvexResultCallback;
import electrosphere.collision.dispatch.CollisionWorld.ConvexResultCallback;
import electrosphere.collision.dispatch.CollisionWorld.LocalConvexResult;
import electrosphere.collision.broadphase.BroadphaseInterface;
import electrosphere.collision.broadphase.BroadphasePair;
import electrosphere.collision.broadphase.BroadphaseProxy;
import electrosphere.collision.broadphase.DbvtBroadphase;
import electrosphere.collision.broadphase.Dispatcher;
import electrosphere.collision.broadphase.OverlappingPairCache;
import electrosphere.collision.dispatch.CollisionDispatcher;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.dispatch.CollisionWorld.ClosestConvexResultCallback;
import electrosphere.collision.dispatch.CollisionWorld.LocalConvexResult;
import electrosphere.collision.dispatch.DefaultCollisionConfiguration;
import electrosphere.collision.narrowphase.ManifoldPoint;
import electrosphere.collision.narrowphase.PersistentManifold;
import electrosphere.collision.shapes.SphereShape;
import electrosphere.dynamics.DiscreteDynamicsWorld;
import electrosphere.dynamics.DynamicsWorld;
import electrosphere.dynamics.InternalTickCallback;
import electrosphere.dynamics.RigidBody;
import electrosphere.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
import electrosphere.util.ObjectArrayList;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.collidable.Impulse;
import electrosphere.entity.types.hitbox.HitboxData;
import electrosphere.game.collision.collidable.Collidable;
import java.util.ArrayList;
import java.util.List;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
/**
*
* TODO: https://stackoverflow.com/questions/32445679/3d-java-collision-detection-with-jbullet
*/
public class CollisionEngine {
//world data that the collision engine leverages for position correction and the like
CollisionWorldData collisionWorldData;
DiscreteDynamicsWorld world;
SequentialImpulseConstraintSolver solver;
BroadphaseInterface broadphase;
DefaultCollisionConfiguration collisionConfiguration;
CollisionDispatcher dispatcher;
InternalTickCallback callback;
List<Entity> collisionEntities = new ArrayList<Entity>();
List<Entity> physicsEntities = new ArrayList<Entity>();
List<Entity> dynamicPhysicsEntities = new ArrayList<Entity>();
List<Entity> structurePhysicsEntities = new ArrayList<Entity>();
List<CollisionObject> collisionObject = new ArrayList<CollisionObject>();
List<Collidable> collidableList = new ArrayList<Collidable>();
static final float linearDamping = 0.02f;
public CollisionEngine(){
broadphase = new DbvtBroadphase();
collisionConfiguration = new DefaultCollisionConfiguration();
dispatcher = new CollisionDispatcher(collisionConfiguration);
solver = new SequentialImpulseConstraintSolver();
world = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
// CollisionShape boxShape = new BoxShape(new javax.vecmath.Vector3f(1,1,1));
// float mass = 1.0f;
// DefaultMotionState fallMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(0,50,0),1.0f)));
// RigidBodyConstructionInfo boxShapeRigidBodyCI = new RigidBodyConstructionInfo(mass, fallMotionState, boxShape);
// RigidBody boxRigidBody = new RigidBody(boxShapeRigidBodyCI);
//
// world.addRigidBody(boxRigidBody);
callback = new InternalTickCallback(){
@Override
public void internalTick(DynamicsWorld dw, float f) {
Dispatcher dispatcher = dw.getDispatcher();
int manifoldCount = dispatcher.getNumManifolds();
for (int i = 0; i < manifoldCount; i++) {
PersistentManifold manifold = dispatcher.getManifoldByIndexInternal(i);
// The following two lines are optional.
CollisionObject object1 = (CollisionObject)manifold.getBody0();
CollisionObject object2 = (CollisionObject)manifold.getBody1();
Collidable physicsObject1 = (Collidable)object1.getUserPointer();
Collidable physicsObject2 = (Collidable)object2.getUserPointer();
boolean hit = false;
Vector3d normal = null;
Vector3d localPosition1 = null;
Vector3d localPosition2 = null;
Vector3d worldPosA = null;
Vector3d worldPosB = null;
float magnitude = 0.0f;
for (int j = 0; j < manifold.getNumContacts(); j++) {
ManifoldPoint contactPoint = manifold.getContactPoint(j);
if (contactPoint.getDistance() < 0.0f) {
magnitude = -contactPoint.getDistance();
//linear dampen
// magnitude = magnitude;// * (float)Math.pow(1.0f - linearDamping,deltaTime * 2);
hit = true;
// System.out.println(contactPoint.positionWorldOnA + " " + contactPoint.positionWorldOnB);
normal = new Vector3d(contactPoint.normalWorldOnB.x,contactPoint.normalWorldOnB.y,contactPoint.normalWorldOnB.z);
localPosition1 = new Vector3d(contactPoint.localPointA.x,contactPoint.localPointA.y,contactPoint.localPointA.z);
localPosition2 = new Vector3d(contactPoint.localPointB.x,contactPoint.localPointB.y,contactPoint.localPointB.z);
worldPosA = new Vector3d(contactPoint.positionWorldOnA.x,contactPoint.positionWorldOnA.y,contactPoint.positionWorldOnA.z);
worldPosB = new Vector3d(contactPoint.positionWorldOnB.x,contactPoint.positionWorldOnB.y,contactPoint.positionWorldOnB.z);
break;
}
}
if (hit) {
resolveCollision(physicsObject1,physicsObject2, new Vector3d(normal).mul(-1.0), localPosition1, worldPosA, magnitude);
resolveCollision(physicsObject2,physicsObject1, normal, localPosition2, worldPosB, magnitude);
// System.out.println("HIT + " + normal);
// Collision happened between physicsObject1 and physicsObject2. Collision normal is in variable 'normal'.
}
}
}
};
world.setInternalTickCallback(callback, world);
//https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=11507
//https://www.google.com/search?client=firefox-b-1-d&q=bullet+set+position+and+check+if+collision
//https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=11399
}
public CollisionEngine(InternalTickCallback callback){
broadphase = new DbvtBroadphase();
collisionConfiguration = new DefaultCollisionConfiguration();
dispatcher = new CollisionDispatcher(collisionConfiguration);
solver = new SequentialImpulseConstraintSolver();
world = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
this.callback = callback;
world.setInternalTickCallback(callback, world);
}
public static void resolveCollision(Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
switch(receiver.getType()){
case Collidable.TYPE_CREATURE:
switch(impactor.getType()){
case Collidable.TYPE_TERRAIN:
// System.out.println(EntityUtils.getPosition(impactor.getParent()) + " " + EntityUtils.getPosition(receiver.getParent()));
// System.out.println();
// System.out.println("Terrain-creature collision: " + normal + " mag:" + magnitude);
// if(normal.y > normal.x + normal.z){
// normal.x = 0;
// normal.z = 0;
// }
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude * 2, Collidable.TYPE_TERRAIN));
break;
case Collidable.TYPE_CREATURE:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_CREATURE));
break;
case Collidable.TYPE_STRUCTURE:
// float realMag = 1f/(float)Math.pow(0.1, magnitude);
// System.out.println(normal + " - " + realMag);
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_STRUCTURE));
// System.out.println("Structure-creature collision");
break;
case Collidable.TYPE_ITEM:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_ITEM));
break;
case Collidable.TYPE_OBJECT:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_OBJECT));
break;
}
break;
case Collidable.TYPE_ITEM:
switch(impactor.getType()){
case Collidable.TYPE_TERRAIN:
// System.out.println(EntityUtils.getPosition(impactor.getParent()) + " " + EntityUtils.getPosition(receiver.getParent()));
// System.out.println();
// System.out.println("Terrain-item collision: " + normal + " mag:" + magnitude);
// if(normal.y > normal.x + normal.z){
// normal.x = 0;
// normal.z = 0;
// }
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude * 2, Collidable.TYPE_TERRAIN));
break;
case Collidable.TYPE_CREATURE:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_CREATURE));
break;
case Collidable.TYPE_STRUCTURE:
// float realMag = 1f/(float)Math.pow(0.1, magnitude);
// System.out.println(normal + " - " + realMag);
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_STRUCTURE));
// System.out.println("Structure-creature collision");
break;
case Collidable.TYPE_ITEM:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_ITEM));
break;
case Collidable.TYPE_OBJECT:
receiver.addImpulse(new Impulse(normal, localPosition, worldPos, magnitude, Collidable.TYPE_OBJECT));
break;
}
break;
}
}
public void clearCollidableImpulseLists(){
for(Collidable collidable : collidableList){
collidable.clear();
}
}
/**
*
* @param e the entity that wants to move
* @param positionToCheck the position that it wants to move to
* @return true if it can occupy that position, false otherwise
*/
public boolean checkCanOccupyPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){
boolean rVal = true;
//
// check world bounds
//
if(
positionToCheck.x < collisionWorldData.getWorldBoundMin().x ||
positionToCheck.z < collisionWorldData.getWorldBoundMin().z ||
positionToCheck.x > collisionWorldData.getWorldBoundMax().x ||
positionToCheck.z > collisionWorldData.getWorldBoundMax().z
){
return false;
}
// //
// // are we below the terrain?
// //
// if(w.getElevationAtPoint(positionToCheck) > positionToCheck.y){
// return false;
// }
return rVal;
}
public void simulatePhysics(float time){
world.performDiscreteCollisionDetection();
callback.internalTick(world, time);
// world.stepSimulation(time);
}
/**
*
* @param e the entity that's trying to move
* @param positionToCheck the position the entity wants to be at
* @return the position the engine recommends it move to instead (this is
* guaranteed to be a valid position)
*/
public Vector3d suggestMovementPosition(CollisionWorldData w, Entity e, Vector3d positionToCheck){
Vector3d suggestedPosition = new Vector3d(positionToCheck);
//
// adjust for minimum height (Terrain)
//
// float heightMapBias = 0.00001f;
// if(w.getElevationAtPoint(positionToCheck) > positionToCheck.y){
// suggestedPosition.y = w.getElevationAtPoint(positionToCheck) + heightMapBias;
// }
//
// adjust for world bounds
//
if(suggestedPosition.x < collisionWorldData.getWorldBoundMin().x){
suggestedPosition.x = collisionWorldData.getWorldBoundMin().x;
}
if(suggestedPosition.z < collisionWorldData.getWorldBoundMin().z){
suggestedPosition.z = collisionWorldData.getWorldBoundMin().z;
}
if(suggestedPosition.x > collisionWorldData.getWorldBoundMax().x){
suggestedPosition.x = collisionWorldData.getWorldBoundMax().x;
}
if(suggestedPosition.z > collisionWorldData.getWorldBoundMax().z){
suggestedPosition.z = collisionWorldData.getWorldBoundMax().z;
}
return suggestedPosition;
}
public void registerCollidableEntity(Entity collidable){
collisionEntities.add(collidable);
}
public List<Entity> getCollisionEntities(){
return collisionEntities;
}
/**
* Sets the collision world data
* @param collisionWorldData The collision world data
*/
public void setCollisionWorldData(CollisionWorldData collisionWorldData){
this.collisionWorldData = collisionWorldData;
}
public boolean collisionSphereCheck(Entity hitbox1, HitboxData hitbox1data, Entity hitbox2, HitboxData hitbox2data){
Vector3d position1 = EntityUtils.getPosition(hitbox1);
Vector3d position2 = EntityUtils.getPosition(hitbox2);
float radius1 = hitbox1data.getRadius();
float radius2 = hitbox2data.getRadius();
double distance = position1.distance(position2);
if(distance < radius1 + radius2){
return true;
} else {
return false;
}
}
public void registerPhysicsEntity(Entity physicsEntity){
physicsEntities.add(physicsEntity);
}
public List<Entity> getPhysicsEntities(){
return physicsEntities;
}
public void deregisterPhysicsEntity(Entity physicsEntity){
physicsEntities.remove(physicsEntity);
}
public void registerDynamicPhysicsEntity(Entity dynamicEntity){
dynamicPhysicsEntities.add(dynamicEntity);
}
public void deregisterDynamicPhysicsEntity(Entity dynamicEntity){
dynamicPhysicsEntities.remove(dynamicEntity);
}
public List<Entity> getDynamicPhysicsEntities(){
return dynamicPhysicsEntities;
}
public void registerStructurePhysicsEntity(Entity structureEntity){
structurePhysicsEntities.add(structureEntity);
}
public List<Entity> getStructurePhysicsEntities(){
return structurePhysicsEntities;
}
public void updateDynamicObjectTransforms(){
for(Entity dynamicEntity : dynamicPhysicsEntities){
CollisionObject rigidBody = (CollisionObject)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
Vector3f offset = (Vector3f)dynamicEntity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY_OFFSET);
Vector3f newPosition = PhysicsUtils.getRigidBodyPosition(rigidBody).sub(offset);
Quaternionf newRotation = PhysicsUtils.getRigidBodyRotation(rigidBody);
// System.out.println(rigidBody + " position " + newPosition);
// System.out.println("Linear velocity: " + rigidBody.getLinearVelocity(new javax.vecmath.Vector3f()));
EntityUtils.getPosition(dynamicEntity).set(newPosition);
EntityUtils.getRotation(dynamicEntity).set(newRotation);
}
}
public void registerCollisionObject(CollisionObject object, Collidable collidable){
world.addCollisionObject(object);
object.setUserPointer(collidable);
collidableList.add(collidable);
collisionObject.add(object);
}
public void listBodyPositions(){
for(CollisionObject body : collisionObject){
System.out.println(body);
System.out.println(PhysicsUtils.getRigidBodyPosition(body));
}
}
/*
Check if the entity is being accelerated by gravity
*/
// public boolean gravityCheck(CommonWorldData w, Entity e){
// double worldHeight = w.getElevationAtPoint(EntityUtils.getPosition(e));
// double entityHeight = EntityUtils.getPosition(e).y;
// return entityHeight > worldHeight + 0.1f;
// }
public float sweepTest(CollisionObject object, Vector3f startPos, Vector3f endPos){
SphereShape sphere = new SphereShape(0.1f);
// CollisionObject collider = new CollisionObject();
// collider.setCollisionShape(sphere);
ClosestConvexResultCallbackImpl callback = new ClosestConvexResultCallbackImpl(startPos,endPos,object,dispatcher,world.getPairCache());
callback.collisionFilterGroup = 1;
callback.collisionFilterMask = 1;
world.convexSweepTest(sphere, PhysicsUtils.jomlVecToTransform(startPos), PhysicsUtils.jomlVecToTransform(endPos), callback);
// callback.hasHit()
if(callback.hasHit()){
return callback.closestHitFraction;
} else {
return -1.0f;
}
}
private static class ClosestConvexResultCallbackImpl extends ClosestConvexResultCallback {
CollisionObject me;
private OverlappingPairCache pairCache;
private Dispatcher dispatcher;
public ClosestConvexResultCallbackImpl(Vector3f startPos, Vector3f endPos, CollisionObject me, Dispatcher dispatcher, OverlappingPairCache pairCache){
super(PhysicsUtils.jomlToVecmathVector3f(startPos),PhysicsUtils.jomlToVecmathVector3f(endPos));
this.me = me;
this.pairCache = pairCache;
this.dispatcher = dispatcher;
}
@Override
public float addSingleResult(LocalConvexResult convexResult, boolean normalInWorldSpace) {
if (convexResult.hitCollisionObject == me) {
return 1f;
}
Vector3f linVelA = new Vector3f(), linVelB = new Vector3f();
linVelA.sub(PhysicsUtils.vecmathToJomlVector3f(convexToWorld), PhysicsUtils.vecmathToJomlVector3f(convexFromWorld));
linVelB.set(0f, 0f, 0f);//toB.getOrigin()-fromB.getOrigin();
Vector3f relativeVelocity = new Vector3f();
relativeVelocity.sub(linVelA, linVelB);
// don't report time of impact for motion away from the contact normal (or causes minor penetration)
if (convexResult.hitNormalLocal.dot(PhysicsUtils.jomlToVecmathVector3f(relativeVelocity)) >= -0f) {
return 1f;
}
return super.addSingleResult(convexResult, normalInWorldSpace);
}
@Override
public boolean needsCollision(BroadphaseProxy proxy0) {
// don't collide with itself
if (proxy0.clientObject == me) {
return false;
}
// don't do CCD when the collision filters are not matching
if (!super.needsCollision(proxy0)) {
return false;
}
CollisionObject otherObj = (CollisionObject)proxy0.clientObject;
// call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
if (dispatcher.needsResponse(me, otherObj)) {
// don't do CCD when there are already contact points (touching contact/penetration)
ObjectArrayList<PersistentManifold> manifoldArray = new ObjectArrayList<PersistentManifold>();
BroadphasePair collisionPair = pairCache.findPair(me.getBroadphaseHandle(), proxy0);
if (collisionPair != null) {
if (collisionPair.algorithm != null) {
//manifoldArray.resize(0);
collisionPair.algorithm.getAllContactManifolds(manifoldArray);
for (int j=0; j<manifoldArray.size(); j++) {
PersistentManifold manifold = manifoldArray.getQuick(j);
if (manifold.getNumContacts() > 0) {
return false;
}
}
}
}
}
return true;
}
}
public void registerPhysicsObject(CollisionObject object){
if(!collisionObject.contains(object)){
collisionObject.add(object);
world.addCollisionObject(object);
}
}
public void deregisterPhysicsObject(CollisionObject object){
if(collisionObject.contains(object)){
collisionObject.remove(object);
}
world.removeCollisionObject(object);
}
public void deregisterRigidBody(RigidBody body){
if(collisionObject.contains(body)){
collisionObject.remove(body);
}
if((body) != null){
body.destroy();
// world.removeRigidBody(body);
}
}
public void deregisterCollidableEntity(Entity e){
if(collisionEntities.contains(e)){
collisionEntities.remove(e);
}
if(physicsEntities.contains(e)){
physicsEntities.remove(e);
}
if(dynamicPhysicsEntities.contains(e)){
dynamicPhysicsEntities.remove(e);
}
if(structurePhysicsEntities.contains(e)){
structurePhysicsEntities.remove(e);
}
}
public void destroyEntityThatHasPhysics(Entity e){
//make uncollidable
if(e.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && e.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
CollisionObject rigidBody = (CollisionObject)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
deregisterPhysicsObject(rigidBody);
}
deregisterCollidableEntity(e);
}
}

View File

@ -1,701 +0,0 @@
package electrosphere.game.collision;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.collision.shapes.BoxShape;
import electrosphere.collision.shapes.BvhTriangleMeshShape;
import electrosphere.collision.shapes.CylinderShape;
import electrosphere.collision.shapes.IndexedMesh;
import electrosphere.collision.shapes.TriangleIndexVertexArray;
import electrosphere.dynamics.RigidBody;
import electrosphere.dynamics.RigidBodyConstructionInfo;
import electrosphere.engine.Globals;
import electrosphere.linearmath.DefaultMotionState;
import electrosphere.linearmath.Transform;
import electrosphere.server.datacell.Realm;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.types.terrain.TerrainChunkData;
import electrosphere.game.collision.collidable.Collidable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.lwjgl.PointerBuffer;
import org.lwjgl.assimp.AIFace;
import org.lwjgl.assimp.AIMesh;
import org.lwjgl.assimp.AIScene;
import org.lwjgl.assimp.AIVector3D;
/**
*
* @author amaterasu
*/
public class PhysicsUtils {
/**
* Constructor for rigid body:
* http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/CylinderShape.html
* Creates a sphere where the dimensions are twice the size of the vector passed in
* ie diameter = x * 2 or z * 2
* @param entity
* @param halfDimensions
*/
public static void attachCylinderRigidBody(Entity entity, Vector3f halfDimensions){
new electrosphere.collision.shapes.CylinderShape(new javax.vecmath.Vector3f(halfDimensions.x,halfDimensions.y,halfDimensions.z));
}
public static RigidBody attachTerrainRigidBody(Entity terrain, float[][] heightfield, boolean isServer){
Vector3d position = EntityUtils.getPosition(terrain);
int arrayLength = heightfield.length;
int arrayWidth = heightfield[0].length;
float collisionMargin = 0.08f;
/*
Traditional buffer code not working for some reason
the approach of
https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
works much better
IDK why
*/
int numberTriangles = (arrayLength - 1) * (arrayWidth - 1) * 2;
int triangleStride = 0;
int numberVertices = arrayLength * arrayWidth;
int vertexStride = 0;
float[] vertices = new float[numberVertices * 3];
int vertexInserterPos = 0;
int[] indices = new int[numberTriangles * 3];
int indexInserterPos = 0;
for(int x = 0; x < arrayLength; x++){
for(int y = 0; y < arrayWidth; y++){
vertices[vertexInserterPos] = x;
vertexInserterPos++;
vertices[vertexInserterPos] = heightfield[x][y] - collisionMargin;
vertexInserterPos++;
vertices[vertexInserterPos] = y;
vertexInserterPos++;
if(x < arrayLength - 1 && y < arrayWidth - 1){
//if we should also add a triangle index
/*
as copied from ModelUtil's terrain mesh generation function
faces.put((x / stride + 0) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 1) * actualHeight + (y / stride + 0));
faces.put((x / stride + 0) * actualHeight + (y / stride + 1));
faces.put((x / stride + 1) * actualHeight + (y / stride + 1));
*/
indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 0);
indexInserterPos++;
indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1);
indexInserterPos++;
indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0);
indexInserterPos++;
indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 0);
indexInserterPos++;
indices[indexInserterPos] = (x + 0) * arrayWidth + (y + 1);
indexInserterPos++;
indices[indexInserterPos] = (x + 1) * arrayWidth + (y + 1);
indexInserterPos++;
}
}
}
javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f();
javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f();
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html
electrosphere.collision.shapes.IndexedMesh indexedMesh = new electrosphere.collision.shapes.IndexedMesh();
indexedMesh.numTriangles = indices.length / 3;
indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
indexedMesh.triangleIndexStride = 3 * Float.BYTES;
indexedMesh.numVertices = vertices.length / 3;
indexedMesh.vertexBase = ByteBuffer.allocateDirect(vertices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.vertexBase.asFloatBuffer().put(vertices);
indexedMesh.vertexStride = 3 * Float.BYTES;
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray();
triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer
// triangleIndexArray.calculateAabbBruteForce(aabbMin, aabbMax);
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
electrosphere.collision.shapes.BvhTriangleMeshShape terrainShape = new electrosphere.collision.shapes.BvhTriangleMeshShape(
triangleIndexArray,
true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
);
//uncomment if we start falling through things again
terrainShape.setMargin(collisionMargin);
// terrainShape.localGetSupportingVertex(new javax.vecmath.Vector3f(1,0,0), aabbMin);
// terrainShape.recalcLocalAabb();
// terrainShape.getLocalAabbMin(aabbMin);
// terrainShape.getLocalAabbMax(aabbMax);
DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f((float)position.x,(float)position.y,(float)position.z),1.0f)));
RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
// terrainRigidBody.setFriction(1f);
if(isServer){
Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain);
terrainRealm.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
} else {
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
}
// terrainRigidBody.getAabb(aabbMin, aabbMax);
//
// System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax);
terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainRigidBody);
return terrainRigidBody;
}
public static RigidBody clientAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){
Vector3d position = EntityUtils.getPosition(terrain);
float collisionMargin = 0.08f;
/*
Traditional buffer code not working for some reason
the approach of
https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
works much better
IDK why
*/
int numberTriangles = data.getFaceElements().size() / 3;
int triangleStride = 0;
int numberVertices = data.getVertices().size() / 3;
int vertexStride = 0;
float[] vertices = new float[numberVertices * 3];
int vertexInserterPos = 0;
int[] indices = new int[numberTriangles * 3];
int indexInserterPos = 0;
for(float vertexValue : data.getVertices()){
vertices[vertexInserterPos] = vertexValue;
vertexInserterPos++;
}
for(int element : data.getFaceElements()){
indices[indexInserterPos] = element;
indexInserterPos++;
}
javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f();
javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f();
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html
electrosphere.collision.shapes.IndexedMesh indexedMesh = new electrosphere.collision.shapes.IndexedMesh();
indexedMesh.numTriangles = indices.length / 3;
indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
indexedMesh.triangleIndexStride = 3 * Float.BYTES;
indexedMesh.numVertices = vertices.length / 3;
indexedMesh.vertexBase = ByteBuffer.allocateDirect(vertices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.vertexBase.asFloatBuffer().put(vertices);
indexedMesh.vertexStride = 3 * Float.BYTES;
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray();
triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer
// triangleIndexArray.calculateAabbBruteForce(aabbMin, aabbMax);
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
electrosphere.collision.shapes.BvhTriangleMeshShape terrainShape = new electrosphere.collision.shapes.BvhTriangleMeshShape(
triangleIndexArray,
true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
);
//uncomment if we start falling through things again
terrainShape.setMargin(collisionMargin);
// terrainShape.localGetSupportingVertex(new javax.vecmath.Vector3f(1,0,0), aabbMin);
// terrainShape.recalcLocalAabb();
// terrainShape.getLocalAabbMin(aabbMin);
// terrainShape.getLocalAabbMax(aabbMax);
DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f((float)position.x,(float)position.y,(float)position.z),1.0f)));
RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
// terrainRigidBody.setFriction(1f);
Globals.clientSceneWrapper.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
// terrainRigidBody.getAabb(aabbMin, aabbMax);
//
// System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax);
terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainRigidBody);
return terrainRigidBody;
}
public static RigidBody serverAttachTerrainChunkRigidBody(Entity terrain, TerrainChunkData data){
Vector3d position = EntityUtils.getPosition(terrain);
float collisionMargin = 0.08f;
/*
Traditional buffer code not working for some reason
the approach of
https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
works much better
IDK why
*/
int numberTriangles = data.getFaceElements().size() / 3;
int triangleStride = 0;
int numberVertices = data.getVertices().size() / 3;
int vertexStride = 0;
float[] vertices = new float[numberVertices * 3];
int vertexInserterPos = 0;
int[] indices = new int[numberTriangles * 3];
int indexInserterPos = 0;
for(float vertexValue : data.getVertices()){
vertices[vertexInserterPos] = vertexValue;
vertexInserterPos++;
}
for(int element : data.getFaceElements()){
indices[indexInserterPos] = element;
indexInserterPos++;
}
javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f();
javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f();
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html
electrosphere.collision.shapes.IndexedMesh indexedMesh = new electrosphere.collision.shapes.IndexedMesh();
indexedMesh.numTriangles = indices.length / 3;
indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
indexedMesh.triangleIndexStride = 3 * Float.BYTES;
indexedMesh.numVertices = vertices.length / 3;
indexedMesh.vertexBase = ByteBuffer.allocateDirect(vertices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.vertexBase.asFloatBuffer().put(vertices);
indexedMesh.vertexStride = 3 * Float.BYTES;
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray();
triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer
// triangleIndexArray.calculateAabbBruteForce(aabbMin, aabbMax);
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
electrosphere.collision.shapes.BvhTriangleMeshShape terrainShape = new electrosphere.collision.shapes.BvhTriangleMeshShape(
triangleIndexArray,
true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
);
//uncomment if we start falling through things again
terrainShape.setMargin(collisionMargin);
// terrainShape.localGetSupportingVertex(new javax.vecmath.Vector3f(1,0,0), aabbMin);
// terrainShape.recalcLocalAabb();
// terrainShape.getLocalAabbMin(aabbMin);
// terrainShape.getLocalAabbMax(aabbMax);
DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f((float)position.x,(float)position.y,(float)position.z),1.0f)));
RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
// terrainRigidBody.setFriction(1f);
Realm terrainRealm = Globals.realmManager.getEntityRealm(terrain);
terrainRealm.getCollisionEngine().registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
// terrainRigidBody.getAabb(aabbMin, aabbMax);
//
// System.out.println("aabbMin: " + aabbMin + " aabbMax: " + aabbMax);
terrain.putData(EntityDataStrings.PHYSICS_COLLISION_BODY, terrainRigidBody);
return terrainRigidBody;
}
//
// This has to use arrays and I have no fucking clue why
// If you buffer one at a time it just breaks???????????
//
/**
* Generates a rigid body from an AIScene
* @param scene The AIScene to generate a rigid body off of
* @return A rigid body based on the AIScene
*/
public static RigidBody generateRigidBodyFromAIScene(AIScene scene){
//was 0.08
float collisionMargin = 0.08f;
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray();
PointerBuffer meshesBuffer = scene.mMeshes();
while(meshesBuffer.hasRemaining()){
AIMesh aiMesh = AIMesh.create(meshesBuffer.get());
//create indexed mesh
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/IndexedMesh.html
electrosphere.collision.shapes.IndexedMesh indexedMesh = new electrosphere.collision.shapes.IndexedMesh();
//allocate buffer for vertices
indexedMesh.vertexBase = ByteBuffer.allocateDirect(aiMesh.mNumVertices()*3*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.numVertices = aiMesh.mNumVertices();
indexedMesh.vertexStride = 3 * Float.BYTES;
float[] verts = new float[indexedMesh.numVertices * 3];
//read vertices
AIVector3D.Buffer vertexBuffer = aiMesh.mVertices();
int vertPos = 0;
while(vertexBuffer.hasRemaining()){
AIVector3D vector = vertexBuffer.get();
verts[vertPos+0] = vector.x();
verts[vertPos+1] = vector.y();
verts[vertPos+2] = vector.z();
vertPos = vertPos + 3;
}
indexedMesh.vertexBase.asFloatBuffer().put(verts);
//allocate buffer for indices
indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(aiMesh.mNumFaces()*3*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.numTriangles = aiMesh.mNumFaces();
indexedMesh.triangleIndexStride = 3 * Float.BYTES;
int[] indices = new int[indexedMesh.numTriangles * 3];
int indicesPos = 0;
//read faces
AIFace.Buffer faceBuffer = aiMesh.mFaces();
while(faceBuffer.hasRemaining()){
AIFace currentFace = faceBuffer.get();
IntBuffer indexBuffer = currentFace.mIndices();
while(indexBuffer.hasRemaining()){
int index = indexBuffer.get();
indices[indicesPos] = index;
indicesPos++;
}
}
indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
//push indexed mesh into triangle index array
triangleIndexArray.addIndexedMesh(indexedMesh); //this assumes the scalar type is integer (assumes bytebuffer is actually integer
// triangleIndexArray.calculateAabbBruteForce(aabbMin, aabbMax);
}
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
electrosphere.collision.shapes.BvhTriangleMeshShape terrainShape = new electrosphere.collision.shapes.BvhTriangleMeshShape(
triangleIndexArray,
true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
);
//uncomment if we start falling through things again
terrainShape.setMargin(collisionMargin);
// terrainShape.localGetSupportingVertex(new javax.vecmath.Vector3f(1,0,0), aabbMin);
// terrainShape.recalcLocalAabb();
// terrainShape.getLocalAabbMin(aabbMin);
// terrainShape.getLocalAabbMax(aabbMax);
DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f)));
RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
return terrainRigidBody;
}
public static void addTestPlaneRigidBody(){
/*
Traditional buffer code not working for some reason
the approach of
https://stackoverflow.com/questions/40855945/lwjgl-mesh-to-jbullet-collider
works much better
IDK why
*/
int[] indices = {
0, 1, 3,
1, 2, 3
};
float[] coords = {
0, 0, 0,
100, 0, 0,
0, 0, 100,
100, 0, 100
};
IndexedMesh indexedMesh = new IndexedMesh();
indexedMesh.numTriangles = indices.length / 3;
indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
indexedMesh.triangleIndexStride = 3 * Float.BYTES;
indexedMesh.numVertices = coords.length / 3;
indexedMesh.vertexBase = ByteBuffer.allocateDirect(coords.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.vertexBase.asFloatBuffer().put(coords);
indexedMesh.vertexStride = 3 * Float.BYTES;
javax.vecmath.Vector3f aabbMin = new javax.vecmath.Vector3f();
javax.vecmath.Vector3f aabbMax = new javax.vecmath.Vector3f();
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
electrosphere.collision.shapes.TriangleIndexVertexArray triangleIndexArray = new electrosphere.collision.shapes.TriangleIndexVertexArray(
// numberTriangles,
// triangleData,
// triangleStride,
// numberVertices,
// vertexData,
// vertexStride
);
triangleIndexArray.addIndexedMesh(indexedMesh);
// triangleIndexArray.setScaling(new javax.vecmath.Vector3f(1.0f,1.0f,1.0f));
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
electrosphere.collision.shapes.BvhTriangleMeshShape terrainShape = new electrosphere.collision.shapes.BvhTriangleMeshShape(
triangleIndexArray,
true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
);
DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,0,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f)));
RigidBodyConstructionInfo terrainRigidBodyCI = new RigidBodyConstructionInfo(0, defaultMotionState, terrainShape);
RigidBody terrainRigidBody = new RigidBody(terrainRigidBodyCI);
// Globals.collisionEngine.registerCollisionObject(terrainRigidBody, new Collidable(terrain,Collidable.TYPE_TERRAIN));
terrainRigidBody.getAabb(aabbMin, aabbMax);
}
public static Vector3f getRigidBodyPosition(CollisionObject body){
javax.vecmath.Vector3f transform = new javax.vecmath.Vector3f(0,0,0);
body.getWorldTransform(new electrosphere.linearmath.Transform()).transform(transform);
// body.getMotionState().getWorldTransform(new com.bulletphysics.linearmath.Transform()).transform(transform);
return vecmathToJomlVector3f(transform);
}
public static Quaternionf getRigidBodyRotation(CollisionObject body){
return vecmathtoJomlQuaternionf(body.getWorldTransform(new electrosphere.linearmath.Transform()).getRotation(new javax.vecmath.Quat4f()));
}
public static Vector3f vecmathToJomlVector3f(javax.vecmath.Vector3f vector){
return new Vector3f(vector.x,vector.y,vector.z);
}
public static Quaternionf vecmathtoJomlQuaternionf(javax.vecmath.Quat4f quaternion){
return new Quaternionf(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
}
public static javax.vecmath.Vector3f jomlToVecmathVector3f(Vector3f vector){
return new javax.vecmath.Vector3f(vector.x, vector.y, vector.z);
}
public static javax.vecmath.Quat4f jomlToVecmathQuaternionf(Quaternionf quaternion){
return new javax.vecmath.Quat4f(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
}
public static electrosphere.linearmath.Transform jomlVecToTransform(Vector3f vector){
electrosphere.linearmath.Transform transform = new electrosphere.linearmath.Transform();
javax.vecmath.Matrix4f transformMatrix = new javax.vecmath.Matrix4f();
transformMatrix.setIdentity();
transformMatrix.setTranslation(new javax.vecmath.Vector3f(vector.x, vector.y, vector.z));
transform.set(transformMatrix);
return transform;
}
public static electrosphere.linearmath.Transform jomlVecToTransform(Vector3d vector){
electrosphere.linearmath.Transform transform = new electrosphere.linearmath.Transform();
javax.vecmath.Matrix4f transformMatrix = new javax.vecmath.Matrix4f();
transformMatrix.setIdentity();
transformMatrix.setTranslation(new javax.vecmath.Vector3f((float)vector.x, (float)vector.y, (float)vector.z));
transform.set(transformMatrix);
return transform;
}
public static void setRigidBodyTransform(Vector3f position, Quaternionf rotation, CollisionObject body){
electrosphere.linearmath.Transform transform = new electrosphere.linearmath.Transform();
javax.vecmath.Matrix4f transformMatrix = new javax.vecmath.Matrix4f();
transformMatrix.setIdentity();
transformMatrix.setTranslation(new javax.vecmath.Vector3f(position.x, position.y, position.z));
transformMatrix.setRotation(new javax.vecmath.Quat4f(rotation.x,rotation.y,rotation.z,rotation.w));
transform.set(transformMatrix);
//https://docs.oracle.com/cd/E17802_01/j2se/javase/technologies/desktop/java3d/forDevelopers/j3dapi/javax/vecmath/Quat4f.html
//constructor is x,y,z,w
// transform.setRotation(new javax.vecmath.Quat4f(rotation.x,rotation.y,rotation.z,rotation.w));
body.setWorldTransform(transform);
}
// public static RigidBody getUnitCylinderRigidBody(float mass){
// CylinderShape cylinderShape = new CylinderShape(jomlToVecmathVector3f(new Vector3f(1.0f,1.0f,1.0f)));
// DefaultMotionState defaultMotionState = new DefaultMotionState(new Transform(new javax.vecmath.Matrix4f(new javax.vecmath.Quat4f(0,1,0,1),new javax.vecmath.Vector3f(0,0,0),1.0f)));
// RigidBodyConstructionInfo cylinderRigidBodyCI = new RigidBodyConstructionInfo(mass, defaultMotionState, cylinderShape);
// RigidBody cylinderRigidBody = new RigidBody(cylinderRigidBodyCI);
//// cylinderRigidBody.setMassProps(mass, PhysicsUtils.jomlToVecmathVector3f(new Vector3f(1.0f,1.0f,1.0f)));
// cylinderRigidBody.clearForces();
// return cylinderRigidBody;
// }
public static CollisionObject getCylinderObject(Vector3f dimensions){
CylinderShape cylinderShape = new CylinderShape(jomlToVecmathVector3f(dimensions));
CollisionObject cylinderCollisionObject = new CollisionObject();
cylinderCollisionObject.setCollisionShape(cylinderShape);
return cylinderCollisionObject;
}
public static CollisionObject getPlaneObject(Vector3f dimensions){
int[] indices = {
0, 1, 2,
1, 2, 3
};
float[] coords = {
-1 * dimensions.x, 0, -1 * dimensions.z,
1 * dimensions.x, 0, -1 * dimensions.z,
-1 * dimensions.x, 0, 1 * dimensions.z,
1 * dimensions.x, 0, 1 * dimensions.z
};
IndexedMesh indexedMesh = new IndexedMesh();
indexedMesh.numTriangles = indices.length / 3;
indexedMesh.triangleIndexBase = ByteBuffer.allocateDirect(indices.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.triangleIndexBase.asIntBuffer().put(indices);
indexedMesh.triangleIndexStride = 3 * Float.BYTES;
indexedMesh.numVertices = coords.length / 3;
indexedMesh.vertexBase = ByteBuffer.allocateDirect(coords.length*Float.BYTES).order(ByteOrder.nativeOrder());
indexedMesh.vertexBase.asFloatBuffer().put(coords);
indexedMesh.vertexStride = 3 * Float.BYTES;
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shpaes/TriangleIndexVertexArray.html
TriangleIndexVertexArray triangleIndexArray = new TriangleIndexVertexArray();
triangleIndexArray.addIndexedMesh(indexedMesh);
// triangleIndexArray.setScaling(new javax.vecmath.Vector3f(1.0f,1.0f,1.0f));
//http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html
BvhTriangleMeshShape planeShape = new BvhTriangleMeshShape(
triangleIndexArray,
true // "useQuantizedAabbCompression" -- apparently means better memory usage ( http://jbullet.advel.cz/javadoc/com/bulletphysics/collision/shapes/BvhTriangleMeshShape.html )
);
CollisionObject planeCollisionObject = new CollisionObject();
planeCollisionObject.setCollisionShape(planeShape);
return planeCollisionObject;
}
public static CollisionObject getCubeObject(Vector3f dimensions){
BoxShape boxShape = new BoxShape(jomlToVecmathVector3f(dimensions));
CollisionObject boxCollisionObject = new CollisionObject();
boxCollisionObject.setCollisionShape(boxShape);
return boxCollisionObject;
}
}

View File

@ -99,7 +99,7 @@ public class EntityProtocol {
Entity parent = Globals.clientSceneWrapper.getEntityFromServerId(message.gettargetID());
LoggerInterface.loggerNetworking.DEBUG("Attach " + message.getentityID() + " to " + message.gettargetID() + " on bone " + message.getbone());
if(child != null && parent != null){
AttachUtils.clientAttachEntityToEntityAtBone(parent, child, message.getbone(), new Quaternionf());
AttachUtils.clientAttachEntityToEntityAtBone(parent, child, message.getbone(), new Quaterniond());
}
break;
case MOVEUPDATE:

View File

@ -1,15 +1,14 @@
package electrosphere.net.client.protocol;
import javax.vecmath.Vector3d;
import org.joml.Vector3f;
import electrosphere.client.scene.ClientWorldData;
import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.collision.CollisionWorldData;
import electrosphere.engine.Globals;
import electrosphere.entity.types.terrain.TerrainChunk;
import electrosphere.entity.types.terrain.TerrainChunkData;
import electrosphere.game.collision.CollisionWorldData;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.TerrainMessage;

View File

@ -2,6 +2,8 @@ package electrosphere.renderer;
import java.util.ArrayList;
import java.util.HashMap;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.lwjgl.assimp.AIBone;
@ -14,18 +16,18 @@ public class Bone {
int numWeights;
HashMap<Integer,Float> weights;
public Matrix4f inverseBindPoseMatrix;
public Matrix4f deform;
public Matrix4d deform;
public Matrix4f transform;
public Matrix4f final_transform;
public AIBone raw_data;
public Bone(){
transform = new Matrix4f();
deform = new Matrix4f();
deform = new Matrix4d();
final_transform = new Matrix4f();
}
public Bone(AIBone raw_data){
transform = new Matrix4f();
deform = new Matrix4f();
deform = new Matrix4d();
final_transform = new Matrix4f();
boneID = raw_data.mName().dataString();
inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrix(raw_data.mOffsetMatrix());

View File

@ -712,7 +712,7 @@ public class Mesh {
Bone currentBone = parent.boneMap.get(boneName);
String currentUniform = "bones[" + incrementer + "]";
if(currentBone != null){
Matrix4f currentMat = new Matrix4f(currentBone.final_transform);
Matrix4d currentMat = new Matrix4d(currentBone.final_transform);
currentMat.get(bufferarray);
// if(boneName.equals("Torso")){
// System.out.println("Found torso bone");
@ -720,11 +720,11 @@ public class Mesh {
// System.out.println(currentMat);
// System.exit(0);
// }
GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, bufferarray);
GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, bufferarray);
} else {
// System.out.println("Bonename: " + boneName);
// System.exit(1);
GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, new float[16]);
GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, new float[16]);
}
incrementer++;
}
@ -738,7 +738,7 @@ public class Mesh {
if(renderPipelineState.getBufferStandardUniforms()){
//buffer model/view/proj matrices
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
GL45.glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16]));
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16]));
glUniform3fv(Globals.renderingEngine.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3)));

View File

@ -18,6 +18,8 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
@ -42,6 +44,7 @@ import java.util.LinkedList;
import java.util.Map;
import java.util.Stack;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.lwjgl.assimp.AIAnimation;
import org.lwjgl.assimp.AIBone;
import org.lwjgl.assimp.AINode;
@ -60,7 +63,7 @@ public class Model {
HashMap<String,Animation> animMap;
public HashMap<String,AnimNode> node_map;
public ArrayList<Material> materials;
public Matrix4f modelMatrix = new Matrix4f();
public Matrix4d modelMatrix = new Matrix4d();
ShaderProgram program;
Matrix4f globalInverseTransform;
@ -198,7 +201,7 @@ public class Model {
boneMap = null;
node_map = null;
materials = null;
modelMatrix = new Matrix4f();
modelMatrix = new Matrix4d();
program = null;
globalInverseTransform = null;
}
@ -295,10 +298,10 @@ public class Model {
if(currentBone != null){
// System.out.println("Applying to bone");
//T * S * R
currentBone.deform = new Matrix4f();
currentBone.deform = new Matrix4d();
currentBone.deform.translate(currentChannel.getCurrentPosition());
currentBone.deform.rotate(currentChannel.getCurrentRotation());
currentBone.deform.scale(currentChannel.getCurrentScale());
currentBone.deform.scale(new Vector3d(currentChannel.getCurrentScale()));
}
}
}
@ -390,9 +393,9 @@ public class Model {
void update_node_transform(AnimNode n, Map<String,ActorBoneRotator> boneRotators, ActorStaticMorph staticMorph){
if(n.parent != null){
n.transform = new Matrix4f(n.parent.transform);
n.transform = new Matrix4d(n.parent.transform);
} else {
n.transform = new Matrix4f();
n.transform = new Matrix4d();
}
if(n.is_bone){
/*

View File

@ -14,6 +14,7 @@ import java.util.List;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.texture.Texture;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
@ -139,7 +140,7 @@ public class RenderUtils {
Model skyboxModel = new Model();
skyboxModel.meshes = new ArrayList<Mesh>();
skyboxModel.modelMatrix = new Matrix4f();
skyboxModel.modelMatrix = new Matrix4d();
@ -380,7 +381,7 @@ public class RenderUtils {
public static Model createParticleModel(){
Model particleModel = new Model();
particleModel.meshes = new ArrayList<Mesh>();
particleModel.modelMatrix = new Matrix4f();
particleModel.modelMatrix = new Matrix4d();
Mesh particleMesh = new Mesh();
@ -501,7 +502,7 @@ public class RenderUtils {
Model rVal = new Model();
rVal.meshes = new ArrayList<Mesh>();
rVal.modelMatrix = new Matrix4f();
rVal.modelMatrix = new Matrix4d();
Mesh planeMesh = new Mesh();

View File

@ -61,7 +61,9 @@ import static org.lwjgl.system.MemoryUtil.NULL;
import java.nio.IntBuffer;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
@ -193,7 +195,7 @@ public class RenderingEngine {
glfwInit();
//Gives hints to glfw to control how opengl will be used
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); Allows you to make the background transparent
// glfwWindowHint(GLFW_OPACITY, 23);
@ -520,7 +522,7 @@ public class RenderingEngine {
static void renderShadowMapContent(){
Matrix4f modelTransformMatrix = new Matrix4f();
Matrix4d modelTransformMatrix = new Matrix4d();
//set the viewport to shadow map size
glViewport(0, 0, 4096, 4096);
@ -568,7 +570,7 @@ public class RenderingEngine {
// D R A W A L L E N T I T I E S
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
modelTransformMatrix = new Matrix4d();
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
@ -585,7 +587,7 @@ public class RenderingEngine {
modelTransformMatrix = modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw(renderPipelineState);
@ -608,7 +610,7 @@ public class RenderingEngine {
static void renderGameContent(){
Matrix4f modelTransformMatrix = new Matrix4f();
Matrix4d modelTransformMatrix = new Matrix4d();
//bind screen fbo
screenFramebuffer.bind();
@ -646,7 +648,6 @@ public class RenderingEngine {
// D R A W A L L E N T I T I E S
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
@ -662,7 +663,7 @@ public class RenderingEngine {
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw(renderPipelineState);
@ -717,7 +718,7 @@ public class RenderingEngine {
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw(renderPipelineState);
@ -737,7 +738,7 @@ public class RenderingEngine {
static void renderGameContentNoOIT(){
Matrix4f modelTransformMatrix = new Matrix4f();
Matrix4d modelTransformMatrix = new Matrix4d();
//bind screen fbo
screenFramebuffer.bind();
@ -774,7 +775,6 @@ public class RenderingEngine {
// D R A W A L L E N T I T I E S
//
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
@ -789,7 +789,7 @@ public class RenderingEngine {
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw(renderPipelineState);
@ -823,7 +823,7 @@ public class RenderingEngine {
renderPipelineState.setUseBones(true);
renderPipelineState.setUseLight(true);
Matrix4f modelTransformMatrix = new Matrix4f();
Matrix4d modelTransformMatrix = new Matrix4d();
if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
@ -895,7 +895,7 @@ public class RenderingEngine {
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){
Vector3d position = EntityUtils.getPosition(physicsEntity);
// Vector3f scale = EntityUtils.getScale(physicsEntity);
Quaternionf rotation = EntityUtils.getRotation(physicsEntity);
Quaterniond rotation = EntityUtils.getRotation(physicsEntity);
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).add(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
modelTransformMatrix.identity();
@ -916,14 +916,14 @@ public class RenderingEngine {
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitplane.fbx")) != null){
Vector3d position = EntityUtils.getPosition(physicsEntity);
Vector3f scale = EntityUtils.getScale(physicsEntity);
Quaternionf rotation = EntityUtils.getRotation(physicsEntity);
Quaterniond rotation = EntityUtils.getRotation(physicsEntity);
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(rotation);
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
modelTransformMatrix.scale(scale);
modelTransformMatrix.scale(new Vector3d(scale));
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
physicsGraphicsModel.draw(renderPipelineState);
}
@ -931,14 +931,14 @@ public class RenderingEngine {
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){
Vector3d position = EntityUtils.getPosition(physicsEntity);
Vector3f scale = EntityUtils.getScale(physicsEntity);
Quaternionf rotation = EntityUtils.getRotation(physicsEntity);
Quaterniond rotation = EntityUtils.getRotation(physicsEntity);
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(rotation);
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
modelTransformMatrix.scale(scale);
modelTransformMatrix.scale(new Vector3d(scale));
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
physicsGraphicsModel.draw(renderPipelineState);
}
@ -963,7 +963,7 @@ public class RenderingEngine {
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(rotation);
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
modelTransformMatrix.scale(scale);
modelTransformMatrix.scale(new Vector3d(scale));
shapeGraphicsModel.modelMatrix = modelTransformMatrix;
shapeGraphicsModel.draw(renderPipelineState);
}
@ -1013,12 +1013,11 @@ public class RenderingEngine {
Matrix4f modelTransformMatrix = new Matrix4f();
Matrix4d modelTransformMatrix = new Matrix4d();
Globals.renderingEngine.setActiveShader(renderPipelineState, renderNormalsShader);
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.clientScene.getEntitiesWithTag(EntityTags.DRAWABLE)){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
@ -1035,7 +1034,7 @@ public class RenderingEngine {
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw(renderPipelineState);
@ -1225,7 +1224,7 @@ public class RenderingEngine {
}
static void updateVolumeBuffer(){
Matrix4f modelTransformMatrix = new Matrix4f();
Matrix4d modelTransformMatrix = new Matrix4d();
//set the viewport to shadow map size
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
@ -1298,7 +1297,7 @@ public class RenderingEngine {
modelTransformMatrix = modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){
@ -1328,7 +1327,7 @@ public class RenderingEngine {
modelTransformMatrix = modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
currentActor.draw(renderPipelineState);
}
@ -1376,7 +1375,7 @@ public class RenderingEngine {
modelTransformMatrix = modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
modelTransformMatrix.scale(new Vector3d(EntityUtils.getScale(currentEntity)));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){

View File

@ -13,7 +13,9 @@ 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.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector4f;
@ -175,7 +177,7 @@ public class Actor {
this.animationScalar = animationScalar;
}
public void applyModelMatrix(Matrix4f modelMatrix){
public void applyModelMatrix(Matrix4d modelMatrix){
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
model.modelMatrix = modelMatrix;
@ -256,8 +258,8 @@ public class Actor {
return rVal;
}
public Quaternionf getBoneRotation(String boneName){
Quaternionf rVal = new Quaternionf();
public Quaterniond getBoneRotation(String boneName){
Quaterniond rVal = new Quaterniond();
Model model = Globals.assetManager.fetchModel(modelPath);
if(model != null){
applyAnimationMasks(model);
@ -269,7 +271,7 @@ public class Actor {
if(currentBone != null){
AxisAngle4f axisAngle = new AxisAngle4f();
currentBone.final_transform.getRotation(axisAngle);
Quaternionf rotation = new Quaternionf(axisAngle);
Quaterniond rotation = new Quaterniond(axisAngle);
rVal.set(rotation);
}
// }

View File

@ -8,6 +8,7 @@ import java.util.TreeMap;
import java.util.Map.Entry;
import org.joml.Matrix4f;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@ -25,7 +26,7 @@ public class AnimChannel {
TreeMap<Double,Keyframe> positionFrameTree;
Quaternionf startingRotation;
Quaterniond startingRotation;
TreeMap<Double,Keyframe> rotationFrameTree;
TreeMap<Double,Keyframe> scaleFrameTree;
@ -77,8 +78,8 @@ public class AnimChannel {
return rVal;
}
public Quaternionf getCurrentRotation(){
Quaternionf rVal = new Quaternionf();
public Quaterniond getCurrentRotation(){
Quaterniond rVal = new Quaterniond();
Entry<Double,Keyframe> previousEntry = rotationFrameTree.floorEntry(timeCurrent);
Entry<Double,Keyframe> nextEntry = rotationFrameTree.ceilingEntry(timeCurrent);
@ -95,13 +96,13 @@ public class AnimChannel {
}
if(previousFrame != null && nextFrame != null){
double percent_Next = ((timeCurrent - previousFrame.time) / (nextFrame.time - previousFrame.time));
rVal = new Quaternionf(previousFrame.rotation).slerp(nextFrame.rotation, (float)percent_Next);
rVal = new Quaterniond(previousFrame.rotation).slerp(nextFrame.rotation, (float)percent_Next);
// rVal = new Vector3f().add(new Vector3f().add(previousFrame.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(nextFrame.position).mul((float)(percent_Next)));
} else if(previousFrame != null){
rVal = new Quaternionf(previousFrame.rotation);
rVal = new Quaterniond(previousFrame.rotation);
// rVal = new Vector3f().add(previousFrame.position);
} else if(nextFrame != null){
rVal = new Quaternionf(nextFrame.rotation);
rVal = new Quaterniond(nextFrame.rotation);
// rVal = new Vector3f().add(nextFrame.position);
}

View File

@ -3,7 +3,7 @@ package electrosphere.renderer.anim;
import java.util.ArrayList;
import java.util.List;
import org.joml.Matrix4f;
import org.joml.Matrix4d;
import org.lwjgl.assimp.AINode;
/**
@ -12,7 +12,7 @@ import org.lwjgl.assimp.AINode;
*/
public class AnimNode {
public String id;
public Matrix4f transform;
public Matrix4d transform;
public AnimNode parent;
public List<AnimNode> children;
public boolean is_bone;
@ -21,7 +21,7 @@ public class AnimNode {
this.id = id;
this.parent = parent;
this.children = new ArrayList<AnimNode>();
this.transform = new Matrix4f();
this.transform = new Matrix4d();
is_bone = false;
this.raw_data = raw_data;
}

View File

@ -5,6 +5,8 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.PriorityQueue;
import org.joml.Quaterniond;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.lwjgl.PointerBuffer;
@ -134,7 +136,7 @@ public class Animation {
if(buff != null && buff.hasRemaining()){
AIQuatKey key = buff.get();
Keyframe currentFrame = new Keyframe(key.mTime());
currentFrame.rotation = new Quaternionf();
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);
@ -146,7 +148,7 @@ public class Animation {
previousFrame = currentFrame;
key = buff.get();
currentFrame = new Keyframe(key.mTime());
currentFrame.rotation = new Quaternionf();
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

View File

@ -1,6 +1,6 @@
package electrosphere.renderer.anim;
import org.joml.Quaternionf;
import org.joml.Quaterniond;
import org.joml.Vector3f;
/**
@ -10,7 +10,7 @@ import org.joml.Vector3f;
public class Keyframe implements Comparable<Keyframe>{
double time;
Vector3f position;
Quaternionf rotation;
Quaterniond rotation;
Vector3f scale;
public Keyframe(double time){

View File

@ -14,8 +14,10 @@ import static org.lwjgl.opengl.GL11.glViewport;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Quaterniond;
import org.joml.Vector3d;
import org.joml.Vector3f;
import electrosphere.engine.Globals;
@ -39,10 +41,10 @@ public class ActorPanel implements DrawableElement, DraggableElement {
Framebuffer elementBuffer;
Actor actor;
Matrix4f modelMatrix = new Matrix4f();
Matrix4d modelMatrix = new Matrix4d();
String currentAnim;
Vector3f actorPosition = new Vector3f(0,0,0);
Quaternionf actorRotation = new Quaternionf();
Quaterniond actorRotation = new Quaterniond();
Vector3f actorScale = new Vector3f(1,1,1);
float FOV = 50.0f;
float aspectRatio = 1.9f;
@ -249,7 +251,7 @@ public class ActorPanel implements DrawableElement, DraggableElement {
recalculateModelMatrix();
}
public void setRotation(Quaternionf rotation){
public void setRotation(Quaterniond rotation){
this.actorRotation.set(rotation);
recalculateModelMatrix();
}
@ -263,7 +265,7 @@ public class ActorPanel implements DrawableElement, DraggableElement {
modelMatrix.identity();
modelMatrix.translate(actorPosition);
modelMatrix.rotate(actorRotation);
modelMatrix.scale(actorScale);
modelMatrix.scale(new Vector3d(actorScale));
actor.applyModelMatrix(modelMatrix);
}

View File

@ -9,7 +9,6 @@ import electrosphere.renderer.ModelUtils;
import electrosphere.renderer.actor.ActorUtils;
import electrosphere.renderer.ui.font.RawFontMap.Glyph;
import java.util.HashMap;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector3i;

View File

@ -17,8 +17,7 @@ import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import org.joml.Vector3f;
import org.joml.Quaternionf;
import org.joml.Quaterniond;
import org.joml.Vector3d;
/**
@ -261,7 +260,7 @@ public class OpportunisticAttacker extends AI {
Vector3d position = EntityUtils.getPosition(character);
Vector3d targetPosition = EntityUtils.getPosition(target);
Vector3d movementVector = new Vector3d(targetPosition).sub(position).normalize();
Quaternionf movementQuaternion = new Quaternionf().rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,0,(float)movementVector.z)).normalize();
Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(movementVector.x,0,movementVector.z)).normalize();
CreatureUtils.setFacingVector(character, movementVector);
EntityUtils.getRotation(character).set(movementQuaternion);
}

View File

@ -9,7 +9,6 @@ import electrosphere.server.datacell.ServerDataCell;
import java.util.List;
import java.util.Random;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector3i;

View File

@ -1,13 +1,13 @@
package electrosphere.server.datacell;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.CollisionWorldData;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.Scene;
import electrosphere.entity.types.hitbox.HitboxManager;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.game.collision.CollisionWorldData;
import electrosphere.game.server.world.ServerWorldData;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.parser.net.message.NetworkMessage;

View File

@ -7,11 +7,11 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import electrosphere.collision.CollisionEngine;
import electrosphere.collision.CollisionWorldData;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.types.hitbox.HitboxManager;
import electrosphere.game.collision.CollisionEngine;
import electrosphere.game.collision.CollisionWorldData;
import electrosphere.game.server.world.ServerWorldData;
/**

View File

@ -1,8 +1,8 @@
package electrosphere.server.datacell.physics;
import electrosphere.client.terrain.cache.ChunkData;
import electrosphere.collision.dispatch.CollisionObject;
import electrosphere.dynamics.RigidBody;
import electrosphere.collision.PhysicsUtils;
import electrosphere.collision.collidable.Collidable;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
@ -10,8 +10,6 @@ import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.types.terrain.TerrainChunk;
import electrosphere.game.collision.PhysicsUtils;
import electrosphere.game.collision.collidable.Collidable;
import electrosphere.game.terrain.processing.TerrainInterpolator;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.Mesh;
@ -29,10 +27,10 @@ import electrosphere.util.Utilities;
import java.util.LinkedList;
import java.util.List;
import org.joml.Quaternionf;
import org.joml.Vector3d;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.ode4j.ode.DBody;
/**
*
@ -46,7 +44,7 @@ public class PhysicsDataCell {
Entity physicsEntity;
CollisionObject physicsObject;
DBody physicsObject;
Realm realm;
@ -99,7 +97,7 @@ public class PhysicsDataCell {
public void destroyPhysics(){
Realm realm = Globals.realmManager.getEntityRealm(physicsEntity);
realm.getCollisionEngine().deregisterCollidableEntity(physicsEntity);
realm.getCollisionEngine().deregisterRigidBody((RigidBody)physicsObject);
realm.getCollisionEngine().deregisterRigidBody((DBody)physicsObject);
}
}

View File

@ -8,7 +8,7 @@ import java.util.PriorityQueue;
import org.joml.AxisAngle4f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Quaterniond;
import org.joml.Vector3f;
import org.joml.Vector4f;
@ -234,8 +234,8 @@ public class PoseActor {
* @param boneName The name of the bone
* @return The rotation quaternion of the bone
*/
public Quaternionf getBoneRotation(String boneName){
Quaternionf rVal = new Quaternionf();
public Quaterniond getBoneRotation(String boneName){
Quaterniond rVal = new Quaterniond();
PoseModel model = Globals.assetManager.fetchPoseModel(modelPath);
if(model != null){
applyAnimationMasks(model);
@ -244,7 +244,7 @@ public class PoseActor {
if(currentBone != null){
AxisAngle4f axisAngle = new AxisAngle4f();
currentBone.final_transform.getRotation(axisAngle);
Quaternionf rotation = new Quaternionf(axisAngle);
Quaterniond rotation = new Quaterniond(axisAngle);
rVal.set(rotation);
}
}

View File

@ -6,7 +6,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Vector3d;
import org.lwjgl.PointerBuffer;
import org.lwjgl.assimp.AIAnimation;
import org.lwjgl.assimp.AIBone;
@ -110,10 +112,10 @@ public class PoseModel {
if(currentBone != null){
// System.out.println("Applying to bone");
//T * S * R
currentBone.deform = new Matrix4f();
currentBone.deform = new Matrix4d();
currentBone.deform.translate(currentChannel.getCurrentPosition());
currentBone.deform.rotate(currentChannel.getCurrentRotation());
currentBone.deform.scale(currentChannel.getCurrentScale());
currentBone.deform.scale(new Vector3d(currentChannel.getCurrentScale()));
}
}
}
@ -160,9 +162,9 @@ public class PoseModel {
void updateNodeTransform(AnimNode n, Map<String,ActorBoneRotator> boneRotators, ActorStaticMorph staticMorph){
//grab parent transform if exists
if(n.parent != null){
n.transform = new Matrix4f(n.parent.transform);
n.transform = new Matrix4d(n.parent.transform);
} else {
n.transform = new Matrix4f();
n.transform = new Matrix4d();
}
//if this is a bone, calculate the transform for the bone
if(n.is_bone){

View File

@ -15,7 +15,6 @@ import electrosphere.entity.state.ParticleTree;
import electrosphere.entity.state.attack.AttackTree;
import electrosphere.entity.state.collidable.ClientCollidableTree;
import electrosphere.entity.state.collidable.ServerCollidableTree;
import electrosphere.entity.state.gravity.GravityTree;
import electrosphere.entity.state.idle.IdleTree;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.hitbox.HitboxManager;