Ejemplo n.º 1
0
        public void Initialize()
        {
            Dictionary<InternalVertexPair, InternalEdge> edges = new Dictionary<InternalVertexPair, InternalEdge>();

            float TotalArea = 0.0f;

            m_localCenter = IndexedVector3.Zero;
            for (int i = 0; i < m_faces.Count; i++)
            {
                int numVertices = m_faces[i].m_indices.Count;
                int NbTris = numVertices;
                for (int j = 0; j < NbTris; j++)
                {
                    int k = (j + 1) % numVertices;
                    InternalVertexPair vp = new InternalVertexPair(m_faces[i].m_indices[j], m_faces[i].m_indices[k]);
                    InternalEdge edptr = edges[vp];
                    IndexedVector3 edge = m_vertices[vp.m_v1] - m_vertices[vp.m_v0];
                    edge.Normalize();

                    bool found = false;

                    for (int p = 0; p < m_uniqueEdges.Count; p++)
                    {

                        if (MathUtil.IsAlmostZero(m_uniqueEdges[p] - edge) ||
                            MathUtil.IsAlmostZero(m_uniqueEdges[p] + edge))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        m_uniqueEdges.Add(edge);
                    }

                    if (edptr != null)
                    {
                        Debug.Assert(edptr.m_face0 >= 0);
                        Debug.Assert(edptr.m_face1 < 0);
                        edptr.m_face1 = (int)i;
                    }
                    else
                    {
                        InternalEdge ed = new InternalEdge();
                        ed.m_face0 = i;
                        edges[vp] = ed;
                    }
                }
            }

#if USE_CONNECTED_FACES
            for (int i = 0; i < m_faces.Count; i++)
            {
                int numVertices = m_faces[i].m_indices.Count;
                m_faces[i].m_connectedFaces.Resize(numVertices);

                for (int j = 0; j < numVertices; j++)
                {
                    int k = (j + 1) % numVertices;
                    InternalVertexPair vp = new InternalVertexPair(m_faces[i].m_indices[j], m_faces[i].m_indices[k]);
                    InternalEdge edptr = edges[vp];
                    Debug.Assert(edptr != null);
                    Debug.Assert(edptr.m_face0 >= 0);
                    Debug.Assert(edptr.m_face1 >= 0);

                    int connectedFace = (edptr.m_face0 == i) ? edptr.m_face1 : edptr.m_face0;
                    m_faces[i].m_connectedFaces[j] = connectedFace;
                }
            }
#endif
            for (int i = 0; i < m_faces.Count; i++)
            {
                int numVertices = m_faces[i].m_indices.Count;
                int NbTris = numVertices - 2;

                IndexedVector3 p0 = m_vertices[m_faces[i].m_indices[0]];
                for (int j = 1; j <= NbTris; j++)
                {
                    int k = (j + 1) % numVertices;
                    IndexedVector3 p1 = m_vertices[m_faces[i].m_indices[j]];
                    IndexedVector3 p2 = m_vertices[m_faces[i].m_indices[k]];
                    float Area = IndexedVector3.Cross((p0 - p1), (p0 - p2)).Length() * 0.5f;
                    IndexedVector3 Center = (p0 + p1 + p2) / 3.0f;
                    m_localCenter += Area * Center;
                    TotalArea += Area;
                }
            }
            m_localCenter /= TotalArea;


#if TEST_INTERNAL_OBJECTS
	if(true)
	{
		m_radius = float.MaxValue;
		for(int i=0;i<m_faces.Count;i++)
		{
			IndexedVector3 Normal = new IndexedVector3(m_faces[i].m_plane[0], m_faces[i].m_plane[1], m_faces[i].m_plane[2]);
			float dist = Math.Abs(m_localCenter.Dot(Normal) + m_faces[i].m_plane[3]);
			if(dist<m_radius)
            {
				m_radius = dist;
            }
		}

	
		float MinX = float.MaxValue;
		float MinY = float.MaxValue;
		float MinZ = float.MaxValue;
		float MaxX = float.MinValue;
		float MaxY = float.MinValue;
		float MaxZ = float.MinValue;
		for(int i=0; i<m_vertices.Count; i++)
		{
            IndexedVector3 pt = m_vertices[i];
			if(pt.X<MinX)	MinX = pt.X;
			if(pt.X>MaxX)	MaxX = pt.X;
			if(pt.Y<MinY)	MinY = pt.Y;
			if(pt.Y>MaxY)	MaxY = pt.Y;
			if(pt.Z<MinZ)	MinZ = pt.Z;
			if(pt.Z>MaxZ)	MaxZ = pt.Z;
		}
		mC = new IndexedVector3(MaxX+MinX, MaxY+MinY, MaxZ+MinZ);
		mE = new IndexedVector3(MaxX-MinX, MaxY-MinY, MaxZ-MinZ);



//		const float r = m_radius / sqrtf(2.0f);
		float r = m_radius / (float)Math.Sqrt(3.0f);
		int LargestExtent = mE.MaxAxis();
		float Step = (mE[LargestExtent]*0.5f - r)/1024.0f;
		m_extents.X = m_extents.Y = m_extents.Z = r;
		m_extents[LargestExtent] = mE[LargestExtent]*0.5f;
		bool FoundBox = false;
		for(int j=0;j<1024;j++)
		{
			if(TestContainment())
			{
				FoundBox = true;
				break;
			}

			m_extents[LargestExtent] -= Step;
		}
		if(!FoundBox)
		{
			m_extents.X = m_extents.Y = m_extents.Z = r;
		}
		else
		{
			// Refine the box
			float innerStep = (m_radius - r)/1024.0f;
			int e0 = (1<<LargestExtent) & 3;
			int e1 = (1<<e0) & 3;

			for(int j=0;j<1024;j++)
			{
				float Saved0 = m_extents[e0];
				float Saved1 = m_extents[e1];
                m_extents[e0] += innerStep;
                m_extents[e1] += innerStep;

				if(!TestContainment())
				{
					m_extents[e0] = Saved0;
					m_extents[e1] = Saved1;
					break;
				}
			}
		}
	}
#endif

        }
Ejemplo n.º 2
0
        public void Initialize()
        {
            Dictionary <InternalVertexPair, InternalEdge> edges = new Dictionary <InternalVertexPair, InternalEdge>();

            float TotalArea = 0.0f;

            m_localCenter = IndexedVector3.Zero;
            for (int i = 0; i < m_faces.Count; i++)
            {
                int numVertices = m_faces[i].m_indices.Count;
                int NbTris      = numVertices;
                for (int j = 0; j < NbTris; j++)
                {
                    int k = (j + 1) % numVertices;
                    InternalVertexPair vp    = new InternalVertexPair(m_faces[i].m_indices[j], m_faces[i].m_indices[k]);
                    InternalEdge       edptr = edges[vp];
                    IndexedVector3     edge  = m_vertices[vp.m_v1] - m_vertices[vp.m_v0];
                    edge.Normalize();

                    bool found = false;

                    for (int p = 0; p < m_uniqueEdges.Count; p++)
                    {
                        if (MathUtil.IsAlmostZero(m_uniqueEdges[p] - edge) ||
                            MathUtil.IsAlmostZero(m_uniqueEdges[p] + edge))
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        m_uniqueEdges.Add(edge);
                    }

                    if (edptr != null)
                    {
                        Debug.Assert(edptr.m_face0 >= 0);
                        Debug.Assert(edptr.m_face1 < 0);
                        edptr.m_face1 = (int)i;
                    }
                    else
                    {
                        InternalEdge ed = new InternalEdge();
                        ed.m_face0 = i;
                        edges[vp]  = ed;
                    }
                }
            }

#if USE_CONNECTED_FACES
            for (int i = 0; i < m_faces.Count; i++)
            {
                int numVertices = m_faces[i].m_indices.Count;
                m_faces[i].m_connectedFaces.Resize(numVertices);

                for (int j = 0; j < numVertices; j++)
                {
                    int k = (j + 1) % numVertices;
                    InternalVertexPair vp    = new InternalVertexPair(m_faces[i].m_indices[j], m_faces[i].m_indices[k]);
                    InternalEdge       edptr = edges[vp];
                    Debug.Assert(edptr != null);
                    Debug.Assert(edptr.m_face0 >= 0);
                    Debug.Assert(edptr.m_face1 >= 0);

                    int connectedFace = (edptr.m_face0 == i) ? edptr.m_face1 : edptr.m_face0;
                    m_faces[i].m_connectedFaces[j] = connectedFace;
                }
            }
#endif
            for (int i = 0; i < m_faces.Count; i++)
            {
                int numVertices = m_faces[i].m_indices.Count;
                int NbTris      = numVertices - 2;

                IndexedVector3 p0 = m_vertices[m_faces[i].m_indices[0]];
                for (int j = 1; j <= NbTris; j++)
                {
                    int            k      = (j + 1) % numVertices;
                    IndexedVector3 p1     = m_vertices[m_faces[i].m_indices[j]];
                    IndexedVector3 p2     = m_vertices[m_faces[i].m_indices[k]];
                    float          Area   = IndexedVector3.Cross((p0 - p1), (p0 - p2)).Length() * 0.5f;
                    IndexedVector3 Center = (p0 + p1 + p2) / 3.0f;
                    m_localCenter += Area * Center;
                    TotalArea     += Area;
                }
            }
            m_localCenter /= TotalArea;


#if TEST_INTERNAL_OBJECTS
            if (true)
            {
                m_radius = float.MaxValue;
                for (int i = 0; i < m_faces.Count; i++)
                {
                    IndexedVector3 Normal = new IndexedVector3(m_faces[i].m_plane[0], m_faces[i].m_plane[1], m_faces[i].m_plane[2]);
                    float          dist   = Math.Abs(m_localCenter.Dot(Normal) + m_faces[i].m_plane[3]);
                    if (dist < m_radius)
                    {
                        m_radius = dist;
                    }
                }


                float MinX = float.MaxValue;
                float MinY = float.MaxValue;
                float MinZ = float.MaxValue;
                float MaxX = float.MinValue;
                float MaxY = float.MinValue;
                float MaxZ = float.MinValue;
                for (int i = 0; i < m_vertices.Count; i++)
                {
                    IndexedVector3 pt = m_vertices[i];
                    if (pt.X < MinX)
                    {
                        MinX = pt.X;
                    }
                    if (pt.X > MaxX)
                    {
                        MaxX = pt.X;
                    }
                    if (pt.Y < MinY)
                    {
                        MinY = pt.Y;
                    }
                    if (pt.Y > MaxY)
                    {
                        MaxY = pt.Y;
                    }
                    if (pt.Z < MinZ)
                    {
                        MinZ = pt.Z;
                    }
                    if (pt.Z > MaxZ)
                    {
                        MaxZ = pt.Z;
                    }
                }
                mC = new IndexedVector3(MaxX + MinX, MaxY + MinY, MaxZ + MinZ);
                mE = new IndexedVector3(MaxX - MinX, MaxY - MinY, MaxZ - MinZ);



//		const float r = m_radius / sqrtf(2.0f);
                float r             = m_radius / (float)Math.Sqrt(3.0f);
                int   LargestExtent = mE.MaxAxis();
                float Step          = (mE[LargestExtent] * 0.5f - r) / 1024.0f;
                m_extents.X = m_extents.Y = m_extents.Z = r;
                m_extents[LargestExtent] = mE[LargestExtent] * 0.5f;
                bool FoundBox = false;
                for (int j = 0; j < 1024; j++)
                {
                    if (TestContainment())
                    {
                        FoundBox = true;
                        break;
                    }

                    m_extents[LargestExtent] -= Step;
                }
                if (!FoundBox)
                {
                    m_extents.X = m_extents.Y = m_extents.Z = r;
                }
                else
                {
                    // Refine the box
                    float innerStep = (m_radius - r) / 1024.0f;
                    int   e0        = (1 << LargestExtent) & 3;
                    int   e1        = (1 << e0) & 3;

                    for (int j = 0; j < 1024; j++)
                    {
                        float Saved0 = m_extents[e0];
                        float Saved1 = m_extents[e1];
                        m_extents[e0] += innerStep;
                        m_extents[e1] += innerStep;

                        if (!TestContainment())
                        {
                            m_extents[e0] = Saved0;
                            m_extents[e1] = Saved1;
                            break;
                        }
                    }
                }
            }
#endif
        }