#include "MLRHeaders.hpp" extern DWORD gEnableLightMaps, gEnableFancyWater; //############################################################################# //## MLRTerrain with no color no lighting w/ detail texture, uv's from xyz ### //############################################################################# DynamicArrayOf *MLR_Water::detailTexCoords; MLR_Water::ClassData* MLR_Water::DefaultData = NULL; Stuff::UnitVector3D MLR_Water::sunLight; Stuff::Scalar MLR_Water::specMult; Stuff::Scalar MLR_Water::specCutoff; int MLR_Water::specPow; BYTE MLR_Water::lookUpSpecular[256]; extern DynamicArrayOf *lightMapUVs; extern DynamicArrayOf *lightMapSqFalloffs; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLR_Water::InitializeClass() { Verify(!DefaultData); Verify(gos_GetCurrentHeap() == StaticHeap); DefaultData = new ClassData( MLR_WaterClassID, "MidLevelRenderer::MLR_Water", MLR_I_C_DeT_TMesh::DefaultData, (MLRPrimitiveBase::Factory)&Make ); Register_Object(DefaultData); Vector3D sl(1.0f, -1.0f, -1.0f); sl.Normalize(sl); sunLight = sl; specMult = 345.0f; specPow = 5; specCutoff = 0.5f; detailTexCoords = new DynamicArrayOf (Limits::Max_Number_Vertices_Per_Mesh); Register_Object(detailTexCoords); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLR_Water::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; Unregister_Object(detailTexCoords); delete detailTexCoords; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLR_Water::SetSpecularValues(Stuff::Scalar fac, int _pow, Scalar cutOff ) { specMult = fac; specPow = _pow; specCutoff = cutOff; Scalar oneOver255 = 1.0f/255.0f; for(int i=0;i<256;i++) { Scalar sval = static_cast(255.5f * specMult * pow(i*oneOver255, specPow)); if(sval>255.0f) { lookUpSpecular[i] = 0xff; } else { lookUpSpecular[i] = Truncate_Float_To_Byte(sval); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLR_Water::MLR_Water( ClassData *class_data, MemoryStream *stream, int version ): MLR_I_C_DeT_TMesh(class_data, stream, version) { Check_Pointer(this); Check_Pointer(stream); referenceState.SetLightingMode(MLRState::LightMapLightingMode); referenceState.SetSpecularOn(); facePlanes.SetLength(0); if (!dataStore) dataStore = new DataStorage; Check_Pointer(dataStore); if (!colors.GetLength()) { #if COLOR_AS_DWORD dataStore->colors.AssignValue(0xFFFFFFFF, coords.GetLength()); #else dataStore->colors.AssignValue(RGBAColor::White, coords.GetLength()); #endif colors.AssignData(dataStore->colors.GetData(), dataStore->colors.GetLength()); } Verify(colors.GetData() == dataStore->colors.GetData()); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLR_Water::MLR_Water(ClassData *class_data): MLR_I_C_DeT_TMesh(class_data) { Check_Pointer(this); facePlanes.SetLength(0); if (!dataStore) dataStore = new DataStorage; Check_Pointer(dataStore); if (!colors.GetLength()) { #if COLOR_AS_DWORD dataStore->colors.AssignValue(0xFFFFFFFF, coords.GetLength()); #else dataStore->colors.AssignValue(RGBAColor::White, coords.GetLength()); #endif colors.AssignData(dataStore->colors.GetData(), dataStore->colors.GetLength()); } Verify(colors.GetData() == dataStore->colors.GetData()); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLR_Water::~MLR_Water() { Check_Object(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MLR_Water* MLR_Water::Make( MemoryStream *stream, int version ) { Check_Object(stream); gos_PushCurrentHeap(PrimitiveHeap); MLR_Water *water = new MLR_Water(DefaultData, stream, version); gos_PopCurrentHeap(); return water; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLR_Water::Save(MemoryStream *stream) { Check_Object(this); Check_Object(stream); MLR_I_C_DeT_TMesh::Save(stream); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLR_Water::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int MLR_Water::FindBackFace(const Point3D& u, const Normal3D& n) { Check_Object(this); MLR_RENDER("Backface::MLR_Water"); Start_Timer(Find_Backface_Time); BYTE *iPtr; if(numOfTriangles <= 0) { visible = 0; Stop_Timer(Find_Backface_Time); return 0; } if(gEnableFancyWater==0) { FindVisibleVertices(); channelUse &= ~(1<colors.GetData(); int len = dataStore->colors.GetLength(); DWORD new_color = paintMeColorDW; for(int i=0;i=255.0f) { *((BYTE *)&new_color + 3) = 0xff; } else { *((BYTE *)&new_color + 3) = Truncate_Float_To_Byte(a); } cols[i] = new_color; #else // SPEW(("micgaert", "%f", v.y/v.GetApproximateLength())); cols[i] = paintMeColorF; cols[i].alpha = a; #endif v.y=0.0f; /* Vector3D reflect_vect(0.0f,1.0f,0.0f), rev_sun; rev_sun.Negate(sunLight); reflect_vect.Multiply(reflect_vect,2*rev_sun.y); reflect_vect.Subtract(reflect_vect, rev_sun); reflect_vect.Normalize(reflect_vect); Scalar sval = reflect_vect*v; */ Scalar sval = sunLight*v; if(svalGetData(); memset(iPtr, 1, numOfTriangles); visible = 1; FindVisibleVertices(); // passes = 1; Stop_Timer(Find_Backface_Time); return 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLR_Water::Copy( MLR_I_C_TMesh *prim, MLRState detailState, Stuff::Scalar xOff, Stuff::Scalar yOff, Stuff::Scalar xFac, Stuff::Scalar yFac ) { MLR_I_C_DeT_TMesh::Copy(prim, detailState, xOff, yOff, xFac, yFac); facePlanes.SetLength(0); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool MLR_Water::Copy(MLR_I_C_DeT_PMesh *prim) { bool b = MLR_I_C_DeT_TMesh::Copy(prim); facePlanes.SetLength(0); return b; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* int MLR_Water::GetNumPasses() { Check_Object(this); return 2; } */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // #define I_SAY_YES_TO_DETAIL_TEXTURES #define I_SAY_YES_TO_WATER #define I_SAY_YES_TO_COLOR #undef I_SAY_YES_TO_TERRAIN2 #undef I_SAY_YES_TO_DUAL_TEXTURES #undef I_SAY_YES_TO_TERRAIN #undef I_SAY_YES_TO_LIGHTING #define CLASSNAME MLR_Water #define CLASSNAMENOCOLOR MLR_I_DeT_TMesh //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // This include contains follwing functions: // void MLR_Water::TransformNoClip(Matrix4D*, GOSVertexPool*); // int MLR_Water::Clip(MLRClippingState, GOSVertexPool*); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include #undef I_SAY_YES_TO_DETAIL_TEXTURES #undef I_SAY_YES_TO_WATER #undef I_SAY_YES_TO_COLOR #undef CLASSNAME #undef CLASSNAMENOCOLOR extern RGBAColor errorColor; extern bool CheckForBigTriangles(DynamicArrayOf *lightMapUVs, int stride); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MLR_Water::LightMapLighting(MLRLight *light) { MLRLightMap *lightMap = light->GetLightMap(); 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; Scalar waterHeight = coords[0].z; BYTE addedVertices = 0; BYTE addedIndicies = 0; int tooBig = 0; Scalar bigUV = MLRState::GetMaxUV(); switch(light->GetLightType()) { case MLRLight::PointLight: { Check_Object(lightMap); light->GetInShapePosition(lightPosInShape); Scalar n, f; Cast_Object(MLRPointLight*, light)->GetFalloffDistance(n, f); Scalar One_Over_Falloff = 1.0f/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 = Vector3D(0.0f, 1.0f, 0.0f); 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; } } } } } break; case MLRLight::SpotLight: { int behindCount = 0, falloffCount = 0; Check_Object(lightMap); 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 1 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 #else if(tooBig != 0) { lightMap->SetPolygonMarker(1); lightMap->AddUShort(3); for(k=0;k<3;k++) { lightMap->AddCoord(coords[index[k+j]]); } for(k=0;k<3;k++) { lightMap->AddColor(RGBAColor(0.0f, 0.0f, 0.5f, 1.0f)); } for(k=0;k<3;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(3); for(k=0;k<3;k++) { lightMap->AddCoord(coords[index[k+j]]); } for(k=0;k<3;k++) { lightMap->AddColor(RGBAColor(0.5f, 0.0f, 0.0f, 1.0f)); } for(k=0;k<3;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, 3) == true) ) { lightMap->SetPolygonMarker(1); lightMap->AddUShort(3); for(k=0;k<3;k++) { lightMap->AddCoord(coords[index[k+j]]); } for(k=0;k<3;k++) { lightMap->AddColor(lightMapSqFalloffs[k], lightMapSqFalloffs[k], lightMapSqFalloffs[k], 1.0f); } for(k=0;k<3;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, 3) == false) { lightMap->SetPolygonMarker(1); lightMap->AddUShort(3); for(k=0;k<3;k++) { lightMap->AddCoord(coords[index[k+j]]); } for(k=0;k<3;k++) { lightMap->AddColor(errorColor); } for(k=0;k<3;k++) { lightMap->AddUVs(0.5f, 0.5f); // DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n"; } } #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: break; default: STOP(("MLR_Water::LightMapLighting: What you want me to do ?")); break; } if(addedIndicies && addedVertices) { lightMap->AddMesh(referenceState.GetPriority()+1, addedVertices, addedIndicies); } } void MLR_Water::FindFacePlanes() { Check_Object(this); int i, j, numPrimitives = GetNumPrimitives(); Vector3D v; Verify(index.GetLength() > 0); for(i=0,j=0;i