/*
* Created on 21 avr. 2004
*
* To change the template for this generated file go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
package syn3d.util;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;
/**
* @author nicolas
*
* To change the template for this generated type comment go to
* Window - Preferences - Java - Code Generation - Code and Comments
*/
public class CommonRoutines {
/**
* Function adapted from the Xith3D project to
* compute vertex normals instead of face normals
*
* Copyright (c) 2004, EADS CCR
*
* Copyright (c) 2003, Xith3D Project Group
* All rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*
*/
public static float[] calculateNormals(float[] coord, int[] idx) {
float normal[] = new float[coord.length];
Vector3f v1 = new Vector3f();
Vector3f v2 = new Vector3f();
Vector3f faceNormal = new Vector3f();
Point3f a = new Point3f();
Point3f b = new Point3f();
Point3f c = new Point3f();
// step through all the faces
for (int i=0; i<idx.length; i+=3) {
int ja = idx[i] * 3;
a.set(coord[ja],coord[ja+1],coord[ja+2]);
int jb = idx[i+1] * 3;
b.set(coord[jb],coord[jb+1],coord[jb+2]);
int jc = idx[i+2] * 3;
c.set(coord[jc],coord[jc+1],coord[jc+2]);
v1.sub(b, a);
v2.sub(c, a);
faceNormal.cross(v1, v2);
if (faceNormal.length()==0) continue;
faceNormal.normalize();
// suppose the faces are nearly flat, with small deflection
// check the scalar product is >0, so each face is the same orientation
// otherwise, reverse the normal
float scalara = normal[ja] * faceNormal.x + normal[ja+1] * faceNormal.y + normal[ja+2] * faceNormal.z;
float scalarb = normal[jb] * faceNormal.x + normal[jb+1] * faceNormal.y + normal[jb+2] * faceNormal.z;
float scalarc = normal[jc] * faceNormal.x + normal[jc+1] * faceNormal.y + normal[jc+2] * faceNormal.z;
// don't know which point to check, suppose it wouldbe reversed on all points
// hack : sum them all, but it doesn not mean much mathematically
if (scalara + scalarb + scalarc <0) {
faceNormal.x = -faceNormal.x;
faceNormal.y = -faceNormal.y;
faceNormal.z = -faceNormal.z;
}
// Sum the normals on each vertex, re-normalize at the end
normal[ja] += faceNormal.x; normal[ja+1] += faceNormal.y; normal[ja+2] += faceNormal.z;
normal[jb] += faceNormal.x; normal[jb+1] += faceNormal.y; normal[jb+2] += faceNormal.z;
normal[jc] += faceNormal.x; normal[jc+1] += faceNormal.y; normal[jc+2] += faceNormal.z;
}
return normal;
}
// Same function using double, but normals are always floats
/** @see same function using floats */
public static float[] calculateNormals(double[] coord, int[] idx) {
float normal[] = new float[coord.length];
Vector3d v1 = new Vector3d();
Vector3d v2 = new Vector3d();
Vector3d faceNormal = new Vector3d();
Point3d a = new Point3d();
Point3d b = new Point3d();
Point3d c = new Point3d();
// step through all the faces
for (int i=0; i<idx.length; i+=3) {
int ja = idx[i] * 3;
a.set(coord[ja],coord[ja+1],coord[ja+2]);
int jb = idx[i+1] * 3;
b.set(coord[jb],coord[jb+1],coord[jb+2]);
int jc = idx[i+2] * 3;
c.set(coord[jc],coord[jc+1],coord[jc+2]);
v1.sub(b, a);
v2.sub(c, a);
faceNormal.cross(v1, v2);
if (faceNormal.length()==0) continue;
faceNormal.normalize();
// suppose the faces are nearly flat, with small deflection
// check the scalar product is >0, so each face is the same orientation
// otherwise, reverse the normal
double scalara = normal[ja] * faceNormal.x + normal[ja+1] * faceNormal.y + normal[ja+2] * faceNormal.z;
double scalarb = normal[jb] * faceNormal.x + normal[jb+1] * faceNormal.y + normal[jb+2] * faceNormal.z;
double scalarc = normal[jc] * faceNormal.x + normal[jc+1] * faceNormal.y + normal[jc+2] * faceNormal.z;
// don't know which point to check, suppose it wouldbe reversed on all points
// hack : sum them all, but it doesn not mean much mathematically
if (scalara + scalarb + scalarc <0) {
faceNormal.x = -faceNormal.x;
faceNormal.y = -faceNormal.y;
faceNormal.z = -faceNormal.z;
}
// Sum the normals on each vertex, re-normalize at the end
normal[ja] += (float)faceNormal.x; normal[ja+1] += (float)faceNormal.y; normal[ja+2] += (float)faceNormal.z;
normal[jb] += (float)faceNormal.x; normal[jb+1] += (float)faceNormal.y; normal[jb+2] += (float)faceNormal.z;
normal[jc] += (float)faceNormal.x; normal[jc+1] += (float)faceNormal.y; normal[jc+2] += (float)faceNormal.z;
}
return normal;
}
}