Support for texture's tube projection.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8059 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
cdf464123d
commit
11b250ffe1
@ -114,8 +114,8 @@ public class UVCoordinatesGenerator {
|
|||||||
uvCoordinates = UVProjectionGenerator.cubeProjection(mesh, bb);
|
uvCoordinates = UVProjectionGenerator.cubeProjection(mesh, bb);
|
||||||
break;
|
break;
|
||||||
case PROJECTION_TUBE:
|
case PROJECTION_TUBE:
|
||||||
// TODO: implement
|
BoundingTube bt = UVCoordinatesGenerator.getBoundingTube(mesh);
|
||||||
// uvCoordinates = UVProjectionGenerator.tubeProjection(mesh, bb);
|
uvCoordinates = UVProjectionGenerator.tubeProjection(mesh, bt);
|
||||||
break;
|
break;
|
||||||
case PROJECTION_SPHERE:
|
case PROJECTION_SPHERE:
|
||||||
uvCoordinates = UVProjectionGenerator.sphereProjection(mesh, bb);
|
uvCoordinates = UVProjectionGenerator.sphereProjection(mesh, bb);
|
||||||
@ -289,11 +289,11 @@ public class UVCoordinatesGenerator {
|
|||||||
maxx = x > maxx ? x : maxx;
|
maxx = x > maxx ? x : maxx;
|
||||||
minx = x < minx ? x : minx;
|
minx = x < minx ? x : minx;
|
||||||
maxy = y > maxy ? y : maxy;
|
maxy = y > maxy ? y : maxy;
|
||||||
miny = x < miny ? y : miny;
|
miny = y < miny ? y : miny;
|
||||||
maxz = x > maxz ? z : maxz;
|
maxz = z > maxz ? z : maxz;
|
||||||
minz = x < minz ? z : minz;
|
minz = z < minz ? z : minz;
|
||||||
}
|
}
|
||||||
center.divideLocal(limit);
|
center.divideLocal(limit/3);
|
||||||
|
|
||||||
float radius = Math.max(maxx - minx, maxy - miny) * 0.5f;
|
float radius = Math.max(maxx - minx, maxy - miny) * 0.5f;
|
||||||
return new BoundingTube(radius, maxz - minz, center);
|
return new BoundingTube(radius, maxz - minz, center);
|
||||||
|
@ -3,22 +3,26 @@ package com.jme3.scene.plugins.blender.textures;
|
|||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
import com.jme3.bounding.BoundingBox;
|
import com.jme3.bounding.BoundingBox;
|
||||||
|
import com.jme3.math.FastMath;
|
||||||
import com.jme3.math.Triangle;
|
import com.jme3.math.Triangle;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
|
import com.jme3.scene.VertexBuffer;
|
||||||
import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTube;
|
import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTube;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class helps with projection calculations.
|
* This class helps with projection calculations.
|
||||||
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/* package */class UVProjectionGenerator {
|
/* package */class UVProjectionGenerator {
|
||||||
/**
|
/**
|
||||||
* Flat projection for 2D textures.
|
* Flat projection for 2D textures.
|
||||||
|
*
|
||||||
* @param mesh
|
* @param mesh
|
||||||
* mesh that is to be projected
|
* mesh that is to be projected
|
||||||
* @param bb
|
* @param bb
|
||||||
* the bounding box for projecting
|
* the bounding box for projecting
|
||||||
* @return UV coordinates after the projection
|
* @return UV coordinates after the projection
|
||||||
*/
|
*/
|
||||||
public static float[] flatProjection(Mesh mesh, BoundingBox bb) {
|
public static float[] flatProjection(Mesh mesh, BoundingBox bb) {
|
||||||
@ -27,7 +31,7 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
}
|
}
|
||||||
Vector3f min = bb.getMin(null);
|
Vector3f min = bb.getMin(null);
|
||||||
float[] ext = new float[] { bb.getXExtent() * 2.0f, bb.getYExtent() * 2.0f };
|
float[] ext = new float[] { bb.getXExtent() * 2.0f, bb.getYExtent() * 2.0f };
|
||||||
FloatBuffer positions = mesh.getFloatBuffer(com.jme3.scene.VertexBuffer.Type.Position);
|
FloatBuffer positions = mesh.getFloatBuffer(VertexBuffer.Type.Position);
|
||||||
float[] uvCoordinates = new float[positions.limit() / 3 * 2];
|
float[] uvCoordinates = new float[positions.limit() / 3 * 2];
|
||||||
for (int i = 0, j = 0; i < positions.limit(); i += 3, j += 2) {
|
for (int i = 0, j = 0; i < positions.limit(); i += 3, j += 2) {
|
||||||
uvCoordinates[j] = (positions.get(i) - min.x) / ext[0];
|
uvCoordinates[j] = (positions.get(i) - min.x) / ext[0];
|
||||||
@ -39,10 +43,11 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cube projection for 2D textures.
|
* Cube projection for 2D textures.
|
||||||
|
*
|
||||||
* @param mesh
|
* @param mesh
|
||||||
* mesh that is to be projected
|
* mesh that is to be projected
|
||||||
* @param bb
|
* @param bb
|
||||||
* the bounding box for projecting
|
* the bounding box for projecting
|
||||||
* @return UV coordinates after the projection
|
* @return UV coordinates after the projection
|
||||||
*/
|
*/
|
||||||
public static float[] cubeProjection(Mesh mesh, BoundingBox bb) {
|
public static float[] cubeProjection(Mesh mesh, BoundingBox bb) {
|
||||||
@ -101,23 +106,72 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tube projection for 2D textures.
|
* Tube projection for 2D textures.
|
||||||
|
*
|
||||||
* @param mesh
|
* @param mesh
|
||||||
* mesh that is to be projected
|
* mesh that is to be projected
|
||||||
* @param bb
|
* @param bt
|
||||||
* the bounding box for projecting
|
* the bounding tube for projecting
|
||||||
* @return UV coordinates after the projection
|
* @return UV coordinates after the projection
|
||||||
*/
|
*/
|
||||||
|
public static float[] tubeProjection(Mesh mesh, BoundingTube bt) {
|
||||||
|
FloatBuffer positions = mesh.getFloatBuffer(VertexBuffer.Type.Position);
|
||||||
|
float[] uvCoordinates = new float[positions.limit() / 3 * 2];
|
||||||
|
Vector3f v = new Vector3f();
|
||||||
|
float cx = bt.getCenter().x, cy = bt.getCenter().y;
|
||||||
|
Vector3f uBase = new Vector3f(0, -1, 0);
|
||||||
|
|
||||||
public static float[] tubeProjection(Mesh mesh, BoundingTube bb) {
|
//the key is the Z-ccordinate of the vertex and the value a map between the vertex's angle nad indexes of its UV-coordinates
|
||||||
return null;// TODO: implement
|
// Map<Float, Map<Float, Integer[]>> lowestAnglesUVCoordinatesMap = new HashMap<Float, Map<Float,Integer[]>>();
|
||||||
|
float vBase = bt.getCenter().z - bt.getHeight() * 0.5f;
|
||||||
|
for (int i = 0, j = 0; i < positions.limit(); i += 3, j += 2) {
|
||||||
|
// calculating U
|
||||||
|
v.set(positions.get(i)-cx, positions.get(i + 1)-cy, 0);
|
||||||
|
v.normalizeLocal();
|
||||||
|
float angle = v.angleBetween(uBase);// result between [0; PI]
|
||||||
|
if (v.x < 0) {// the angle should be greater than PI, we're on the other part of the image then
|
||||||
|
angle = FastMath.TWO_PI - angle;
|
||||||
|
}
|
||||||
|
uvCoordinates[j] = angle / FastMath.TWO_PI;
|
||||||
|
|
||||||
|
// calculating V
|
||||||
|
float z = positions.get(i + 2);
|
||||||
|
uvCoordinates[j + 1] = (vBase - z) / bt.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
//looking for splitted triangles
|
||||||
|
Triangle triangle = new Triangle();
|
||||||
|
for(int i=0;i<mesh.getTriangleCount();++i) {
|
||||||
|
mesh.getTriangle(i, triangle);
|
||||||
|
float sgn1 = Math.signum(triangle.get1().x-cx);
|
||||||
|
float sgn2 = Math.signum(triangle.get2().x-cx);
|
||||||
|
float sgn3 = Math.signum(triangle.get3().x-cx);
|
||||||
|
float xSideFactor = sgn1 + sgn2 + sgn3;
|
||||||
|
float ySideFactor = Math.signum(triangle.get1().y-cy)+
|
||||||
|
Math.signum(triangle.get2().y-cy)+
|
||||||
|
Math.signum(triangle.get3().y-cy);
|
||||||
|
if((xSideFactor>-3 || xSideFactor<3) && ySideFactor<0) {//the triangle is on the splitting plane
|
||||||
|
//indexOfUcoord = (indexOfTriangle*3 + indexOfTrianglesVertex)*2
|
||||||
|
if(sgn1==1.0f) {
|
||||||
|
uvCoordinates[i*3*2] += 1.0f;
|
||||||
|
}
|
||||||
|
if(sgn2==1.0f) {
|
||||||
|
uvCoordinates[(i*3+1)*2] += 1.0f;
|
||||||
|
}
|
||||||
|
if(sgn3==1.0f) {
|
||||||
|
uvCoordinates[(i*3+2)*2] += 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uvCoordinates;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sphere projection for 2D textures.
|
* Sphere projection for 2D textures.
|
||||||
|
*
|
||||||
* @param mesh
|
* @param mesh
|
||||||
* mesh that is to be projected
|
* mesh that is to be projected
|
||||||
* @param bb
|
* @param bb
|
||||||
* the bounding box for projecting
|
* the bounding box for projecting
|
||||||
* @return UV coordinates after the projection
|
* @return UV coordinates after the projection
|
||||||
*/
|
*/
|
||||||
public static float[] sphereProjection(Mesh mesh, BoundingBox bb) {
|
public static float[] sphereProjection(Mesh mesh, BoundingBox bb) {
|
||||||
@ -128,7 +182,8 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
// Vector3f yVec = new Vector3f();
|
// Vector3f yVec = new Vector3f();
|
||||||
// Vector3f zVec = new Vector3f();
|
// Vector3f zVec = new Vector3f();
|
||||||
// for(Geometry geom : geometries) {
|
// for(Geometry geom : geometries) {
|
||||||
// if(materialHelper.hasTexture(geom.getMaterial())) {//generate only when material has a texture
|
// if(materialHelper.hasTexture(geom.getMaterial())) {//generate only
|
||||||
|
// when material has a texture
|
||||||
// geom.getMesh().updateBound();
|
// geom.getMesh().updateBound();
|
||||||
// BoundingSphere bs = this.getBoundingSphere(geom.getMesh());
|
// BoundingSphere bs = this.getBoundingSphere(geom.getMesh());
|
||||||
// float r2 = bs.getRadius() * bs.getRadius();
|
// float r2 = bs.getRadius() * bs.getRadius();
|
||||||
@ -136,7 +191,8 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
// zVec.set(0, 0, -bs.getRadius());
|
// zVec.set(0, 0, -bs.getRadius());
|
||||||
// Vector3f center = bs.getCenter();
|
// Vector3f center = bs.getCenter();
|
||||||
// ray.setOrigin(center);
|
// ray.setOrigin(center);
|
||||||
// //we cast each vertex of the current mesh on the bounding box to determine the UV-coordinates
|
// //we cast each vertex of the current mesh on the bounding box to
|
||||||
|
// determine the UV-coordinates
|
||||||
// for(int i=0;i<geom.getMesh().getIndexBuffer().size();++i) {
|
// for(int i=0;i<geom.getMesh().getIndexBuffer().size();++i) {
|
||||||
// int index = geom.getMesh().getIndexBuffer().get(i);
|
// int index = geom.getMesh().getIndexBuffer().get(i);
|
||||||
//
|
//
|
||||||
@ -148,17 +204,22 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
// bs.collideWith(ray, cr);//there is ALWAYS one collision
|
// bs.collideWith(ray, cr);//there is ALWAYS one collision
|
||||||
// Vector3f p = cr.getCollision(0).getContactPoint();
|
// Vector3f p = cr.getCollision(0).getContactPoint();
|
||||||
// p.subtractLocal(center);
|
// p.subtractLocal(center);
|
||||||
// //arcLength = FastMath.acos(p.dot(yVec)/(p.length * yVec.length)) * r <- an arc length on the sphere (from top to the point on
|
// //arcLength = FastMath.acos(p.dot(yVec)/(p.length * yVec.length)) * r
|
||||||
|
// <- an arc length on the sphere (from top to the point on
|
||||||
// the sphere)
|
// the sphere)
|
||||||
// //but yVec.length == r and p.length == r so: arcLength = FastMath.acos(p.dot(yVec)/r^2)/r
|
// //but yVec.length == r and p.length == r so: arcLength =
|
||||||
|
// FastMath.acos(p.dot(yVec)/r^2)/r
|
||||||
// //U coordinate is as follows: u = arcLength / PI*r
|
// //U coordinate is as follows: u = arcLength / PI*r
|
||||||
// //so to compute it faster we just write: u = FastMath.acos(p.dot(yVec)/r^2) / PI;
|
// //so to compute it faster we just write: u =
|
||||||
|
// FastMath.acos(p.dot(yVec)/r^2) / PI;
|
||||||
// float u = FastMath.acos(p.dot(yVec)/r2) / FastMath.PI;
|
// float u = FastMath.acos(p.dot(yVec)/r2) / FastMath.PI;
|
||||||
// //we use similiar method to compute v
|
// //we use similiar method to compute v
|
||||||
// //the only difference is that we need to cast the p vector on ZX plane
|
// //the only difference is that we need to cast the p vector on ZX
|
||||||
|
// plane
|
||||||
// //and use its length instead of r
|
// //and use its length instead of r
|
||||||
// p.y = 0;
|
// p.y = 0;
|
||||||
// float v = FastMath.acos(p.dot(zVec)/(bs.getRadius()*p.length())) / FastMath.PI;
|
// float v = FastMath.acos(p.dot(zVec)/(bs.getRadius()*p.length())) /
|
||||||
|
// FastMath.PI;
|
||||||
// uvTable[index] = new Vector2f(u, v);
|
// uvTable[index] = new Vector2f(u, v);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user