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.
1282 lines
31 KiB
C++
1282 lines
31 KiB
C++
#include "MLRHeaders.hpp"
|
|
#include "Compost\TerrainTextureLogistic.hpp"
|
|
|
|
//#define HUNT_FOR_THE_RED_TILE "micgaert"
|
|
|
|
extern DWORD gEnableLightMaps;
|
|
|
|
//#############################################################################
|
|
//## MLRTerrain with no color no lighting w/ detail texture, uv's from xyz ###
|
|
//#############################################################################
|
|
|
|
DynamicArrayOf<Vector2DScalar>
|
|
*MLR_Terrain2::detailTexCoords;
|
|
|
|
MLR_Terrain2::ClassData*
|
|
MLR_Terrain2::DefaultData = NULL;
|
|
|
|
extern DynamicArrayOf<Vector2DScalar> *lightMapUVs;
|
|
extern DynamicArrayOf<Scalar> *lightMapSqFalloffs;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
Verify(gos_GetCurrentHeap() == StaticHeap);
|
|
DefaultData =
|
|
new ClassData(
|
|
MLR_Terrain2ClassID,
|
|
"MidLevelRenderer::MLR_Terrain2",
|
|
MLR_I_DeT_TMesh::DefaultData,
|
|
(MLRPrimitiveBase::Factory)&Make
|
|
);
|
|
Register_Object(DefaultData);
|
|
|
|
detailTexCoords = new DynamicArrayOf<Vector2DScalar> (Limits::Max_Number_Vertices_Per_Mesh);
|
|
Register_Object(detailTexCoords);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
|
|
Unregister_Object(detailTexCoords);
|
|
delete detailTexCoords;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLR_Terrain2::MLR_Terrain2(
|
|
ClassData *class_data,
|
|
MemoryStream *stream,
|
|
int version
|
|
):
|
|
MLR_I_DeT_TMesh(class_data, stream, version)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Pointer(stream);
|
|
|
|
*stream >> tileX >> tileZ;
|
|
*stream >> maxDepth >> maxAllDepth;
|
|
|
|
int i;
|
|
if(version>4)
|
|
{
|
|
Scalar *fptr = &frame[0][0];
|
|
|
|
for(int i=0;i<32;i++)
|
|
{
|
|
*stream >> *fptr++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Scalar xOffset, zOffset, xGrid, zGrid;
|
|
|
|
*stream >> xOffset >> zOffset;
|
|
*stream >> xGrid >> zGrid;
|
|
|
|
frame[0][0] = xOffset;
|
|
frame[0][1] = zOffset;
|
|
frame[0][2] = xOffset + 8*xGrid;
|
|
frame[0][3] = zOffset + 8*zGrid;
|
|
|
|
frame[1][0] = xOffset + 4*(tileX/4)*xGrid;
|
|
frame[1][1] = zOffset + 4*(tileZ/4)*zGrid;
|
|
frame[1][2] = frame[1][0] + 4*xGrid;
|
|
frame[1][3] = frame[1][1] + 4*zGrid;
|
|
|
|
for(i=2;i<8;i++)
|
|
{
|
|
frame[i][0] = xOffset + tileX*xGrid;
|
|
frame[i][1] = zOffset + tileZ*zGrid;
|
|
frame[i][2] = frame[i][0] + xGrid;
|
|
frame[i][3] = frame[i][1] + zGrid;
|
|
}
|
|
}
|
|
|
|
for(i=0;i<8;i++)
|
|
{
|
|
OneOverX[i] = 1.0f/(frame[i][2] - frame[i][0]);
|
|
OneOverZ[i] = 1.0f/(frame[i][3] - frame[i][1]);
|
|
}
|
|
|
|
#ifdef BORDERPIXEL
|
|
*stream >> borderPixelFun;
|
|
#else
|
|
Scalar dummy;
|
|
*stream >> dummy;
|
|
#endif
|
|
|
|
BYTE textureFlags, mask = 1;
|
|
|
|
*stream >> textureFlags;
|
|
|
|
textureFlags &= 0xff >> (7 - Compost::TerrainTextureLogistic::GetResolution());
|
|
|
|
for(i=0;i<8;i++)
|
|
{
|
|
if(textureFlags | mask)
|
|
{
|
|
textures[i] = 1;
|
|
}
|
|
else
|
|
{
|
|
textures[i] = 0;
|
|
}
|
|
mask <<= 1;
|
|
}
|
|
|
|
Check_Object(MLRTexturePool::Instance);
|
|
MLRTexture *orgTexture = (*MLRTexturePool::Instance)[referenceState.GetTextureHandle()];
|
|
Check_Object(orgTexture);
|
|
const char *texName = orgTexture->GetTextureName();
|
|
char texRoot[1024], name[1024];
|
|
|
|
int len;
|
|
if((len = strlen(texName)) > 0)
|
|
{
|
|
Verify(len>8);
|
|
int d = texName[len-6] - '0';
|
|
|
|
strncpy(texRoot, texName, len-7);
|
|
texRoot[len-7] = '\0';
|
|
|
|
textures[d] = referenceState.GetTextureHandle();
|
|
|
|
MLRTexture *texture;
|
|
|
|
BYTE mask = 1;
|
|
for(i=0;i<8;i++)
|
|
{
|
|
if(textureFlags & mask)
|
|
{
|
|
sprintf(name, "%s_%1d_%02x%02x", texRoot, i, (7-tileX)/(1<<(maxAllDepth-i)), (7-tileZ)/(1<<(maxAllDepth-i)));
|
|
|
|
texture = (*MLRTexturePool::Instance)(name, 0);
|
|
if (!texture)
|
|
{
|
|
texture = MLRTexturePool::Instance->Add(name, 0);
|
|
}
|
|
Check_Object(texture);
|
|
|
|
texture->SetHint(orgTexture->GetHint());
|
|
|
|
textures[i] = texture->GetTextureHandle();
|
|
}
|
|
else
|
|
{
|
|
textures[i] = 0;
|
|
}
|
|
mask <<= 1;
|
|
}
|
|
i++;
|
|
for(;i<8;i++)
|
|
{
|
|
textures[i] = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int i=0;i<8;i++)
|
|
{
|
|
textures[i] = 0;
|
|
}
|
|
}
|
|
|
|
Verify(textures[0]!=0);
|
|
|
|
currentDepth = -1;
|
|
|
|
SetCurrentDepth(0);
|
|
|
|
referenceState.SetLightingMode(MLRState::LightMapLightingMode);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLR_Terrain2::MLR_Terrain2(ClassData *class_data):
|
|
MLR_I_DeT_TMesh(class_data)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
tileX = 0;
|
|
tileZ = 0;
|
|
maxDepth = 0;
|
|
maxAllDepth = 0;
|
|
|
|
#ifdef BORDERPIXEL
|
|
borderPixelFun = 0.0f;
|
|
#endif
|
|
|
|
Scalar *fptr = &frame[0][0];
|
|
|
|
int i;
|
|
for(i=0;i<32;i++)
|
|
{
|
|
*fptr++ = 0.0f;
|
|
}
|
|
|
|
for(i=0;i<8;i++)
|
|
{
|
|
textures[i] = 0;
|
|
OneOverX[i] = 1.0f;
|
|
OneOverZ[i] = 1.0f;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLR_Terrain2::~MLR_Terrain2()
|
|
{
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLR_Terrain2*
|
|
MLR_Terrain2::Make(
|
|
MemoryStream *stream,
|
|
int version
|
|
)
|
|
{
|
|
Check_Object(stream);
|
|
|
|
gos_PushCurrentHeap(PrimitiveHeap);
|
|
MLR_Terrain2 *terrain = new MLR_Terrain2(DefaultData, stream, version);
|
|
gos_PopCurrentHeap();
|
|
|
|
return terrain;
|
|
}
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::Save(MemoryStream *stream)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
|
|
#ifndef CALCULATEuvONtheFLY
|
|
dynamicUVs.SetLength(0);
|
|
#endif
|
|
texCoords.AssignData(NULL, 0);
|
|
MLR_I_DeT_TMesh::Save(stream);
|
|
CalculateUVs();
|
|
|
|
*stream << tileX << tileZ;
|
|
*stream << maxDepth << maxAllDepth;
|
|
|
|
Scalar *fptr = &frame[0][0];
|
|
|
|
for(int i=0;i<32;i++)
|
|
{
|
|
*stream << *fptr++;
|
|
}
|
|
|
|
#ifdef BORDERPIXEL
|
|
*stream << borderPixelFun;
|
|
#else
|
|
*stream << 0.0f;
|
|
#endif
|
|
|
|
BYTE textureFlags = 0;
|
|
|
|
// HACK
|
|
/*
|
|
Check_Object(MLRTexturePool::Instance);
|
|
MLRTexture *orgTexture = (*MLRTexturePool::Instance)[referenceState.GetTextureHandle()];
|
|
const char *texName = orgTexture->GetTextureName();
|
|
char texRoot[1024], name[1024];
|
|
|
|
int len;
|
|
if((len = strlen(texName)) > 0)
|
|
{
|
|
Verify(len>8);
|
|
int i, d = texName[len-6] - '0';
|
|
Verify(d==maxDepth);
|
|
strncpy(texRoot, texName, len-7);
|
|
texRoot[len-7] = '\0';
|
|
|
|
textures[d] = referenceState.GetTextureHandle();
|
|
|
|
MLRTexture *texture;
|
|
|
|
BYTE mask = 1;
|
|
for(i=0;i<d;i++)
|
|
{
|
|
sprintf(name, "%s_%1d_%02x%02x", texRoot, i, tileX/(1<<(maxAllDepth-i)), tileZ/(1<<(maxAllDepth-i)));
|
|
|
|
Verify((1<<i)>(tileX/(1<<(maxAllDepth-i))));
|
|
Verify((1<<i)>(tileZ/(1<<(maxAllDepth-i))));
|
|
// SPEW(("micgaert", "%s", name));
|
|
|
|
texture = (*MLRTexturePool::Instance)(name, 0);
|
|
if (texture)
|
|
{
|
|
textureFlags |= mask;
|
|
textures[i] = texture->GetTextureHandle();
|
|
}
|
|
mask <<= 1;
|
|
}
|
|
}
|
|
Verify(textures[0]!=0);
|
|
*/
|
|
textureFlags = 3;
|
|
// HACK
|
|
|
|
|
|
*stream << textureFlags;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::SetCurrentDepth(BYTE d)
|
|
{
|
|
if(d == currentDepth)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Verify(d <= maxAllDepth);
|
|
|
|
BYTE dt;
|
|
dt = d<maxDepth ? d : maxDepth;
|
|
|
|
while(dt>0 && textures[dt]==0)
|
|
{
|
|
dt--;
|
|
}
|
|
currentDepth = dt;
|
|
}
|
|
CalculateUVs();
|
|
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
|
|
MLRTexture *tex = (*MLRTexturePool::Instance)[textures[currentDepth]];
|
|
GOSImage *image = tex->GetImage();
|
|
|
|
if(image->GetHandle())
|
|
{
|
|
const char *tex_name = gos_GetTextureName(image->GetHandle());
|
|
|
|
if(*tex_name!='l')
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "<2"));
|
|
}
|
|
else
|
|
{
|
|
int lev, tX, tZ;
|
|
|
|
sscanf(tex_name, "l:%d r:%d c:%d", &lev, &tZ, &tX);
|
|
|
|
if((tZ&0x7)!=(7-tileZ) || (tX&0x7)!=(7-tileX))
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "T2 l:%d r:%d c:%d - N %d %d", lev, tZ, tX, (7-tileZ), (7-tileX)));
|
|
}
|
|
else
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "T2 l:%d r:%d c:%d - Y", lev, tZ, tX));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "?"));
|
|
}
|
|
#endif
|
|
|
|
referenceState.SetTextureHandle(textures[currentDepth]);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::SetLevelTexture(int lev, int handle)
|
|
{
|
|
Check_Object(this);
|
|
Verify(lev>=0 && lev<8);
|
|
textures[lev] = handle;
|
|
|
|
if(lev==currentDepth)
|
|
{
|
|
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
|
|
MLRTexture *tex = (*MLRTexturePool::Instance)[textures[currentDepth]];
|
|
GOSImage *image = tex->GetImage();
|
|
|
|
if(image->GetHandle())
|
|
{
|
|
const char *tex_name = gos_GetTextureName(image->GetHandle());
|
|
|
|
if(*tex_name!='l')
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "<2"));
|
|
}
|
|
else
|
|
{
|
|
int lev, tX, tZ;
|
|
|
|
sscanf(tex_name, "l:%d r:%d c:%d", &lev, &tZ, &tX);
|
|
|
|
if((tZ&0x7)!=(7-tileZ) || (tX&0x7)!=(7-tileX))
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "T2 l:%d r:%d c:%d - N %d %d", lev, tZ, tX, (7-tileZ), (7-tileX)));
|
|
}
|
|
else
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "T2 l:%d r:%d c:%d - Y", lev, tZ, tX));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "?"));
|
|
}
|
|
#endif
|
|
referenceState.SetTextureHandle(textures[currentDepth]);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::CalculateUVs()
|
|
{
|
|
#ifdef CALCULATEuvONtheFLY
|
|
return;
|
|
#else
|
|
if(texCoords.GetLength() != coords.GetLength())
|
|
{
|
|
gos_PushCurrentHeap(PrimitiveHeap);
|
|
dynamicUVs.SetLength(coords.GetLength());
|
|
texCoords.AssignData(dynamicUVs.GetData(), dynamicUVs.GetLength());
|
|
gos_PopCurrentHeap();
|
|
}
|
|
|
|
Scalar maxX = frame[currentDepth][2];
|
|
Scalar maxZ = frame[currentDepth][3];
|
|
|
|
for(int i=0;i<texCoords.GetLength();i++)
|
|
{
|
|
#ifdef BORDERPIXEL
|
|
dynamicUVs[i][0] = borderPixelFun + (1.0f-2*borderPixelFun)*(maxX - coords[i].x)*OneOverX[currentDepth];
|
|
dynamicUVs[i][1] = borderPixelFun + (1.0f-2*borderPixelFun)*(maxZ - coords[i].z)*OneOverZ[currentDepth];
|
|
#else
|
|
dynamicUVs[i][0] = (maxX - coords[i].x)*OneOverX[currentDepth];
|
|
dynamicUVs[i][1] = (maxZ - coords[i].z)*OneOverZ[currentDepth];
|
|
#endif
|
|
|
|
Verify(texCoords[i][0]>=0.0 && texCoords[i][0]<=1.0);
|
|
Verify(texCoords[i][1]>=0.0 && texCoords[i][1]<=1.0);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::CalculateUV(int i, Scalar &u, Scalar &v)
|
|
{
|
|
Scalar maxX = frame[currentDepth][2];
|
|
Scalar maxZ = frame[currentDepth][3];
|
|
|
|
#ifdef BORDERPIXEL
|
|
u = borderPixelFun + (1.0f-2*borderPixelFun)*(maxX - coords[i].x)*OneOverX[currentDepth];
|
|
v = borderPixelFun + (1.0f-2*borderPixelFun)*(maxZ - coords[i].z)*OneOverZ[currentDepth];
|
|
#else
|
|
u = (maxX - coords[i].x)*OneOverX[currentDepth];
|
|
v = (maxZ - coords[i].z)*OneOverZ[currentDepth];
|
|
#endif
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
#define I_SAY_YES_TO_DETAIL_TEXTURES
|
|
#define I_SAY_YES_TO_TERRAIN2
|
|
#undef I_SAY_YES_TO_DUAL_TEXTURES
|
|
#undef I_SAY_YES_TO_COLOR
|
|
#undef I_SAY_YES_TO_TERRAIN
|
|
#undef I_SAY_YES_TO_LIGHTING
|
|
|
|
#define CLASSNAME MLR_Terrain2
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// This include contains follwing functions:
|
|
// void MLR_Terrain2::TransformNoClip(Matrix4D*, GOSVertexPool*);
|
|
// int MLR_Terrain2::Clip(MLRClippingState, GOSVertexPool*);
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
#include <MLR\MLRTriangleClipping.hpp>
|
|
|
|
#undef I_SAY_YES_TO_DETAIL_TEXTURES
|
|
#undef I_SAY_YES_TO_TERRAIN2
|
|
|
|
#undef CLASSNAME
|
|
|
|
extern bool
|
|
CheckForBigTriangles(DynamicArrayOf<Vector2DScalar> *lightMapUVs, int stride);
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MLRPrimitiveBase*
|
|
MLR_Terrain2::StepOnMe(const Stuff::LinearMatrix4D& foot, Stuff::Scalar radius, MLRTexture *tex)
|
|
{
|
|
Point3D stepLoc;
|
|
|
|
stepLoc = foot;
|
|
|
|
UnitVector3D dir, rot;
|
|
|
|
foot.GetLocalForwardInWorld(&dir);
|
|
rot = dir;
|
|
rot.y = 0.0f;
|
|
rot.Normalize(rot);
|
|
|
|
Scalar oneOverRadius = 0.5f / radius;
|
|
|
|
int i, j, k, tooBig, nrOfPoints=0;
|
|
bool lm;
|
|
Scalar bigUV = MLRState::GetMaxUV();
|
|
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// Look at each polygon in the mesh to see if it could accept the lightmap
|
|
//------------------------------------------------------------------------
|
|
//
|
|
for(i=0,j=0,k=0;i<numOfTriangles;i++,j += 3)
|
|
{
|
|
/*
|
|
if((*testList)[i] == 0)
|
|
continue;
|
|
Scalar f = dir*facePlanes[i].normal;
|
|
if(f>=0.0f)
|
|
continue;
|
|
*/
|
|
lm = false;
|
|
tooBig = 0;
|
|
for(k=0;k<3;k++)
|
|
{
|
|
Vector3D vec(coords[index[k+j]]);
|
|
vec -= stepLoc;
|
|
|
|
Scalar u, v;
|
|
u = vec.x * oneOverRadius;
|
|
v = vec.z * oneOverRadius;
|
|
(*lightMapUVs)[k][0] = u*rot.z - v*rot.x;
|
|
(*lightMapUVs)[k][1] = v*rot.z + u*rot.x;
|
|
|
|
if(
|
|
(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
|
|
(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
|
|
|
|
)
|
|
{
|
|
lm = true;
|
|
}
|
|
if(
|
|
bigUV > 0.0f &&
|
|
(
|
|
(*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
|
|
(*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
|
|
)
|
|
)
|
|
{
|
|
tooBig++;
|
|
}
|
|
}
|
|
|
|
if(
|
|
tooBig == 0
|
|
&& ((lm == true) || CheckForBigTriangles(lightMapUVs, 3) == true)
|
|
)
|
|
{
|
|
for(k=0;k<3;k++,nrOfPoints++)
|
|
{
|
|
SetClipCoord(coords[index[k+j]], nrOfPoints);
|
|
(*lightMapUVs)[k][0] += 0.5f;
|
|
(*lightMapUVs)[k][1] += 0.5f;
|
|
SetClipTexCoord((*lightMapUVs)[k], nrOfPoints);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(nrOfPoints>0)
|
|
{
|
|
Verify(nrOfPoints%3==0);
|
|
|
|
gos_PushCurrentHeap(PrimitiveHeap);
|
|
MLR_I_TMesh *ret = new MLR_I_TMesh();
|
|
Register_Object(ret);
|
|
|
|
ret->FlashClipCoords(nrOfPoints);
|
|
ret->FlashClipTexCoords(nrOfPoints);
|
|
ret->TheIndexer(nrOfPoints);
|
|
|
|
ret->SetSubprimitiveLengths(NULL, nrOfPoints/3);
|
|
ret->FindFacePlanes();
|
|
|
|
gos_PopCurrentHeap();
|
|
|
|
MLRState state;
|
|
|
|
state = referenceState;
|
|
state.SetAlphaMode(MLRState::AlphaInvAlphaMode);
|
|
state.SetPriority(1);
|
|
state.SetBackFaceOn();
|
|
state.SetZBufferCompareOn();
|
|
state.SetTextureCorrectionOn();
|
|
if(tex!=NULL)
|
|
{
|
|
state.SetTextureHandle(tex->GetTextureHandle());
|
|
}
|
|
else
|
|
{
|
|
state.SetTextureHandle(0);
|
|
}
|
|
state.SetTextureWrapMode(MLRState::TextureClamp);
|
|
|
|
ret->SetReferenceState(state);
|
|
return ret;
|
|
}
|
|
|
|
|
|
return NULL;
|
|
}
|
|
|
|
extern RGBAColor errorColor;
|
|
extern bool
|
|
CheckForBigTriangles(DynamicArrayOf<Vector2DScalar> *lightMapUVs, int stride);
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MLR_Terrain2::LightMapLighting(MLRLight *light)
|
|
{
|
|
MLRLightMap *lightMap = light->GetLightMap();
|
|
Check_Object(lightMap);
|
|
|
|
if( (!lightMap) || !gEnableLightMaps || lightMap->IsFull()==true)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int i, j, k, len = numOfTriangles;
|
|
LinearMatrix4D matrix = LinearMatrix4D::Identity;
|
|
Point3D lightPosInShape, hitPoint;
|
|
UnitVector3D up, left, forward;
|
|
bool lm;
|
|
Scalar falloff = 1.0f, distance;
|
|
|
|
BYTE addedVertices = 0;
|
|
BYTE addedIndicies = 0;
|
|
|
|
int tooBig = 0;
|
|
Scalar bigUV = MLRState::GetMaxUV();
|
|
|
|
switch(light->GetLightType())
|
|
{
|
|
case MLRLight::PointLight:
|
|
{
|
|
light->GetInShapePosition(lightPosInShape);
|
|
|
|
Scalar n, f;
|
|
Cast_Object(MLRPointLight*, light)->GetFalloffDistance(n, f);
|
|
|
|
Scalar One_Over_Falloff = 0.5f/f;
|
|
|
|
for(i=0,j=0,k=0;i<len;i++,j += 3)
|
|
{
|
|
if((*testList)[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
f = facePlanes[i].GetDistanceTo(lightPosInShape);
|
|
|
|
lm = false;
|
|
|
|
tooBig = 0;
|
|
for(k=0;k<3;k++)
|
|
{
|
|
Vector3D vec(coords[index[k+j]]);
|
|
vec-=lightPosInShape;
|
|
|
|
(*lightMapUVs)[k][0] = vec.x * One_Over_Falloff;
|
|
(*lightMapUVs)[k][1] = vec.z * One_Over_Falloff;
|
|
|
|
falloff = 1.0f;
|
|
|
|
if(
|
|
(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
|
|
(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
|
|
|
|
)
|
|
{
|
|
lm = true;
|
|
}
|
|
if(
|
|
bigUV > 0.0f &&
|
|
(
|
|
(*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
|
|
(*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
|
|
)
|
|
)
|
|
{
|
|
tooBig++;
|
|
}
|
|
}
|
|
|
|
if(tooBig==0 && (lm == true || CheckForBigTriangles(lightMapUVs, 3) == true))
|
|
{
|
|
#if 0
|
|
Vector3D vec(coords[index[j]]);
|
|
SPEW(("micgaert", "\nvertex1 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = coords[index[j+1]];
|
|
SPEW(("micgaert", "vertex2 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = coords[index[j+2]];
|
|
SPEW(("micgaert", "vertex3 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = facePlanes[i].normal;
|
|
SPEW(("micgaert", "normal = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
SPEW(("micgaert", "forward = %f,%f,%f", forward.x, forward.y, forward.z));
|
|
SPEW(("micgaert", "distance = %f", f));
|
|
SPEW(("micgaert", "light = %f,%f,%f", lightPosInShape.x, lightPosInShape.y, lightPosInShape.z));
|
|
SPEW(("micgaert", "projection = %f,%f,%f", hitPoint.x, hitPoint.y, hitPoint.z));
|
|
#endif
|
|
|
|
Scalar sq_falloff
|
|
= falloff*falloff*light->GetIntensity();
|
|
|
|
RGBAColor color;
|
|
light->GetColor(color);
|
|
|
|
color.red *= sq_falloff;
|
|
color.green *= sq_falloff;
|
|
color.blue *= sq_falloff;
|
|
color.alpha = 1.0f;
|
|
|
|
for(k=0;k<3;k++)
|
|
{
|
|
(*lightMapUVs)[k][0] += 0.5f;
|
|
(*lightMapUVs)[k][1] += 0.5f;
|
|
|
|
if(
|
|
lightMap->AddIndex(addedIndicies++, addedVertices)==false ||
|
|
#if COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], GOSCopyColor(&color))==false
|
|
#else // COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], color)==false
|
|
#endif // COLOR_AS_DWORD
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(addedIndicies >= 252 && addedVertices > 0)
|
|
{
|
|
lightMap->AddMesh(referenceState.GetPriority()+1, addedVertices, addedIndicies);
|
|
addedIndicies = 0;
|
|
addedVertices = 0;
|
|
}
|
|
// DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MLRLight::SpotLight:
|
|
{
|
|
int behindCount = 0, falloffCount = 0;
|
|
|
|
light->GetInShapePosition(matrix);
|
|
lightPosInShape = matrix;
|
|
|
|
Scalar tanSpeadAngle = Cast_Object(MLRSpotLight*, light)->GetTanSpreadAngle();
|
|
|
|
#ifndef TOP_DOWN_ONLY
|
|
matrix.GetLocalLeftInWorld(&left);
|
|
matrix.GetLocalUpInWorld(&up);
|
|
matrix.GetLocalForwardInWorld(&forward);
|
|
#else
|
|
forward = UnitVector3D(0.0f, -1.0f, 0.0);
|
|
up = UnitVector3D(1.0f, 0.0f, 0.0);
|
|
left = UnitVector3D(0.0f, 0.0f, 1.0);
|
|
#endif
|
|
|
|
Verify(Small_Enough(up*left));
|
|
|
|
for(i=0,j=0,k=0;i<len;i++,j += 3)
|
|
{
|
|
behindCount = 0;
|
|
falloffCount = 0;
|
|
|
|
if((*testList)[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
lm = false;
|
|
|
|
if(!facePlanes[i].IsSeenBy(lightPosInShape))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
#if SPEW_AWAY
|
|
Scalar maxX, maxZ;
|
|
Scalar minX, minZ;
|
|
|
|
minX = maxX = coords[index[j]].x;
|
|
minZ = maxZ = coords[index[j]].z;
|
|
|
|
if(minX>coords[index[j+1]].x)
|
|
{
|
|
minX = coords[index[j+1]].x;
|
|
}
|
|
if(minX>coords[index[j+2]].x)
|
|
{
|
|
minX = coords[index[j+2]].x;
|
|
}
|
|
if(minZ>coords[index[j+1]].z)
|
|
{
|
|
minZ = coords[index[j+1]].z;
|
|
}
|
|
if(minX>coords[index[j+2]].z)
|
|
{
|
|
minZ = coords[index[j+2]].z;
|
|
}
|
|
if(maxX<coords[index[j+1]].x)
|
|
{
|
|
maxX = coords[index[j+1]].x;
|
|
}
|
|
if(maxX<coords[index[j+2]].x)
|
|
{
|
|
maxX = coords[index[j+2]].x;
|
|
}
|
|
if(maxZ<coords[index[j+1]].z)
|
|
{
|
|
maxZ = coords[index[j+1]].z;
|
|
}
|
|
if(maxX<coords[index[j+2]].z)
|
|
{
|
|
maxZ = coords[index[j+2]].z;
|
|
}
|
|
|
|
if(lightPosInShape.x > minX && lightPosInShape.x < maxX && lightPosInShape.z > minZ && lightPosInShape.z < maxZ)
|
|
{
|
|
SPEW(("micgaert", "On Target !!"));
|
|
}
|
|
#endif
|
|
|
|
tooBig = 0;
|
|
for(k=0;k<3;k++)
|
|
{
|
|
Vector3D vec;
|
|
Scalar oneOver;
|
|
|
|
vec.Subtract(coords[index[k+j]], lightPosInShape);
|
|
|
|
#ifndef TOP_DOWN_ONLY
|
|
distance = (vec*forward);
|
|
#else
|
|
distance = -vec.y;
|
|
#endif
|
|
|
|
#if SPEW_AWAY
|
|
SPEW(("micgaert", "vertex%d = %f,%f,%f", k, coords[index[k+j]].x, coords[index[k+j]].y, coords[index[k+j]].z));
|
|
SPEW(("micgaert", "distance = %f", distance));
|
|
#endif
|
|
if(distance > SMALL)
|
|
{
|
|
if(Cast_Object(MLRInfiniteLightWithFalloff*, light)->GetFalloff(distance, falloff) == false)
|
|
{
|
|
falloffCount++;
|
|
}
|
|
(*lightMapSqFalloffs)[k] = falloff*falloff*light->GetIntensity();
|
|
|
|
oneOver
|
|
#if 0
|
|
= 1.0f/(2.0f*distance*tanSpeadAngle);
|
|
#else
|
|
= OneOverApproximate(2.0f*distance*tanSpeadAngle);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
behindCount++;
|
|
oneOver = 1.0f/50.0f;
|
|
(*lightMapSqFalloffs)[k] = 0.0f;
|
|
#if SPEW_AWAY
|
|
SPEW(("micgaert", "Behind"));
|
|
#endif
|
|
}
|
|
|
|
#ifndef TOP_DOWN_ONLY
|
|
(*lightMapUVs)[k][0] = (left*vec) * oneOver;
|
|
(*lightMapUVs)[k][1] = -(up*vec) * oneOver;
|
|
#else
|
|
(*lightMapUVs)[k][0] = vec.x * oneOver;
|
|
(*lightMapUVs)[k][1] = -vec.z * oneOver;
|
|
#endif
|
|
|
|
#if SPEW_AWAY
|
|
SPEW(("micgaert", "uv%d = %f,%f", k, (*lightMapUVs)[k][0], (*lightMapUVs)[k][1]));
|
|
#endif
|
|
if(
|
|
(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
|
|
(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
|
|
|
|
)
|
|
{
|
|
lm = true;
|
|
}
|
|
if(
|
|
bigUV > 0.0f &&
|
|
(
|
|
(*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
|
|
(*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
|
|
)
|
|
|
|
)
|
|
{
|
|
tooBig++;
|
|
}
|
|
}
|
|
if(
|
|
tooBig == 0
|
|
&& behindCount < 3
|
|
&& falloffCount < 3
|
|
&& ((lm == true) || CheckForBigTriangles(lightMapUVs, 3) == true)
|
|
)
|
|
{
|
|
for(k=0;k<3;k++)
|
|
{
|
|
RGBAColor color;
|
|
|
|
color.red = (*lightMapSqFalloffs)[k];
|
|
color.green = (*lightMapSqFalloffs)[k];
|
|
color.blue = (*lightMapSqFalloffs)[k];
|
|
color.alpha = 1.0f;
|
|
|
|
(*lightMapUVs)[k][0] += 0.5f;
|
|
(*lightMapUVs)[k][1] += 0.5f;
|
|
|
|
if(
|
|
lightMap->AddIndex(addedIndicies++, addedVertices)==false ||
|
|
#if COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], GOSCopyColor(&color))==false
|
|
#else // COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], color)==false
|
|
#endif // COLOR_AS_DWORD
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(addedIndicies >= 252 && addedVertices > 0)
|
|
{
|
|
lightMap->AddMesh(referenceState.GetPriority()+1, addedVertices, addedIndicies);
|
|
addedIndicies = 0;
|
|
addedVertices = 0;
|
|
}
|
|
}
|
|
#if SPEW_AWAY
|
|
SPEW(("micgaert", "See the Light !"));
|
|
#endif
|
|
}
|
|
#if SPEW_AWAY
|
|
Vector3D vec = facePlanes[i].normal;
|
|
SPEW(("micgaert", "normal = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
SPEW(("micgaert", "forward = %f,%f,%f", forward.x, forward.y, forward.z));
|
|
SPEW(("micgaert", "left = %f,%f,%f", left.x, left.y, left.z));
|
|
SPEW(("micgaert", "up = %f,%f,%f", up.x, up.y, up.z));
|
|
SPEW(("micgaert", "light = %f,%f,%f\n", lightPosInShape.x, lightPosInShape.y, lightPosInShape.z));
|
|
#endif
|
|
}
|
|
}
|
|
break;
|
|
#define TOP_DOWN_ONLY
|
|
case MLRLight::ProjectLight:
|
|
{
|
|
MLRProjectLight *pLight = Cast_Object(MLRProjectLight*, light);
|
|
|
|
light->GetInShapePosition(lightPosInShape);
|
|
|
|
|
|
Scalar n, f;
|
|
pLight->GetFalloffDistance(n, f);
|
|
|
|
Scalar ray_distance = light->GetIntensity();
|
|
|
|
UnitVector3D dir, rot;
|
|
light->GetInShapeDirection(dir);
|
|
|
|
lightPosInShape.AddScaled(lightPosInShape, dir, ray_distance);
|
|
|
|
rot = dir;
|
|
rot.y = 0.0f;
|
|
|
|
rot.Normalize(rot);
|
|
|
|
if(ray_distance <= SMALL)
|
|
{
|
|
break;
|
|
}
|
|
// Scalar One_Over_Falloff = 1.0f/(3.0f*f);
|
|
Scalar oneOverRadius = 0.5f / (pLight->GetTanSpreadAngle() * ray_distance);
|
|
|
|
if(pLight->GetFalloff(ray_distance, falloff))
|
|
{
|
|
for(i=0,j=0,k=0;i<len;i++,j += 3)
|
|
{
|
|
if((*testList)[i] == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/*
|
|
f = dir*facePlanes[i].normal;
|
|
|
|
if(f>0.0f)
|
|
{
|
|
continue;
|
|
}
|
|
*/
|
|
lm = false;
|
|
|
|
tooBig = 0;
|
|
for(k=0;k<3;k++)
|
|
{
|
|
Vector3D vec(coords[index[k+j]]);
|
|
vec-=lightPosInShape;
|
|
|
|
Scalar u, v;
|
|
u = vec.x * oneOverRadius;
|
|
v = vec.z * oneOverRadius;
|
|
(*lightMapUVs)[k][0] = u*rot.z - v*rot.x;
|
|
(*lightMapUVs)[k][1] = v*rot.z + u*rot.x;
|
|
|
|
|
|
if(
|
|
(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
|
|
(*lightMapUVs)[k][1] >= -0.25f && (*lightMapUVs)[k][1] <= 0.75f
|
|
|
|
)
|
|
{
|
|
lm = true;
|
|
}
|
|
if(
|
|
bigUV > 0.0f &&
|
|
(
|
|
(*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
|
|
(*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
|
|
)
|
|
)
|
|
{
|
|
tooBig++;
|
|
}
|
|
}
|
|
|
|
if(tooBig==0 && (lm == true || CheckForBigTriangles(lightMapUVs, 3) == true))
|
|
{
|
|
#if 0
|
|
Vector3D vec(coords[index[j]]);
|
|
SPEW(("micgaert", "\nvertex1 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = coords[index[j+1]];
|
|
SPEW(("micgaert", "vertex2 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = coords[index[j+2]];
|
|
SPEW(("micgaert", "vertex3 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = facePlanes[i].normal;
|
|
SPEW(("micgaert", "normal = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
SPEW(("micgaert", "forward = %f,%f,%f", forward.x, forward.y, forward.z));
|
|
SPEW(("micgaert", "distance = %f", f));
|
|
SPEW(("micgaert", "light = %f,%f,%f", lightPosInShape.x, lightPosInShape.y, lightPosInShape.z));
|
|
SPEW(("micgaert", "projection = %f,%f,%f", hitPoint.x, hitPoint.y, hitPoint.z));
|
|
#endif
|
|
|
|
Scalar sq_falloff
|
|
= falloff*falloff; //*light->GetIntensity();
|
|
|
|
RGBAColor color;
|
|
light->GetColor(color);
|
|
|
|
color.red *= sq_falloff;
|
|
color.green *= sq_falloff;
|
|
color.blue *= sq_falloff;
|
|
color.alpha = 1.0f;
|
|
|
|
for(k=0;k<3;k++)
|
|
{
|
|
(*lightMapUVs)[k][0] += 0.5f;
|
|
(*lightMapUVs)[k][1] += 0.25f;
|
|
|
|
if(
|
|
lightMap->AddIndex(addedIndicies++, addedVertices)==false ||
|
|
#if COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], GOSCopyColor(&color))==false
|
|
#else // COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], color)==false
|
|
#endif // COLOR_AS_DWORD
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(addedIndicies >= 252 && addedVertices > 0)
|
|
{
|
|
lightMap->AddMesh(referenceState.GetPriority()+1, addedVertices, addedIndicies);
|
|
addedIndicies = 0;
|
|
addedVertices = 0;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case MLRLight::ShadowLight:
|
|
{
|
|
MLRShadowLight *shadow = Cast_Object(MLRShadowLight*, light);
|
|
|
|
light->GetInShapePosition(lightPosInShape);
|
|
|
|
UnitVector3D dir, rot;
|
|
light->GetInShapeDirection(dir);
|
|
rot = dir;
|
|
rot.y = 0.0f;
|
|
rot.Normalize(rot);
|
|
|
|
//
|
|
//--------------------------------------------------
|
|
// If the light is at or below zero to us, ignore it
|
|
//--------------------------------------------------
|
|
//
|
|
if(lightPosInShape.y <= SMALL)
|
|
{
|
|
break;
|
|
}
|
|
Scalar oneOverRadius = 0.5f / shadow->GetFalloffFar();
|
|
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// Look at each polygon in the mesh to see if it could accept the lightmap
|
|
//------------------------------------------------------------------------
|
|
//
|
|
for(i=0,j=0,k=0;i<len;i++,j += 3)
|
|
{
|
|
if((*testList)[i] == 0)
|
|
continue;
|
|
Scalar f = dir*facePlanes[i].normal;
|
|
if(f>=0.0f)
|
|
continue;
|
|
|
|
lm = false;
|
|
tooBig = 0;
|
|
for(k=0;k<3;k++)
|
|
{
|
|
Vector3D vec(coords[index[k+j]]);
|
|
vec -= lightPosInShape;
|
|
|
|
Scalar u, v;
|
|
u = vec.x * oneOverRadius;
|
|
v = vec.z * oneOverRadius;
|
|
(*lightMapUVs)[k][0] = u*rot.z - v*rot.x;
|
|
(*lightMapUVs)[k][1] = v*rot.z + u*rot.x;
|
|
|
|
if(
|
|
(*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
|
|
(*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
|
|
|
|
)
|
|
{
|
|
lm = true;
|
|
}
|
|
if(
|
|
bigUV > 0.0f &&
|
|
(
|
|
(*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
|
|
(*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
|
|
)
|
|
)
|
|
{
|
|
tooBig++;
|
|
}
|
|
}
|
|
|
|
if(tooBig==0 && (lm == true || CheckForBigTriangles(lightMapUVs, 3) == true))
|
|
{
|
|
#if 0
|
|
Vector3D vec(coords[index[j]]);
|
|
SPEW(("micgaert", "\nvertex1 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = coords[index[j+1]];
|
|
SPEW(("micgaert", "vertex2 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = coords[index[j+2]];
|
|
SPEW(("micgaert", "vertex3 = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
vec = facePlanes[i].normal;
|
|
SPEW(("micgaert", "normal = %f,%f,%f", vec.x, vec.y, vec.z));
|
|
SPEW(("micgaert", "forward = %f,%f,%f", forward.x, forward.y, forward.z));
|
|
SPEW(("micgaert", "distance = %f", f));
|
|
SPEW(("micgaert", "light = %f,%f,%f", lightPosInShape.x, lightPosInShape.y, lightPosInShape.z));
|
|
SPEW(("micgaert", "projection = %f,%f,%f", hitPoint.x, hitPoint.y, hitPoint.z));
|
|
#endif
|
|
RGBAColor color;
|
|
color = RGBAColor::White;
|
|
color.alpha = shadow->GetIntensity();
|
|
|
|
for(k=0;k<3;k++)
|
|
{
|
|
(*lightMapUVs)[k][0] += 0.5f;
|
|
(*lightMapUVs)[k][1] += 0.5f;
|
|
|
|
if(
|
|
lightMap->AddIndex(addedIndicies++, addedVertices)==false ||
|
|
#if COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], GOSCopyColor(&color))==false
|
|
#else // COLOR_AS_DWORD
|
|
lightMap->AddVertex(addedVertices++, coords[index[k+j]], (*lightMapUVs)[k], color)==false
|
|
#endif // COLOR_AS_DWORD
|
|
)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(addedIndicies >= 252 && addedVertices > 0)
|
|
{
|
|
lightMap->AddMesh(referenceState.GetPriority()+1, addedVertices, addedIndicies);
|
|
addedIndicies = 0;
|
|
addedVertices = 0;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
STOP(("MLR_Terrain2::LightMapLighting: What you want me to do ?"));
|
|
break;
|
|
}
|
|
|
|
if(addedIndicies && addedVertices)
|
|
{
|
|
lightMap->AddMesh(referenceState.GetPriority()+1, addedVertices, addedIndicies);
|
|
}
|
|
} |