📄 mlr_i_pmesh.cpp
字号:
Scalar u1v0, u0v1;
int up=0, down=0, right=0, left=0;
for(k0=0;k0<stride;k0++)
{
if((*lightMapUVs)[k0][1] > 0.5f)
{
up++;
}
if((*lightMapUVs)[k0][1] < -0.5f)
{
down++;
}
if((*lightMapUVs)[k0][0] > 0.5f)
{
right++;
}
if((*lightMapUVs)[k0][0] < -0.5f)
{
left++;
}
}
if(up==stride || down==stride || left==stride || right==stride)
{
errorColor = RGBAColor(0.5f, 0.5f, 0.0f, 1.0f);
return false;
}
#if 1
Scalar sign = -1.0f;
if(
((*lightMapUVs)[1][0]-(*lightMapUVs)[0][0]) * ((*lightMapUVs)[stride-1][1]-(*lightMapUVs)[0][1]) >
((*lightMapUVs)[1][1]-(*lightMapUVs)[0][1]) * ((*lightMapUVs)[stride-1][0]-(*lightMapUVs)[0][0])
)
{
sign = 1.0f;
}
#endif
for(k0=0;k0<stride;k0++)
{
k1 = (k0+1<stride) ? k0+1 : 0;
u1v0 = (*lightMapUVs)[k1][0] * (*lightMapUVs)[k0][1];
u0v1 = (*lightMapUVs)[k0][0] * (*lightMapUVs)[k1][1];
if( sign*(u1v0 - u0v1) < 0.0f )
// if( (u1v0 - u0v1) < 0.0f )
{
continue;
}
if(
(
((*lightMapUVs)[k1][0]*(*lightMapUVs)[k1][0] - 2.0f*(*lightMapUVs)[k1][0]*(*lightMapUVs)[k0][0] + (*lightMapUVs)[k0][0]*(*lightMapUVs)[k0][0]) +
((*lightMapUVs)[k1][1]*(*lightMapUVs)[k1][1] - 2.0f*(*lightMapUVs)[k1][1]*(*lightMapUVs)[k0][1] + (*lightMapUVs)[k0][1]*(*lightMapUVs)[k0][1])
) < (2.0f*(u1v0*u1v0 - 2.0f*u1v0*u0v1 + u0v1*u0v1))
)
{
#if UV_TEST
DEBUG_STREAM << k0 << endl;
for(int i=0;i<stride;i++)
{
DEBUG_STREAM << (*lightMapUVs)[i][0] << " " << (*lightMapUVs)[i][1] << endl;
}
DEBUG_STREAM << endl;
#endif
errorColor = RGBAColor(0.0f, 0.5f, 0.0f, 1.0f);
return false;
}
}
return true;
}
//---------------------------------------------------------------------------
//
void
MLR_I_PMesh::LightMapLighting(MLRLight *light)
{
if(!gEnableLightMaps)
{
return;
}
unsigned short stride;
int i, j, k, len = lengths.GetLength();
LinearMatrix4D matrix = LinearMatrix4D::Identity;
Point3D lightPosInShape, hitPoint;
UnitVector3D up, left, forward;
bool lm;
Scalar f, rhf, falloff = 1.0f, distance;
MLRLightMap *lightMap = light->GetLightMap();
if( (!lightMap) || (!gEnableLightMaps) )
{
return;
}
switch(light->GetLightType())
{
case MLRLight::PointLight:
{
lightMap->AddState(referenceState.GetPriority()+1);
light->GetInShapePosition(lightPosInShape);
for(i=0,j=0,k=0;i<len;i++,j += stride)
{
stride = lengths[i];
if(testList[i] == 0)
{
continue;
}
f = facePlanes[i].GetDistanceTo(lightPosInShape);
lm = false;
if(f>0.0f && Cast_Object(MLRInfiniteLightWithFalloff*, light)->GetFalloff(f, falloff) == true)
{
rhf = 1.0f/f;
matrix = LinearMatrix4D::Identity;
matrix.AlignLocalAxisToWorldVector(facePlanes[i].normal, Z_Axis, Y_Axis, X_Axis);
matrix.GetWorldLeftInLocal(&left);
matrix.GetWorldUpInLocal(&up);
matrix.GetWorldForwardInLocal(&forward);
Verify(Small_Enough(up*left));
#if defined(_ARMOR)
Scalar diff = forward*left;
Verify(Small_Enough(diff));
diff = up*forward;
Verify(Small_Enough(diff));
#endif
Check_Object(&forward);
hitPoint.Multiply(forward, -f);
hitPoint+=lightPosInShape;
for(k=0;k<stride;k++)
{
Vector3D vec(coords[index[k+j]]);
vec-=hitPoint;
(*lightMapUVs)[k][0] = -(left*vec)*rhf;
(*lightMapUVs)[k][1] = -(up*vec)*rhf;
if(
(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
)
{
lm = true;
}
}
}
else
{
continue;
}
if(lm == true || CheckForBigTriangles(lightMapUVs, stride) == true)
{
lightMap->SetPolygonMarker(0);
lightMap->AddUShort(stride);
Scalar sq_falloff
= falloff*falloff*light->GetIntensity();
RGBAColor color(sq_falloff, sq_falloff, sq_falloff, 1.0f);
lightMap->AddColor(color);
for(k=0;k<stride;k++)
{
lightMap->AddCoord(coords[index[k+j]]);
}
for(k=0;k<stride;k++)
{
lightMap->AddUVs((*lightMapUVs)[k][0]+0.5f, (*lightMapUVs)[k][1]+0.5f);
// DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
}
}
}
}
break;
case MLRLight::SpotLight:
{
int behindCount = 0, falloffCount = 0;
lightMap->AddState(referenceState.GetPriority()+1);
light->GetInShapePosition(matrix);
lightPosInShape = matrix;
Scalar tanSpeadAngle = Cast_Object(MLRSpotLight*, light)->GetTanSpreadAngle();
matrix.GetLocalLeftInWorld(&left);
matrix.GetLocalUpInWorld(&up);
matrix.GetLocalForwardInWorld(&forward);
Verify(Small_Enough(up*left));
for(i=0,j=0,k=0;i<len;i++,j += stride)
{
behindCount = 0;
falloffCount = 0;
stride = lengths[i];
if(testList[i] == 0)
{
continue;
}
lm = false;
if(!facePlanes[i].IsSeenBy(lightPosInShape))
{
continue;
}
int tooBig = 0;
for(k=0;k<stride;k++)
{
Vector3D vec;
vec.Subtract(coords[index[k+j]], lightPosInShape);
distance = (vec*forward);
if(distance > SMALL)
{
if(Cast_Object(MLRInfiniteLightWithFalloff*, light)->GetFalloff(distance, falloff) == false)
{
falloffCount++;
}
(*lightMapSqFalloffs)[k] = falloff*falloff*light->GetIntensity();
}
else
{
behindCount++;
break;
}
(*lightMapUVs)[k][0] = (left*vec)/(2.0f*distance*tanSpeadAngle);
(*lightMapUVs)[k][1] = -(up*vec)/(2.0f*distance*tanSpeadAngle);
if(
(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
)
{
lm = true;
}
if(
(*lightMapUVs)[k][0] < -1.5f || (*lightMapUVs)[k][0] > 1.5f ||
(*lightMapUVs)[k][1] < -1.5f && (*lightMapUVs)[k][1] > 1.5f
)
{
tooBig++;
}
}
#if 1
if(
tooBig == 0 &&
behindCount == 0 &&
falloffCount < stride &&
(lm == true || CheckForBigTriangles(lightMapUVs, stride) == true)
)
{
lightMap->SetPolygonMarker(1);
lightMap->AddUShort(stride);
for(k=0;k<stride;k++)
{
lightMap->AddCoord(coords[index[k+j]]);
}
for(k=0;k<stride;k++)
{
lightMap->AddColor((*lightMapSqFalloffs)[k], (*lightMapSqFalloffs)[k], (*lightMapSqFalloffs)[k], 1.0f);
}
for(k=0;k<stride;k++)
{
lightMap->AddUVs((*lightMapUVs)[k][0]+0.5f, (*lightMapUVs)[k][1]+0.5f);
// DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
}
}
#else
if(tooBig != 0)
{
lightMap->SetPolygonMarker(1);
lightMap->AddUShort(stride);
for(k=0;k<stride;k++)
{
lightMap->AddCoord(coords[index[k+j]]);
}
for(k=0;k<stride;k++)
{
lightMap->AddColor(RGBAColor(0.0f, 0.0f, 0.5f, 1.0f));
}
for(k=0;k<stride;k++)
{
lightMap->AddUVs(0.5f, 0.5f);
// DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
}
}
else if(behindCount != 0)
{
lightMap->SetPolygonMarker(1);
lightMap->AddUShort(stride);
for(k=0;k<stride;k++)
{
lightMap->AddCoord(coords[index[k+j]]);
}
for(k=0;k<stride;k++)
{
lightMap->AddColor(RGBAColor(0.5f, 0.0f, 0.0f, 1.0f));
}
for(k=0;k<stride;k++)
{
lightMap->AddUVs(0.5f, 0.5f);
// DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
}
}
else if(behindCount == 0 && (lm == true || CheckForBigTriangles(&lightMapUVs, stride) == true) )
{
lightMap->SetPolygonMarker(1);
lightMap->AddUShort(stride);
for(k=0;k<stride;k++)
{
lightMap->AddCoord(coords[index[k+j]]);
}
for(k=0;k<stride;k++)
{
lightMap->AddColor(lightMapSqFalloffs[k], lightMapSqFalloffs[k], lightMapSqFalloffs[k], 1.0f);
}
for(k=0;k<stride;k++)
{
lightMap->AddUVs(lightMapUVs[k][0]+0.5f, lightMapUVs[k][1]+0.5f);
// DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
}
}
else if(CheckForBigTriangles(&lightMapUVs, stride) == false)
{
lightMap->SetPolygonMarker(1);
lightMap->AddUShort(stride);
for(k=0;k<stride;k++)
{
lightMap->AddCoord(coords[index[k+j]]);
}
for(k=0;k<stride;k++)
{
lightMap->AddColor(errorColor);
}
for(k=0;k<stride;k++)
{
lightMap->AddUVs(0.5f, 0.5f);
// DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
}
}
#endif
}
}
break;
default:
STOP(("MLR_I_PMesh::LightMapLighting: What you want me to do ?"));
break;
}
}
//---------------------------------------------------------------------------
//
bool
MLR_I_PMesh::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->GetDistanceTo(*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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -