123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- #include "StdAfx.h"
- #include "Vertex.h"
- #include "Polygon.h"
- CVertexArray *CPolygon::pack_verts;
- CPolygon::CPolygon()
- {
- m_pVertexObjects = NULL;
- m_pVertexIndices = NULL;
- m_iPolyIndex = -1;
- m_iVertexCount = 0;
- m_iPolyType = 0;
- m_iCullType = 0;
- m_Face1_UVIndices = NULL;
- m_Face2_UVIndices = NULL;
- m_Face1_TexIndex = -1;
- m_Face2_TexIndex = -1;
- m_pVertexUnks = NULL;
- }
- CPolygon::~CPolygon()
- {
- Destroy();
- }
- void CPolygon::Destroy()
- {
- if (m_Face1_UVIndices)
- {
- delete[] m_Face1_UVIndices;
- m_Face1_UVIndices = NULL;
- }
- if (m_iCullType == 2)
- {
- if (m_Face2_UVIndices)
- {
- delete[] m_Face2_UVIndices;
- m_Face2_UVIndices = NULL;
- }
- }
- if (m_pVertexObjects)
- {
- delete[] m_pVertexObjects;
- m_pVertexObjects = NULL;
- }
- if (m_pVertexIndices)
- {
- delete[] m_pVertexIndices;
- m_pVertexIndices = NULL;
- }
- if (m_pVertexUnks)
- {
- delete[] m_pVertexUnks;
- m_pVertexUnks = NULL;
- }
- m_iVertexCount = 0;
- m_iPolyType = 0;
- m_Face1_TexIndex = -1;
- m_Face2_TexIndex = -1;
- m_iPolyIndex = -1;
- }
- void CPolygon::SetPackVerts(CVertexArray *Verts)
- {
- pack_verts = Verts;
- }
- BOOL CPolygon::UnPack(BYTE** ppData, ULONG iSize)
- {
- UNPACK(short, m_iPolyIndex);
- UNPACK(BYTE, m_iVertexCount);
- UNPACK(BYTE, m_iPolyType);
- UNPACK(DWORD, m_iCullType);
- UNPACK(short, m_Face1_TexIndex);
- UNPACK(short, m_Face2_TexIndex);
- m_pVertexObjects = new CSWVertex*[m_iVertexCount];
- m_pVertexIndices = new WORD[m_iVertexCount];
- m_pVertexUnks = new CSWVertex*[m_iVertexCount];
- for (DWORD i = 0; i < m_iVertexCount; i++)
- {
- WORD Index;
- UNPACK(WORD, Index);
- m_pVertexIndices[i] = Index;
- m_pVertexObjects[i] = (CSWVertex *)((BYTE *)pack_verts->m_pVertexBuffer + Index * CVertexArray::vertex_size);
- }
- if (!(m_iPolyType & 4))
- {
- m_Face1_UVIndices = new BYTE[m_iVertexCount];
- for (DWORD i = 0; i < m_iVertexCount; i++)
- UNPACK(BYTE, m_Face1_UVIndices[i]);
- }
- if ((m_iCullType == 2) && !(m_iPolyType & 8))
- {
- m_Face2_UVIndices = new BYTE[m_iVertexCount];
- for (DWORD i = 0; i < m_iVertexCount; i++)
- UNPACK(BYTE, m_Face2_UVIndices[i]);
- }
- if (m_iCullType == CullNone)
- {
- m_Face2_TexIndex = m_Face1_TexIndex;
- m_Face2_UVIndices = m_Face1_UVIndices;
- }
- #ifdef PRE_TOD
- PACK_ALIGN();
- #endif
- make_plane();
- return TRUE;
- }
- void CPolygon::make_plane()
- {
- // Not meant for human eyes.
- int i;
- CSWVertex *pPin;
- CSWVertex **ppSpread;
- Vector Norm(0, 0, 0);
- for (i = m_iVertexCount - 2, pPin = m_pVertexObjects[0], ppSpread = &m_pVertexObjects[1]; i > 0; i--, ppSpread++)
- {
- Vector V1 = ppSpread[0]->origin - pPin->origin;
- Vector V2 = ppSpread[1]->origin - pPin->origin;
- Norm = Norm + cross_product(V1, V2);
- }
- Norm.normalize();
- float distsum = 0;
- for (i = m_iVertexCount, ppSpread = m_pVertexObjects; i > 0; i--, ppSpread++)
- distsum += Norm.dot_product(ppSpread[0]->origin);
- m_plane.m_dist = -(distsum / m_iVertexCount);
- m_plane.m_normal = Norm;
- }
- BOOL CPolygon::polygon_hits_ray(const Ray& ray, float *time)
- {
- // return peafixed_polygon_hits_ray(ray, time);
- if (!m_iCullType && (m_plane.m_normal.dot_product(ray.m_direction) > 0))
- return FALSE;
- if (!m_plane.compute_time_of_intersection(ray, time))
- return FALSE;
- return point_in_polygon(ray.m_origin + (ray.m_direction * (*time)));
- }
- BOOL CPolygon::peafixed_polygon_hits_ray(const Ray& ray, float *depth)
- {
- if (!m_iCullType && (m_plane.m_normal.dot_product(ray.m_direction) > 0))
- return FALSE;
- float u, v;
- for (int i = 1; i < m_iVertexCount - 1;)
- {
- CSWVertex* CurrVertex1 = m_pVertexObjects[0];
- CSWVertex* CurrVertex2 = m_pVertexObjects[i];
- CSWVertex* CurrVertex3 = m_pVertexObjects[++i];
- if (D3DXIntersectTri(
- (D3DXVECTOR3 *)&CurrVertex1->origin,
- (D3DXVECTOR3 *)&CurrVertex2->origin,
- (D3DXVECTOR3 *)&CurrVertex3->origin,
- (D3DXVECTOR3 *)&ray.m_origin,
- (D3DXVECTOR3 *)&ray.m_direction,
- &u, &v, depth))
- return TRUE;
- }
- return FALSE;
- }
- BOOL CPolygon::point_in_polygon(const Vector& point)
- {
- CSWVertex* LastVertex = m_pVertexObjects[m_iVertexCount - 1];
- for (int i = 0; i < m_iVertexCount; i++)
- {
- CSWVertex* CurrVertex = m_pVertexObjects[i];
- Vector crossp =
- cross_product(m_plane.m_normal, CurrVertex->origin - LastVertex->origin);
- float dotp = crossp.dot_product(point - LastVertex->origin);
- if (dotp < 0.0)
- return FALSE;
- LastVertex = CurrVertex;
- }
- return TRUE;
- }
- //
- // For ray-tracing vertices -- something not in the client.
- //
- CSWVertex *PickVertexFromPolygon(CPolygon *pPoly, const Ray& ray)
- {
- if (!pPoly->m_iCullType && (pPoly->m_plane.m_normal.dot_product(ray.m_direction) > 0))
- return FALSE;
- float curr_depth = FLT_MAX;
- CSWVertex*
- result = NULL;
- for (int i = 1; i < pPoly->m_iVertexCount - 1;)
- {
- CSWVertex* CurrVertex1 = pPoly->m_pVertexObjects[0];
- CSWVertex* CurrVertex2 = pPoly->m_pVertexObjects[i];
- CSWVertex* CurrVertex3 = pPoly->m_pVertexObjects[++i];
- float u, v, depth;
- if (D3DXIntersectTri(
- (D3DXVECTOR3 *)&CurrVertex1->origin,
- (D3DXVECTOR3 *)&CurrVertex2->origin,
- (D3DXVECTOR3 *)&CurrVertex3->origin,
- (D3DXVECTOR3 *)&ray.m_origin,
- (D3DXVECTOR3 *)&ray.m_direction,
- &u, &v, &depth) && (depth < curr_depth))
- {
- Vector u_scalar = (CurrVertex2->origin - CurrVertex1->origin);
- Vector v_scalar = (CurrVertex3->origin - CurrVertex1->origin);
- Vector face_point = CurrVertex1->origin + (u_scalar * u) + (v_scalar * v);
- float vdist1 = (face_point - CurrVertex1->origin).magnitude();
- float vdist2 = (face_point - CurrVertex2->origin).magnitude();
- float vdist3 = (face_point - CurrVertex3->origin).magnitude();
- if (vdist1 <= vdist2)
- result = ((vdist1 <= vdist3) ? CurrVertex1 : CurrVertex3);
- else
- result = ((vdist2 <= vdist3) ? CurrVertex2 : CurrVertex3);
- }
- }
- return result;
- }
|