#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 *MLR_Terrain2::detailTexCoords; MLR_Terrain2::ClassData* MLR_Terrain2::DefaultData = NULL; extern DynamicArrayOf *lightMapUVs; extern DynamicArrayOf *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 (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(tileX/(1<<(maxAllDepth-i)))); Verify((1<(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 = d0 && 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=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 #undef I_SAY_YES_TO_DETAIL_TEXTURES #undef I_SAY_YES_TO_TERRAIN2 #undef CLASSNAME extern bool CheckForBigTriangles(DynamicArrayOf *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=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 *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= -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;icoords[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 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;i0.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=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); } }