예제 #1
0
			public bool Equals( btInternalVertexPair other )
			{
				return m_v0 == other.m_v0 & m_v1 == other.m_v1;
			}
예제 #2
0
		public void initialize()
		{

			btHashMap<btInternalVertexPair, btInternalEdge> edges = new btHashMap<btInternalVertexPair, btInternalEdge>();

			double TotalArea = 0.0f;
			btVector3[] arr_vertices = m_vertices.InternalArray;
			m_localCenter.setValue( 0, 0, 0 );
			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;
					btInternalVertexPair vp = new btInternalVertexPair( m_faces[i].m_indices[j], m_faces[i].m_indices[k] );
					btInternalEdge edptr = edges.find( ref vp );
					btVector3 edge; arr_vertices[vp.m_v1].Sub( ref arr_vertices[vp.m_v0], out edge );
					edge.normalize();

					bool found = false;

					for( int p = 0; p < m_uniqueEdges.Count; p++ )
					{
						btVector3 tmp;
						m_uniqueEdges[p].Sub( ref edge, out tmp );
						if( btVector3.IsAlmostZero( ref tmp ) ) { found = true; break; }
						m_uniqueEdges[p].Add( ref edge, out tmp );
						if( btVector3.IsAlmostZero( ref tmp ) ) { found = true; break; }
					}

					if( !found )
					{
						m_uniqueEdges.Add( edge );
					}
					/* this is broken; it did not port correctly... */
					Debugger.Break();
					if( edptr.m_face0 == edptr.m_face1 )
					{
						btInternalEdge ed;
						ed.m_face0 = (short)i;
						ed.m_face1 = (short)j;
						edges.insert( ref vp, ref ed );
					}
					else
					{
						Debug.Assert( edptr.m_face0 >= 0 );
						Debug.Assert( edptr.m_face1 < 0 );
						edptr.m_face1 = (short)i;
					}
				}
			}

#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;
					btInternalVertexPair vp( m_faces[i].m_indices[j], m_faces[i].m_indices[k]);
			btInternalEdge* edptr = edges.find( vp );
			Debug.Assert( edptr );
			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//USE_CONNECTED_FACES

			for( int i = 0; i < m_faces.Count; i++ )
			{
				int numVertices = m_faces[i].m_indices.Count;
				int NbTris = numVertices - 2;

				btVector3 p0 = m_vertices[m_faces[i].m_indices[0]];
				for( int j = 1; j <= NbTris; j++ )
				{
					int k = ( j + 1 ) % numVertices;
					btVector3 p1 = m_vertices[m_faces[i].m_indices[j]];
					btVector3 p2 = m_vertices[m_faces[i].m_indices[k]];
					btVector3 tmp;
					btVector3 tmp2;
					btVector3 tmp3;
					p0.Sub( ref p1, out tmp );
					p0.Sub( ref p2, out tmp2 );
					tmp.cross( ref tmp2, out tmp3 );

					double Area = ( tmp3 ).length() * 0.5f;
					p0.Add( ref p1, out tmp );
					tmp.Add( ref p2, out tmp );
					btVector3 Center; tmp.Div( 3.0, out Center );
					m_localCenter.AddScale( ref Center, Area, out m_localCenter );
					TotalArea += Area;
				}
			}
			m_localCenter.Div( TotalArea, out m_localCenter );
			//m_localCenter /= TotalArea;




#if TEST_INTERNAL_OBJECTS
			if( true )
			{
				m_radius = double.MaxValue;
				for( int i = 0; i < m_faces.Count; i++ )
				{
					btVector3 Normal = new btVector3( m_faces[i].m_plane[0], m_faces[i].m_plane[1], m_faces[i].m_plane[2] );
					double dist = btScalar.btFabs( m_localCenter.dot( ref Normal ) + m_faces[i].m_plane[3] );
					if( dist < m_radius )
						m_radius = dist;
				}

				double MinX = double.MaxValue;
				double MinY = double.MaxValue;
				double MinZ = double.MaxValue;
				double MaxX = double.MinValue;
				double MaxY = double.MinValue;
				double MaxZ = double.MinValue;
				unsafe
				{
					fixed ( btVector3* _pt = arr_vertices )
					{
						for( int i = 0; i < m_vertices.Count; i++ )
						{
							btVector3* pt = _pt + 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.setValue( MaxX + MinX, MaxY + MinY, MaxZ + MinZ );
				mE.setValue( MaxX - MinX, MaxY - MinY, MaxZ - MinZ );



				//		double r = m_radius / sqrtf(2.0f);
				double r = m_radius / btScalar.btSqrt( 3.0f );
				int LargestExtent = mE.maxAxis();
				double Step = ( mE[LargestExtent] * 0.5f - r ) / 1024.0f;
				m_extents[0] = m_extents[1] = m_extents[2] = 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[0] = m_extents[1] = m_extents[2] = r;
				}
				else
				{
					// Refine the box
					double Step2 = ( m_radius - r ) / 1024.0f;
					int e0 = ( 1 << LargestExtent ) & 3;
					int e1 = ( 1 << e0 ) & 3;

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

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