12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322 |
- //===========================================================================//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- #include "MLRHeaders.hpp"
- #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
- BitTrace *MLR_I_TMesh_Clip;
- #endif
- extern DWORD gEnableLightMaps;
- #define UV_TEST 0
- #define SPEW_AWAY 0
- //#define TOP_DOWN_ONLY
- //#############################################################################
- //###### MLRIndexedTriMesh with no color no lighting one texture layer ######
- //#############################################################################
- MLR_I_TMesh::ClassData*
- MLR_I_TMesh::DefaultData = NULL;
- extern DynamicArrayOf<Vector2DScalar> *lightMapUVs;
- extern DynamicArrayOf<Scalar> *lightMapSqFalloffs;
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLR_I_TMesh::InitializeClass()
- {
- Verify(!DefaultData);
- Verify(gos_GetCurrentHeap() == StaticHeap);
- DefaultData =
- new ClassData(
- MLR_I_TMeshClassID,
- "MidLevelRenderer::MLR_I_TMesh",
- MLRIndexedPrimitiveBase::DefaultData,
- (MLRPrimitiveBase::Factory)&Make
- );
- Register_Object(DefaultData);
- #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
- MLR_I_TMesh_Clip = new BitTrace("MLR_I_TMesh_Clip");
- Register_Object(MLR_I_TMesh_Clip);
- #endif
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLR_I_TMesh::TerminateClass()
- {
- Unregister_Object(DefaultData);
- delete DefaultData;
- DefaultData = NULL;
- #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
- Unregister_Object(MLR_I_TMesh_Clip);
- delete MLR_I_TMesh_Clip;
- #endif
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLR_I_TMesh::MLR_I_TMesh(
- ClassData *class_data,
- MemoryStream *stream,
- int version
- ):
- MLRIndexedPrimitiveBase(class_data, stream, version)
- {
- Check_Pointer(this);
- Check_Pointer(stream);
- Verify(gos_GetCurrentHeap() == Heap);
- numOfTriangles = index.GetLength()/3;
- facePlanes.SetLength(numOfTriangles);
- testList.SetLength(numOfTriangles);
- FindFacePlanes();
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLR_I_TMesh::MLR_I_TMesh(ClassData *class_data):
- MLRIndexedPrimitiveBase(class_data)
- {
- Check_Pointer(this);
- Verify(gos_GetCurrentHeap() == Heap);
- drawMode = SortData::TriIndexedList;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLR_I_TMesh::~MLR_I_TMesh()
- {
- Check_Object(this);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLR_I_TMesh*
- MLR_I_TMesh::Make(
- MemoryStream *stream,
- int version
- )
- {
- Check_Object(stream);
- gos_PushCurrentHeap(Heap);
- MLR_I_TMesh *mesh = new MLR_I_TMesh(DefaultData, stream, version);
- gos_PopCurrentHeap();
- return mesh;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLR_I_TMesh::Save(MemoryStream *stream)
- {
- Check_Object(this);
- Check_Object(stream);
- MLRIndexedPrimitiveBase::Save(stream);
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLR_I_TMesh::TestInstance() const
- {
- Verify(IsDerivedFrom(DefaultData));
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- bool
- MLR_I_TMesh::Copy(MLR_I_PMesh *pMesh)
- {
- Check_Object(this);
- Check_Object(pMesh);
- Verify(gos_GetCurrentHeap() == Heap);
- int len;
- unsigned short *_index;
- Point3D *_coords;
- Vector2DScalar *_texCoords;
- pMesh->GetCoordData(&_coords, &len);
- SetCoordData(_coords, len);
- pMesh->GetIndexData(&_index, &len);
- SetIndexData(_index, len);
- SetSubprimitiveLengths(NULL, pMesh->GetNumPrimitives());
- facePlanes.SetLength(GetNumPrimitives());
- testList.SetLength(GetNumPrimitives());
- FindFacePlanes();
- pMesh->GetTexCoordData(&_texCoords, &len);
- SetTexCoordData(_texCoords, len);
- referenceState = pMesh->GetReferenceState();
- visibleIndexedVerticesKey = false;
- visibleIndexedVertices.SetLength(coords.GetLength());
- return true;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLR_I_TMesh::InitializeDrawPrimitive(unsigned char vis, int parameter)
- {
- MLRIndexedPrimitiveBase::InitializeDrawPrimitive(vis, parameter);
- if(parameter & 1)
- {
- ResetTestList();
- }
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLR_I_TMesh::FindFacePlanes()
- {
- Check_Object(this);
- int i, j, numPrimitives = GetNumPrimitives();
- Vector3D v;
- Verify(index.GetLength() > 0);
- for(i=0,j=0;i<numPrimitives;++i,j+=3)
- {
- facePlanes[i].BuildPlane(
- coords[index[j]],
- coords[index[j+1]],
- coords[index[j+2]]
- );
- ;
- }
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- int
- MLR_I_TMesh::FindBackFace(const Point3D& u)
- {
- Check_Object(this);
- int ret = 0;
- unsigned char *iPtr;
- Plane *p;
- if(numOfTriangles <= 0)
- {
- visible = 0;
- return 0;
- }
- p = &facePlanes[numOfTriangles-1];
- iPtr = &testList[0];
- if(state.GetBackFaceMode() == MLRState::BackFaceOffMode)
- {
- ResetTestList();
- ret = 1;
- }
- else
- {
- memset(iPtr, 0, numOfTriangles);
- for(int i=numOfTriangles-1;i>=0;p--,i--)
- {
- if(p->GetDistanceTo(u)>= 0.0f)
- {
- iPtr[i] = (unsigned char)(ret = 1);
- }
- }
- }
- visible = (unsigned char)ret;
- FindVisibleVertices();
- return ret;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- void
- MLR_I_TMesh::ResetTestList()
- {
- int i, numPrimitives = GetNumPrimitives();
- unsigned char *iPtr = &testList[0];
- for(i=0;i<numPrimitives;i++,iPtr++)
- {
- *iPtr = 1;
- }
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- int
- MLR_I_TMesh::FindVisibleVertices()
- {
- Check_Object(this);
- Verify(index.GetLength() > 0);
- int ret, i, j;
- DWORD *indices = (DWORD *)index.GetData();
- for(i=0,j=0,ret=0;i<(numOfTriangles>>1);++i)
- {
- if(testList[i<<1] != 0)
- {
- visibleIndexedVertices[(*(indices+j))&0xffff] = 1;
- visibleIndexedVertices[(*(indices+j))>>16] = 1;
- visibleIndexedVertices[(*(indices+j+1))&0xffff] = 1;
- ret = 1;
- }
- if(testList[(i<<1)+1] != 0)
- {
- visibleIndexedVertices[(*(indices+j+1))>>16] = 1;
- visibleIndexedVertices[(*(indices+j+2))&0xffff] = 1;
- visibleIndexedVertices[(*(indices+j+2))>>16] = 1;
- ret = 1;
- }
- j+=3;
- }
- if(numOfTriangles&1)
- {
- if(testList[numOfTriangles-1] != 0)
- {
- j <<= 1;
- visibleIndexedVertices[index[j++]] = 1;
- visibleIndexedVertices[index[j++]] = 1;
- visibleIndexedVertices[index[j++]] = 1;
- ret = 1;
- }
- }
- visibleIndexedVerticesKey = true;
- return ret;
- }
- extern DWORD gEnableTextureSort, gEnableAlphaSort;
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- /*
- void
- MLR_I_TMesh::Transform(Matrix4D *mat)
- {
- Check_Object(this);
- Verify(index.GetLength() > 0);
- int i, len = coords.GetLength();
- if(visibleIndexedVerticesKey == false)
- {
- FindVisibleVertices();
- }
- Stuff::Vector4D *v4d = transformedCoords.GetData();
- Stuff::Point3D *p3d = coords.GetData();
- MLRClippingState *cs = clipPerVertex.GetData();
- unsigned char *viv = visibleIndexedVertices.GetData();
- for(i=0;i<len;i++,p3d++,v4d++,cs++,viv++)
- {
- if(*viv == 0)
- {
- continue;
- }
-
- v4d->Multiply(*p3d, *mat);
- #ifdef LAB_ONLY
- Statistics::MLR_TransformedVertices++;
- #endif
- cs->Clip4dVertex(v4d);
- //
- //--------------------------------------------------------
- // I claims all vertices are in. lets check it. who knows
- //--------------------------------------------------------
- //
- #ifdef LAB_ONLY
- if( (*cs)==0)
- {
- #if defined(_ARMOR)
- if(ArmorLevel > 3)
- {
- //
- //--------------------------------------------------------
- // I claims all vertices are in. lets check it. who knows
- //--------------------------------------------------------
- //
- Verify(v4d->x >= 0.0f && v4d->x <= v4d->w );
- Verify(v4d->y >= 0.0f && v4d->y <= v4d->w );
- Verify(v4d->z >= 0.0f && v4d->z <= v4d->w );
- }
- #endif
- Statistics::MLR_NonClippedVertices++;
- }
- else
- {
- Statistics::MLR_ClippedVertices++;
- }
- #endif
- }
- }
- */
- #undef I_SAY_YES_TO_DUAL_TEXTURES
- #undef I_SAY_YES_TO_COLOR
- #undef I_SAY_YES_TO_LIGHTING
- #define CLASSNAME MLR_I_TMesh
- #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
- #define SET_MLR_TMESH_CLIP() MLR_I_TMesh_Clip->Set()
- #define CLEAR_MLR_TMESH_CLIP() MLR_I_TMesh_Clip->Clear()
- #else
- #define SET_MLR_TMESH_CLIP()
- #define CLEAR_MLR_TMESH_CLIP()
- #endif
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // This include contains follwing functions:
- // void MLR_I_TMesh::TransformNoClip(Matrix4D*, GOSVertexPool*);
- // int MLR_I_TMesh::Clip(MLRClippingState, GOSVertexPool*);
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- #include <MLR\MLRTriangleClipping.hpp>
- #undef CLASSNAME
- //---------------------------------------------------------------------------
- //
- void
- MLR_I_TMesh::Lighting(MLRLight* const* lights, int nrLights)
- {
- int i;
- MLRLightMap *lightMap;
- for(i=0;i<nrLights;i++)
- {
- lightMap = lights[i]->GetLightMap();
- if(lightMap!=NULL)
- {
- Start_Timer(LightMap_Light_Time);
- LightMapLighting(lights[i]);
- Stop_Timer(LightMap_Light_Time);
- }
- }
- }
- extern RGBAColor errorColor;
- extern bool
- CheckForBigTriangles(DynamicArrayOf<Vector2DScalar> *lightMapUVs, int stride);
- //---------------------------------------------------------------------------
- //
- void
- MLR_I_TMesh::LightMapLighting(MLRLight *light)
- {
- int i, j, k, len = numOfTriangles;
- 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;
- }
- Scalar bigUV = MLRState::GetMaxUV();
- int tooBig = 0;
- switch(light->GetLightType())
- {
- case MLRLight::PointLight:
- {
- Check_Object(lightMap);
- lightMap->AddState(referenceState.GetPriority()+1);
-
- light->GetInShapePosition(lightPosInShape);
- for(i=0,j=0,k=0;i<len;i++,j += 3)
- {
- 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, X_Axis, Y_Axis);
- matrix.GetLocalLeftInWorld(&left);
- matrix.GetLocalUpInWorld(&up);
- matrix.GetLocalForwardInWorld(&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;
- tooBig = 0;
- for(k=0;k<3;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;
- }
- if(
- (*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
- (*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
- )
- {
- tooBig++;
- }
- }
- }
- else
- {
- continue;
- }
- if(tooBig==0 && (lm == true || CheckForBigTriangles(lightMapUVs, 3) == true))
- {
- lightMap->SetPolygonMarker(0);
- lightMap->AddUShort(3);
- #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(sq_falloff, sq_falloff, sq_falloff, 1.0f);
- lightMap->AddColor(color);
- for(k=0;k<3;k++)
- {
- lightMap->AddCoord(coords[index[k+j]]);
- }
- 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";
- }
- }
- }
- }
- break;
- case MLRLight::SpotLight:
- {
- int behindCount = 0, falloffCount = 0;
- Check_Object(lightMap);
- lightMap->AddState(referenceState.GetPriority()+1);
-
- 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(
- (*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)
- )
- {
- 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";
- }
- #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;
- default:
- STOP(("MLR_I_PMesh::LightMapLighting: What you want me to do ?"));
- break;
- }
- }
- //---------------------------------------------------------------------------
- //
- bool
- MLR_I_TMesh::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;
- bool hit = false;
- for (int polygon=0; polygon<numOfTriangles; poly_start += 3,++polygon)
- {
- //
- //---------------------------------
- // 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)
- {
- continue;
- }
- bool negate = false;
- if (product > -SMALL)
- {
- if (GetCurrentState().GetBackFaceMode() == MLRState::BackFaceOnMode)
- {
- 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;
- 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);
- }
- }
- //
- //
- //----------------------------------------------------
- // 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);
- }
- }
- //
- //----------------------
- // Return the hit status
- //----------------------
- //
- return hit;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLR_I_TMesh*
- MidLevelRenderer::CreateIndexedTriCube_NoColor_NoLit(
- Scalar half,
- MLRState *state
- )
- {
- #if 0
- gos_PushCurrentHeap(Heap);
- MLR_I_TMesh *ret = new MLR_I_TMesh();
- Register_Object(ret);
- Point3D *coords = new Point3D [8];
- Register_Object(coords);
- 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];
- Register_Pointer(lengths);
- int i;
- for(i=0;i<6;i++)
- {
- lengths[i] = 4;
- }
- ret->SetSubprimitiveLengths(lengths, 6);
- ret->SetCoordData(coords, 8);
- unsigned short *index = new unsigned short [6*4];
- Register_Pointer(index);
- 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();
- Vector2DScalar *texCoords = new Vector2DScalar[8];
- Register_Object(texCoords);
- 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);
- Unregister_Object(texCoords);
- delete [] texCoords;
- Unregister_Pointer(index);
- delete [] index;
- Unregister_Pointer(lengths);
- delete [] lengths;
- Unregister_Object(coords);
- delete [] coords;
-
- gos_PopCurrentHeap();
- return ret;
- #endif
- return NULL;
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- MLRShape*
- MidLevelRenderer::CreateIndexedTriIcosahedron_NoColor_NoLit(
- IcoInfo& icoInfo,
- MLRState *state
- )
- {
- gos_PushCurrentHeap(Heap);
- MLRShape *ret = new MLRShape(20);
- Register_Object(ret);
- int i, j, k;
- long nrTri = (long) ceil (icoInfo.all * pow (4.0f, icoInfo.depth));
- Point3D v[3];
- if(3*nrTri >= Limits::Max_Number_Vertices_Per_Mesh)
- {
- nrTri = Limits::Max_Number_Vertices_Per_Mesh/3;
- }
- Point3D *coords = new Point3D [nrTri*3];
- Register_Pointer(coords);
-
- Point3D *collapsedCoords = NULL;
- if(icoInfo.indexed==true)
- {
- collapsedCoords = new Point3D [nrTri*3];
- Register_Pointer(collapsedCoords);
- }
- unsigned short *index = new unsigned short [nrTri*3];
- Register_Pointer(index);
- Vector2DScalar *texCoords = new Vector2DScalar[nrTri*3];
- Register_Pointer(texCoords);
- int uniquePoints = 0;
- for (k=0;k<20;k++)
- {
- triDrawn = 0;
- MLR_I_TMesh *mesh = new MLR_I_TMesh();
- Register_Object(mesh);
- // setup vertex position information
- for (j=0;j<3;j++)
- {
- v[j].x = vdata[tindices[k][j]][0];
- v[j].y = vdata[tindices[k][j]][1];
- v[j].z = vdata[tindices[k][j]][2];
- }
- subdivide (coords, v[0], v[1], v[2], icoInfo.depth, nrTri, icoInfo.radius);
- mesh->SetSubprimitiveLengths(NULL, nrTri);
- if(icoInfo.indexed==true)
- {
- uniquePoints = 1;
- collapsedCoords[0] = coords[0];
- index[0] = 0;
- for(i=1;i<nrTri*3;i++)
- {
- for(j=0;j<uniquePoints;j++)
- {
- if(coords[i] == collapsedCoords[j])
- {
- break;
- }
- }
- if(j==uniquePoints)
- {
- collapsedCoords[uniquePoints++] = coords[i];
- }
- index[i] = static_cast<unsigned short>(j);
- }
- mesh->SetCoordData(collapsedCoords, uniquePoints);
- }
- else
- {
- uniquePoints = nrTri*3;
- for(i=0;i<nrTri*3;i++)
- {
- index[i] = static_cast<unsigned short>(i);
- }
- mesh->SetCoordData(coords, nrTri*3);
- }
- mesh->SetIndexData(index, nrTri*3);
- mesh->FindFacePlanes();
- if(state == NULL)
- {
- for(i=0;i<uniquePoints;i++)
- {
- texCoords[i] = Vector2DScalar(0.0f, 0.0f);
- }
- }
- else
- {
- mesh->SetReferenceState(*state);
- if(state->GetTextureHandle() > 0)
- {
- if(icoInfo.indexed==true)
- {
- for(i=0;i<uniquePoints;i++)
- {
- texCoords[i] =
- Vector2DScalar(
- (1.0f + collapsedCoords[i].x)/2.0f,
- (1.0f + collapsedCoords[i].y)/2.0f
- );
- }
- }
- else
- {
- for(i=0;i<nrTri;i++)
- {
- texCoords[3*i] =
- Vector2DScalar(
- (1.0f + coords[3*i].x)/2.0f,
- (1.0f + coords[3*i].y)/2.0f
- );
- texCoords[3*i+1] =
- Vector2DScalar(
- (1.0f + coords[3*i+1].x)/2.0f,
- (1.0f + coords[3*i+1].y)/2.0f
- );
- texCoords[3*i+2] =
- Vector2DScalar(
- (1.0f + coords[3*i+2].x)/2.0f,
- (1.0f + coords[3*i+2].y)/2.0f
- );
- }
- }
- }
- else
- {
- for(i=0;i<uniquePoints;i++)
- {
- texCoords[i] = Vector2DScalar(0.0f, 0.0f);
- }
- }
- }
- mesh->SetTexCoordData(texCoords, uniquePoints);
- ret->Add(mesh);
- mesh->DetachReference();
- }
- Unregister_Pointer(texCoords);
- delete [] texCoords;
- Unregister_Pointer(index);
- delete [] index;
- if(icoInfo.indexed==true)
- {
- Unregister_Pointer(collapsedCoords);
- delete [] collapsedCoords;
- }
-
- Unregister_Pointer(coords);
- delete [] coords;
- gos_PopCurrentHeap();
- return ret;
- }
|