Search in sources :

Example 1 with BoundingBox

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();
    }
}
Also used : BoundingBox(org.rajawali3d.bounds.BoundingBox) Material(org.rajawali3d.materials.Material) Matrix4(org.rajawali3d.math.Matrix4)

Example 2 with BoundingBox

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));
    }
}
Also used : BoundingSphere(org.rajawali3d.bounds.BoundingSphere) BoundingBox(org.rajawali3d.bounds.BoundingBox) Vector3(org.rajawali3d.math.vector.Vector3) ATransformable3D(org.rajawali3d.ATransformable3D) IBoundingVolume(org.rajawali3d.bounds.IBoundingVolume)

Example 3 with BoundingBox

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);
}
Also used : BoundingBox(org.rajawali3d.bounds.BoundingBox) Vector3(org.rajawali3d.math.vector.Vector3)

Example 4 with BoundingBox

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
}
Also used : BoundingBox(org.rajawali3d.bounds.BoundingBox)

Example 5 with BoundingBox

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();
}
Also used : BoundingBox(org.rajawali3d.bounds.BoundingBox) Vector3(org.rajawali3d.math.vector.Vector3)

Aggregations

BoundingBox (org.rajawali3d.bounds.BoundingBox)8 Vector3 (org.rajawali3d.math.vector.Vector3)5 BoundingSphere (org.rajawali3d.bounds.BoundingSphere)3 IBoundingVolume (org.rajawali3d.bounds.IBoundingVolume)2 ATransformable3D (org.rajawali3d.ATransformable3D)1 Object3D (org.rajawali3d.Object3D)1 Material (org.rajawali3d.materials.Material)1 Matrix4 (org.rajawali3d.math.Matrix4)1