use of org.rajawali3d.bounds.BoundingBox in project Rajawali by Rajawali.
the class Object3D method render.
/**
* Renders the object
*
* @param camera The camera
* @param vpMatrix {@link Matrix4} The view-projection matrix
* @param projMatrix {@link Matrix4} The projection matrix
* @param vMatrix {@link Matrix4} The view matrix
* @param parentMatrix {@link Matrix4} This object's parent matrix
* @param sceneMaterial The scene-wide Material to use, if any.
*/
public void render(Camera camera, final Matrix4 vpMatrix, final Matrix4 projMatrix, final Matrix4 vMatrix, final Matrix4 parentMatrix, Material sceneMaterial) {
if (isDestroyed() || (!mIsVisible && !mRenderChildrenAsBatch) || isZeroScale()) {
return;
}
if (parentMatrix != null) {
if (mParentMatrix == null) {
mParentMatrix = new Matrix4();
}
mParentMatrix.setAll(parentMatrix);
}
Material material = sceneMaterial == null ? mMaterial : sceneMaterial;
preRender();
// -- move view matrix transformation first
boolean modelMatrixWasRecalculated = onRecalculateModelMatrix(parentMatrix);
// -- calculate model view matrix;
mMVMatrix.setAll(vMatrix).multiply(mMMatrix);
//Create MVP Matrix from View-Projection Matrix
mMVPMatrix.setAll(vpMatrix).multiply(mMMatrix);
// Transform the bounding volumes if they exist
if (mGeometry.hasBoundingBox())
getBoundingBox().transform(getModelMatrix());
if (mGeometry.hasBoundingSphere())
mGeometry.getBoundingSphere().transform(getModelMatrix());
// only if mFrustrumTest == true it check frustum
mIsInFrustum = true;
if (mFrustumTest && mGeometry.hasBoundingBox()) {
BoundingBox bbox = getBoundingBox();
if (!camera.getFrustum().boundsInFrustum(bbox)) {
mIsInFrustum = false;
}
}
if (!mIsContainerOnly && mIsInFrustum) {
mPMatrix = projMatrix;
if (mDoubleSided) {
GLES20.glDisable(GLES20.GL_CULL_FACE);
} else {
GLES20.glEnable(GLES20.GL_CULL_FACE);
if (mBackSided) {
GLES20.glCullFace(GLES20.GL_FRONT);
} else {
GLES20.glCullFace(GLES20.GL_BACK);
GLES20.glFrontFace(GLES20.GL_CCW);
}
}
if (mEnableBlending) {
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(mBlendFuncSFactor, mBlendFuncDFactor);
}
if (!mEnableDepthTest)
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
else {
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LESS);
}
GLES20.glDepthMask(mEnableDepthMask);
if (!mIsPartOfBatch) {
if (material == null) {
RajLog.e("[" + this.getClass().getName() + "] This object can't render because there's no material attached to it.");
/*throw new RuntimeException(
"This object can't render because there's no material attached to it.");*/
if (mEnableBlending) {
GLES20.glDisable(GLES20.GL_BLEND);
}
if (mDoubleSided) {
GLES20.glEnable(GLES20.GL_CULL_FACE);
} else if (mBackSided) {
GLES20.glCullFace(GLES20.GL_BACK);
}
if (!mEnableDepthTest) {
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LESS);
}
return;
}
material.useProgram();
setShaderParams(camera);
material.bindTextures();
if (mGeometry.hasTextureCoordinates())
material.setTextureCoords(mGeometry.getTexCoordBufferInfo());
if (mGeometry.hasNormals())
material.setNormals(mGeometry.getNormalBufferInfo());
if (mMaterial.usingVertexColors())
material.setVertexColors(mGeometry.getColorBufferInfo());
material.setVertices(mGeometry.getVertexBufferInfo());
}
material.setCurrentObject(this);
if (mOverrideMaterialColor) {
material.setColor(mColor);
}
material.applyParams();
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
material.setMVPMatrix(mMVPMatrix);
material.setModelMatrix(mMMatrix);
material.setModelViewMatrix(mMVMatrix);
if (mIsVisible) {
int bufferType = mGeometry.getIndexBufferInfo().bufferType == Geometry3D.BufferType.SHORT_BUFFER ? GLES20.GL_UNSIGNED_SHORT : GLES20.GL_UNSIGNED_INT;
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mGeometry.getIndexBufferInfo().bufferHandle);
GLES20.glDrawElements(mDrawingMode, mGeometry.getNumIndices(), bufferType, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
}
if (!mIsPartOfBatch && !mRenderChildrenAsBatch && sceneMaterial == null) {
material.unbindTextures();
}
material.unsetCurrentObject(this);
if (mEnableBlending) {
GLES20.glDisable(GLES20.GL_BLEND);
}
if (mDoubleSided) {
GLES20.glEnable(GLES20.GL_CULL_FACE);
} else if (mBackSided) {
GLES20.glCullFace(GLES20.GL_BACK);
}
if (!mEnableDepthTest) {
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LESS);
}
}
if (mShowBoundingVolume) {
if (mGeometry.hasBoundingBox())
getBoundingBox().drawBoundingVolume(camera, vpMatrix, projMatrix, vMatrix, mMMatrix);
if (mGeometry.hasBoundingSphere())
mGeometry.getBoundingSphere().drawBoundingVolume(camera, vpMatrix, projMatrix, vMatrix, mMMatrix);
}
// Draw children without frustum test
for (int i = 0, j = mChildren.size(); i < j; i++) {
Object3D child = mChildren.get(i);
if (mRenderChildrenAsBatch || mIsPartOfBatch) {
child.setPartOfBatch(true);
}
if (modelMatrixWasRecalculated)
child.markModelMatrixDirty();
child.render(camera, vpMatrix, projMatrix, vMatrix, mMMatrix, sceneMaterial);
}
if (mRenderChildrenAsBatch && sceneMaterial == null) {
material.unbindTextures();
}
}
use of org.rajawali3d.bounds.BoundingBox in project Rajawali by Rajawali.
the class A_nAABBTree method grow.
/**
* Grows the tree.
*/
protected void grow() {
RajLog.d("[" + this.getClass().getName() + "] Growing tree: " + this);
Vector3 min = new Vector3(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
Vector3 max = new Vector3(-Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE);
//Get a full list of all the members, including members in the children
ArrayList<IGraphNodeMember> members = getAllMembersRecursively(true);
int members_count = members.size();
for (int i = 0; i < members_count; ++i) {
IBoundingVolume volume = members.get(i).getTransformedBoundingVolume();
Vector3 test_against_min = null;
Vector3 test_against_max = null;
if (volume == null) {
ATransformable3D object = (ATransformable3D) members.get(i);
test_against_min = object.getPosition();
test_against_max = test_against_min;
} else {
if (volume instanceof BoundingBox) {
BoundingBox bb = (BoundingBox) volume;
test_against_min = bb.getTransformedMin();
test_against_max = bb.getTransformedMax();
} else if (volume instanceof BoundingSphere) {
BoundingSphere bs = (BoundingSphere) volume;
Vector3 bs_position = bs.getPosition();
double radius = bs.getScaledRadius();
Vector3 rad = new Vector3();
rad.setAll(radius, radius, radius);
test_against_min = Vector3.subtractAndCreate(bs_position, rad);
test_against_max = Vector3.addAndCreate(bs_position, rad);
} else {
RajLog.e("[" + this.getClass().getName() + "] Received a bounding box of unknown type.");
throw new IllegalArgumentException("Received a bounding box of unknown type.");
}
}
if (test_against_min != null && test_against_max != null) {
if (test_against_min.x < min.x)
min.x = test_against_min.x;
if (test_against_min.y < min.y)
min.y = test_against_min.y;
if (test_against_min.z < min.z)
min.z = test_against_min.z;
if (test_against_max.x > max.x)
max.x = test_against_max.x;
if (test_against_max.y > max.y)
max.y = test_against_max.y;
if (test_against_max.z > max.z)
max.z = test_against_max.z;
}
}
mMin.setAll(min);
mMax.setAll(max);
mTransformedMin.setAll(min);
mTransformedMax.setAll(max);
calculatePoints();
calculateChildSideLengths();
if (mSplit) {
for (int i = 0; i < CHILD_COUNT; ++i) {
((Octree) mChildren[i]).setChildRegion(i, mChildLengths);
}
}
for (int i = 0; i < members_count; ++i) {
internalAddObject(members.get(i));
}
}
use of org.rajawali3d.bounds.BoundingBox in project Rajawali by Rajawali.
the class A_nAABBTree method isContainedBy.
/*
* (non-Javadoc)
* @see rajawali.scenegraph.IGraphNode#isContainedBy(rajawali.bounds.IBoundingVolume)
*/
public boolean isContainedBy(IBoundingVolume boundingVolume) {
if (!(boundingVolume instanceof BoundingBox))
return false;
BoundingBox boundingBox = (BoundingBox) boundingVolume;
Vector3 otherMin = boundingBox.getTransformedMin();
Vector3 otherMax = boundingBox.getTransformedMax();
Vector3 min = mTransformedMin;
Vector3 max = mTransformedMax;
return (max.x <= otherMax.x) && (min.x >= otherMin.x) && (max.y <= otherMax.y) && (min.y >= otherMin.y) && (max.z <= otherMax.z) && (min.z >= otherMin.z);
}
use of org.rajawali3d.bounds.BoundingBox in project Rajawali by Rajawali.
the class Object3D method renderColorPicking.
/**
* Renders the object for color-picking
*
* @param camera The camera
* @param pickingMaterial The color-picking Material
*/
public void renderColorPicking(final Camera camera, final Material pickingMaterial) {
if (isDestroyed() || (!mIsVisible && !mRenderChildrenAsBatch) || isZeroScale())
// Neither the object nor any of its children are visible
return;
// Color-picking assumes much of the object state set in the prior frame is intact:
// No need to prerender (color-picking always runs before any children changes)
// All matrices already updated during prior frame
// Bounding box already transformed
// only if mFrustrumTest == true it check frustum
mIsInFrustum = true;
if (mFrustumTest && mGeometry.hasBoundingBox()) {
BoundingBox bbox = getBoundingBox();
if (!camera.getFrustum().boundsInFrustum(bbox)) {
mIsInFrustum = false;
}
}
// Render this object only if it has visible geometry and didn't fail frustum test
if (!mIsContainerOnly && mIsInFrustum && mIsVisible) {
// Render same faces as visible render
if (mDoubleSided) {
GLES20.glDisable(GLES20.GL_CULL_FACE);
} else {
GLES20.glEnable(GLES20.GL_CULL_FACE);
if (mBackSided) {
GLES20.glCullFace(GLES20.GL_FRONT);
} else {
GLES20.glCullFace(GLES20.GL_BACK);
GLES20.glFrontFace(GLES20.GL_CCW);
}
}
// Blending and depth testing are set up globally in Scene.doColorPicking()
// Material setup is independent of batching, and has no need for
// shader params, textures, normals, vertex colors, or current object...
pickingMaterial.useProgram();
pickingMaterial.setVertices(mGeometry.getVertexBufferInfo());
pickingMaterial.setColor(mPickingColor);
pickingMaterial.applyParams();
// Unbind the array buffer
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
// Apply this object's matrices to the pickingMaterial
pickingMaterial.setMVPMatrix(mMVPMatrix);
pickingMaterial.setModelMatrix(mMMatrix);
pickingMaterial.setModelViewMatrix(mMVMatrix);
// Draw the object using its picking color
int bufferType = mGeometry.getIndexBufferInfo().bufferType == Geometry3D.BufferType.SHORT_BUFFER ? GLES20.GL_UNSIGNED_SHORT : GLES20.GL_UNSIGNED_INT;
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mGeometry.getIndexBufferInfo().bufferHandle);
GLES20.glDrawElements(mDrawingMode, mGeometry.getNumIndices(), bufferType, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
// Only need to undo face culling
if (mDoubleSided) {
GLES20.glEnable(GLES20.GL_CULL_FACE);
} else if (mBackSided) {
GLES20.glCullFace(GLES20.GL_BACK);
}
}
// Draw children without frustum test
for (int i = 0, j = mChildren.size(); i < j; i++) {
// Child rendering is independent of batching, and matrices already updated
mChildren.get(i).renderColorPicking(camera, pickingMaterial);
}
// No textures to unbind, all done
}
use of org.rajawali3d.bounds.BoundingBox in project Rajawali by Rajawali.
the class Object3D method getBoundingBox.
/**
* Returns a {@link BoundingBox} for this Object3D and creates it if needed.
* Utilizes children's bounding values to calculate its own {@link BoundingBox}.
* @return
*/
public BoundingBox getBoundingBox() {
if (getNumChildren() > 0 && !mGeometry.hasBoundingBox()) {
Vector3 min = new Vector3(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
Vector3 max = new Vector3(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE);
for (int i = 0; i < getNumChildren(); i++) {
Object3D child = getChildAt(i);
updateMaxMinCoords(min, max, child);
}
if (mGeometry.getVertices() != null) {
updateMaxMinCoords(min, max, this);
}
mGeometry.setBoundingBox(new BoundingBox(min, max));
}
return mGeometry.getBoundingBox();
}
Aggregations