From 11b250ffe173baf4e3efbc459524e88978e87965 Mon Sep 17 00:00:00 2001 From: "Kae..pl" Date: Mon, 22 Aug 2011 21:10:52 +0000 Subject: [PATCH] Support for texture's tube projection. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8059 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../textures/UVCoordinatesGenerator.java | 12 +-- .../textures/UVProjectionGenerator.java | 99 +++++++++++++++---- 2 files changed, 86 insertions(+), 25 deletions(-) diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java index 7746431bd..221d799b3 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java @@ -114,8 +114,8 @@ public class UVCoordinatesGenerator { uvCoordinates = UVProjectionGenerator.cubeProjection(mesh, bb); break; case PROJECTION_TUBE: - // TODO: implement - // uvCoordinates = UVProjectionGenerator.tubeProjection(mesh, bb); + BoundingTube bt = UVCoordinatesGenerator.getBoundingTube(mesh); + uvCoordinates = UVProjectionGenerator.tubeProjection(mesh, bt); break; case PROJECTION_SPHERE: uvCoordinates = UVProjectionGenerator.sphereProjection(mesh, bb); @@ -289,11 +289,11 @@ public class UVCoordinatesGenerator { maxx = x > maxx ? x : maxx; minx = x < minx ? x : minx; maxy = y > maxy ? y : maxy; - miny = x < miny ? y : miny; - maxz = x > maxz ? z : maxz; - minz = x < minz ? z : minz; + miny = y < miny ? y : miny; + maxz = z > maxz ? z : maxz; + minz = z < minz ? z : minz; } - center.divideLocal(limit); + center.divideLocal(limit/3); float radius = Math.max(maxx - minx, maxy - miny) * 0.5f; return new BoundingTube(radius, maxz - minz, center); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVProjectionGenerator.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVProjectionGenerator.java index 8bd28491c..aa2060c1a 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVProjectionGenerator.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVProjectionGenerator.java @@ -3,22 +3,26 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.FloatBuffer; import com.jme3.bounding.BoundingBox; +import com.jme3.math.FastMath; import com.jme3.math.Triangle; import com.jme3.math.Vector3f; import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer; import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTube; /** * This class helps with projection calculations. + * * @author Marcin Roguski (Kaelthas) */ /* package */class UVProjectionGenerator { /** * Flat projection for 2D textures. + * * @param mesh - * mesh that is to be projected + * mesh that is to be projected * @param bb - * the bounding box for projecting + * the bounding box for projecting * @return UV coordinates after the projection */ 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); 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]; for (int i = 0, j = 0; i < positions.limit(); i += 3, j += 2) { 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. + * * @param mesh - * mesh that is to be projected + * mesh that is to be projected * @param bb - * the bounding box for projecting + * the bounding box for projecting * @return UV coordinates after the projection */ 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. + * * @param mesh - * mesh that is to be projected - * @param bb - * the bounding box for projecting + * mesh that is to be projected + * @param bt + * the bounding tube for projecting * @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); + + //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 +// Map> lowestAnglesUVCoordinatesMap = new HashMap>(); + 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; - public static float[] tubeProjection(Mesh mesh, BoundingTube bb) { - return null;// TODO: implement + // 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-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. + * * @param mesh - * mesh that is to be projected + * mesh that is to be projected * @param bb - * the bounding box for projecting + * the bounding box for projecting * @return UV coordinates after the projection */ 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 zVec = new Vector3f(); // 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(); // BoundingSphere bs = this.getBoundingSphere(geom.getMesh()); // 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()); // Vector3f center = bs.getCenter(); // 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