use of net.drewke.tdme.engine.primitives.BoundingVolume in project tdme by andreasdr.
the class LevelEditorView method pasteObjects.
/**
* Paste objects
*/
private void pasteObjects() {
// determine top left of paste objects
float pasteObjectsMinX = Float.MAX_VALUE;
float pasteObjectsMinZ = Float.MAX_VALUE;
float pasteObjectsMinY = Float.MIN_VALUE;
for (LevelEditorObject object : pasteObjects) {
BoundingVolume obv = object.getEntity().getModel().getBoundingBox();
BoundingVolume cbv = obv.clone();
cbv.fromBoundingVolumeWithTransformations(obv, object.getTransformations());
float[] objectBBMinXYZ = ((BoundingBox) cbv).getMin().getArray();
if (objectBBMinXYZ[0] < pasteObjectsMinX)
pasteObjectsMinX = objectBBMinXYZ[0];
if (objectBBMinXYZ[1] < pasteObjectsMinY)
pasteObjectsMinY = objectBBMinXYZ[1];
if (objectBBMinXYZ[2] < pasteObjectsMinZ)
pasteObjectsMinZ = objectBBMinXYZ[2];
}
// determine top left of selected objects
float selectedObjectsMinX = Float.MAX_VALUE;
float selectedObjectsMinZ = Float.MAX_VALUE;
float selectedObjectsMaxY = Float.MIN_VALUE;
for (Entity object : selectedObjects) {
LevelEditorObject levelEditorObject = level.getObjectById(object.getId());
if (levelEditorObject == null)
continue;
BoundingVolume obv = levelEditorObject.getEntity().getModel().getBoundingBox();
BoundingVolume cbv = obv.clone();
cbv.fromBoundingVolumeWithTransformations(obv, levelEditorObject.getTransformations());
float[] objectBBMinXYZ = ((BoundingBox) cbv).getMin().getArray();
float[] objectBBMaxXYZ = ((BoundingBox) cbv).getMax().getArray();
if (objectBBMinXYZ[0] < selectedObjectsMinX)
selectedObjectsMinX = objectBBMinXYZ[0];
if (objectBBMaxXYZ[1] > selectedObjectsMaxY)
selectedObjectsMaxY = objectBBMaxXYZ[1];
if (objectBBMinXYZ[2] < selectedObjectsMinZ)
selectedObjectsMinZ = objectBBMinXYZ[2];
}
// paste objects
for (LevelEditorObject pasteObject : pasteObjects) {
// get selected level entity if it is one
LevelEditorEntity pasteModel = pasteObject.getEntity();
// create level entity, copy transformations from original
Transformations levelEditorObjectTransformations = new Transformations();
levelEditorObjectTransformations.fromTransformations(pasteObject.getTransformations());
// compute new translation
float objectDiffX = pasteObject.getTransformations().getTranslation().getX() - pasteObjectsMinX;
float objectDiffY = pasteObject.getTransformations().getTranslation().getY() - pasteObjectsMinY;
float objectDiffZ = pasteObject.getTransformations().getTranslation().getZ() - pasteObjectsMinZ;
levelEditorObjectTransformations.getTranslation().setX(selectedObjectsMinX + objectDiffX);
levelEditorObjectTransformations.getTranslation().setY(selectedObjectsMaxY + objectDiffY);
levelEditorObjectTransformations.getTranslation().setZ(selectedObjectsMinZ + objectDiffZ);
levelEditorObjectTransformations.update();
// check if entity already exists
for (int i = 0; i < level.getObjectCount(); i++) {
LevelEditorObject levelEditorObject = level.getObjectAt(i);
if (levelEditorObject.getEntity() == pasteModel && levelEditorObject.getTransformations().getTranslation().equals(levelEditorObjectTransformations.getTranslation())) {
// we already have a object with selected model on this translation
return;
}
}
// create new level editor object
LevelEditorObject levelEditorObject = new LevelEditorObject(pasteModel.getName() + "_" + level.allocateObjectId(), "", levelEditorObjectTransformations, pasteModel);
// copy properties
for (PropertyModelClass property : pasteObject.getProperties()) {
levelEditorObject.addProperty(property.getName(), property.getValue());
}
// add to level
level.addObject(levelEditorObject);
// add to 3d engine
Object3D object = new Object3D(levelEditorObject.getId(), levelEditorObject.getEntity().getModel());
object.fromTransformations(levelEditorObjectTransformations);
object.setPickable(true);
engine.addEntity(object);
}
// add to objects listbox
levelEditorScreenController.setObjectListbox(level.getObjectIdsIterator());
}
use of net.drewke.tdme.engine.primitives.BoundingVolume in project tdme by andreasdr.
the class World method clone.
/**
* Clone this world
*/
public World clone() {
World clonedWorld = new World();
for (int i = 0; i < rigidBodies.size(); i++) {
RigidBody rigidBody = rigidBodies.get(i);
// clone obv
BoundingVolume obv = rigidBody.obv == null ? null : rigidBody.obv.clone();
// clone static rigid body
RigidBody clonedRigidBody = null;
if (rigidBody.isStatic == true) {
clonedRigidBody = clonedWorld.addStaticRigidBody(rigidBody.id, rigidBody.enabled, rigidBody.typeId, rigidBody.transformations, obv, rigidBody.friction);
} else {
// update dynamic rigid body
clonedRigidBody = clonedWorld.addRigidBody(rigidBody.id, rigidBody.enabled, rigidBody.typeId, rigidBody.transformations, obv, rigidBody.restitution, rigidBody.friction, rigidBody.mass, rigidBody.inverseInertia.clone());
}
// synch additional properties
synch(clonedRigidBody, clonedRigidBody);
}
return clonedWorld;
}
use of net.drewke.tdme.engine.primitives.BoundingVolume in project tdme by andreasdr.
the class World method determineHeight.
/**
* Determine height on x,y,u while respecting step up max
* @param type ids
* @param step up max
* @param point on which height should be calculated
* @param point where height has been determined
* @return rigid body from which height was determined or null
*/
public RigidBody determineHeight(int typeIds, float stepUpMax, Vector3 point, Vector3 dest) {
dest.set(point);
float[] pointXYZ = point.getArray();
// height bounding box to determine partition bounding volumes
heightBoundingBox.getMin().set(pointXYZ[0], -10000f, pointXYZ[2]);
heightBoundingBox.getMax().set(pointXYZ[0], +10000f, pointXYZ[2]);
heightBoundingBox.update();
// determine height of point on x, z
heightOnPointCandidate.set(pointXYZ[0], 10000f, pointXYZ[2]);
float height = -10000f;
RigidBody heightRigidBody = null;
for (RigidBody rigidBody : partition.getObjectsNearTo(heightBoundingBox)) {
if (((rigidBody.typeId & typeIds) == rigidBody.typeId) == false)
continue;
BoundingVolume cbv = rigidBody.cbv;
if (cbv instanceof BoundingBox) {
if (heightOnPointLineSegment.doesBoundingBoxCollideWithLineSegment((BoundingBox) cbv, heightBoundingBox.getMin(), heightBoundingBox.getMax(), heightOnPointA, heightOnPointB) == true) {
Vector3 heightOnPoint = higher(heightOnPointA, heightOnPointB);
if (heightOnPoint.getY() >= height && heightOnPoint.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPoint.getY();
heightRigidBody = rigidBody;
}
}
} else if (cbv instanceof OrientedBoundingBox) {
if (heightOnPointLineSegment.doesOrientedBoundingBoxCollideWithLineSegment((OrientedBoundingBox) cbv, heightBoundingBox.getMin(), heightBoundingBox.getMax(), heightOnPointA, heightOnPointB) == true) {
Vector3 heightOnPoint = higher(heightOnPointA, heightOnPointB);
if (heightOnPoint.getY() >= height && heightOnPoint.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPoint.getY();
heightRigidBody = rigidBody;
}
}
} else {
// compute closest point on height candidate
cbv.computeClosestPointOnBoundingVolume(heightOnPointCandidate, heightOnPointA);
// check new height, take only result into account which is near to candidate
if (Math.abs(heightOnPointCandidate.getX() - heightOnPointA.getX()) < 0.1f && Math.abs(heightOnPointCandidate.getZ() - heightOnPointA.getZ()) < 0.1f && heightOnPointA.getY() >= height && heightOnPointA.getY() < pointXYZ[1] + Math.max(0.1f, stepUpMax)) {
//
height = heightOnPointA.getY();
heightRigidBody = rigidBody;
}
}
}
// check if we have a ground
if (heightRigidBody == null) {
return null;
}
// nope, no collision
dest.setY(height);
return heightRigidBody;
}
use of net.drewke.tdme.engine.primitives.BoundingVolume in project tdme by andreasdr.
the class PartitionQuadTree method addRigidBody.
/**
* Adds a object
* @param rigidBody
*/
protected void addRigidBody(RigidBody rigidBody) {
// update if already exists
ArrayList<PartitionTreeNode> objectPartitionsVector = rigidBodyPartitionNodes.get(rigidBody.getId());
if (objectPartitionsVector != null) {
while (objectPartitionsVector.size() > 0) {
int lastIdx = objectPartitionsVector.size() - 1;
objectPartitionsVector.get(lastIdx).partitionRidigBodies.remove(rigidBody);
objectPartitionsVector.remove(lastIdx);
}
}
// determine max first level partition dimension
// convert to aabb for fast collision tests
BoundingVolume cbv = rigidBody.cbv;
Vector3 center = cbv.getCenter();
halfExtension.set(cbv.computeDimensionOnAxis(sideVector) + 0.2f, cbv.computeDimensionOnAxis(upVector) + 0.2f, cbv.computeDimensionOnAxis(forwardVector) + 0.2f).scale(0.5f);
boundingBox.getMin().set(center);
boundingBox.getMin().sub(halfExtension);
boundingBox.getMax().set(center);
boundingBox.getMax().add(halfExtension);
boundingBox.update();
// find, create root nodes if not exists
int minXPartition = (int) Math.floor(boundingBox.getMin().getX() / PARTITION_SIZE_MAX);
int minYPartition = (int) Math.floor(boundingBox.getMin().getY() / PARTITION_SIZE_MAX);
int minZPartition = (int) Math.floor(boundingBox.getMin().getZ() / PARTITION_SIZE_MAX);
int maxXPartition = (int) Math.floor(boundingBox.getMax().getX() / PARTITION_SIZE_MAX);
int maxYPartition = (int) Math.floor(boundingBox.getMax().getY() / PARTITION_SIZE_MAX);
int maxZPartition = (int) Math.floor(boundingBox.getMax().getZ() / PARTITION_SIZE_MAX);
for (int yPartition = minYPartition; yPartition <= maxYPartition; yPartition++) for (int xPartition = minXPartition; xPartition <= maxXPartition; xPartition++) for (int zPartition = minZPartition; zPartition <= maxZPartition; zPartition++) {
// try to find node by key
key.reset();
key.append(xPartition);
key.append(",");
key.append(yPartition);
key.append(",");
key.append(zPartition);
PartitionTreeNode node = treeRoot.subNodesByCoordinate.get(key);
if (node == null) {
node = createPartition(treeRoot, xPartition, yPartition, zPartition, PARTITION_SIZE_MAX);
}
}
// add rigid body to tree
addToPartitionTree(rigidBody, boundingBox);
}
use of net.drewke.tdme.engine.primitives.BoundingVolume in project tdme by andreasdr.
the class ModelMetaDataFileImport method parseBoundingVolume.
/**
* Parse bounding volume
* @param idx
* @param level editor entity
* @param JSON bounding volume node
* @return level editor entity bounding volume
* @throws JSONException
*/
private static LevelEditorEntityBoundingVolume parseBoundingVolume(int idx, LevelEditorEntity levelEditorEntity, JSONObject jBv) throws JSONException {
LevelEditorEntityBoundingVolume entityBoundingVolume = new LevelEditorEntityBoundingVolume(idx, levelEditorEntity);
BoundingVolume bv;
String bvTypeString = jBv.getString("type");
if (bvTypeString.equalsIgnoreCase("none") == true) {
entityBoundingVolume.setupNone();
} else if (bvTypeString.equalsIgnoreCase("sphere") == true) {
entityBoundingVolume.setupSphere(new Vector3((float) jBv.getDouble("cx"), (float) jBv.getDouble("cy"), (float) jBv.getDouble("cz")), (float) jBv.getDouble("r"));
} else if (bvTypeString.equalsIgnoreCase("capsule") == true) {
entityBoundingVolume.setupCapsule(new Vector3((float) jBv.getDouble("ax"), (float) jBv.getDouble("ay"), (float) jBv.getDouble("az")), new Vector3((float) jBv.getDouble("bx"), (float) jBv.getDouble("by"), (float) jBv.getDouble("bz")), (float) jBv.getDouble("r"));
} else if (bvTypeString.equalsIgnoreCase("aabb") == true) {
entityBoundingVolume.setupAabb(new Vector3((float) jBv.getDouble("mix"), (float) jBv.getDouble("miy"), (float) jBv.getDouble("miz")), new Vector3((float) jBv.getDouble("max"), (float) jBv.getDouble("may"), (float) jBv.getDouble("maz")));
} else if (bvTypeString.equalsIgnoreCase("obb") == true) {
entityBoundingVolume.setupObb(new Vector3((float) jBv.getDouble("cx"), (float) jBv.getDouble("cy"), (float) jBv.getDouble("cz")), new Vector3((float) jBv.getDouble("a0x"), (float) jBv.getDouble("a0y"), (float) jBv.getDouble("a0z")), new Vector3((float) jBv.getDouble("a1x"), (float) jBv.getDouble("a1y"), (float) jBv.getDouble("a1z")), new Vector3((float) jBv.getDouble("a2x"), (float) jBv.getDouble("a2y"), (float) jBv.getDouble("a2z")), new Vector3((float) jBv.getDouble("hex"), (float) jBv.getDouble("hey"), (float) jBv.getDouble("hez")));
} else if (bvTypeString.equalsIgnoreCase("convexmesh") == true) {
try {
entityBoundingVolume.setupConvexMesh(jBv.getString("file"));
} catch (Exception e) {
e.printStackTrace();
}
}
// done
return entityBoundingVolume;
}
Aggregations