开发者

Code for finding the vertex normals in Java?

I have this code in C from this source:

#import <Foundation/Foundation.h>
#import "OpenGLCommon.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSMutableString *result = [NSMutableString string];

    static const Vertex3D vertices[]= {
        {0, -0.525731, 0.850651},             // vertices[0]
        {0.850651, 0, 0.525731},              // vertices[1]
        {0.850651, 0, -0.525731},             // vertices[2]
        {-0.850651, 0, -0.525731},            // vertices[3]
        {-0.850651, 0, 0.525731},             // vertices[4]
        {-0.525731, 0.850651, 0},             // vertices[5]
        {0.525731, 0.850651, 0},              // vertices[6]
        {0.525731, -0.850651, 0},             // vertices[7]
        {-0.525731, -0.850651, 0},            // vertices[8]
        {0, -0.525731, -0.850651},            // vertices[9]
        {0, 0.525731, -0.850651},             // vertices[10]
        {0, 0.525731, 0.850651}               // vertices[11]
    };

    static const GLubyte icosahedronFaces[] = {
        1, 2, 6,
        1, 7, 2,
        3, 4, 5,
        4, 3, 8,
        6, 5, 11,
        5, 6, 10,
        9, 10, 2,
     开发者_JAVA百科   10, 9, 3,
        7, 8, 9,
        8, 7, 0,
        11, 0, 1,
        0, 11, 4,
        6, 2, 10,
        1, 6, 11,
        3, 5, 10,
        5, 4, 11,
        2, 7, 9,
        7, 1, 0,
        3, 9, 8,
        4, 8, 0,
    };

    Vector3D *surfaceNormals = calloc(20, sizeof(Vector3D));

    // Calculate the surface normal for each triangle

    for (int i = 0; i < 20; i++)
    {
        Vertex3D vertex1 = vertices[icosahedronFaces[(i*3)]];
        Vertex3D vertex2 = vertices[icosahedronFaces[(i*3)+1]];
        Vertex3D vertex3 = vertices[icosahedronFaces[(i*3)+2]];
        Triangle3D triangle = Triangle3DMake(vertex1, vertex2, vertex3);
        Vector3D surfaceNormal = Triangle3DCalculateSurfaceNormal(triangle);
        Vector3DNormalize(&surfaceNormal);
        surfaceNormals[i] = surfaceNormal;
    }

    Vertex3D *normals = calloc(12, sizeof(Vertex3D));
    [result appendString:@"static const Vector3D normals[] = {\n"];
    for (int i = 0; i < 12; i++)
    {
        int faceCount = 0;
        for (int j = 0; j < 20; j++)
        {
            BOOL contains = NO;
            for (int k = 0; k < 3; k++)
            {
                if (icosahedronFaces[(j * 3) + k] == i)
                    contains = YES;
            }
            if (contains)
            {
                faceCount++;
                normals[i] = Vector3DAdd(normals[i], surfaceNormals[j]);
            }
        }

        normals[i].x /= (GLfloat)faceCount;
        normals[i].y /= (GLfloat)faceCount;
        normals[i].z /= (GLfloat)faceCount;
        [result appendFormat:@"\t{%f, %f, %f},\n", normals[i].x, normals[i].y, normals[i].z];
    }
    [result appendString:@"};\n"];
    NSLog(result);
    [pool drain];
    return 0;
}

Can some one point me to Java code that does the same thing as above? I would also need to modify it so that it works not just for isohadron but for any vertex array with associated index array.


This works for any triangle based mesh.

for(int i = 0; i < indices.Length; i += 3)
{
   Vector3 v0 = vertices[indicies[i]].Position;
   Vector3 v1 = vertices[indicies[i+1]].Position;
   Vector3 v2 = vertices[indicies[i+2]].Position;

   Vector3 normal = Vector3.Normalize(Vector3.Cross(v2 - v0, v1 - v0));

   vertices[indicies[i]].Normal += normal;
   vertices[indicies[i+1]].Normal += normal;
   vertices[indicies[i+2]].Normal += normal;
}
for(int i = 0; i < vertices.Length; i++)
{
   vertices[i].Normal = Vector3.Normalize(vertices[i].Normal);
}

Heres a stripped down version of the Vector3 struct

public struct Vector3
{
   float X, Y, Z;

   public Vector3(float x, float y, float z)
   {
      X = x; Y = y; Z = z;
   }

   public static Vector3 Cross(Vector3 v1, Vector3 v2)
   {
      Vector3 result;
      result.X = (v1.Y * v2.Z) - (v1.Z * v2.Y);
      result.Y = (v1.Z * v2.X) - (v1.X * v2.Z);
      result.Z = (v1.X * v2.Y) - (v1.Y * v2.X);
      return result;
   }
   public static Vector3 Normalize(Vector3 v1)
   {
       float length = v1.X * v1.X + v1.Y * v1.Y + v1.Z * v1.Z;
       length = Math.Sqrt(length);
       v1.X /= length; v1.Y /= length; v1.Z /= length;
   }
}

I hope that helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜