📄 mlrtriangleclipping.hpp
字号:
if( (*cs)==0)
{
#if defined(_ARMOR)
if(ArmorLevel > 3)
{
//
//--------------------------------------------------------
// I claims all vertices are in. lets check it. who knows
//--------------------------------------------------------
//
Verify(v4d->x >= 0.0f && v4d->x <= v4d->w );
Verify(v4d->y >= 0.0f && v4d->y <= v4d->w );
Verify(v4d->z >= 0.0f && v4d->z <= v4d->w );
}
#endif // _ARMOR
Set_Statistic(NonClippedVertices, NonClippedVertices+1);
}
else
{
Set_Statistic(ClippedVertices, ClippedVertices+1);
}
#endif // LAB_ONLY
}
Stop_Timer(Transform_Time);
Start_Timer(Clipping_Time);
int mask, k0, k1, ct=0;
Scalar a=0.0f;
bool textureAnimation = false;
Scalar deltaU=0.0f, deltaV=0.0f;
if(state.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state.GetTextureHandle()];
Check_Object(texture);
textureAnimation = texture->GetAnimateTexture();
if(textureAnimation)
{
Stuff::AffineMatrix4D &textureMatrix = texture->GetTextureMatrix();
deltaU = textureMatrix(3, 0);
deltaV = textureMatrix(3, 1);
}
}
#if defined(I_SAY_YES_TO_DUAL_TEXTURES) || defined(I_SAY_YES_TO_DETAIL_TEXTURES)
gos_vertices2uv = vt->GetActualVertexPool2UV(db);
bool textureAnimation2 = false;
Scalar deltaU2=0.0f, deltaV2=0.0f;
if(state2.GetTextureHandle())
{
MLRTexture *texture = (*MLRTexturePool::Instance)[state2.GetTextureHandle()];
Verify(texture);
textureAnimation2 = texture->GetAnimateTexture();
if(textureAnimation2)
{
Stuff::AffineMatrix4D &textureMatrix = texture->GetTextureMatrix();
deltaU2 = textureMatrix(3, 0);
deltaV2 = textureMatrix(3, 1);
}
}
#endif // I_SAY_YES_TO_DUAL_TEXTURES || I_SAY_YES_TO_DETAIL_TEXTURES
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
int tex2count = 0;
int numVertices = GetNumVertices();
#endif // I_SAY_YES_TO_DUAL_TEXTURES
#ifdef I_SAY_YES_TO_MULTI_TEXTURES
int m;
gos_PushCurrentHeap(StaticHeap);
int tex2count[Limits::Max_Number_Of_Multitextures];
gos_PopCurrentHeap();
for(m=0;m<currentNrOfPasses;m++)
{
tex2count[m] = 0;
}
#endif // I_SAY_YES_TO_MULTI_TEXTURES
int myNumberUsedClipVertex, myNumberUsedClipIndex, myNumberUsedClipLength;
myNumberUsedClipVertex = 0;
myNumberUsedClipIndex = 0;
myNumberUsedClipLength = 0;
Verify(index.GetLength() > 0);
//
//------------------------
// Handle the indexed case
//------------------------
//
//
//-----------------------------------------------------------------
// Step through each polygon, making sure that we don't try to clip
// backfaced polygons
//-----------------------------------------------------------------
//
cs = (int *)clipPerVertex->GetData();
int index0, index1, index2;
for(i=0,j=0;i<numOfTriangles;j+=3,++i)
{
// if(testList[i] == 0)
// {
// 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
//-------------------------------------------------------------------
//
theAnd = theOr = 0; //ASSUME NO CLIPPING NEEDED FOR MC2. Its just not done here!
if (theAnd != 0)
{
testList[i] = 0;
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButOutside, PolysClippedButOutside+1);
#endif // LAB_ONLY
}
else if (theOr == 0)
{
ret++;
visibleIndexedVertices[index0] = 1;
visibleIndexedVertices[index1] = 1;
visibleIndexedVertices[index2] = 1;
#ifdef I_SAY_YES_TO_TERRAIN
(*clipTexCoords)[index0][0] = borderPixelFun + (coords[index0].x - minX)*xUVFac;
(*clipTexCoords)[index0][1] = borderPixelFun + (coords[index0].z - minZ)*zUVFac;
(*clipTexCoords)[index1][0] = borderPixelFun + (coords[index1].x - minX)*xUVFac;
(*clipTexCoords)[index1][1] = borderPixelFun + (coords[index1].z - minZ)*zUVFac;
(*clipTexCoords)[index2][0] = borderPixelFun + (coords[index2].x - minX)*xUVFac;
(*clipTexCoords)[index2][1] = borderPixelFun + (coords[index2].z - minZ)*zUVFac;
#endif // I_SAY_YES_TO_TERRAIN
#ifdef LAB_ONLY
Set_Statistic(PolysClippedButInside, PolysClippedButInside+1);
#endif // LAB_ONLY
}
//
//-----------------------------------------------------------------
// It is not a trivial case, so we must now do real clipping on the
// polygon
//-----------------------------------------------------------------
//
else
{
unsigned short numberVerticesPerPolygon = 0;
#ifdef I_SAY_YES_TO_TERRAIN
(*clipTexCoords)[index0][0] = borderPixelFun + (coords[index0].x - minX)*xUVFac;
(*clipTexCoords)[index0][1] = borderPixelFun + (coords[index0].z - minZ)*zUVFac;
(*clipTexCoords)[index1][0] = borderPixelFun + (coords[index1].x - minX)*xUVFac;
(*clipTexCoords)[index1][1] = borderPixelFun + (coords[index1].z - minZ)*zUVFac;
(*clipTexCoords)[index2][0] = borderPixelFun + (coords[index2].x - minX)*xUVFac;
(*clipTexCoords)[index2][1] = borderPixelFun + (coords[index2].z - minZ)*zUVFac;
#endif // I_SAY_YES_TO_TERRAIN
//
//---------------------------------------------------------------
// 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 // LAB_ONLY
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];
#ifdef I_SAY_YES_TO_COLOR
Verify((*actualColors).GetLength() > 0);
(*clipExtraColors)[clipped_index] = (*actualColors)[k0];
#endif // I_SAY_YES_TO_COLOR
#ifdef I_SAY_YES_TO_TERRAIN
(*clipExtraTexCoords)[clipped_index] = (*clipTexCoords)[k0];
#else // I_SAY_YES_TO_TERRAIN
Verify(texCoords.GetLength() > 0);
(*clipExtraTexCoords)[clipped_index] = texCoords[k0];
#endif // I_SAY_YES_TO_TERRAIN
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*clipExtraTexCoords2)[clipped_index] = texCoords[k0+numVertices];
#endif
#ifdef I_SAY_YES_TO_MULTI_TEXTURES
for(m=1;m<currentNrOfPasses;m++)
{
clipExtraMultiTexCoords[m][clipped_index] = multiTexCoordsPointers[m][k0];
}
#endif // I_SAY_YES_TO_MULTI_TEXTURES
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
//--------------------------------------------------
//
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
//----------------------------------------------------------
//
#ifdef I_SAY_YES_TO_COLOR
Verify((*actualColors).GetLength() > 0);
#if COLOR_AS_DWORD
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
(*actualColors)[k0],
(*actualColors)[k1],
a
);
#else // COLOR_AS_DWORD
(*clipExtraColors)[clipped_index].Lerp(
(*actualColors)[k0],
(*actualColors)[k1],
a
);
#endif // COLOR_AS_DWORD
#endif // I_SAY_YES_TO_COLOR
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
#ifdef I_SAY_YES_TO_TERRAIN
(*clipExtraTexCoords)[clipped_index].Lerp
(
(*clipTexCoords)[k0],
(*clipTexCoords)[k1],
a
);
#else // I_SAY_YES_TO_TERRAIN
Verify(texCoords.GetLength() > 0);
(*clipExtraTexCoords)[clipped_index].Lerp
(
texCoords[k0],
texCoords[k1],
a
);
#endif // I_SAY_YES_TO_TERRAIN
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*clipExtraTexCoords2)[clipped_index].Lerp
(
texCoords[k0+numVertices],
texCoords[k1+numVertices],
a
);
#endif // I_SAY_YES_TO_DUAL_TEXTURES
#ifdef I_SAY_YES_TO_MULTI_TEXTURES
for(m=1;m<currentNrOfPasses;m++)
{
(*clipExtraMultiTexCoords)[m][clipped_index] .Lerp
(
multiTexCoordsPointers[m][k0],
multiTexCoordsPointers[m][k1],
a
);
}
#endif // I_SAY_YES_TO_MULTI_TEXTURES
}
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
//----------------------------------------------------------
//
#ifdef I_SAY_YES_TO_COLOR
Verify((*actualColors).GetLength() > 0);
#if COLOR_AS_DWORD
(*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
(*actualColors)[k1],
(*actualColors)[k0],
a
);
#else // COLOR_AS_DWORD
(*clipExtraColors)[clipped_index].Lerp(
(*actualColors)[k1],
(*actualColors)[k0],
a
);
#endif // COLOR_AS_DWORD
#endif // I_SAY_YES_TO_COLOR
//
//-----------------------------------------------------
// If there are texture uv's, we need to lerp them in a
// perspective correct manner
//-----------------------------------------------------
//
#ifdef I_SAY_YES_TO_TERRAIN
(*clipExtraTexCoords)[clipped_index].Lerp
(
(*clipTexCoords)[k1],
(*clipTexCoords)[k0],
a
);
#else // I_SAY_YES_TO_TERRAIN
Verify(texCoords.GetLength() > 0);
(*clipExtraTexCoords)[clipped_index].Lerp
(
texCoords[k1],
texCoords[k0],
a
);
#endif // I_SAY_YES_TO_TERRAIN
#ifdef I_SAY_YES_TO_DUAL_TEXTURES
(*clipExtraTexCoords2)[clipped_index].Lerp
(
texCoords[k1+numVertices],
texCoords[k0+numVertices],
a
);
#endif // I_SAY_YES_TO_DUAL_TEXTURES
#ifdef I_SAY_YES_TO_MULTI_TEXTURES
for(m=1;m<currentNrOfPasses;m++)
{
(*clipExtraMultiTexCoords)[m][clipped_index] .Lerp
(
multiTexCoordsPointers[m][k1],
multiTexCoordsPointers[m][k0],
a
);
}
#endif // I_SAY_YES_TO_MULTI_TEXTURES
}
//
//--------------------------------
// Bump the polygon's vertex count
//--------------------------------
//
numberVerticesPerPolygon++;
}
(*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
#ifdef _ARMOR
(*clipExtraLength)[myNumberUsedClipLength] &= ~0x8000;
#endif // _ARMOR
}
//
//---------------------------------------------------------------
// 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 // LAB_ONLY
ClipData2 srcPolygon, dstPolygon;
int dstBuffer = 1;
#ifndef I_SAY_YES_TO_TERRAIN
Verify(texCoords.GetLength() > 0);
#endif // I_SAY_YES_TO_TERRAIN
srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
#ifdef I_SAY_YES_TO_COLOR
Verify((*actualColors).GetLength() > 0);
srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
#endif // I_SAY_YES_TO_COLOR
srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
//
//----------------------------------------------------------
// unravel and copy the original data into the source buffer
//----------------------------------------------------------
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -