use of org.rajawali3d.math.Matrix4 in project Rajawali by Rajawali.
the class LensFlarePlugin method render.
@Override
public void render() {
super.render();
int f, i, numLensFlares = mLensFlares.size();
// Calculate world space position to normalized screen space.
double viewportWidth = mRenderer.getViewportWidth(), viewportHeight = mRenderer.getDefaultViewportHeight();
double invAspect = viewportHeight / viewportWidth;
double size;
Vector2 scale = new Vector2();
double halfViewportWidth = viewportWidth / 2;
double halfViewportHeight = viewportHeight / 2;
Vector3 screenPosition = new Vector3();
double screenPositionPixels_x, screenPositionPixels_y;
Camera camera = mRenderer.getCurrentScene().getCamera();
Matrix4 viewMatrix = camera.getViewMatrix().clone(), projMatrix = camera.getProjectionMatrix().clone();
useProgram(mProgram);
// Push the VBOs to the GPU.
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGeometry.getVertexBufferInfo().bufferHandle);
GLES20.glEnableVertexAttribArray(maPositionHandle);
GLES20.glVertexAttribPointer(maPositionHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
// Push texture coordinates to the GPU.
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mGeometry.getTexCoordBufferInfo().bufferHandle);
GLES20.glEnableVertexAttribArray(maTextureCoordHandle);
GLES20.glVertexAttribPointer(maTextureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
// Push vertex element indices to the GPU.
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mGeometry.getIndexBufferInfo().bufferHandle);
// Set up texture locations.
GLES20.glUniform1i(muOcclusionMapTextureHandle, 0);
GLES20.glUniform1i(muMapTextureHandle, 1);
GLES20.glDisable(GLES20.GL_CULL_FACE);
GLES20.glDepthMask(false);
// Calculate camera direction vector.
Vector3 cameraPosition = camera.getPosition().clone();
Vector3 cameraLookAt = camera.getLookAt() != null ? camera.getLookAt().clone() : new Vector3(0, 0, 1);
Vector3 cameraDirection = cameraLookAt.clone().subtract(cameraPosition);
cameraDirection.normalize();
synchronized (mLensFlares) {
for (i = 0; i < numLensFlares; i++) {
size = 16 / viewportHeight;
scale.setX(size * invAspect);
scale.setY(size);
LensFlare lensFlare = mLensFlares.get(i);
// Calculate normalized device coordinates.
screenPosition.setAll(lensFlare.getPosition().clone());
screenPosition.multiply(viewMatrix);
screenPosition.project(projMatrix);
// Calculate actual device coordinates.
screenPositionPixels_x = screenPosition.x * halfViewportWidth + halfViewportWidth;
screenPositionPixels_y = screenPosition.y * halfViewportHeight + halfViewportHeight;
// Calculate the angle between the camera and the light vector.
Vector3 lightToCamDirection = lensFlare.getPosition().clone().subtract(cameraPosition);
lightToCamDirection.normalize();
double angleLightCamera = lightToCamDirection.dot(cameraDirection);
// viewing frustum.
if (mVertexTextureSupported || (angleLightCamera > 0 && screenPositionPixels_x > -64 && screenPositionPixels_x < viewportWidth + 64 && screenPositionPixels_y > -64 && screenPositionPixels_y < viewportHeight + 64)) {
// Bind current framebuffer to texture.
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMapTexture.getTextureId());
GLES20.glCopyTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, (int) screenPositionPixels_x - 8, (int) screenPositionPixels_y - 8, 16, 16, 0);
// First render pass.
GLES20.glUniform1i(muRenderTypeHandle, 1);
GLES20.glUniform2fv(muScaleHandle, 1, new float[] { (float) scale.getX(), (float) scale.getY() }, 0);
GLES20.glUniform3fv(muScreenPositionHandle, 1, new float[] { (float) screenPosition.x, (float) screenPosition.y, (float) screenPosition.z }, 0);
GLES20.glDisable(GLES20.GL_BLEND);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_INT, 0);
// Copy result to occlusion map.
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mOcclusionMapTexture.getTextureId());
GLES20.glCopyTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, (int) screenPositionPixels_x - 8, (int) screenPositionPixels_y - 8, 16, 16, 0);
// Second render pass.
GLES20.glUniform1i(muRenderTypeHandle, 2);
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mMapTexture.getTextureId());
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_INT, 0);
// Update the flare's screen positions.
lensFlare.setPositionScreen(screenPosition);
lensFlare.updateLensFlares();
// Third render pass.
GLES20.glUniform1i(muRenderTypeHandle, 3);
GLES20.glEnable(GLES20.GL_BLEND);
for (f = 0; f < lensFlare.getLensFlares().size(); f++) {
FlareInfo sprite = lensFlare.getLensFlares().get(f);
// Don't bother rendering if the sprite's too transparent or too small.
if (sprite.getOpacity() > 0.001 && sprite.getScale() > 0.001) {
screenPosition.setAll(sprite.getScreenPosition());
// Calculate pixel size to normalized size
size = sprite.getSize() * sprite.getScale() / viewportHeight;
scale.setX(size * invAspect);
scale.setY(size);
GLES20.glUniform3fv(muScreenPositionHandle, 1, new float[] { (float) screenPosition.x, (float) screenPosition.y, (float) screenPosition.z }, 0);
GLES20.glUniform2fv(muScaleHandle, 1, new float[] { (float) scale.getX(), (float) scale.getY() }, 0);
GLES20.glUniform1f(muRotationHandle, (float) sprite.getRotation());
GLES20.glUniform1f(muOpacityHandle, (float) sprite.getOpacity());
GLES20.glUniform3fv(muColorHandle, 1, new float[] { (float) sprite.getColor().x, (float) sprite.getColor().y, (float) sprite.getColor().z }, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, sprite.getTexture().getTextureId());
//GLES20.glBlendEquation(GLES20.GL_FUNC_ADD);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);
// Draw the elements.
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mGeometry.getNumIndices(), GLES20.GL_UNSIGNED_INT, 0);
// Unbind texture.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
}
}
}
}
}
// Unbind element array.
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthMask(true);
}
use of org.rajawali3d.math.Matrix4 in project Rajawali by Rajawali.
the class Vector3Test method testMultiplyFromMatrix4.
@Test
public void testMultiplyFromMatrix4() throws Exception {
final Vector3 v = new Vector3(1d, 2d, 3d);
final double[] matrix = new double[] { 1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d, 9d, 10d, 11d, 12d, 13d, 14d, 15d, 16d };
final Matrix4 matrix4 = new Matrix4(matrix);
final Vector3 out = v.multiply(matrix4);
assertNotNull(out);
assertTrue(out == v);
assertEquals(51d, v.x, 0);
assertEquals(58d, v.y, 0);
assertEquals(65d, v.z, 0);
}
use of org.rajawali3d.math.Matrix4 in project Rajawali by Rajawali.
the class BlockAnimator method buildSkeleton.
// apply joint hierarchy to joint pose frames
private void buildSkeleton(BlockHeader blockHeader, long skelAddr) throws ParsingException {
SkeletonJoint[] joints = lookupSkeleton(blockHeader, skelAddr);
SkeletalAnimationSequence[] skelAnims = new SkeletalAnimationSequence[mAnimSet.length];
for (int i = 0; i < mAnimSet.length; i++) skelAnims[i] = (SkeletalAnimationSequence) mAnimSet[i];
Matrix4 scratch1 = new Matrix4();
Matrix4 scratch2 = new Matrix4();
for (SkeletalAnimationSequence skelSeq : skelAnims) {
for (SkeletalAnimationFrame frame : skelSeq.getFrames()) {
SkeletonJoint[] poses = frame.getSkeleton().getJoints();
// apply parent transforms
for (int i = 0; i < poses.length; i++) {
// matrix and index already set, need parent & other attribs
poses[i].setParentIndex(joints[i].getParentIndex());
if (// has parent joint
poses[i].getParentIndex() >= 0) {
SkeletonJoint parentPose = poses[poses[i].getParentIndex()];
scratch1.setAll(parentPose.getMatrix()).multiply(scratch2.setAll(poses[i].getMatrix()));
poses[i].setMatrix(scratch1.getDoubleValues());
} else
scratch1.setAll(poses[i].getMatrix());
// assign pos + rot from final matrix
scratch1.getTranslation(poses[i].getPosition());
poses[i].getOrientation().fromMatrix(scratch1);
poses[i].getOrientation().computeW();
}
}
}
for (int i = 0; i < mTargets.length; i++) {
SkeletalAnimationObject3D obj = (SkeletalAnimationObject3D) mTargets[i];
// assigns INVBP, builds BP, sets joints
obj.setJointsWithInverseBindPoseMatrices(joints);
for (int j = 0; j < obj.getNumChildren(); j++) {
SkeletalAnimationChildObject3D child = (SkeletalAnimationChildObject3D) obj.getChildAt(j);
SkeletalAnimationMaterialPlugin plugin = new SkeletalAnimationMaterialPlugin(child.getNumJoints(), child.getMaxBoneWeightsPerVertex());
child.getMaterial().addPlugin(plugin);
}
obj.setAnimationSequences(skelAnims);
obj.setAnimationSequence(mActive);
if (mAutoPlay)
obj.play(true);
}
}
use of org.rajawali3d.math.Matrix4 in project Rajawali by Rajawali.
the class Vector3Test method testProjectFromMatrix4.
@Test
public void testProjectFromMatrix4() throws Exception {
final double[] m = new double[] { 1d, 0d, 0d, 0d, 0d, 1d, 0d, 0d, 0d, 0d, 1d, 1d, 0d, 0d, 0d, 0d };
Vector3 v = new Vector3(2d, 3d, 4d);
final Vector3 out = v.project(new Matrix4(m));
assertNotNull(out);
assertSame(out, v);
assertEquals(0.5, out.x, 1e-14);
assertEquals(0.75, out.y, 1e-14);
assertEquals(1d, out.z, 1e-14);
}
use of org.rajawali3d.math.Matrix4 in project Rajawali by Rajawali.
the class ScreenQuad method init.
private void init(boolean createVBOs) {
int i, j;
int numVertices = (mSegmentsW + 1) * (mSegmentsH + 1);
float[] vertices = new float[numVertices * 3];
float[] textureCoords = null;
if (mCreateTextureCoords)
textureCoords = new float[numVertices * 2];
float[] normals = new float[numVertices * 3];
float[] colors = null;
if (mCreateVertexColorBuffer)
colors = new float[numVertices * 4];
int[] indices = new int[mSegmentsW * mSegmentsH * 6];
int vertexCount = 0;
int texCoordCount = 0;
mCamera = new Camera2D();
mCamera.setProjectionMatrix(0, 0);
mVPMatrix = new Matrix4();
for (i = 0; i <= mSegmentsW; i++) {
for (j = 0; j <= mSegmentsH; j++) {
float v1 = ((float) i / (float) mSegmentsW - 0.5f);
float v2 = ((float) j / (float) mSegmentsH - 0.5f);
vertices[vertexCount] = v1;
vertices[vertexCount + 1] = v2;
vertices[vertexCount + 2] = 0;
if (mCreateTextureCoords) {
float u = (float) i / (float) mSegmentsW;
textureCoords[texCoordCount++] = u * mNumTextureTiles;
float v = (float) j / (float) mSegmentsH;
textureCoords[texCoordCount++] = (1.0f - v) * mNumTextureTiles;
}
normals[vertexCount] = 0;
normals[vertexCount + 1] = 0;
normals[vertexCount + 2] = 1;
vertexCount += 3;
}
}
int colspan = mSegmentsH + 1;
int indexCount = 0;
for (int col = 0; col < mSegmentsW; col++) {
for (int row = 0; row < mSegmentsH; row++) {
int ul = col * colspan + row;
int ll = ul + 1;
int ur = (col + 1) * colspan + row;
int lr = ur + 1;
indices[indexCount++] = (int) ur;
indices[indexCount++] = (int) lr;
indices[indexCount++] = (int) ul;
indices[indexCount++] = (int) lr;
indices[indexCount++] = (int) ll;
indices[indexCount++] = (int) ul;
}
}
if (mCreateVertexColorBuffer) {
int numColors = numVertices * 4;
for (j = 0; j < numColors; j += 4) {
colors[j] = 1.0f;
colors[j + 1] = 1.0f;
colors[j + 2] = 1.0f;
colors[j + 3] = 1.0f;
}
}
setData(vertices, normals, textureCoords, colors, indices, createVBOs);
vertices = null;
normals = null;
textureCoords = null;
colors = null;
indices = null;
mEnableDepthTest = false;
mEnableDepthMask = false;
}
Aggregations