Files
firestorm/Gameleap/code/mw4/Libraries/mlr/MLRIndexedTriangleCloud.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1024 lines
29 KiB
C++

#include "MLRHeaders.hpp"
#if !defined(MLR_MLRCLIPTRICK_HPP)
#include <MLR\MLRClipTrick.hpp>
#endif
#if !defined(MLR_MLRINDEXEDTRIANGLECLOUD_HPP)
#include <MLR\MLRIndexedTriangleCloud.hpp>
#endif
extern DWORD gShowClippedPolys;
extern WORD *indexOffset; // [MidLevelRenderer::Max_Number_Vertices_Per_Effect]
//#############################################################################
//#################### MLRIndexedTriangleCloud ##########################
//#############################################################################
DynamicArrayOf<WORD>
*MLRIndexedTriangleCloud::clipExtraIndex;
DynamicArrayOf<Vector2DScalar>
*MLRIndexedTriangleCloud::clipExtraTexCoords;
DynamicArrayOf<BYTE>
*MLRIndexedTriangleCloud::visibleIndexedVertices;
MLRIndexedTriangleCloud::ClassData*
MLRIndexedTriangleCloud::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRIndexedTriangleCloud::InitializeClass()
{
Verify(!DefaultData);
Verify(gos_GetCurrentHeap() == StaticHeap);
DefaultData =
new ClassData(
MLRIndexedTriangleCloudClassID,
"MidLevelRenderer::MLRIndexedTriangleCloud",
MLRTriangleCloud::DefaultData
);
Register_Object(DefaultData);
clipExtraIndex = new DynamicArrayOf<WORD> (Limits::Max_Number_Vertices_Per_Effect);
Register_Pointer(clipExtraIndex);
clipExtraTexCoords = new DynamicArrayOf<Vector2DScalar> (Limits::Max_Number_Vertices_Per_Effect);
Register_Pointer(clipExtraTexCoords);
visibleIndexedVertices = new DynamicArrayOf<BYTE> (Limits::Max_Number_Vertices_Per_Effect);
Register_Pointer(visibleIndexedVertices);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRIndexedTriangleCloud::TerminateClass()
{
Unregister_Pointer(clipExtraIndex);
delete clipExtraIndex;
Unregister_Pointer(clipExtraTexCoords);
delete clipExtraTexCoords;
Unregister_Pointer(visibleIndexedVertices);
delete visibleIndexedVertices;
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRIndexedTriangleCloud::MLRIndexedTriangleCloud(int nr) :
MLRTriangleCloud(nr)
{
Verify(gos_GetCurrentHeap() == EffectHeap);
usedNrOfPoints = NULL;
Check_Pointer(this);
drawMode = SortData::TriIndexedList;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRIndexedTriangleCloud::~MLRIndexedTriangleCloud()
{
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRIndexedTriangleCloud::SetData
(
const int *tri_count,
const int *point_count,
const WORD *index_data,
const Stuff::Point3D *point_data,
const Stuff::RGBAColor *color_data,
const Vector2DScalar *uv_data
)
{
Check_Pointer(this);
usedNrOfTriangles = tri_count;
usedNrOfPoints = point_count;
Verify(*usedNrOfTriangles <= maxNrOf);
index = index_data;
points = point_data;
colors = color_data;
texCoords = uv_data;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRIndexedTriangleCloud::Draw (DrawEffectInformation *dInfo, GOSVertexPool *allVerticesToDraw, MLRSorter *sorter)
{
Check_Object(this);
#ifdef LAB_ONLY
if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw->GetLast() + *usedNrOfPoints)
{
SPEWALWAYS((0, "Not drawing MLRIndexedTriangleCloud. Too many vertices! Raid a bug to Art!"));
return;
}
if(Limits::Max_Number_Vertices_Per_Frame < allVerticesToDraw->GetLastIndex() + *usedNrOfTriangles * 3)
{
SPEWALWAYS((0, "Not drawing MLRIndexedTriangleCloud. Too many indices! Raid a bug to Art!"));
return;
}
#endif
worldToEffect.Invert(*dInfo->effectToWorld);
Vector4D *v4 = transformedCoords->GetData();
for(int k=0;k<*usedNrOfPoints;k++, v4++)
{
v4->Multiply(points[k], effectToClipMatrix);
(*clipPerVertex)[k].Clip4dVertex(v4);
}
if( Clip(dInfo->clippingFlags, allVerticesToDraw, false) )
{
sorter->AddEffect(this, dInfo->state);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MLRIndexedTriangleCloud::Draw (ToBeDrawnPrimitive *tbdp, MLRSorter *sorter)
{
Check_Object(this);
Vector4D *v4 = transformedCoords->GetData();
for(int k=0;k<*usedNrOfPoints;k++, v4++)
{
v4->Multiply(points[k], tbdp->shapeToClipMatrix);
(*clipPerVertex)[k].Clip4dVertex(v4);
}
int index = -1;
if( Clip(tbdp->clippingFlags, tbdp->allVerticesToDraw, true) )
{
sorter->AddEffect(this, tbdp->state, index);
}
return index;
}
static MLRClippingState theAnd, theOr, theTest;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
MLRIndexedTriangleCloud::Clip(MLRClippingState clippingFlags, GOSVertexPool *vt, bool db)
{
int myNumberUsedClipVertex, myNumberUsedClipIndex, myNumberUsedClipLength;
myNumberUsedClipVertex = 0;
myNumberUsedClipIndex = 0;
myNumberUsedClipLength = 0;
Verify(*usedNrOfTriangles > 0);
//
//------------------------
// Handle the indexed case
//------------------------
//
memset(visibleIndexedVertices->GetData(), 0, *usedNrOfPoints);
//
//-----------------------------------------------------------------
// Step through each polygon, making sure that we don't try to clip
// backfaced polygons
//-----------------------------------------------------------------
//
int i, j, k, k0, k1, *cs = (int *)clipPerVertex->GetData();
WORD l;
int index0, index1, index2, ret = 0;
int mask;
Scalar a = 0.0f;
for(i=0,j=0;i<*usedNrOfTriangles;j+=3,++i)
{
// if(IsOn(i) == false)
// {
// continue;
// }
index0 = index[j];
index1 = index[j+1];
index2 = index[j+2];
//
//---------------------------------------------------------------
// Test each vertex of the polygon against the allowed clipping
// planes, and accumulate status for which planes always clip and
// which planes clipped at least once
//---------------------------------------------------------------
//
theAnd = cs[index0];
theOr = theAnd;
theAnd &= (cs[index1] & cs[index2]);
theOr |= (cs[index1] | cs[index2]);
//
//-------------------------------------------------------------------
// If any bit is set for all vertices, then the polygon is completely
// outside the viewing space and we don't have to draw it. On the
// other hand, if no bits at all were ever set, we can do a trivial
// accept of the polygon
//-------------------------------------------------------------------
//
if (theAnd != 0)
{
testList[i] = 0;
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButOutside, PolysClippedButOutside+1);
#endif
}
else if (theOr == 0)
{
testList[i] = 1;
ret++;
(*visibleIndexedVertices)[index0] = 1;
(*visibleIndexedVertices)[index1] = 1;
(*visibleIndexedVertices)[index2] = 1;
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButInside, PolysClippedButInside+1);
#endif
}
//
//-----------------------------------------------------------------
// It is not a trivial case, so we must now do real clipping on the
// polygon
//-----------------------------------------------------------------
//
else
{
WORD numberVerticesPerPolygon = 0;
//
//---------------------------------------------------------------
// Handle the case of a single clipping plane by stepping through
// the vertices and finding the edge it originates
//---------------------------------------------------------------
//
bool firstIsIn;
if (theOr.GetNumberOfSetBits() == 1)
{
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButOnePlane, PolysClippedButOnePlane+1);
#endif
for(k=j;k<j+3;k++)
{
k0 = index[k];
k1 = index[(k+1) < j+3 ? k+1 : j];
//
//----------------------------------------------------
// If this vertex is inside the viewing space, copy it
// directly to the clipping buffer
//----------------------------------------------------
//
int clipped_index =
myNumberUsedClipVertex + numberVerticesPerPolygon;
theTest = cs[k0];
if(theTest == 0)
{
firstIsIn = true;
(*clipExtraCoords)[clipped_index] = (*transformedCoords)[k0];
(*clipExtraColors)[clipped_index] = colors[k0];
(*clipExtraTexCoords)[clipped_index] = texCoords[k0];
numberVerticesPerPolygon++;
clipped_index++;
//
//-------------------------------------------------------
// We don't need to clip this edge if the next vertex is
// also in the viewing space, so just move on to the next
// vertex
//-------------------------------------------------------
//
if(cs[k1] == 0)
{
continue;
}
}
//
//---------------------------------------------------------
// This vertex is outside the viewing space, so if the next
// vertex is also outside the viewing space, no clipping is
// needed and we throw this vertex away. Since only one
// clipping plane is involved, it must be in the same space
// as the first vertex
//---------------------------------------------------------
//
else
{
firstIsIn = false;
if(cs[k1] != 0)
{
Verify(cs[k1] == cs[k0]);
continue;
}
}
//
//--------------------------------------------------
// We now find the distance along the edge where the
// clipping plane will intersect
//--------------------------------------------------
//
int ct = 0;
mask = 1;
theTest |= cs[k1];
//
//-----------------------------------------------------
// Find the boundary conditions that match our clipping
// plane
//-----------------------------------------------------
//
for (l=0; l<MLRClippingState::NextBit; l++)
{
if(theTest.IsClipped(mask))
{
// GetDoubleBC(l, bc0, bc1, transformedCoords[k0], transformedCoords[k1]);
//
//-------------------------------------------
// Find the clipping interval from bc0 to bc1
//-------------------------------------------
//
if(firstIsIn==true)
{
a = GetLerpFactor(l, (*transformedCoords)[k0], (*transformedCoords)[k1]);
}
else
{
a = GetLerpFactor(l, (*transformedCoords)[k1], (*transformedCoords)[k0]);
}
Verify(a >= 0.0f && a <= 1.0f);
ct = l;
break;
}
mask <<= 1;
}
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
if(firstIsIn==true)
{
(*clipExtraCoords)[clipped_index].Lerp(
(*transformedCoords)[k0],
(*transformedCoords)[k1],
a
);
DoClipTrick((*clipExtraCoords)[clipped_index], ct);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
(*clipExtraColors)[clipped_index].Lerp(
colors[k0],
colors[k1],
a
);
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
(*clipExtraTexCoords)[clipped_index].Lerp
(
texCoords[k0],
texCoords[k1],
a
);
}
else
{
(*clipExtraCoords)[clipped_index].Lerp(
(*transformedCoords)[k1],
(*transformedCoords)[k0],
a
);
DoClipTrick((*clipExtraCoords)[clipped_index], ct);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
(*clipExtraColors)[clipped_index].Lerp(
colors[k1],
colors[k0],
a
);
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
(*clipExtraTexCoords)[clipped_index].Lerp
(
texCoords[k1],
texCoords[k0],
a
);
}
//
//--------------------------------
// Bump the polygon's vertex count
//--------------------------------
//
numberVerticesPerPolygon++;
}
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
#ifdef _ARMOR
(*clipExtraLength)[myNumberUsedClipLength] &= ~0x8000;
#endif
}
//
//---------------------------------------------------------------
// We have to handle multiple planes. We do this by creating two
// buffers and we switch between them as we clip plane by plane
//---------------------------------------------------------------
//
else
{
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButGOnePlane, PolysClippedButGOnePlane+1);
#endif
ClipData2 srcPolygon, dstPolygon;
int dstBuffer = 1;
srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
//
//----------------------------------------------------------
// unravel and copy the original data into the source buffer
//----------------------------------------------------------
//
for(k=j,l=0;k<j+3;k++,l++)
{
int indexK = index[k];
srcPolygon.coords[l] = (*transformedCoords)[indexK];
srcPolygon.colors[l] = colors[indexK];
srcPolygon.texCoords[l] = texCoords[indexK];
srcPolygon.clipPerVertex[l] = (*clipPerVertex)[indexK];
}
srcPolygon.length = l;
//
//--------------------------------
// Point to the destination buffer
//--------------------------------
//
dstBuffer = 0;
dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
dstPolygon.length = 0;
//
//-----------------------------------------------------------
// Spin through each plane that clipped the primitive and use
// it to actually clip the primitive
//-----------------------------------------------------------
//
mask = 1;
MLRClippingState theNewOr(0);
int loop = 4;
#if HUNT_CLIP_ERROR
for(k=0;k<srcPolygon.length;k++)
{
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< srcPolygon.coords[k].x << " "
<< srcPolygon.coords[k].y << " "
<< srcPolygon.coords[k].z << " "
<< srcPolygon.coords[k].w << '\n';
}
#endif
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "TheOriginalOR: " << hex << theOr.GetClippingState() << dec << '\n';
#endif
do
{
for(l=0; l<MLRClippingState::NextBit; l++)
{
if(theOr.IsClipped(mask))
{
//
//-----------------------------------
// Clip each vertex against the plane
//-----------------------------------
//
#if HUNT_CLIP_ERROR
DEBUG_STREAM << l << ": " << '\n';
#endif
for(k=0;k<srcPolygon.length;k++)
{
k1 = (k+1) < srcPolygon.length ? k+1 : 0;
theTest = srcPolygon.clipPerVertex[k];
//
//----------------------------------------------------
// If this vertex is inside the viewing space, copy it
// directly to the clipping buffer
//----------------------------------------------------
//
if(theTest.IsClipped(mask) == 0)
{
firstIsIn = true;
dstPolygon.coords[dstPolygon.length] =
srcPolygon.coords[k];
#if HUNT_CLIP_ERROR
DEBUG_STREAM << k << " goes " << setiosflags( ios::scientific) << setprecision(20)
<< srcPolygon.coords[k].x << " "
<< srcPolygon.coords[k].y << " "
<< srcPolygon.coords[k].z << " "
<< srcPolygon.coords[k].w << '\n';
#endif
dstPolygon.clipPerVertex[dstPolygon.length] =
srcPolygon.clipPerVertex[k];
dstPolygon.colors[dstPolygon.length] =
srcPolygon.colors[k];
dstPolygon.texCoords[dstPolygon.length] =
srcPolygon.texCoords[k];
dstPolygon.length++;
//
//-------------------------------------------------------
// We don't need to clip this edge if the next vertex is
// also in the viewing space, so just move on to the next
// vertex
//-------------------------------------------------------
//
if(srcPolygon.clipPerVertex[k1].IsClipped(mask) == 0)
{
continue;
}
}
//
//---------------------------------------------------------
// This vertex is outside the viewing space, so if the next
// vertex is also outside the viewing space, no clipping is
// needed and we throw this vertex away. Since only one
// clipping plane is involved, it must be in the same space
// as the first vertex
//---------------------------------------------------------
//
else
{
firstIsIn = false;
if(srcPolygon.clipPerVertex[k1].IsClipped(mask) != 0)
{
Verify(
srcPolygon.clipPerVertex[k1].IsClipped(mask)
== srcPolygon.clipPerVertex[k].IsClipped(mask)
);
continue;
}
}
//
//-------------------------------------------
// Find the clipping interval from bc0 to bc1
//-------------------------------------------
//
if(firstIsIn == true)
{
a = GetLerpFactor (l, srcPolygon.coords[k], srcPolygon.coords[k1]);
Verify(a >= 0.0f && a <= 1.0f);
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
dstPolygon.coords[dstPolygon.length].Lerp(
srcPolygon.coords[k],
srcPolygon.coords[k1],
a
);
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "True " << a << " " << k << " " << k1 << " we get " << dstPolygon.length << '\n';
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< dstPolygon.coords[dstPolygon.length].x << " "
<< dstPolygon.coords[dstPolygon.length].y << " "
<< dstPolygon.coords[dstPolygon.length].z << " "
<< dstPolygon.coords[dstPolygon.length].w << '\n';
#endif
DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
dstPolygon.colors[dstPolygon.length].Lerp(
srcPolygon.colors[k],
srcPolygon.colors[k1],
a
);
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
dstPolygon.texCoords[dstPolygon.length].Lerp
(
srcPolygon.texCoords[k],
srcPolygon.texCoords[k1],
a
);
}
else
{
a = GetLerpFactor (l, srcPolygon.coords[k1], srcPolygon.coords[k]);
Verify(a >= 0.0f && a <= 1.0f);
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
dstPolygon.coords[dstPolygon.length].Lerp(
srcPolygon.coords[k1],
srcPolygon.coords[k],
a
);
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "False " << a << " " << k << " " << k1 << " we get " << dstPolygon.length << '\n';
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< dstPolygon.coords[dstPolygon.length].x << " "
<< dstPolygon.coords[dstPolygon.length].y << " "
<< dstPolygon.coords[dstPolygon.length].z << " "
<< dstPolygon.coords[dstPolygon.length].w << '\n';
#endif
DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
dstPolygon.colors[dstPolygon.length].Lerp(
srcPolygon.colors[k1],
srcPolygon.colors[k],
a
);
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
dstPolygon.texCoords[dstPolygon.length].Lerp
(
srcPolygon.texCoords[k1],
srcPolygon.texCoords[k],
a
);
}
//
//-------------------------------------
// We have to generate a new clip state
//-------------------------------------
//
dstPolygon.clipPerVertex[dstPolygon.length].Clip4dVertex(&dstPolygon.coords[dstPolygon.length]);
//
//----------------------------------
// Bump the new polygon vertex count
//----------------------------------
//
dstPolygon.length++;
}
//
//-----------------------------------------------
// Swap source and destination buffer pointers in
// preparation for the next plane test
//-----------------------------------------------
//
srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
srcPolygon.length = dstPolygon.length;
dstBuffer = !dstBuffer;
dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
dstPolygon.length = 0;
}
mask = mask << 1;
}
theNewOr = 0;
for(k=0;k<srcPolygon.length;k++)
{
theNewOr |= srcPolygon.clipPerVertex[k];
}
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "TheOR: " << hex << theNewOr.GetClippingState() << dec << '\n';
#endif
theOr = theNewOr;
} while (theNewOr != 0 && loop--);
//
//--------------------------------------------------
// could not clip this rare case, just ignore it
//--------------------------------------------------
//
if(theNewOr != 0)
{
testList[i] = 0;
continue;
}
//
//--------------------------------------------------
// Move the most recent polygon into the clip buffer
//--------------------------------------------------
//
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "Final: " << srcPolygon.length << '\n';
#endif
for(k=0;k<srcPolygon.length;k++)
{
int clipped_index = myNumberUsedClipVertex + k;
#if HUNT_CLIP_ERROR
DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
<< srcPolygon.coords[k].x << " "
<< srcPolygon.coords[k].y << " "
<< srcPolygon.coords[k].z << " "
<< srcPolygon.coords[k].w << '\n';
#endif
(*clipExtraCoords)[clipped_index] = srcPolygon.coords[k];
(*clipExtraColors)[clipped_index] = srcPolygon.colors[k];
(*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[k];
}
numberVerticesPerPolygon = srcPolygon.length;
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "---" << '\n';
#endif
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
#ifdef _ARMOR
(*clipExtraLength)[myNumberUsedClipLength] |= 0x8000;
#endif
}
myNumberUsedClipVertex += numberVerticesPerPolygon;
myNumberUsedClipLength++;
ret++;
// clip
// dont draw the original
testList[i] = 0;
}
}
Check_Object(vt);
gos_vertices = vt->GetActualVertexPool(db);
numGOSVertices = 0;
gos_indices = vt->GetActualIndexPool(db);
numGOSIndices = 0;
WORD strideIndex;
for(j=0,strideIndex=0;j<*usedNrOfPoints;j++)
{
if((*visibleIndexedVertices)[j] == 0)
{
strideIndex++;
}
else
{
indexOffset[j] = static_cast<WORD>(j-strideIndex);
GOSCopyData(
&gos_vertices[numGOSVertices],
transformedCoords->GetData(),
colors,
texCoords,
j
);
#ifdef LAB_ONLY
if(gShowClippedPolys)
{
gos_vertices[numGOSVertices].argb = 0xff0000ff;
gos_vertices[numGOSVertices].u = 0.0f;
gos_vertices[numGOSVertices].v = 0.0f;
}
#endif
numGOSVertices++;
}
}
for(i=0,j=0;i<*usedNrOfTriangles;j+=3,++i)
{
if(testList[i] == 0)
{
continue;
}
if(db==false)
{
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
}
Verify(indexOffset[index[j]] < numGOSVertices);
gos_indices[numGOSIndices] = indexOffset[index[j]];
Verify(indexOffset[index[j+2]] < numGOSVertices);
gos_indices[numGOSIndices+1] = indexOffset[index[j+2]];
Verify(indexOffset[index[j+1]] < numGOSVertices);
gos_indices[numGOSIndices+2] = indexOffset[index[j+1]];
numGOSIndices += 3;
}
WORD stride;
if(myNumberUsedClipLength > 0)
{
for(i=0,j=0;i<myNumberUsedClipLength;i++)
{
#ifdef _ARMOR
stride = static_cast<WORD>((*clipExtraLength)[i] & 0x7fff);
#else
stride = static_cast<WORD>((*clipExtraLength)[i]);
#endif
for(k=1;k<stride-1;k++)
{
if(db==false)
{
Verify((vt->GetLast() + 3 + numGOSVertices) < vt->GetLength());
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
}
GOSCopyTriangleData(
&gos_vertices[numGOSVertices],
clipExtraCoords->GetData(),
clipExtraColors->GetData(),
clipExtraTexCoords->GetData(),
j, j+k+1, j+k
);
#ifdef LAB_ONLY
if(gShowClippedPolys)
{
if((*clipExtraLength)[i] & 0x8000)
{
gos_vertices[numGOSVertices].argb = 0xffff0000;
gos_vertices[numGOSVertices].u = 0.0f;
gos_vertices[numGOSVertices].v = 0.0f;
gos_vertices[numGOSVertices+1].argb = 0xffff0000;
gos_vertices[numGOSVertices+1].u = 0.0f;
gos_vertices[numGOSVertices+1].v = 0.0f;
gos_vertices[numGOSVertices+2].argb = 0xffff0000;
gos_vertices[numGOSVertices+2].u = 0.0f;
gos_vertices[numGOSVertices+2].v = 0.0f;
}
else
{
gos_vertices[numGOSVertices].argb = 0xffff9999;
gos_vertices[numGOSVertices].u = 0.0f;
gos_vertices[numGOSVertices].v = 0.0f;
gos_vertices[numGOSVertices+1].argb = 0xffff9999;
gos_vertices[numGOSVertices+1].u = 0.0f;
gos_vertices[numGOSVertices+1].v = 0.0f;
gos_vertices[numGOSVertices+2].argb = 0xffff9999;
gos_vertices[numGOSVertices+2].u = 0.0f;
gos_vertices[numGOSVertices+2].v = 0.0f;
}
}
#endif
if(db==false)
{
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
Verify(numGOSIndices%3 == 0);
}
gos_indices[numGOSIndices] = (WORD)numGOSVertices;
gos_indices[numGOSIndices+1] = (WORD)(numGOSVertices + 1);
gos_indices[numGOSIndices+2] = (WORD)(numGOSVertices + 2);
numGOSVertices += 3;
numGOSIndices += 3;
}
j += stride;
}
#if HUNT_CLIP_ERROR
DEBUG_STREAM << "***" << endl << endl;
#endif
}
if(db==false)
{
vt->Increase(numGOSVertices);
vt->IncreaseIndex(numGOSIndices);
}
return numGOSIndices;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRIndexedTriangleCloud::TestInstance() const
{
if (usedNrOfTriangles)
{
Check_Pointer(usedNrOfTriangles);
Verify(*usedNrOfTriangles >= 0);
Verify(*usedNrOfTriangles <= maxNrOf);
}
}