📄 mlrindexedpolymesh.cpp
字号:
if(visible)
{
}
else
{
}
CLEAR_MLRIndexedPolyMesh_CLIP();
EndCycleTiming( &Statistics::MLR_ClipTime );
return ret;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
MLRIndexedPolyMesh::Lighting (
MLRLight **lights,
int nrLights
)
{
Check_Object(this);
// set the to use colors to the original colors ...
// only lighting could overwrite this;
actualColors = &colors;
if(nrLights == 0)
{
return;
}
if(normals.GetLength() == 0)
{
return;
}
if(lights == NULL)
{
return;
}
switch (GetCurrentState().GetLightingMode())
{
case MLRState::LightingOffMode:
return;
case MLRState::LightingClassicOnlyMode:
{
Verify(colors.GetLength() == litColors.GetLength());
Verify(normals.GetLength() == colors.GetLength());
Verify(coords.GetLength() == colors.GetLength());
int i, k, len = colors.GetLength();
MLRVertexData vertexData;
#if COLOR_AS_DWORD
TO_DO;
#else
RGBAColor *color = &colors[0];
RGBAColor *litColor = &litColors[0];
#if USE_ASSEMBLER_CODE
_asm {
push esi
push edi
mov esi, color
mov edi, litColor
mov ecx, len
_loop1:
mov eax, dword ptr [esi]
mov ebx, dword ptr [esi+4]
mov dword ptr [edi], eax
mov dword ptr [edi+ 4], ebx
mov eax, dword ptr [esi + 8]
mov ebx, dword ptr [esi + 12]
mov dword ptr [edi + 8], eax
mov dword ptr [edi + 12], ebx
add esi,16
add edi,16
dec ecx
jnz _loop1
pop edi
pop esi
}
#else // it doesnt know that ...
memcpy(litColor, color, (len<<2)*sizeof(Scalar));
#endif
#endif
//
//-----------------------------------
// Test each light against the vertex
//-----------------------------------
//
for (i=0;i<nrLights;i++)
{
MLRLight *light = lights[i];
Check_Object(light);
vertexData.point = &coords[0];
vertexData.color = &litColors[0];
vertexData.normal = &normals[0];
for(k=0;k<len;k++)
{
if(visibleIndexedVertices[k] != 0)
{
light->LightVertex(vertexData);
}
vertexData.point++;
vertexData.color++;
vertexData.normal++;
}
}
#ifdef LAB_ONLY
Statistics::MLR_LitVertices += len*nrLights;
#endif
// set the to use colors to the original colors ...
// only lighting could overwrite this;
actualColors = &litColors;
}
break;
case MLRState::LightingLightMapOnlyMode:
{
Verify(state.GetAlphaMode() == MLRState::OneZeroMode);
int i;
for (i=0;i<nrLights;i++)
{
LightMapLighting(lights[i]);
}
}
break;
case MLRState::LightingClassicAndLightMapMode:
{
Verify(state.GetAlphaMode() == MLRState::OneZeroMode);
Verify(colors.GetLength() == litColors.GetLength());
Verify(normals.GetLength() == colors.GetLength());
Verify(coords.GetLength() == colors.GetLength());
int i, k, len = colors.GetLength();
MLRVertexData vertexData;
#if COLOR_AS_DWORD
TO_DO;
#else
RGBAColor *color = &colors[0];
RGBAColor *litColor = &litColors[0];
#if USE_ASSEMBLER_CODE
_asm {
push esi
push edi
mov esi, color
mov edi, litColor
mov ecx, len
_loop2:
mov eax, dword ptr [esi]
mov ebx, dword ptr [esi+4]
mov dword ptr [edi], eax
mov dword ptr [edi+ 4], ebx
mov eax, dword ptr [esi + 8]
mov ebx, dword ptr [esi + 12]
mov dword ptr [edi + 8], eax
mov dword ptr [edi + 12], ebx
add esi,16
add edi,16
dec ecx
jnz _loop2
pop edi
pop esi
}
#else // it doesnt know that ...
memcpy(litColor, color, (len<<2)*sizeof(Scalar));
#endif
#endif
//
//-----------------------------------
// Test each light against the vertex
//-----------------------------------
//
for (i=0;i<nrLights;i++)
{
MLRLight *light = lights[i];
Check_Object(light);
vertexData.point = &coords[0];
vertexData.color = &litColors[0];
vertexData.normal = &normals[0];
for(k=0;k<len;k++)
{
light->LightVertex(vertexData);
vertexData.point++;
vertexData.color++;
vertexData.normal++;
}
}
#ifdef LAB_ONLY
Statistics::MLR_LitVertices += len*nrLights;
#endif
// set the to use colors to the original colors ...
// only lighting could overwrite this;
actualColors = &litColors;
STOP(("Lightmaps not implemented yet."));
}
break;
}
}
//---------------------------------------------------------------------------
//
MLRPrimitive *
MLRIndexedPolyMesh::LightMapLighting(MLRLight *light)
{
int i, j, k, stride, len = lengths.GetLength();
LinearMatrix4D matrix = LinearMatrix4D::Identity;
Point3D lightPos, hitPoint;
UnitVector3D up, right;
Scalar f, u, v;
light->GetInShapePosition(lightPos);
for(i=0,j=0,k=0;i<len;i++)
{
stride = lengths[i];
if(testList[i] == 0)
{
j += stride;
continue;
}
f = facePlanes[i].DistanceTo(lightPos);
if(f>0.0f)
{
hitPoint.Multiply(facePlanes[i].normal, -f);
hitPoint+=lightPos;
matrix.AlignAxis(facePlanes[i].normal, Z_Axis, X_Axis, Y_Axis);
matrix.GetWorldRightInLocal(&right);
matrix.GetWorldUpInLocal(&up);
for(k=j;k<stride+j;k++)
{
Vector3D vec(coords[index[k]]);
vec-=hitPoint;
u = (right*vec)/f;
v = (up*vec)/f;
}
testList[i] = 0;
}
j += stride;
}
return NULL;
}
//---------------------------------------------------------------------------
//
bool
MLRIndexedPolyMesh::CastRay(
Line3D *line,
Normal3D *normal
)
{
Check_Object(this);
Check_Object(line);
Check_Pointer(normal);
//
//---------------------------------------------------------------------
// We have to spin through each of the polygons stored in the shape and
// collide the ray against each
//---------------------------------------------------------------------
//
int poly_start = 0, numPrimitives = GetNumPrimitives();
bool hit = false;
for (int polygon=0; polygon<numPrimitives; ++polygon)
{
int stride = lengths[polygon];
Verify(stride>2);
//
//---------------------------------
// See if the line misses the plane
//---------------------------------
//
Scalar product;
const Plane *plane = &facePlanes[polygon];
Check_Object(plane);
Scalar distance = line->DistanceTo(*plane, &product);
if (distance < 0.0f || distance > line->length)
{
poly_start += stride;
continue;
}
bool negate = false;
if (product > -SMALL)
{
if (GetCurrentState().GetBackFaceMode() == MLRState::BackFaceOnMode)
{
poly_start += stride;
continue;
}
negate = true;
}
//
//-------------------------------------------
// Figure out where on the plane the line hit
//-------------------------------------------
//
Point3D impact;
line->Project(distance, &impact);
//
//-------------------------------------------------------------------
// We now need to find out which cardinal plane we should project the
// triangle onto
//-------------------------------------------------------------------
//
int s,t;
Scalar nx = Abs(plane->normal.x);
Scalar ny = Abs(plane->normal.y);
Scalar nz = Abs(plane->normal.z);
if (nx > ny)
{
if (nx > nz)
{
s = Y_Axis;
t = Z_Axis;
}
else
{
s = X_Axis;
t = Y_Axis;
}
}
else if (ny > nz)
{
s = Z_Axis;
t = X_Axis;
}
else
{
s = X_Axis;
t = Y_Axis;
}
//
//----------------------------------------
// Initialize the vertex and leg variables
//----------------------------------------
//
Point3D *v1, *v2, *v3;
v1 = &coords[index[poly_start]];
v2 = &coords[index[poly_start+1]];
v3 = &coords[index[poly_start+2]];
//
//---------------------------------------
// Get the projection of the impact point
//---------------------------------------
//
Scalar s0 = impact[s] - (*v1)[s];
Scalar t0 = impact[t] - (*v1)[t];
Scalar s1 = (*v2)[s] - (*v1)[s];
Scalar t1 = (*v2)[t] - (*v1)[t];
//
//------------------------------------------------------------
// For each triangle, figure out what the second leg should be
//------------------------------------------------------------
//
bool local_hit = false;
int next_v = 3;
Test_Triangle:
Check_Pointer(v3);
Scalar s2 = (*v3)[s] - (*v1)[s];
Scalar t2 = (*v3)[t] - (*v1)[t];
//
//--------------------------------
// Now, see if we hit the triangle
//--------------------------------
//
if (Small_Enough(s1))
{
Verify(!Small_Enough(s2));
Scalar beta = s0 / s2;
if (beta >= 0.0f && beta < 1.0f)
{
Verify(!Small_Enough(t1));
Scalar alpha = (t0 - beta*t2) / t1;
local_hit = (alpha >= 0.0f && alpha+beta <= 1.0f);
}
}
else
{
Scalar beta = (t0*s1 - s0*t1);
Scalar alpha = (t2*s1 - s2*t1);
beta /= alpha;
if (beta >= 0.0f && beta <= 1.0f)
{
alpha = (s0 - beta*s2) / s1;
local_hit = (alpha >= 0.0f && alpha+beta <= 1.0f);
}
}
//
//-----------------------------
// Set up for the next triangle
//-----------------------------
//
if (next_v < stride && !local_hit)
{
v2 = v3;
v3 = &coords[index[poly_start+next_v++]];
s1 = s2;
t1 = t2;
goto Test_Triangle;
}
//
//----------------------------------------------------
// Handle the hit status, and move to the next polygon
//----------------------------------------------------
//
if (local_hit)
{
hit = true;
line->length = distance;
if (negate)
normal->Negate(plane->normal);
else
*normal = plane->normal;
Verify(*normal * line->direction <= -SMALL);
}
poly_start += stride;
}
//
//----------------------
// Return the hit status
//----------------------
//
return hit;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRIndexedPolyMesh*
MidLevelRenderer::CreateIndexedCube(
Scalar half,
RGBAColor *eightColors,
Vector3D *eightNormals,
MLRState *state
)
{
MLRIndexedPolyMesh *ret = new MLRIndexedPolyMesh;
Register_Object(ret);
Point3D *coords = new Point3D [8];
coords[0] = Point3D( half, -half, half);
coords[1] = Point3D(-half, -half, half);
coords[2] = Point3D( half, -half, -half);
coords[3] = Point3D(-half, -half, -half);
coords[4] = Point3D(-half, half, half);
coords[5] = Point3D( half, half, half);
coords[6] = Point3D( half, half, -half);
coords[7] = Point3D(-half, half, -half);
unsigned char *lengths = new unsigned char [6];
int i;
for(i=0;i<6;i++)
{
lengths[i] = 4;
}
ret->SetPrimitiveLength(lengths, 6);
ret->SetCoordData(coords, 8);
unsigned short *index = new unsigned short [6*4];
index[0] = 0;
index[1] = 2;
index[2] = 6;
index[3] = 5;
index[4] = 0;
index[5] = 5;
index[6] = 4;
index[7] = 1;
index[8] = 5;
index[9] = 6;
index[10] = 7;
index[11] = 4;
index[12] = 2;
index[13] = 3;
index[14] = 7;
index[15] = 6;
index[16] = 1;
index[17] = 4;
index[18] = 7;
index[19] = 3;
index[20] = 0;
index[21] = 1;
index[22] = 3;
index[23] = 2;
ret->SetIndexData(index, 6*4);
ret->FindFacePlanes();
if(eightColors!=NULL)
{
#if COLOR_AS_DWORD
DWORD *dwColor = new DWORD [8];
for(i=0;i<8;i++)
{
dwColor[i] = GOSCopyColor(eightColors+i);
}
ret->SetColorData(dwColor, 8);
#else
ret->SetColorData(eightColors, 8);
#endif
}
if(eightNormals!=NULL)
{
ret->SetNormalData(eightNormals, 8);
}
Vector2DScalar *texCoords = new Vector2DScalar[8];
texCoords[0] = Vector2DScalar(0.0f, 0.0f);
texCoords[1] = Vector2DScalar(0.0f, 0.0f);
texCoords[2] = Vector2DScalar(0.0f, 0.0f);
texCoords[3] = Vector2DScalar(0.0f, 0.0f);
texCoords[4] = Vector2DScalar(0.0f, 0.0f);
texCoords[5] = Vector2DScalar(0.0f, 0.0f);
texCoords[6] = Vector2DScalar(0.0f, 0.0f);
texCoords[7] = Vector2DScalar(0.0f, 0.0f);
if(state != NULL)
{
ret->SetReferenceState(*state);
if(state->GetTextureHandle() > 0)
{
texCoords[0] = Vector2DScalar(0.0f, 0.0f);
texCoords[1] = Vector2DScalar(1.0f, 0.0f);
texCoords[2] = Vector2DScalar(0.25f, 0.25f);
texCoords[3] = Vector2DScalar(0.75f, 0.25f);
texCoords[4] = Vector2DScalar(1.0f, 1.0f);
texCoords[5] = Vector2DScalar(0.0f, 1.0f);
texCoords[6] = Vector2DScalar(0.25f, 0.75f);
texCoords[7] = Vector2DScalar(0.75f, 0.75f);
}
}
ret->SetTexCoordData(texCoords, 8);
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -