📄 mlrindexedpolymesh.cpp
字号:
{
ret++;
for(k=j;k<end;k++)
{
visibleIndexedVertices[index[k]] = 1;
}
#ifdef LAB_ONLY
Statistics::MLR_PolysClippedButInside++;
#endif
}
//
//-----------------------------------------------------------------
// It is not a trivial case, so we must now do real clipping on the
// polygon
//-----------------------------------------------------------------
//
else
{
unsigned short numberVerticesPerPolygon = 0;
//
//---------------------------------------------------------------
// Handle the case of a single clipping plane by stepping through
// the vertices and finding the edge it originates
//---------------------------------------------------------------
//
if (theOr.GetNumberOfSetBits() == 1)
{
#ifdef LAB_ONLY
Statistics::MLR_PolysClippedButOnePlane++;
#endif
for(k=j;k<end;k++)
{
k0 = index[k];
k1 = index[(k+1) < end ? k+1 : j];
//
//----------------------------------------------------
// If this vertex is inside the viewing space, copy it
// directly to the clipping buffer
//----------------------------------------------------
//
int clipped_index =
myNumberUsedClipVertex + numberVerticesPerPolygon;
theTest = clipPerVertex[k0];
if(theTest == 0)
{
clipExtraCoords[clipped_index] = transformedCoords[k0];
Verify((*actualColors).GetLength() > 0);
clipExtraColors[clipped_index] = (*actualColors)[k0];
Verify(texCoords.GetLength() > 0);
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(clipPerVertex[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 if(clipPerVertex[k1] != 0)
{
Verify(clipPerVertex[k1] == clipPerVertex[k0]);
continue;
}
//
//--------------------------------------------------
// We now find the distance along the edge where the
// clipping plane will intersect
//--------------------------------------------------
//
mask = 1;
theTest |= clipPerVertex[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
//-------------------------------------------
//
// Verify(!Close_Enough(bc0, bc1));
// a = bc0 / (bc0 - bc1);
a = GetLerpFactor(l, transformedCoords[k0], transformedCoords[k1]);
Verify(a >= 0.0f && a <= 1.0f);
ct = l;
break;
}
mask <<= 1;
}
//
//------------------------------
// Lerp the homogeneous position
//------------------------------
//
clipExtraCoords[clipped_index].Lerp(
transformedCoords[k0],
transformedCoords[k1],
a
);
clipExtraCoords[clipped_index][clipTrick[ct][0]] = clipTrick[ct][1] ? clipExtraCoords[clipped_index].w : 0.0f;
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
Verify((*actualColors).GetLength() > 0);
#if COLOR_AS_DWORD
clipExtraColors[clipped_index] = Color_DWORD_Lerp (
(*actualColors)[k0],
(*actualColors)[k1],
a
);
#else
clipExtraColors[clipped_index].Lerp(
(*actualColors)[k0],
(*actualColors)[k1],
a
);
#endif
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
Verify(texCoords.GetLength() > 0);
clipExtraTexCoords[clipped_index].Lerp
(
texCoords[k0],
texCoords[k1],
a
);
//
//--------------------------------
// Bump the polygon's vertex count
//--------------------------------
//
numberVerticesPerPolygon++;
}
}
//
//---------------------------------------------------------------
// 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
Statistics::MLR_PolysClippedButGOnePlane++;
#endif
ClipPolygon clipBuffer[2];
ClipData srcPolygon, dstPolygon;
int dstBuffer = 1;
Verify((*actualColors).GetLength() > 0);
Verify(texCoords.GetLength() > 0);
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<end;k++,l++)
{
int indexK = index[k];
srcPolygon.coords[l] = transformedCoords[indexK];
srcPolygon.colors[l] = (*actualColors)[indexK];
srcPolygon.texCoords[l] = texCoords[indexK];
srcPolygon.clipPerVertex[l] = clipPerVertex[indexK];
}
srcPolygon.length = l;
srcPolygon.flags |= 3;
//
//--------------------------------
// 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.flags = srcPolygon.flags;
dstPolygon.length = 0;
//
//-----------------------------------------------------------
// Spin through each plane that clipped the primitive and use
// it to actually clip the primitive
//-----------------------------------------------------------
//
mask = 1;
for(l=0; l<MLRClippingState::NextBit; l++)
{
if(theOr.IsClipped(mask))
{
//
//-----------------------------------
// Clip each vertex against the plane
//-----------------------------------
//
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)
{
dstPolygon.coords[dstPolygon.length] =
srcPolygon.coords[k];
dstPolygon.clipPerVertex[dstPolygon.length] =
srcPolygon.clipPerVertex[k];
if(srcPolygon.flags & 0x1)
{
dstPolygon.colors[dstPolygon.length] =
srcPolygon.colors[k];
}
if(srcPolygon.flags & 0x2)
{
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 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
//-------------------------------------------
//
// GetDoubleBC(l, bc0, bc1, srcPolygon.coords[k], srcPolygon.coords[k1]);
// Verify(!Close_Enough(bc0, bc1));
// a = bc0 / (bc0 - bc1);
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
);
dstPolygon.coords[dstPolygon.length][clipTrick[l][0]] = clipTrick[l][1] ? dstPolygon.coords[dstPolygon.length].w : 0.0f;
//
//----------------------------------------------------------
// If there are colors, lerp them in screen space for now as
// most cards do that anyway
//----------------------------------------------------------
//
if(srcPolygon.flags & 1)
{
#if COLOR_AS_DWORD
dstPolygon.colors[dstPolygon.length] = Color_DWORD_Lerp(
srcPolygon.colors[k],
srcPolygon.colors[k1],
a
);
#else
dstPolygon.colors[dstPolygon.length].Lerp(
srcPolygon.colors[k],
srcPolygon.colors[k1],
a
);
#endif
}
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
if(srcPolygon.flags & 2)
{
dstPolygon.texCoords[dstPolygon.length].Lerp
(
srcPolygon.texCoords[k],
srcPolygon.texCoords[k1],
a
);
}
//
//-------------------------------------
// We have to generate a new clip state
//-------------------------------------
//
dstPolygon.clipPerVertex[dstPolygon.length].SetClippingState(0);
switch (l)
{
case 0:
if(clippingFlags.IsTopClipped())
{
if(dstPolygon.coords[dstPolygon.length].w < dstPolygon.coords[dstPolygon.length].y)
{
dstPolygon.clipPerVertex[dstPolygon.length].SetTopClip();
}
}
case 1:
if(clippingFlags.IsBottomClipped())
{
if(dstPolygon.coords[dstPolygon.length].y < 0.0f)
{
dstPolygon.clipPerVertex[dstPolygon.length].SetBottomClip();
}
}
case 2:
if(clippingFlags.IsLeftClipped())
{
if(dstPolygon.coords[dstPolygon.length].w < dstPolygon.coords[dstPolygon.length].x)
{
dstPolygon.clipPerVertex[dstPolygon.length].SetLeftClip();
}
}
case 3:
if(clippingFlags.IsRightClipped())
{
if(dstPolygon.coords[dstPolygon.length].x < 0.0f)
{
dstPolygon.clipPerVertex[dstPolygon.length].SetRightClip();
}
}
case 4:
if(clippingFlags.IsNearClipped())
{
if(dstPolygon.coords[dstPolygon.length].z < 0.0f)
{
dstPolygon.clipPerVertex[dstPolygon.length].SetNearClip();
}
}
case 5:
if(clippingFlags.IsFarClipped())
{
if(dstPolygon.coords[dstPolygon.length].w < dstPolygon.coords[dstPolygon.length].z)
{
dstPolygon.clipPerVertex[dstPolygon.length].SetFarClip();
}
}
}
//
//----------------------------------
// 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;
}
//
//--------------------------------------------------
// Move the most recent polygon into the clip buffer
//--------------------------------------------------
//
for(k=0;k<srcPolygon.length;k++)
{
int clipped_index = myNumberUsedClipVertex + k;
clipExtraCoords[clipped_index] = srcPolygon.coords[k];
if(srcPolygon.flags & 0x1)
{
clipExtraColors[clipped_index] = srcPolygon.colors[k];
}
if(srcPolygon.flags & 0x2)
{
clipExtraTexCoords[clipped_index] = srcPolygon.texCoords[k];
}
}
numberVerticesPerPolygon = srcPolygon.length;
}
clipExtraLength[myNumberUsedClipLength] = numberVerticesPerPolygon;
myNumberUsedClipVertex += numberVerticesPerPolygon;
myNumberUsedClipLength++;
ret++;
// clip
// dont draw the original
testList[i] = 0;
}
j += stride;
}
Check_Object(vt);
gos_vertices = vt->GetActualVertexPool();
numGOSVertices = 0;
gos_indices = vt->GetActualIndexPool();
numGOSIndices = 0;
k = visibleIndexedVertices.GetLength();
for(j=0,stride=0;j<k;j++)
{
if(visibleIndexedVertices[j] == 0)
{
stride++;
}
else
{
visibleIndexedVertices[j] = stride;
//
//--------------------------------------------------------
// JM claims all vertices are in. lets check it. who knows
//--------------------------------------------------------
//
Verify(transformedCoords[j].x >= 0.0f && transformedCoords[j].x <= transformedCoords[j].w );
Verify(transformedCoords[j].y >= 0.0f && transformedCoords[j].y <= transformedCoords[j].w );
Verify(transformedCoords[j].z >= 0.0f && transformedCoords[j].z <= transformedCoords[j].w );
GOSCopyData(
&gos_vertices[numGOSVertices],
transformedCoords.GetData(),
actualColors->GetData(),
texCoords.GetData(),
j
);
numGOSVertices++;
}
}
for(i=0,j=0;i<len;i++)
{
stride = lengths[i];
Verify(stride >= 3);
if(testList[i] == 0)
{
j += stride;
continue;
}
for(k=1;k<stride-1;k++)
{
Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
gos_indices[numGOSIndices] = (unsigned short)(index[j] - visibleIndexedVertices[index[j]]);
gos_indices[numGOSIndices+1] = (unsigned short)(index[j+k+1] - visibleIndexedVertices[index[j+k+1]]);
gos_indices[numGOSIndices+2] = (unsigned short)(index[j+k] - visibleIndexedVertices[index[j+k]]);
numGOSIndices += 3;
}
j += stride;
}
if(myNumberUsedClipLength > 0)
{
for(i=0,j=0;i<myNumberUsedClipLength;i++)
{
stride = clipExtraLength[i];
for(k=1;k<stride-1;k++)
{
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
);
Verify(numGOSIndices%3 == 0);
gos_indices[numGOSIndices] = numGOSVertices;
gos_indices[numGOSIndices+1] = (unsigned short)(numGOSVertices + 1);
gos_indices[numGOSIndices+2] = (unsigned short)(numGOSVertices + 2);
numGOSVertices += 3;
numGOSIndices += 3;
}
j += stride;
}
}
vt->IncreaseIndex(numGOSIndices);
vt->Increase(numGOSVertices);
visible = numGOSVertices ? 1 : 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -