Example #1
0
        // Calculates the vertex normals corresponding to the smoothing group
        // settings for each face of a mesh.
        //
        // \param mesh      A pointer to the mesh to calculate the normals for.
        // \param normals   A pointer to a buffer to store the calculated
        //                  normals. The buffer must have the size:
        //                  3*3*sizeof(float)*mesh.nfaces.
        //
        // To allocate the normal buffer do for example the following:
        // \code
        //  Lib3dsVector *normals = malloc(3*3*sizeof(float)*mesh.nfaces);
        // \endcode
        //
        // To access the normal of the i-th vertex of the j-th face do the
        // following:
        // \code
        //   normals[3*j+i]
        // \endcode
        public static void lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh mesh, float[][] normals)
        {
            if (mesh.nfaces == 0)
            {
                return;
            }

            Lib3dsFaces[] fl = new Lib3dsFaces[mesh.nvertices];
            Lib3dsFaces[] fa = new Lib3dsFaces[3 * mesh.nfaces];
            for (int i = 0; i < fa.Length; i++)
            {
                fa[i] = new Lib3dsFaces();
            }

            for (int i = 0; i < mesh.nfaces; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    Lib3dsFaces l = fa[3 * i + j];
                    float[]     p = new float[3], q = new float[3], n = new float[3];
                    float       len, weight;

                    l.index = i;
                    l.next  = fl[mesh.faces[i].index[j]];
                    fl[mesh.faces[i].index[j]] = l;

                    lib3ds_vector_sub(p, mesh.vertices[mesh.faces[i].index[j < 2?j + 1:0]], mesh.vertices[mesh.faces[i].index[j]]);
                    lib3ds_vector_sub(q, mesh.vertices[mesh.faces[i].index[j > 0?j - 1:2]], mesh.vertices[mesh.faces[i].index[j]]);
                    lib3ds_vector_cross(n, p, q);
                    len = lib3ds_vector_length(n);
                    if (len > 0)
                    {
                        weight = (float)Math.Atan2(len, lib3ds_vector_dot(p, q));
                        lib3ds_vector_scalar_mul(l.normal, n, weight / len);
                    }
                    else
                    {
                        lib3ds_vector_zero(l.normal);
                    }
                }
            }

            for (int i = 0; i < mesh.nfaces; i++)
            {
                Lib3dsFace f = mesh.faces[i];
                for (int j = 0; j < 3; j++)
                {
                    float[]     n = new float[3];
                    Lib3dsFaces p;
                    Lib3dsFace  pf;

                    Debug.Assert(mesh.faces[i].index[j] < mesh.nvertices);

                    if (f.smoothing_group != 0)
                    {
                        uint smoothing_group = f.smoothing_group;

                        lib3ds_vector_zero(n);
                        for (p = fl[mesh.faces[i].index[j]]; p != null; p = p.next)
                        {
                            pf = mesh.faces[p.index];
                            if ((pf.smoothing_group & f.smoothing_group) != 0)
                            {
                                smoothing_group |= pf.smoothing_group;
                            }
                        }

                        for (p = fl[mesh.faces[i].index[j]]; p != null; p = p.next)
                        {
                            pf = mesh.faces[p.index];
                            if ((smoothing_group & pf.smoothing_group) != 0)
                            {
                                lib3ds_vector_add(n, n, p.normal);
                            }
                        }
                    }
                    else
                    {
                        lib3ds_vector_copy(n, fa[3 * i + j].normal);
                    }

                    lib3ds_vector_normalize(n);
                    lib3ds_vector_copy(normals[3 * i + j], n);
                }
            }
        }
Example #2
0
		// Calculates the vertex normals corresponding to the smoothing group
		// settings for each face of a mesh.
		//
		// \param mesh      A pointer to the mesh to calculate the normals for.
		// \param normals   A pointer to a buffer to store the calculated
		//                  normals. The buffer must have the size:
		//                  3*3*sizeof(float)*mesh.nfaces.
		//
		// To allocate the normal buffer do for example the following:
		// \code
		//  Lib3dsVector *normals = malloc(3*3*sizeof(float)*mesh.nfaces);
		// \endcode
		//
		// To access the normal of the i-th vertex of the j-th face do the
		// following:
		// \code
		//   normals[3*j+i]
		// \endcode
		public static void lib3ds_mesh_calculate_vertex_normals(Lib3dsMesh mesh, float[][] normals)
		{
			if(mesh.nfaces==0) return;

			Lib3dsFaces[] fl=new Lib3dsFaces[mesh.nvertices];
			Lib3dsFaces[] fa=new Lib3dsFaces[3*mesh.nfaces];
			for(int i=0; i<fa.Length; i++) fa[i]=new Lib3dsFaces();

			for(int i=0; i<mesh.nfaces; i++)
			{
				for(int j=0; j<3; j++)
				{
					Lib3dsFaces l=fa[3*i+j];
					float[] p=new float[3], q=new float[3], n=new float[3];
					float len, weight;

					l.index=i;
					l.next=fl[mesh.faces[i].index[j]];
					fl[mesh.faces[i].index[j]]=l;

					lib3ds_vector_sub(p, mesh.vertices[mesh.faces[i].index[j<2?j+1:0]], mesh.vertices[mesh.faces[i].index[j]]);
					lib3ds_vector_sub(q, mesh.vertices[mesh.faces[i].index[j>0?j-1:2]], mesh.vertices[mesh.faces[i].index[j]]);
					lib3ds_vector_cross(n, p, q);
					len=lib3ds_vector_length(n);
					if(len>0)
					{
						weight=(float)Math.Atan2(len, lib3ds_vector_dot(p, q));
						lib3ds_vector_scalar_mul(l.normal, n, weight/len);
					}
					else lib3ds_vector_zero(l.normal);
				}
			}

			for(int i=0; i<mesh.nfaces; i++)
			{
				Lib3dsFace f=mesh.faces[i];
				for(int j=0; j<3; j++)
				{
					float[] n=new float[3];
					Lib3dsFaces p;
					Lib3dsFace pf;

					Debug.Assert(mesh.faces[i].index[j]<mesh.nvertices);

					if(f.smoothing_group!=0)
					{
						uint smoothing_group=f.smoothing_group;

						lib3ds_vector_zero(n);
						for(p=fl[mesh.faces[i].index[j]]; p!=null; p=p.next)
						{
							pf=mesh.faces[p.index];
							if((pf.smoothing_group&f.smoothing_group)!=0) smoothing_group|=pf.smoothing_group;
						}

						for(p=fl[mesh.faces[i].index[j]]; p!=null; p=p.next)
						{
							pf=mesh.faces[p.index];
							if((smoothing_group&pf.smoothing_group)!=0) lib3ds_vector_add(n, n, p.normal);
						}
					}
					else lib3ds_vector_copy(n, fa[3*i+j].normal);

					lib3ds_vector_normalize(n);
					lib3ds_vector_copy(normals[3*i+j], n);
				}
			}
		}