use of org.rajawali3d.math.vector.Vector3 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.vector.Vector3 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.math.vector.Vector3 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.math.vector.Vector3 in project Rajawali by Rajawali.
the class A_nAABBTree method calculateChildSideLengths.
/**
* Calculates the side lengths that child nodes
* of this node should have.
*/
protected void calculateChildSideLengths() {
//Determine the distance on each axis
Vector3 temp = Vector3.subtractAndCreate(mTransformedMax, mTransformedMin);
//Divide it in half
temp.multiply(0.5f);
float overlap = 1.0f + mOverlap / 100.0f;
temp.multiply(overlap);
temp.absoluteValue();
mChildLengths.setAll(temp);
}
use of org.rajawali3d.math.vector.Vector3 in project Rajawali by Rajawali.
the class TerrainGenerator method createSquareTerrainFromBitmap.
/**
* Generate a Square Terrain using Bitmap as depth map (green component of ARGB)
*
* @param Parameters
* object that specify: ARGB Bitmap (R is temparature G is depth, A and B not used) Color Bitmpa
* (Optional) Number of divisions Scale of x,y,z coordinate TextureMult Specify the grid/texture relation
* Basecolor start color in relation with depth Middlecolor middle color Upcolor max depth color
* @param createVBOs
* @return
*/
public static SquareTerrain createSquareTerrainFromBitmap(SquareTerrain.Parameters prs, boolean createVBOs) {
int divisions = prs.divisions;
if (!((prs.divisions != 0) && ((prs.divisions & (prs.divisions - 1)) == 0))) {
throw new RuntimeException("Divisions must be x^2");
}
double[][] terrain = new double[divisions + 1][divisions + 1];
double[][] temperature = new double[divisions + 1][divisions + 1];
Vector3[][] normals = new Vector3[divisions + 1][divisions + 1];
boolean useColorBitmap = prs.colorMapBitmap != null;
int[] colorpixels = null;
Bitmap bnew = Bitmap.createBitmap(divisions + 1, divisions + 1, Bitmap.Config.ARGB_8888);
Canvas cnv = new Canvas(bnew);
cnv.drawBitmap(prs.heightMapBitmap, new Rect(0, 0, prs.heightMapBitmap.getWidth(), prs.heightMapBitmap.getHeight()), new Rect(0, 0, divisions + 1, divisions + 1), null);
int[] pixels = new int[(divisions + 1) * (divisions + 1)];
bnew.getPixels(pixels, 0, divisions + 1, 0, 0, divisions + 1, divisions + 1);
if (useColorBitmap) {
colorpixels = new int[(divisions + 1) * (divisions + 1)];
Paint clearPaint = new Paint();
clearPaint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.CLEAR));
cnv.drawRect(0, 0, prs.colorMapBitmap.getWidth(), prs.colorMapBitmap.getHeight(), clearPaint);
cnv.drawBitmap(prs.colorMapBitmap, new Rect(0, 0, prs.colorMapBitmap.getWidth(), prs.colorMapBitmap.getHeight()), new Rect(0, 0, divisions + 1, divisions + 1), null);
bnew.getPixels(colorpixels, 0, divisions + 1, 0, 0, divisions + 1, divisions + 1);
}
bnew.recycle();
int color;
int cols = divisions + 1;
double min, max;
terrain[0][0] = Color.green(0) / 255f * prs.scale.y;
min = max = terrain[0][0];
double alt;
double temp;
float oneover255 = 1f / 255f;
for (int i = 0; i <= divisions; ++i) {
for (int j = 0; j <= divisions; ++j) {
color = pixels[i + j * cols];
alt = Color.green(color) * oneover255 * prs.scale.y;
temp = Color.red(color) * oneover255 * (prs.maxTemp - prs.minTemp) + prs.minTemp;
if (i > 0 && j > 0) {
temp = ((temperature[i - 1][j] + temperature[i][j - 1]) * 0.5f + temp) * 0.5f;
alt = ((terrain[i - 1][j] + terrain[i][j - 1]) * 0.5f + alt) * 0.5f;
} else if (j > 0) {
temp = (temperature[i][j - 1] + temp) * 0.5f;
alt = (terrain[i][j - 1] + alt) * 0.5f;
} else if (i > 0) {
temp = (temperature[i - 1][j] + temp) * 0.5f;
alt = (terrain[i - 1][j] + alt) * 0.5f;
}
temperature[i][j] = temp;
terrain[i][j] = alt;
if (alt < min)
min = alt;
else if (alt > max)
max = alt;
normals[i][j] = new Vector3(0f, 1f, 0f);
}
}
Vector3 scale = prs.scale;
Vector3 v0 = new Vector3();
Vector3 v1 = new Vector3();
Vector3 v2 = new Vector3();
Vector3 na = new Vector3();
Vector3 nb = new Vector3();
Vector3 nc = new Vector3();
Vector3 nd = new Vector3();
for (int x = 1; x < divisions; x++) {
for (int z = 1; z < divisions; z++) {
// O z-1
// /|\
// / | \
// x-1 O--O--O x+1
// \ | /
// \|/
// O z+1
v0.x = (x - 1) * scale.x;
v0.z = z * scale.z;
v0.y = terrain[x - 1][z];
v1.x = x * scale.x;
v1.z = (z - 1) * scale.z;
v1.y = terrain[x][z - 1];
v2.x = x * scale.x;
v2.z = z * scale.z;
v2.y = terrain[x][z];
na = v1.subtract(v0).cross(v2.subtract(v0));
v0.x = x * scale.x;
v0.z = z * scale.z;
v0.y = terrain[x][z];
v1.x = x * scale.x;
v1.z = (z - 1) * scale.z;
v1.y = terrain[x][z - 1];
v2.x = (x + 1) * scale.x;
v2.z = z * scale.z;
v2.y = terrain[x + 1][z];
nb = v1.subtract(v0).cross(v2.subtract(v0));
v0.x = x * scale.x;
v0.z = z * scale.z;
v0.y = terrain[x][z];
v1.x = (x + 1) * scale.x;
v1.z = z * scale.z;
v1.y = terrain[x + 1][z];
v2.x = x * scale.x;
v2.z = (z + 1) * scale.z;
v2.y = terrain[x][z + 1];
nc = v1.subtract(v0).cross(v2.subtract(v0));
v0.x = x * scale.x;
v0.z = z * scale.z;
v0.y = terrain[x][z];
v1.x = x * scale.x;
v1.z = (z + 1) * scale.z;
v1.y = terrain[x][z + 1];
v2.x = (x - 1) * scale.x;
v2.z = z * scale.z;
v2.y = terrain[x - 1][z];
nd = v1.subtract(v0).cross(v2.subtract(v0));
// pre-set to 1
normals[x][z].y = 0f;
normals[x][z].add(na);
normals[x][z].add(nb);
normals[x][z].add(nc);
normals[x][z].add(nd);
}
}
SquareTerrain sq = new SquareTerrain(divisions, terrain, normals, temperature, scale.x, scale.z);
float[] vertices = new float[(divisions + 1) * (divisions + 1) * 3];
float[] nors = new float[(divisions + 1) * (divisions + 1) * 3];
float[] colors = new float[(divisions + 1) * (divisions + 1) * 4];
float[] textureCoords = new float[(divisions + 1) * (divisions + 1) * 2];
int[] indices = new int[(divisions) * (divisions) * 6];
int ii = 0;
int nn = 0;
int tt = 0;
int xx = 0;
int cc = 0;
double maxtt = 1f / (divisions + 1);
double xmid = (divisions * scale.x) / 2f;
double zmid = (divisions * scale.z) / 2f;
double percalt = 0;
float r, g, b, a;
a = 1f;
float a_basecolor = (float) ((float) Color.alpha(prs.basecolor) * oneover255);
float a_middlecolor = (float) Color.alpha(prs.middlecolor) * oneover255;
float a_upcolor = (float) Color.alpha(prs.upcolor) * oneover255;
float g_basecolor = (float) Color.green(prs.basecolor) * oneover255;
float g_middlecolor = (float) Color.green(prs.middlecolor) * oneover255;
float g_upcolor = (float) Color.green(prs.upcolor) * oneover255;
float b_basecolor = (float) Color.blue(prs.basecolor) * oneover255;
float b_middlecolor = (float) Color.blue(prs.middlecolor) * oneover255;
float b_upcolor = (float) Color.blue(prs.upcolor) * oneover255;
float r_basecolor = (float) Color.red(prs.basecolor) * oneover255;
float r_middlecolor = (float) Color.red(prs.middlecolor) * oneover255;
float r_upcolor = (float) Color.red(prs.upcolor) * oneover255;
int bmpcolor;
float a_bmp;
float r_bmp;
float g_bmp;
float b_bmp;
for (int i = 0; i <= divisions; ++i) {
for (int j = 0; j <= divisions; ++j) {
vertices[ii++] = (float) (i * scale.x - xmid);
vertices[ii++] = (float) terrain[i][j];
vertices[ii++] = (float) (j * scale.z - zmid);
percalt = sq.getPercAltitude(i, j);
if (percalt < 0.5) {
temp = (percalt - 0.0) * 2;
r = (float) (r_basecolor + (r_middlecolor - r_basecolor) * temp);
g = (float) (g_basecolor + (g_middlecolor - g_basecolor) * temp);
b = (float) (b_basecolor + (b_middlecolor - b_basecolor) * temp);
a = (float) (a_basecolor + (a_middlecolor - a_basecolor) * temp);
} else {
temp = (percalt - 0.5) * 2;
r = (float) (r_middlecolor + (r_upcolor - r_middlecolor) * temp);
g = (float) (g_middlecolor + (g_upcolor - g_middlecolor) * temp);
b = (float) (b_middlecolor + (b_upcolor - b_middlecolor) * temp);
a = (float) (a_middlecolor + (a_upcolor - a_middlecolor) * temp);
}
if (useColorBitmap) {
bmpcolor = colorpixels[i + j * cols];
a_bmp = (float) Color.alpha(bmpcolor) * oneover255;
r_bmp = (float) Color.red(bmpcolor) * oneover255;
g_bmp = (float) Color.green(bmpcolor) * oneover255;
b_bmp = (float) Color.blue(bmpcolor) * oneover255;
r = r * (1f - a_bmp) + a_bmp * r_bmp;
g = g * (1f - a_bmp) + a_bmp * g_bmp;
b = b * (1f - a_bmp) + a_bmp * b_bmp;
}
r = r < 0f ? 0f : r;
r = r > 1f ? 1f : r;
g = g < 0f ? 0f : g;
g = g > 1f ? 1f : g;
b = b < 0f ? 0f : b;
b = b > 1f ? 1f : b;
a = a < 0f ? 0f : a;
a = a > 1f ? 1f : a;
colors[cc++] = r;
colors[cc++] = g;
colors[cc++] = b;
colors[cc++] = a;
normals[i][j].normalize();
nors[nn++] = (float) normals[i][j].x;
nors[nn++] = (float) normals[i][j].y;
nors[nn++] = (float) normals[i][j].z;
textureCoords[tt++] = (float) (i * maxtt * prs.textureMult);
textureCoords[tt++] = (float) (j * maxtt * prs.textureMult);
}
}
for (int i = 0; i < divisions; i += 2) {
for (int j = 0; j < divisions; j += 2) {
// O--O--O--O--O
// |A/|\D| /|\ |
// |/B|C\|/ | \|
// O--O--O--O--O
// |\F|G/|\ | /|
// |E\|/H| \|/ |
// O--O--O--O--O
// A
indices[xx++] = (i) + (j) * cols;
indices[xx++] = (i + 1) + (j) * cols;
indices[xx++] = (i) + (j + 1) * cols;
// B
indices[xx++] = (i + 1) + (j) * cols;
indices[xx++] = (i + 1) + (j + 1) * cols;
indices[xx++] = (i) + (j + 1) * cols;
// C
indices[xx++] = (i + 1) + (j) * cols;
indices[xx++] = (i + 2) + (j + 1) * cols;
indices[xx++] = (i + 1) + (j + 1) * cols;
// D
indices[xx++] = (i + 1) + (j) * cols;
indices[xx++] = (i + 2) + (j) * cols;
indices[xx++] = (i + 2) + (j + 1) * cols;
// E
indices[xx++] = (i) + (j + 1) * cols;
indices[xx++] = (i + 1) + (j + 2) * cols;
indices[xx++] = (i) + (j + 2) * cols;
// F
indices[xx++] = (i) + (j + 1) * cols;
indices[xx++] = (i + 1) + (j + 1) * cols;
indices[xx++] = (i + 1) + (j + 2) * cols;
// G
indices[xx++] = (i + 1) + (j + 1) * cols;
indices[xx++] = (i + 2) + (j + 1) * cols;
indices[xx++] = (i + 1) + (j + 2) * cols;
// H
indices[xx++] = (i + 2) + (j + 1) * cols;
indices[xx++] = (i + 2) + (j + 2) * cols;
indices[xx++] = (i + 1) + (j + 2) * cols;
}
}
sq.setData(vertices, nors, textureCoords, colors, indices, createVBOs);
nors = null;
colors = null;
indices = null;
textureCoords = null;
vertices = null;
return sq;
}
Aggregations