From b4ea1123dce419f4d61f534abea0a2634cd16fe1 Mon Sep 17 00:00:00 2001 From: thecelloman Date: Fri, 5 Apr 2013 12:39:26 -0400 Subject: [PATCH] Remove Interior Object format (DIF) --- Engine/source/T3D/aiClient.cpp | 2 +- Engine/source/T3D/aiPlayer.cpp | 2 +- Engine/source/T3D/camera.cpp | 1 - Engine/source/T3D/convexShape.cpp | 62 - Engine/source/T3D/debris.cpp | 3 +- Engine/source/T3D/fps/guiCrossHairHud.cpp | 2 +- Engine/source/T3D/fps/guiShapeNameHud.cpp | 2 +- Engine/source/T3D/fx/fxFoliageReplicator.cpp | 5 - Engine/source/T3D/fx/fxFoliageReplicator.h | 4 - Engine/source/T3D/fx/fxShapeReplicator.cpp | 5 - Engine/source/T3D/fx/fxShapeReplicator.h | 4 - Engine/source/T3D/fx/precipitation.cpp | 1 - Engine/source/T3D/gameFunctions.cpp | 1 - Engine/source/T3D/item.cpp | 5 +- Engine/source/T3D/objectTypes.h | 48 +- Engine/source/T3D/player.cpp | 4 +- Engine/source/T3D/projectile.cpp | 7 +- Engine/source/T3D/rigidShape.cpp | 6 +- Engine/source/T3D/shapeBase.cpp | 4 +- Engine/source/T3D/tsStatic.cpp | 2 +- Engine/source/T3D/turret/aiTurretShape.cpp | 1 - Engine/source/T3D/turret/turretShape.cpp | 2 +- Engine/source/T3D/vehicles/flyingVehicle.cpp | 8 +- Engine/source/T3D/vehicles/hoverVehicle.cpp | 8 +- Engine/source/T3D/vehicles/wheeledVehicle.cpp | 8 +- Engine/source/collision/convex.h | 1 - Engine/source/environment/waterBlock.cpp | 4 +- .../source/gui/worldEditor/terrainEditor.cpp | 68 - Engine/source/interior/forceField.cpp | 469 --- Engine/source/interior/forceField.h | 195 -- Engine/source/interior/interior.cpp | 2645 ----------------- Engine/source/interior/interior.h | 1172 -------- Engine/source/interior/interiorCollision.cpp | 1775 ----------- Engine/source/interior/interiorDebug.cpp | 711 ----- Engine/source/interior/interiorIO.cpp | 1669 ----------- Engine/source/interior/interiorInstance.cpp | 1547 ---------- Engine/source/interior/interiorInstance.h | 254 -- Engine/source/interior/interiorLMManager.cpp | 384 --- Engine/source/interior/interiorLMManager.h | 92 - Engine/source/interior/interiorRender.cpp | 359 --- Engine/source/interior/interiorRes.cpp | 355 --- Engine/source/interior/interiorRes.h | 170 -- Engine/source/interior/interiorResObjects.cpp | 246 -- Engine/source/interior/interiorResObjects.h | 151 - Engine/source/interior/interiorSimpleMesh.cpp | 644 ---- Engine/source/interior/interiorSimpleMesh.h | 208 -- Engine/source/interior/interiorSubObject.cpp | 108 - Engine/source/interior/interiorSubObject.h | 80 - Engine/source/interior/mirrorSubObject.cpp | 286 -- Engine/source/interior/mirrorSubObject.h | 104 - Engine/source/interior/pathedInterior.cpp | 586 ---- Engine/source/interior/pathedInterior.h | 157 - .../lighting/basic/basicLightManager.cpp | 4 - .../source/lighting/basic/basicLightManager.h | 2 - .../lighting/basic/blInteriorSystem.cpp | 1472 --------- .../source/lighting/basic/blInteriorSystem.h | 57 - Engine/source/lighting/common/blobShadow.cpp | 2 +- .../source/lighting/common/sceneLighting.cpp | 25 - .../lighting/shadowMap/shadowMapPass.cpp | 3 +- .../source/renderInstance/renderBinManager.h | 1 - .../source/renderInstance/renderGlowMgr.cpp | 1 - .../renderInstance/renderPassManager.cpp | 1 - .../source/renderInstance/renderPassManager.h | 1 - .../renderInstance/renderPrePassMgr.cpp | 4 +- Engine/source/scene/pathManager.cpp | 1 - Engine/source/ts/collada/colladaUtils.cpp | 2 +- .../Empty/game/core/scripts/client/metrics.cs | 2 - .../game/core/scripts/client/renderManager.cs | 1 - .../Empty/game/core/scripts/client/shaders.cs | 13 - .../Empty/game/scripts/client/default.bind.cs | 64 - .../game/shaders/common/debugInteriorsP.hlsl | 53 - .../game/shaders/common/debugInteriorsV.hlsl | 49 - .../shaders/common/gl/debugInteriorsP.glsl | 34 - .../shaders/common/gl/debugInteriorsV.glsl | 33 - .../scripts/materialEditor.ed.cs | 33 +- .../gui/WorldEditorTreeWindow.ed.gui | 2 +- .../worldEditor/gui/guiInteriorExportGui.gui | 240 -- .../gui/guiWorldEditorCreatorWindow.ed.gui | 2 +- .../Empty/game/tools/worldEditor/main.cs | 1 - .../tools/worldEditor/scripts/EditorGui.ed.cs | 6 - .../worldEditor/scripts/editors/creator.ed.cs | 54 +- .../tools/worldEditor/scripts/menus.ed.cs | 1 - .../Full/game/core/scripts/client/metrics.cs | 2 - .../game/core/scripts/client/renderManager.cs | 1 - .../Full/game/core/scripts/client/shaders.cs | 13 - .../Full/game/scripts/client/default.bind.cs | 64 - .../game/shaders/common/debugInteriorsP.hlsl | 53 - .../game/shaders/common/debugInteriorsV.hlsl | 49 - .../shaders/common/gl/debugInteriorsP.glsl | 34 - .../shaders/common/gl/debugInteriorsV.glsl | 33 - .../scripts/materialEditor.ed.cs | 37 +- .../gui/WorldEditorTreeWindow.ed.gui | 2 +- .../worldEditor/gui/guiInteriorExportGui.gui | 240 -- .../gui/guiWorldEditorCreatorWindow.ed.gui | 2 +- Templates/Full/game/tools/worldEditor/main.cs | 1 - .../tools/worldEditor/scripts/EditorGui.ed.cs | 6 - .../worldEditor/scripts/editors/creator.ed.cs | 54 +- .../tools/worldEditor/scripts/menus.ed.cs | 1 - Tools/projectGenerator/modules/T3D.inc | 1 - 99 files changed, 76 insertions(+), 17318 deletions(-) delete mode 100644 Engine/source/interior/forceField.cpp delete mode 100644 Engine/source/interior/forceField.h delete mode 100644 Engine/source/interior/interior.cpp delete mode 100644 Engine/source/interior/interior.h delete mode 100644 Engine/source/interior/interiorCollision.cpp delete mode 100644 Engine/source/interior/interiorDebug.cpp delete mode 100644 Engine/source/interior/interiorIO.cpp delete mode 100644 Engine/source/interior/interiorInstance.cpp delete mode 100644 Engine/source/interior/interiorInstance.h delete mode 100644 Engine/source/interior/interiorLMManager.cpp delete mode 100644 Engine/source/interior/interiorLMManager.h delete mode 100644 Engine/source/interior/interiorRender.cpp delete mode 100644 Engine/source/interior/interiorRes.cpp delete mode 100644 Engine/source/interior/interiorRes.h delete mode 100644 Engine/source/interior/interiorResObjects.cpp delete mode 100644 Engine/source/interior/interiorResObjects.h delete mode 100644 Engine/source/interior/interiorSimpleMesh.cpp delete mode 100644 Engine/source/interior/interiorSimpleMesh.h delete mode 100644 Engine/source/interior/interiorSubObject.cpp delete mode 100644 Engine/source/interior/interiorSubObject.h delete mode 100644 Engine/source/interior/mirrorSubObject.cpp delete mode 100644 Engine/source/interior/mirrorSubObject.h delete mode 100644 Engine/source/interior/pathedInterior.cpp delete mode 100644 Engine/source/interior/pathedInterior.h delete mode 100644 Engine/source/lighting/basic/blInteriorSystem.cpp delete mode 100644 Engine/source/lighting/basic/blInteriorSystem.h delete mode 100644 Templates/Empty/game/shaders/common/debugInteriorsP.hlsl delete mode 100644 Templates/Empty/game/shaders/common/debugInteriorsV.hlsl delete mode 100644 Templates/Empty/game/shaders/common/gl/debugInteriorsP.glsl delete mode 100644 Templates/Empty/game/shaders/common/gl/debugInteriorsV.glsl delete mode 100644 Templates/Empty/game/tools/worldEditor/gui/guiInteriorExportGui.gui delete mode 100644 Templates/Full/game/shaders/common/debugInteriorsP.hlsl delete mode 100644 Templates/Full/game/shaders/common/debugInteriorsV.hlsl delete mode 100644 Templates/Full/game/shaders/common/gl/debugInteriorsP.glsl delete mode 100644 Templates/Full/game/shaders/common/gl/debugInteriorsV.glsl delete mode 100644 Templates/Full/game/tools/worldEditor/gui/guiInteriorExportGui.gui diff --git a/Engine/source/T3D/aiClient.cpp b/Engine/source/T3D/aiClient.cpp index ee16964ae..3decd3462 100644 --- a/Engine/source/T3D/aiClient.cpp +++ b/Engine/source/T3D/aiClient.cpp @@ -355,7 +355,7 @@ U32 AIClient::getMoveList( Move **movePtr,U32 *numMoves ) { Point3F targetLoc = mMoveDestination; // Change this if( mPlayer ) { - if( !mPlayer->getContainer()->castRay( mLocation, targetLoc, InteriorObjectType | + if( !mPlayer->getContainer()->castRay( mLocation, targetLoc, StaticShapeObjectType | StaticObjectType | TerrainObjectType, &dummy ) ) { if( !mTargetInLOS ) diff --git a/Engine/source/T3D/aiPlayer.cpp b/Engine/source/T3D/aiPlayer.cpp index de9cb1400..725aaed29 100644 --- a/Engine/source/T3D/aiPlayer.cpp +++ b/Engine/source/T3D/aiPlayer.cpp @@ -427,7 +427,7 @@ bool AIPlayer::getAIMove(Move *movePtr) // if it hit something. RayInfo dummy; if (getContainer()->castRay( location, targetLoc, - InteriorObjectType | StaticShapeObjectType | StaticObjectType | + StaticShapeObjectType | StaticObjectType | TerrainObjectType, &dummy)) { if (mTargetInLOS) { throwCallback( "onTargetExitLOS" ); diff --git a/Engine/source/T3D/camera.cpp b/Engine/source/T3D/camera.cpp index 0d742b620..67f13c1af 100644 --- a/Engine/source/T3D/camera.cpp +++ b/Engine/source/T3D/camera.cpp @@ -1363,7 +1363,6 @@ void Camera::_validateEyePoint(F32 pos, MatrixF *mat) disableCollision(); RayInfo collision; U32 mask = TerrainObjectType | - InteriorObjectType | WaterObjectType | StaticShapeObjectType | PlayerObjectType | diff --git a/Engine/source/T3D/convexShape.cpp b/Engine/source/T3D/convexShape.cpp index 622b28fa2..8f9cecaae 100644 --- a/Engine/source/T3D/convexShape.cpp +++ b/Engine/source/T3D/convexShape.cpp @@ -924,68 +924,6 @@ void ConvexShape::exportToCollada() Con::errorf( "ConvexShape::exportToCollada() - has no surfaces to export!" ); return; } -/* - // Get an optimized version of our mesh - OptimizedPolyList polyList; - - if (bakeTransform) - { - MatrixF mat = getTransform(); - Point3F scale = getScale(); - - pInterior->buildExportPolyList(interiorMesh, &mat, &scale); - } - else - pInterior->buildExportPolyList(interiorMesh); - - // Get our export path - Torque::Path colladaFile = mInteriorRes.getPath(); - - // Make sure to set our Collada extension - colladaFile.setExtension("dae"); - - // Use the InteriorInstance name if possible - String meshName = getName(); - - // Otherwise use the DIF's file name - if (meshName.isEmpty()) - meshName = colladaFile.getFileName(); - - // If we are baking the transform then append - // a CRC version of the transform to the mesh/file name - if (bakeTransform) - { - F32 trans[19]; - - const MatrixF& mat = getTransform(); - const Point3F& scale = getScale(); - - // Copy in the transform - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 4; j++) - { - trans[i * 4 + j] = mat(i, j); - } - } - - // Copy in the scale - trans[16] = scale.x; - trans[17] = scale.y; - trans[18] = scale.z; - - U32 crc = CRC::calculateCRC(trans, sizeof(F32) * 19); - - meshName += String::ToString("_%x", crc); - } - - // Set the file name as the meshName - colladaFile.setFileName(meshName); - - // Use a ColladaUtils function to do the actual export to a Collada file - ColladaUtils::exportToCollada(colladaFile, interiorMesh, meshName); - } - */ } void ConvexShape::resizePlanes( const Point3F &size ) diff --git a/Engine/source/T3D/debris.cpp b/Engine/source/T3D/debris.cpp index 637fe933b..78526b7ad 100644 --- a/Engine/source/T3D/debris.cpp +++ b/Engine/source/T3D/debris.cpp @@ -41,8 +41,7 @@ #include "lighting/lightQuery.h" -const U32 csmStaticCollisionMask = TerrainObjectType | - InteriorObjectType; +const U32 csmStaticCollisionMask = TerrainObjectType; const U32 csmDynamicCollisionMask = StaticShapeObjectType; diff --git a/Engine/source/T3D/fps/guiCrossHairHud.cpp b/Engine/source/T3D/fps/guiCrossHairHud.cpp index 90fc62bc1..a8cd3e1ba 100644 --- a/Engine/source/T3D/fps/guiCrossHairHud.cpp +++ b/Engine/source/T3D/fps/guiCrossHairHud.cpp @@ -138,7 +138,7 @@ void GuiCrossHairHud::onRender(Point2I offset, const RectI &updateRect) // Collision info. We're going to be running LOS tests and we // don't want to collide with the control object. - static U32 losMask = TerrainObjectType | InteriorObjectType | ShapeBaseObjectType; + static U32 losMask = TerrainObjectType | ShapeBaseObjectType; control->disableCollision(); RayInfo info; diff --git a/Engine/source/T3D/fps/guiShapeNameHud.cpp b/Engine/source/T3D/fps/guiShapeNameHud.cpp index ddfcdcdf2..d63cb2eee 100644 --- a/Engine/source/T3D/fps/guiShapeNameHud.cpp +++ b/Engine/source/T3D/fps/guiShapeNameHud.cpp @@ -177,7 +177,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect) // Collision info. We're going to be running LOS tests and we // don't want to collide with the control object. - static U32 losMask = TerrainObjectType | InteriorObjectType | ShapeBaseObjectType; + static U32 losMask = TerrainObjectType | ShapeBaseObjectType; control->disableCollision(); // All ghosted objects are added to the server connection group, diff --git a/Engine/source/T3D/fx/fxFoliageReplicator.cpp b/Engine/source/T3D/fx/fxFoliageReplicator.cpp index f44947eec..04b6c8976 100644 --- a/Engine/source/T3D/fx/fxFoliageReplicator.cpp +++ b/Engine/source/T3D/fx/fxFoliageReplicator.cpp @@ -397,7 +397,6 @@ void fxFoliageReplicator::initPersistFields() addGroup( "Restrictions" ); // MM: Added Group Header. addField( "AllowOnTerrain", TypeBool, Offset( mFieldData.mAllowOnTerrain, fxFoliageReplicator ), "Foliage will be placed on terrain when set." ); - addField( "AllowOnInteriors", TypeBool, Offset( mFieldData.mAllowOnInteriors, fxFoliageReplicator ), "Foliage will be placed on InteriorInstances when set." ); addField( "AllowOnStatics", TypeBool, Offset( mFieldData.mAllowStatics, fxFoliageReplicator ), "Foliage will be placed on Static shapes when set." ); addField( "AllowOnWater", TypeBool, Offset( mFieldData.mAllowOnWater, fxFoliageReplicator ), "Foliage will be placed on/under water when set." ); addField( "AllowWaterSurface", TypeBool, Offset( mFieldData.mAllowWaterSurface, fxFoliageReplicator ), "Foliage will be placed on water when set. Requires AllowOnWater." ); @@ -435,7 +434,6 @@ void fxFoliageReplicator::CreateFoliage(void) // Check that we can position somewhere! if (!( mFieldData.mAllowOnTerrain || - mFieldData.mAllowOnInteriors || mFieldData.mAllowStatics || mFieldData.mAllowOnWater)) { @@ -633,7 +631,6 @@ void fxFoliageReplicator::CreateFoliage(void) // Check Illegal Placements, fail if we hit a disallowed type. if (((CollisionType & TerrainObjectType) && !mFieldData.mAllowOnTerrain) || - ((CollisionType & InteriorObjectType) && !mFieldData.mAllowOnInteriors) || ((CollisionType & StaticShapeObjectType ) && !mFieldData.mAllowStatics) || ((CollisionType & WaterObjectType) && !mFieldData.mAllowOnWater) ) continue; @@ -1700,7 +1697,6 @@ U32 fxFoliageReplicator::packUpdate(NetConnection * con, U32 mask, BitStream * s stream->write(mFieldData.mLightTime); // Foliage Light Time. stream->writeFlag(mFieldData.mAllowOnTerrain); // Allow on Terrain. - stream->writeFlag(mFieldData.mAllowOnInteriors); // Allow on Interiors. stream->writeFlag(mFieldData.mAllowStatics); // Allow on Statics. stream->writeFlag(mFieldData.mAllowOnWater); // Allow on Water. stream->writeFlag(mFieldData.mAllowWaterSurface); // Allow on Water Surface. @@ -1777,7 +1773,6 @@ void fxFoliageReplicator::unpackUpdate(NetConnection * con, BitStream * stream) stream->read(&mFieldData.mLightTime); // Foliage Light Time. mFieldData.mAllowOnTerrain = stream->readFlag(); // Allow on Terrain. - mFieldData.mAllowOnInteriors = stream->readFlag(); // Allow on Interiors. mFieldData.mAllowStatics = stream->readFlag(); // Allow on Statics. mFieldData.mAllowOnWater = stream->readFlag(); // Allow on Water. mFieldData.mAllowWaterSurface = stream->readFlag(); // Allow on Water Surface. diff --git a/Engine/source/T3D/fx/fxFoliageReplicator.h b/Engine/source/T3D/fx/fxFoliageReplicator.h index 8d4e09d35..deaac64cb 100644 --- a/Engine/source/T3D/fx/fxFoliageReplicator.h +++ b/Engine/source/T3D/fx/fxFoliageReplicator.h @@ -47,12 +47,10 @@ #define AREA_ANIMATION_ARC (1.0f / 360.0f) #define FXFOLIAGEREPLICATOR_COLLISION_MASK ( TerrainObjectType | \ - InteriorObjectType | \ StaticShapeObjectType | \ WaterObjectType ) #define FXFOLIAGEREPLICATOR_NOWATER_COLLISION_MASK ( TerrainObjectType | \ - InteriorObjectType | \ StaticShapeObjectType ) @@ -311,7 +309,6 @@ public: F32 mLightTime; bool mAllowOnTerrain; - bool mAllowOnInteriors; bool mAllowStatics; bool mAllowOnWater; bool mAllowWaterSurface; @@ -371,7 +368,6 @@ public: mLightTime = 5.0f; mAllowOnTerrain = true; - mAllowOnInteriors = true; mAllowStatics = true; mAllowOnWater = false; mAllowWaterSurface = false; diff --git a/Engine/source/T3D/fx/fxShapeReplicator.cpp b/Engine/source/T3D/fx/fxShapeReplicator.cpp index c9a3e7f52..908212716 100644 --- a/Engine/source/T3D/fx/fxShapeReplicator.cpp +++ b/Engine/source/T3D/fx/fxShapeReplicator.cpp @@ -166,7 +166,6 @@ void fxShapeReplicator::initPersistFields() addGroup( "Restraints" ); // MM: Added Group Header. addField( "AllowOnTerrain", TypeBool, Offset( mFieldData.mAllowOnTerrain, fxShapeReplicator ), "Shapes will be placed on terrain when set." ); - addField( "AllowOnInteriors", TypeBool, Offset( mFieldData.mAllowOnInteriors, fxShapeReplicator ), "Shapes will be placed on InteriorInstances when set." ); addField( "AllowOnStatics", TypeBool, Offset( mFieldData.mAllowStatics, fxShapeReplicator ), "Shapes will be placed on Static shapes when set." ); addField( "AllowOnWater", TypeBool, Offset( mFieldData.mAllowOnWater, fxShapeReplicator ), "Shapes will be placed on/under water when set." ); addField( "AllowWaterSurface", TypeBool, Offset( mFieldData.mAllowWaterSurface, fxShapeReplicator ), "Shapes will be placed on water when set. Requires AllowOnWater." ); @@ -214,7 +213,6 @@ void fxShapeReplicator::CreateShapes(void) // Check that we can position somewhere! if (!( mFieldData.mAllowOnTerrain || - mFieldData.mAllowOnInteriors || mFieldData.mAllowStatics || mFieldData.mAllowOnWater)) { @@ -318,7 +316,6 @@ void fxShapeReplicator::CreateShapes(void) // Check Illegal Placements. if (((CollisionType & TerrainObjectType) && !mFieldData.mAllowOnTerrain) || - ((CollisionType & InteriorObjectType) && !mFieldData.mAllowOnInteriors) || ((CollisionType & StaticShapeObjectType) && !mFieldData.mAllowStatics) || ((CollisionType & WaterObjectType) && !mFieldData.mAllowOnWater) ) continue; @@ -696,7 +693,6 @@ U32 fxShapeReplicator::packUpdate(NetConnection * con, U32 mask, BitStream * str mathWrite(*stream, mFieldData.mShapeRotateMax); // Shapes Rotate Max. stream->writeSignedInt(mFieldData.mOffsetZ, 32); // Shapes Offset Z. stream->writeFlag(mFieldData.mAllowOnTerrain); // Allow on Terrain. - stream->writeFlag(mFieldData.mAllowOnInteriors); // Allow on Interiors. stream->writeFlag(mFieldData.mAllowStatics); // Allow on Statics. stream->writeFlag(mFieldData.mAllowOnWater); // Allow on Water. stream->writeFlag(mFieldData.mAllowWaterSurface); // Allow on Water Surface. @@ -742,7 +738,6 @@ void fxShapeReplicator::unpackUpdate(NetConnection * con, BitStream * stream) mathRead(*stream, &mFieldData.mShapeRotateMax); // Shapes Rotate Max. mFieldData.mOffsetZ = stream->readSignedInt(32); // Shapes Offset Z. mFieldData.mAllowOnTerrain = stream->readFlag(); // Allow on Terrain. - mFieldData.mAllowOnInteriors = stream->readFlag(); // Allow on Interiors. mFieldData.mAllowStatics = stream->readFlag(); // Allow on Statics. mFieldData.mAllowOnWater = stream->readFlag(); // Allow on Water. mFieldData.mAllowWaterSurface = stream->readFlag(); // Allow on Water Surface. diff --git a/Engine/source/T3D/fx/fxShapeReplicator.h b/Engine/source/T3D/fx/fxShapeReplicator.h index 66ec29baa..8cd9efa4e 100644 --- a/Engine/source/T3D/fx/fxShapeReplicator.h +++ b/Engine/source/T3D/fx/fxShapeReplicator.h @@ -36,12 +36,10 @@ #define AREA_ANIMATION_ARC (1.0f / 360.0f) #define FXREPLICATOR_COLLISION_MASK ( TerrainObjectType | \ - InteriorObjectType | \ StaticShapeObjectType | \ WaterObjectType ) #define FXREPLICATOR_NOWATER_COLLISION_MASK ( TerrainObjectType | \ - InteriorObjectType | \ StaticShapeObjectType ) @@ -139,7 +137,6 @@ public: U32 mOuterRadiusY; S32 mOffsetZ; bool mAllowOnTerrain; - bool mAllowOnInteriors; bool mAllowStatics; bool mAllowOnWater; S32 mAllowedTerrainSlope; @@ -166,7 +163,6 @@ public: mOffsetZ = 0; mAllowOnTerrain = true; - mAllowOnInteriors = true; mAllowStatics = true; mAllowOnWater = false; mAllowWaterSurface = false; diff --git a/Engine/source/T3D/fx/precipitation.cpp b/Engine/source/T3D/fx/precipitation.cpp index e267dcd69..639d0c747 100644 --- a/Engine/source/T3D/fx/precipitation.cpp +++ b/Engine/source/T3D/fx/precipitation.cpp @@ -45,7 +45,6 @@ static const U32 dropHitMask = TerrainObjectType | - InteriorObjectType | WaterObjectType | StaticShapeObjectType; diff --git a/Engine/source/T3D/gameFunctions.cpp b/Engine/source/T3D/gameFunctions.cpp index c3b3967a3..ead82412b 100644 --- a/Engine/source/T3D/gameFunctions.cpp +++ b/Engine/source/T3D/gameFunctions.cpp @@ -404,7 +404,6 @@ static void RegisterGameFunctions() Con::setIntVariable("$TypeMasks::StaticObjectType", StaticObjectType); Con::setIntVariable("$TypeMasks::EnvironmentObjectType", EnvironmentObjectType); Con::setIntVariable("$TypeMasks::TerrainObjectType", TerrainObjectType); - Con::setIntVariable("$TypeMasks::InteriorObjectType", InteriorObjectType); Con::setIntVariable("$TypeMasks::WaterObjectType", WaterObjectType); Con::setIntVariable("$TypeMasks::TriggerObjectType", TriggerObjectType); Con::setIntVariable("$TypeMasks::MarkerObjectType", MarkerObjectType); diff --git a/Engine/source/T3D/item.cpp b/Engine/source/T3D/item.cpp index 6546404e8..50a43c1e8 100644 --- a/Engine/source/T3D/item.cpp +++ b/Engine/source/T3D/item.cpp @@ -53,8 +53,9 @@ static S32 sMaxWarpTicks = 3; // Max warp duration in ticks F32 Item::mGravity = -20.0f; const U32 sClientCollisionMask = (TerrainObjectType | - InteriorObjectType | StaticShapeObjectType | - VehicleObjectType | PlayerObjectType); + StaticShapeObjectType | + VehicleObjectType | + PlayerObjectType); const U32 sServerCollisionMask = (sClientCollisionMask); diff --git a/Engine/source/T3D/objectTypes.h b/Engine/source/T3D/objectTypes.h index 47363ea85..e65745e1b 100644 --- a/Engine/source/T3D/objectTypes.h +++ b/Engine/source/T3D/objectTypes.h @@ -53,25 +53,21 @@ enum SceneObjectTypes /// @see TerrainBlock TerrainObjectType = BIT( 2 ), - /// A legacy DIF interior object. - /// @see InteriorInstance - InteriorObjectType = BIT( 3 ), - /// An object defining a water volume. /// @see WaterObject - WaterObjectType = BIT( 4 ), + WaterObjectType = BIT( 3 ), /// An object defining an invisible trigger volume. /// @see Trigger - TriggerObjectType = BIT( 5 ), + TriggerObjectType = BIT( 4 ), /// An object defining an invisible marker. /// @see MissionMarker - MarkerObjectType = BIT( 6 ), + MarkerObjectType = BIT( 5 ), /// A light emitter. /// @see LightBase - LightObjectType = BIT( 7 ), + LightObjectType = BIT( 6 ), /// An object that manages zones. This is automatically set by /// SceneZoneSpaceManager when a SceneZoneSpace registers zones. Should @@ -79,7 +75,7 @@ enum SceneObjectTypes /// /// @see SceneZoneSpace /// @see SceneZoneSpaceManager - ZoneObjectType = BIT( 8 ), + ZoneObjectType = BIT( 7 ), /// Any object that defines one or more solid, renderable static geometries that /// should be included in collision and raycasts. @@ -87,13 +83,13 @@ enum SceneObjectTypes /// Use this mask to find objects that are part of the static level geometry. /// /// @note If you set this, you will also want to set StaticObjectType. - StaticShapeObjectType = BIT( 9 ), + StaticShapeObjectType = BIT( 8 ), /// Any object that defines one or more solid, renderable dynamic geometries that /// should be included in collision and raycasts. /// /// Use this mask to find objects that are part of the dynamic game geometry. - DynamicShapeObjectType = BIT( 10 ), + DynamicShapeObjectType = BIT( 9 ), /// @} @@ -102,54 +98,54 @@ enum SceneObjectTypes /// Any GameBase-derived object. /// @see GameBase - GameBaseObjectType = BIT( 11 ), + GameBaseObjectType = BIT( 10 ), /// An object that uses hifi networking. - GameBaseHiFiObjectType = BIT( 12 ), + GameBaseHiFiObjectType = BIT( 11 ), /// Any ShapeBase-derived object. /// @see ShapeBase - ShapeBaseObjectType = BIT( 13 ), + ShapeBaseObjectType = BIT( 12 ), /// A camera object. /// @see Camera - CameraObjectType = BIT( 14 ), + CameraObjectType = BIT( 13 ), /// A human or AI player object. /// @see Player - PlayerObjectType = BIT( 15 ), + PlayerObjectType = BIT( 14 ), /// An item pickup. /// @see Item - ItemObjectType = BIT( 16 ), + ItemObjectType = BIT( 15 ), /// A vehicle. /// @see Vehicle - VehicleObjectType = BIT( 17 ), + VehicleObjectType = BIT( 16 ), /// An object that blocks vehicles. /// @see VehicleBlocker - VehicleBlockerObjectType = BIT( 18 ), + VehicleBlockerObjectType = BIT( 17 ), /// A weapon projectile. /// @see Projectile - ProjectileObjectType = BIT( 19 ), + ProjectileObjectType = BIT( 18 ), /// An explosion object. /// @see Explosion - ExplosionObjectType = BIT( 20 ), + ExplosionObjectType = BIT( 19 ), /// A dead player. This is dynamically set and unset. /// @see Player - CorpseObjectType = BIT( 21 ), + CorpseObjectType = BIT( 20 ), /// A debris object. /// @see Debris - DebrisObjectType = BIT( 22 ), + DebrisObjectType = BIT( 21 ), /// A volume that asserts forces on player objects. /// @see PhysicalZone - PhysicalZoneObjectType = BIT( 23 ), + PhysicalZoneObjectType = BIT( 22 ), /// @} }; @@ -173,8 +169,7 @@ enum SceneObjectTypeMasks /// /// Also, objects that do their own culling internally (terrains, forests, etc.) /// should be excluded. - CULLING_INCLUDE_TYPEMASK = ( InteriorObjectType | - GameBaseObjectType | // Includes most other renderable types; but broader than we ideally want. + CULLING_INCLUDE_TYPEMASK = ( GameBaseObjectType | // Includes most other renderable types; but broader than we ideally want. StaticShapeObjectType | DynamicShapeObjectType | ZoneObjectType ), // This improves the result of zone traversals. @@ -200,7 +195,6 @@ enum SceneObjectTypeMasks /// /// @note Terrains have their own means for rendering inside interior zones. OUTDOOR_OBJECT_TYPEMASK = ( TerrainObjectType | - InteriorObjectType | EnvironmentObjectType ) }; diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 7133468a3..e055d8600 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -101,7 +101,6 @@ const F32 sAnchorMaxDistance = 32.0f; // static U32 sCollisionMoveMask = TerrainObjectType | - InteriorObjectType | WaterObjectType | PlayerObjectType | StaticShapeObjectType | @@ -3386,8 +3385,7 @@ void Player::updateDeathOffsets() //---------------------------------------------------------------------------- -static const U32 sPlayerConformMask = InteriorObjectType|StaticShapeObjectType| - StaticObjectType|TerrainObjectType; +static const U32 sPlayerConformMask = StaticShapeObjectType | StaticObjectType | TerrainObjectType; static void accel(F32& from, F32 to, F32 rate) { diff --git a/Engine/source/T3D/projectile.cpp b/Engine/source/T3D/projectile.cpp index 9dddb8fde..47474eb24 100644 --- a/Engine/source/T3D/projectile.cpp +++ b/Engine/source/T3D/projectile.cpp @@ -126,12 +126,9 @@ IMPLEMENT_CALLBACK( ProjectileData, onCollision, void, ( Projectile* proj, Scene "@see Projectile\n" ); -const U32 Projectile::csmStaticCollisionMask = TerrainObjectType | - InteriorObjectType | - StaticShapeObjectType; +const U32 Projectile::csmStaticCollisionMask = TerrainObjectType | StaticShapeObjectType; -const U32 Projectile::csmDynamicCollisionMask = PlayerObjectType | - VehicleObjectType; +const U32 Projectile::csmDynamicCollisionMask = PlayerObjectType | VehicleObjectType; const U32 Projectile::csmDamageableMask = Projectile::csmDynamicCollisionMask; diff --git a/Engine/source/T3D/rigidShape.cpp b/Engine/source/T3D/rigidShape.cpp index 0553a9482..abd04937b 100644 --- a/Engine/source/T3D/rigidShape.cpp +++ b/Engine/source/T3D/rigidShape.cpp @@ -198,9 +198,9 @@ namespace { static F32 sRestTol = 0.5; // % of gravity energy to be at rest static int sRestCount = 10; // Consecutive ticks before comming to rest - const U32 sCollisionMoveMask = (TerrainObjectType | InteriorObjectType | - PlayerObjectType | StaticShapeObjectType | VehicleObjectType | - VehicleBlockerObjectType); + const U32 sCollisionMoveMask = ( TerrainObjectType | PlayerObjectType | + StaticShapeObjectType | VehicleObjectType | + VehicleBlockerObjectType ); const U32 sServerCollisionMask = sCollisionMoveMask; // ItemObjectType const U32 sClientCollisionMask = sCollisionMoveMask; diff --git a/Engine/source/T3D/shapeBase.cpp b/Engine/source/T3D/shapeBase.cpp index a68ed764d..438eff608 100644 --- a/Engine/source/T3D/shapeBase.cpp +++ b/Engine/source/T3D/shapeBase.cpp @@ -622,7 +622,7 @@ DefineEngineMethod( ShapeBaseData, checkDeployPos, bool, ( TransformF txfm ),, polyList.mPlaneList[i] = temp; } - if (gServerContainer.buildPolyList(PLC_Collision, wBox, InteriorObjectType | StaticShapeObjectType, &polyList)) + if (gServerContainer.buildPolyList(PLC_Collision, wBox, StaticShapeObjectType, &polyList)) return false; return true; } @@ -5038,7 +5038,7 @@ DefineEngineMethod( ShapeBase, dumpMeshVisibility, void, (),, #endif // #ifndef TORQUE_SHIPPING //------------------------------------------------------------------------ -//These functions are duplicated in tsStatic, shapeBase, and interiorInstance. +//These functions are duplicated in tsStatic and shapeBase. //They each function a little differently; but achieve the same purpose of gathering //target names/counts without polluting simObject. diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 9a36b15f2..1910ad707 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -1036,7 +1036,7 @@ void TSStaticPolysoupConvex::getFeatures(const MatrixF& mat,const VectorF& n, Co } //------------------------------------------------------------------------ -//These functions are duplicated in tsStatic, shapeBase, and interiorInstance. +//These functions are duplicated in tsStatic and shapeBase. //They each function a little differently; but achieve the same purpose of gathering //target names/counts without polluting simObject. diff --git a/Engine/source/T3D/turret/aiTurretShape.cpp b/Engine/source/T3D/turret/aiTurretShape.cpp index c6dd5ca1f..f4da6522d 100644 --- a/Engine/source/T3D/turret/aiTurretShape.cpp +++ b/Engine/source/T3D/turret/aiTurretShape.cpp @@ -37,7 +37,6 @@ static U32 sScanTypeMask = PlayerObjectType | VehicleObjectType; static U32 sAimTypeMask = TerrainObjectType | - InteriorObjectType | WaterObjectType | PlayerObjectType | StaticShapeObjectType | diff --git a/Engine/source/T3D/turret/turretShape.cpp b/Engine/source/T3D/turret/turretShape.cpp index 59f20a3e1..0ec55c97d 100644 --- a/Engine/source/T3D/turret/turretShape.cpp +++ b/Engine/source/T3D/turret/turretShape.cpp @@ -40,7 +40,7 @@ static F32 sMinWarpTicks = 0.5 ; // Fraction of tick at which instant war static S32 sMaxWarpTicks = 3; // Max warp duration in ticks const U32 sClientCollisionMask = (TerrainObjectType | - InteriorObjectType | StaticShapeObjectType | + StaticShapeObjectType | VehicleObjectType); const U32 sServerCollisionMask = (sClientCollisionMask); diff --git a/Engine/source/T3D/vehicles/flyingVehicle.cpp b/Engine/source/T3D/vehicles/flyingVehicle.cpp index 6cfbf6005..ccd89c621 100644 --- a/Engine/source/T3D/vehicles/flyingVehicle.cpp +++ b/Engine/source/T3D/vehicles/flyingVehicle.cpp @@ -43,10 +43,10 @@ //---------------------------------------------------------------------------- -const static U32 sCollisionMoveMask = ( TerrainObjectType | InteriorObjectType | - WaterObjectType | PlayerObjectType | - StaticShapeObjectType | VehicleObjectType | - VehicleBlockerObjectType ); +const static U32 sCollisionMoveMask = ( TerrainObjectType | WaterObjectType | + PlayerObjectType | StaticShapeObjectType | + VehicleObjectType | VehicleBlockerObjectType ); + static U32 sServerCollisionMask = sCollisionMoveMask; // ItemObjectType static U32 sClientCollisionMask = sCollisionMoveMask; diff --git a/Engine/source/T3D/vehicles/hoverVehicle.cpp b/Engine/source/T3D/vehicles/hoverVehicle.cpp index 6ccfa7053..b212807e0 100644 --- a/Engine/source/T3D/vehicles/hoverVehicle.cpp +++ b/Engine/source/T3D/vehicles/hoverVehicle.cpp @@ -73,9 +73,9 @@ namespace { const U32 sIntergrationsPerTick = 1; const F32 sHoverVehicleGravity = -20; -const U32 sCollisionMoveMask = (TerrainObjectType | InteriorObjectType | - PlayerObjectType | StaticShapeObjectType | - VehicleObjectType | VehicleBlockerObjectType); +const U32 sCollisionMoveMask = (TerrainObjectType | PlayerObjectType | + StaticShapeObjectType | VehicleObjectType | + VehicleBlockerObjectType); const U32 sServerCollisionMask = sCollisionMoveMask; // ItemObjectType const U32 sClientCollisionMask = sCollisionMoveMask; @@ -724,7 +724,7 @@ void HoverVehicle::updateForces(F32 /*dt*/) for (j = 0; j < 2; j++) { if (getContainer()->castRay(stabPoints[j].wsPoint, stabPoints[j].wsPoint + stabPoints[j].wsExtension * 2.0, TerrainObjectType | - InteriorObjectType | WaterObjectType, &rinfo)) + WaterObjectType, &rinfo)) { reallyFloating = false; diff --git a/Engine/source/T3D/vehicles/wheeledVehicle.cpp b/Engine/source/T3D/vehicles/wheeledVehicle.cpp index 9558b65dc..39556168c 100644 --- a/Engine/source/T3D/vehicles/wheeledVehicle.cpp +++ b/Engine/source/T3D/vehicles/wheeledVehicle.cpp @@ -47,12 +47,12 @@ #include "lighting/lightQuery.h" -// Collision masks are used to determin what type of objects the +// Collision masks are used to determine what type of objects the // wheeled vehicle will collide with. static U32 sClientCollisionMask = - TerrainObjectType | InteriorObjectType | - PlayerObjectType | StaticShapeObjectType | - VehicleObjectType | VehicleBlockerObjectType; + TerrainObjectType | PlayerObjectType | + StaticShapeObjectType | VehicleObjectType | + VehicleBlockerObjectType; // Gravity constant static F32 sWheeledVehicleGravity = -20; diff --git a/Engine/source/collision/convex.h b/Engine/source/collision/convex.h index 8b289b6bf..5de048abc 100644 --- a/Engine/source/collision/convex.h +++ b/Engine/source/collision/convex.h @@ -83,7 +83,6 @@ enum ConvexType { TSConvexType, BoxConvexType, TerrainConvexType, - InteriorConvexType, ShapeBaseConvexType, TSStaticConvexType, AtlasChunkConvexType, ///< @deprecated diff --git a/Engine/source/environment/waterBlock.cpp b/Engine/source/environment/waterBlock.cpp index 78438eec2..50494355c 100644 --- a/Engine/source/environment/waterBlock.cpp +++ b/Engine/source/environment/waterBlock.cpp @@ -243,7 +243,7 @@ void WaterBlock::setupVertexBlock( U32 width, U32 height, U32 rowOffset ) // to a ray cast could detected. if(gClientContainer.castRay(start, end, //StaticObjectType | - InteriorObjectType | + //InteriorObjectType | //ShapeBaseObjectType | //StaticShapeObjectType | //ItemObjectType | @@ -280,7 +280,7 @@ void WaterBlock::setupVertexBlock( U32 width, U32 height, U32 rowOffset ) if(gClientContainer.castRay(worldPoint, worldPoint + sunVector * 9000.f, //StaticObjectType | - InteriorObjectType | + //InteriorObjectType | //ShapeBaseObjectType | //StaticShapeObjectType | //ItemObjectType | diff --git a/Engine/source/gui/worldEditor/terrainEditor.cpp b/Engine/source/gui/worldEditor/terrainEditor.cpp index df8d95d44..0228eb8c6 100644 --- a/Engine/source/gui/worldEditor/terrainEditor.cpp +++ b/Engine/source/gui/worldEditor/terrainEditor.cpp @@ -33,7 +33,6 @@ #include "gfx/gfxDrawUtil.h" #include "gui/core/guiCanvas.h" #include "gui/worldEditor/terrainActions.h" -#include "interior/interiorInstance.h" #include "terrain/terrMaterial.h" @@ -2244,73 +2243,6 @@ void TerrainEditor::markEmptySquares() { if(!checkTerrainBlock(this, "markEmptySquares")) return; - - // TODO! - /* - // build a list of all the marked interiors - Vector interiors; - U32 mask = InteriorObjectType; - gServerContainer.findObjects(mask, findObjectsCallback, &interiors); - - // walk the terrains and empty any grid which clips to an interior - for (U32 i = 0; i < mTerrainBlocks.size(); i++) - { - for(U32 x = 0; x < TerrainBlock::BlockSize; x++) - { - for(U32 y = 0; y < TerrainBlock::BlockSize; y++) - { - TerrainBlock::Material * material = mTerrainBlocks[i]->getMaterial(x,y); - material->flags |= ~(TerrainBlock::Material::Empty); - - Point3F a, b; - gridToWorld(Point2I(x,y), a, mTerrainBlocks[i]); - gridToWorld(Point2I(x+1,y+1), b, mTerrainBlocks[i]); - - Box3F box; - box.minExtents = a; - box.maxExtents = b; - - box.minExtents.setMin(b); - box.maxExtents.setMax(a); - - const MatrixF & terrOMat = mTerrainBlocks[i]->getTransform(); - const MatrixF & terrWMat = mTerrainBlocks[i]->getWorldTransform(); - - terrWMat.mulP(box.minExtents); - terrWMat.mulP(box.maxExtents); - - for(U32 i = 0; i < interiors.size(); i++) - { - MatrixF mat = interiors[i]->getWorldTransform(); - mat.scale(interiors[i]->getScale()); - mat.mul(terrOMat); - - U32 waterMark = FrameAllocator::getWaterMark(); - U16* zoneVector = (U16*)FrameAllocator::alloc(interiors[i]->getDetailLevel(0)->getNumZones()); - U32 numZones = 0; - interiors[i]->getDetailLevel(0)->scanZones(box, mat, - zoneVector, &numZones); - if (numZones != 0) - { - Con::printf("%d %d", x, y); - material->flags |= TerrainBlock::Material::Empty; - FrameAllocator::setWaterMark(waterMark); - break; - } - FrameAllocator::setWaterMark(waterMark); - } - } - } - } - - // rebuild stuff.. - for (U32 i = 0; i < mTerrainBlocks.size(); i++) - { - mTerrainBlocks[i]->buildGridMap(); - mTerrainBlocks[i]->rebuildEmptyFlags(); - mTerrainBlocks[i]->packEmptySquares(); - } - */ } void TerrainEditor::mirrorTerrain(S32 mirrorIndex) diff --git a/Engine/source/interior/forceField.cpp b/Engine/source/interior/forceField.cpp deleted file mode 100644 index 1ef09ad57..000000000 --- a/Engine/source/interior/forceField.cpp +++ /dev/null @@ -1,469 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "interior/forceField.h" - -#include "core/stream/stream.h" -#include "math/mathIO.h" -#include "console/console.h" -#include "collision/abstractPolyList.h" -#include "scene/sceneObject.h" - - -ForceField::ForceField() -{ - VECTOR_SET_ASSOCIATION( mTriggers ); - VECTOR_SET_ASSOCIATION( mPlanes ); - VECTOR_SET_ASSOCIATION( mPoints ); - VECTOR_SET_ASSOCIATION( mBSPNodes ); - VECTOR_SET_ASSOCIATION( mBSPSolidLeaves ); - VECTOR_SET_ASSOCIATION( mSolidLeafSurfaces ); - VECTOR_SET_ASSOCIATION( mWindings ); - VECTOR_SET_ASSOCIATION( mSurfaces ); - - mPreppedForRender = false; -} - -ForceField::~ForceField() -{ - mPreppedForRender = false; -} - - -bool ForceField::prepForRendering() -{ - if (mPreppedForRender == true) - return true; - - mPreppedForRender = true; - return true; -} - - -void ForceField::render(const ColorF& rColor, const F32 fade) -{ -} - - -//-------------------------------------------------------------------------- -//-------------------------------------- Persistence interfaces -// -const U32 ForceField::smFileVersion = 0; - -bool ForceField::read(Stream& stream) -{ - AssertFatal(stream.hasCapability(Stream::StreamRead), "ForceField::read: non-read capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "ForceField::read: Error, stream in inconsistent state"); - - U32 i; - - // Version this stream - U32 fileVersion; - stream.read(&fileVersion); - if (fileVersion != smFileVersion) { - Con::errorf(ConsoleLogEntry::General, "ForceField::read: incompatible file version found."); - return false; - } - - mName = stream.readSTString(); - U32 numTriggers; - stream.read(&numTriggers); - mTriggers.setSize(numTriggers); - for (i = 0; i < mTriggers.size(); i++) - mTriggers[i] = stream.readSTString(); - - // Geometry factors... - mathRead(stream, &mBoundingBox); - mathRead(stream, &mBoundingSphere); - - // Now read in our data vectors. - U32 vectorSize; - // mPlanes - readPlaneVector(stream); - - // mPoints - stream.read(&vectorSize); - mPoints.setSize(vectorSize); - for (i = 0; i < mPoints.size(); i++) - mathRead(stream, &mPoints[i]); - - // mBSPNodes; - stream.read(&vectorSize); - mBSPNodes.setSize(vectorSize); - for (i = 0; i < mBSPNodes.size(); i++) { - stream.read(&mBSPNodes[i].planeIndex); - stream.read(&mBSPNodes[i].frontIndex); - stream.read(&mBSPNodes[i].backIndex); - } - - // mBSPSolidLeaves - stream.read(&vectorSize); - mBSPSolidLeaves.setSize(vectorSize); - for (i = 0; i < mBSPSolidLeaves.size(); i++) { - stream.read(&mBSPSolidLeaves[i].surfaceIndex); - stream.read(&mBSPSolidLeaves[i].surfaceCount); - } - - // mWindings - stream.read(&vectorSize); - mWindings.setSize(vectorSize); - for (i = 0; i < mWindings.size(); i++) { - stream.read(&mWindings[i]); - } - - // mSurfaces - stream.read(&vectorSize); - mSurfaces.setSize(vectorSize); - for (i = 0; i < mSurfaces.size(); i++) { - stream.read(&mSurfaces[i].windingStart); - stream.read(&mSurfaces[i].windingCount); - stream.read(&mSurfaces[i].planeIndex); - stream.read(&mSurfaces[i].surfaceFlags); - stream.read(&mSurfaces[i].fanMask); - } - - // mSolidLeafSurfaces - stream.read(&vectorSize); - mSolidLeafSurfaces.setSize(vectorSize); - for (i = 0; i < mSolidLeafSurfaces.size(); i++) { - stream.read(&mSolidLeafSurfaces[i]); - } - - stream.read(&mColor); - - return stream.getStatus() == Stream::Ok; -} - -bool ForceField::write(Stream& stream) const -{ - AssertFatal(stream.hasCapability(Stream::StreamWrite), "Interior::write: non-write capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::write: Error, stream in inconsistent state"); - - U32 i; - - // Version this stream - stream.write(smFileVersion); - - stream.writeString(mName); - stream.write(mTriggers.size()); - for (i = 0; i < mTriggers.size(); i++) - stream.writeString(mTriggers[i]); - - mathWrite(stream, mBoundingBox); - mathWrite(stream, mBoundingSphere); - - // Now write out our data vectors. Remember, for cross-platform capability, no - // structure writing is allowed... - - // mPlanes - writePlaneVector(stream); - - // mPoints - stream.write(mPoints.size()); - for (i = 0; i < mPoints.size(); i++) - mathWrite(stream, mPoints[i]); - - // mBSPNodes; - stream.write(mBSPNodes.size()); - for (i = 0; i < mBSPNodes.size(); i++) { - stream.write(mBSPNodes[i].planeIndex); - stream.write(mBSPNodes[i].frontIndex); - stream.write(mBSPNodes[i].backIndex); - } - - // mBSPSolidLeaves - stream.write(mBSPSolidLeaves.size()); - for (i = 0; i < mBSPSolidLeaves.size(); i++) { - stream.write(mBSPSolidLeaves[i].surfaceIndex); - stream.write(mBSPSolidLeaves[i].surfaceCount); - } - - // mWindings - stream.write(mWindings.size()); - for (i = 0; i < mWindings.size(); i++) { - stream.write(mWindings[i]); - } - - // mSurfaces - stream.write(mSurfaces.size()); - for (i = 0; i < mSurfaces.size(); i++) { - stream.write(mSurfaces[i].windingStart); - stream.write(mSurfaces[i].windingCount); - stream.write(mSurfaces[i].planeIndex); - stream.write(mSurfaces[i].surfaceFlags); - stream.write(mSurfaces[i].fanMask); - } - - // mSolidLeafSurfaces - stream.write(mSolidLeafSurfaces.size()); - for (i = 0; i < mSolidLeafSurfaces.size(); i++) { - stream.write(mSolidLeafSurfaces[i]); - } - - stream.write(mColor); - - return stream.getStatus() == Stream::Ok; -} - -bool ForceField::writePlaneVector(Stream& stream) const -{ - // This is pretty slow, but who cares? - // - Vector uniqueNormals(mPlanes.size()); - Vector uniqueIndices(mPlanes.size()); - - U32 i; - - for (i = 0; i < mPlanes.size(); i++) { - bool inserted = false; - for (U32 j = 0; j < uniqueNormals.size(); j++) { - if (mPlanes[i] == uniqueNormals[j]) { - // Hah! Already have this one... - uniqueIndices.push_back(j); - inserted = true; - break; - } - } - - if (inserted == false) { - // Gotta do it ourselves... - uniqueIndices.push_back(uniqueNormals.size()); - uniqueNormals.push_back(Point3F(mPlanes[i].x, mPlanes[i].y, mPlanes[i].z)); - } - } - - // Ok, what we have now, is a list of unique normals, a set of indices into - // that vector, and the distances that we still have to write out by hand. - // Hop to it! - stream.write(uniqueNormals.size()); - for (i = 0; i < uniqueNormals.size(); i++) - mathWrite(stream, uniqueNormals[i]); - - stream.write(mPlanes.size()); - for (i = 0; i < mPlanes.size(); i++) { - stream.write(uniqueIndices[i]); - stream.write(mPlanes[i].d); - } - - return (stream.getStatus() == Stream::Ok); -} - -bool ForceField::readPlaneVector(Stream& stream) -{ - Vector normals; - U32 vectorSize; - - stream.read(&vectorSize); - normals.setSize(vectorSize); - U32 i; - for (i = 0; i < normals.size(); i++) - mathRead(stream, &normals[i]); - - U16 index; - stream.read(&vectorSize); - mPlanes.setSize(vectorSize); - for (i = 0; i < mPlanes.size(); i++) { - stream.read(&index); - stream.read(&mPlanes[i].d); - mPlanes[i].x = normals[index].x; - mPlanes[i].y = normals[index].y; - mPlanes[i].z = normals[index].z; - } - - return (stream.getStatus() == Stream::Ok); -} - - -//-------------------------------------------------------------------------- -//-------------------------------------- Collision support. Essentially -// copied from the interiorCollision -// -void ForceField::collisionFanFromSurface(const Surface& rSurface, U32* fanIndices, U32* numIndices) const -{ - U32 tempIndices[32]; - - tempIndices[0] = 0; - U32 idx = 1; - U32 i; - for (i = 1; i < rSurface.windingCount; i += 2) - tempIndices[idx++] = i; - for (i = ((rSurface.windingCount - 1) & (~0x1)); i > 0; i -= 2) - tempIndices[idx++] = i; - - idx = 0; - for (i = 0; i < rSurface.windingCount; i++) { - if (rSurface.fanMask & (1 << i)) { - fanIndices[idx++] = mWindings[rSurface.windingStart + tempIndices[i]]; - } - } - *numIndices = idx; -} - -bool ForceField::castRay(const Point3F& s, const Point3F& e, RayInfo* info) -{ - bool hit = castRay_r(0, s, e, info); - if (hit) { - Point3F vec = e - s; - F32 len = vec.len(); - vec /= len; - info->t = mDot(info->point - s, vec) / len; - } - - return hit; -} - -bool ForceField::castRay_r(const U16 node, - const Point3F& s, - const Point3F& e, - RayInfo* info) -{ - if (isBSPLeafIndex(node) == false) { - const IBSPNode& rNode = mBSPNodes[node]; - const PlaneF& rPlane = getPlane(rNode.planeIndex); - - PlaneF::Side sSide = rPlane.whichSide(s); - PlaneF::Side eSide = rPlane.whichSide(e); - - switch (PlaneSwitchCode(sSide, eSide)) { - case PlaneSwitchCode(PlaneF::Front, PlaneF::Front): - case PlaneSwitchCode(PlaneF::Front, PlaneF::On): - case PlaneSwitchCode(PlaneF::On, PlaneF::Front): - return castRay_r(rNode.frontIndex, s, e, info); - break; - - case PlaneSwitchCode(PlaneF::On, PlaneF::Back): - case PlaneSwitchCode(PlaneF::Back, PlaneF::On): - case PlaneSwitchCode(PlaneF::Back, PlaneF::Back): - return castRay_r(rNode.backIndex, s, e, info); - break; - - case PlaneSwitchCode(PlaneF::On, PlaneF::On): - // Line lies on the plane - if (isBSPLeafIndex(rNode.backIndex) == false) { - if (castRay_r(rNode.backIndex, s, e, info)) - return true; - } - if (isBSPLeafIndex(rNode.frontIndex) == false) { - if (castRay_r(rNode.frontIndex, s, e, info)) - return true; - } - return false; - break; - - case PlaneSwitchCode(PlaneF::Front, PlaneF::Back): { - Point3F ip; - F32 intersectT = rPlane.intersect(s, e); - AssertFatal(intersectT != PARALLEL_PLANE, "Error, this should never happen in this case!"); - ip.interpolate(s, e, intersectT); - if (castRay_r(rNode.frontIndex, s, ip, info)) - return true; - return castRay_r(rNode.backIndex, ip, e, info); - } - break; - - case PlaneSwitchCode(PlaneF::Back, PlaneF::Front): { - Point3F ip; - F32 intersectT = rPlane.intersect(s, e); - AssertFatal(intersectT != PARALLEL_PLANE, "Error, this should never happen in this case!"); - ip.interpolate(s, e, intersectT); - if (castRay_r(rNode.backIndex, s, ip, info)) - return true; - return castRay_r(rNode.frontIndex, ip, e, info); - } - break; - - default: - AssertFatal(false, "Misunderstood switchCode in ForceField::castRay_r"); - return false; - } - } - - if (isBSPSolidLeaf(node)) { - // DMM: Set material info here - info->point = s; - return true; - } - return false; -} - -void ForceField::buildPolyList_r(const U16 node, Vector& collPlanes, AbstractPolyList* list, SphereF& s) -{ - if (isBSPLeafIndex(node) == false) { - const IBSPNode& rNode = mBSPNodes[node]; - const PlaneF& rPlane = getPlane(rNode.planeIndex); - - F32 dist = rPlane.distToPlane(s.center); - if (mFabs(dist) <= s.radius) { - // Have to do both, and push the plane back on the list... - collPlanes.push_back(rNode.planeIndex); - buildPolyList_r(rNode.frontIndex, collPlanes, list, s); - buildPolyList_r(rNode.backIndex, collPlanes, list, s); - collPlanes.pop_back(); - } else if (dist > 0.0f) { - buildPolyList_r(rNode.frontIndex, collPlanes, list, s); - } else { - buildPolyList_r(rNode.backIndex, collPlanes, list, s); - } - return; - } - - if (isBSPSolidLeaf(node)) { - const IBSPLeafSolid& rLeaf = mBSPSolidLeaves[getBSPSolidLeafIndex(node)]; - for (U32 i = 0; i < rLeaf.surfaceCount; i++) { - U32 surfaceIndex = mSolidLeafSurfaces[rLeaf.surfaceIndex + i]; - const Surface& rSurface = mSurfaces[surfaceIndex]; - for (U32 j = 0; j < collPlanes.size(); j++) { - if (areEqualPlanes(rSurface.planeIndex, collPlanes[j]) == true) { - - U32 fanVerts[32]; - U32 numVerts; - collisionFanFromSurface(rSurface, fanVerts, &numVerts); - - // DMM: Material here - list->begin(0, rSurface.planeIndex); - - U32 vertStart = list->addPoint(mPoints[fanVerts[0]]); - list->vertex(vertStart); - for (U32 k = 1; k < numVerts; k++) { - list->addPoint(mPoints[fanVerts[k]]); - list->vertex(vertStart + k); - } - list->plane(vertStart, vertStart + 1, vertStart + 2); - list->end(); - - break; - } - } - - } - } -} - -bool ForceField::buildPolyList(AbstractPolyList* list, SphereF& sphere) -{ - Vector planes; - buildPolyList_r(0, planes, list, sphere); - AssertFatal(planes.size() == 0, "Error, unbalanced plane stack!"); - - return !list->isEmpty(); -} diff --git a/Engine/source/interior/forceField.h b/Engine/source/interior/forceField.h deleted file mode 100644 index b849df01d..000000000 --- a/Engine/source/interior/forceField.h +++ /dev/null @@ -1,195 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _FORCEFIELD_H_ -#define _FORCEFIELD_H_ - -#ifndef _PLATFORM_H_ -#include "platform/platform.h" -#endif -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif -#ifndef _MBOX_H_ -#include "math/mBox.h" -#endif -#ifndef _MSPHERE_H_ -#include "math/mSphere.h" -#endif -#ifndef _MPLANE_H_ -#include "math/mPlane.h" -#endif -#ifndef _MPOINT3_H_ -#include "math/mPoint3.h" -#endif -#ifndef _COLOR_H_ -#include "core/color.h" -#endif - -//-------------------------------------- forward decls. -class EditGeometry; -class InteriorInstance; -class Stream; -class AbstractPolyList; -struct RayInfo; - -//-------------------------------------------------------------------------- -class ForceField -{ - static const U32 smFileVersion; - friend class EditGeometry; - friend class InteriorInstance; - - //-------------------------------------- Public interfaces - public: - ForceField(); - ~ForceField(); - - bool prepForRendering(); - void render(const ColorF& color, const F32 fadeLevel); - const Box3F& getBoundingBox() const; - - bool castRay(const Point3F&, const Point3F&, RayInfo*); - bool buildPolyList(AbstractPolyList*, SphereF&); - //-------------------------------------- Persistence interface - public: - bool read(Stream& stream); - bool write(Stream& stream) const; - - public: - static U16 getPlaneIndex(U16 index); - static bool planeIsFlipped(U16 index); - - //-------------------------------------- BSP Structures - private: - struct IBSPNode { - U16 planeIndex; - U16 frontIndex; - U16 backIndex; - U16 __padding__; - }; - struct IBSPLeafSolid { - U32 surfaceIndex; - U16 surfaceCount; - U16 __padding__; - }; - - bool isBSPLeafIndex(U16 index) const; - bool isBSPSolidLeaf(U16 index) const; - bool isBSPEmptyLeaf(U16 index) const; - U16 getBSPSolidLeafIndex(U16 index) const; - - bool writePlaneVector(Stream&) const; - bool readPlaneVector(Stream&); - - private: - const PlaneF& getPlane(U16 index) const; - bool areEqualPlanes(U16, U16) const; - - struct Surface { - U32 windingStart; - U32 fanMask; - - U16 planeIndex; - U8 windingCount; - U8 surfaceFlags; - }; - - protected: - StringTableEntry mName; - ColorF mColor; - Vector mTriggers; - - Box3F mBoundingBox; - SphereF mBoundingSphere; - Vector mPlanes; - Vector mPoints; - - Vector mBSPNodes; - Vector mBSPSolidLeaves; - Vector mSolidLeafSurfaces; - - bool mPreppedForRender; - - Vector mWindings; - Vector mSurfaces; - - protected: - bool castRay_r(const U16, const Point3F&, const Point3F&, RayInfo*); - void buildPolyList_r(const U16, Vector&, AbstractPolyList*, SphereF&); - void collisionFanFromSurface(const Surface&, U32* fan, U32* numIndices) const; -}; - -//------------------------------------------------------------------------------ -inline bool ForceField::isBSPLeafIndex(U16 index) const -{ - return (index & 0x8000) != 0; -} - -inline bool ForceField::isBSPSolidLeaf(U16 index) const -{ - AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!"); - return (index & 0x4000) != 0; -} - -inline bool ForceField::isBSPEmptyLeaf(U16 index) const -{ - AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!"); - return (index & 0x4000) == 0; -} - -inline U16 ForceField::getBSPSolidLeafIndex(U16 index) const -{ - AssertFatal(isBSPSolidLeaf(index) == true, "Error, only call for leaves!"); - return (index & ~0xC000); -} - -inline const PlaneF& ForceField::getPlane(U16 index) const -{ - AssertFatal(U32(index & ~0x8000) < mPlanes.size(), - "ForceField::getPlane: planeIndex out of range"); - - return mPlanes[index & ~0x8000]; -} - -inline U16 ForceField::getPlaneIndex(U16 index) -{ - return index & ~0x8000; -} - -inline bool ForceField::planeIsFlipped(U16 index) -{ - return (index & 0x8000) != 0; -} - -inline bool ForceField::areEqualPlanes(U16 o, U16 t) const -{ - return (o & ~0x8000) == (t & ~0x8000); -} - -inline const Box3F& ForceField::getBoundingBox() const -{ - return mBoundingBox; -} - -#endif // _H_FORCEFIELD_ - diff --git a/Engine/source/interior/interior.cpp b/Engine/source/interior/interior.cpp deleted file mode 100644 index 2a722c31c..000000000 --- a/Engine/source/interior/interior.cpp +++ /dev/null @@ -1,2645 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "interior/interior.h" - -#include "scene/sceneRenderState.h" -#include "scene/sceneManager.h" -#include "gfx/bitmap/gBitmap.h" -#include "math/mMatrix.h" -#include "math/mRect.h" -#include "core/bitVector.h" -#include "core/frameAllocator.h" -#include "scene/sgUtil.h" -#include "platform/profiler.h" -#include "gfx/gfxDevice.h" -#include "gfx/gfxTextureHandle.h" -#include "materials/materialList.h" -#include "materials/matInstance.h" -#include "materials/materialManager.h" -#include "renderInstance/renderPassManager.h" -#include "materials/processedMaterial.h" -#include "materials/materialFeatureTypes.h" - -U32 Interior::smRenderMode = 0; -bool Interior::smFocusedDebug = false; -bool Interior::smUseVertexLighting = false; -bool Interior::smLightingCastRays = false; -bool Interior::smLightingBuildPolyList = false; - -// These are setup by setupActivePolyList -U16* sgActivePolyList = NULL; -U32 sgActivePolyListSize = 0; -U16* sgEnvironPolyList = NULL; -U32 sgEnvironPolyListSize = 0; -U16* sgFogPolyList = NULL; -U32 sgFogPolyListSize = 0; -bool sgFogActive = false; - -// Always the same size as the mPoints array -Point2F* sgFogTexCoords = NULL; - -class PlaneRange -{ -public: - U32 start; - U32 count; -}; - -namespace { - -struct PortalRenderInfo -{ - bool render; - - F64 frustum[4]; - RectI viewport; -}; - -//-------------------------------------- Rendering state variables. -Point3F sgCamPoint; -F64 sgStoredFrustum[6]; -RectI sgStoredViewport; - -Vector sgZoneRenderInfo(__FILE__, __LINE__); - -// Takes OS coords to clip space... -MatrixF sgWSToOSMatrix; -MatrixF sgProjMatrix; - -PlaneF sgOSPlaneFar; -PlaneF sgOSPlaneXMin; -PlaneF sgOSPlaneXMax; -PlaneF sgOSPlaneYMin; -PlaneF sgOSPlaneYMax; - -struct ZoneRect { - RectD rect; - bool active; -}; - -Vector sgZoneRects(__FILE__, __LINE__); - -//-------------------------------------- Little utility functions -RectD outlineRects(const Vector& rects) -{ - F64 minx = 1e10; - F64 maxx = -1e10; - F64 miny = 1e10; - F64 maxy = -1e10; - - for (S32 i = 0; i < rects.size(); i++) - { - if (rects[i].point.x < minx) - minx = rects[i].point.x; - if (rects[i].point.y < miny) - miny = rects[i].point.y; - - if (rects[i].point.x + rects[i].extent.x > maxx) - maxx = rects[i].point.x + rects[i].extent.x; - if (rects[i].point.y + rects[i].extent.y > maxy) - maxy = rects[i].point.y + rects[i].extent.y; - } - - return RectD(minx, miny, maxx - minx, maxy - miny); -} - -void insertZoneRects(ZoneRect& rZoneRect, const RectD* rects, const U32 numRects) -{ - F64 minx = 1e10; - F64 maxx = -1e10; - F64 miny = 1e10; - F64 maxy = -1e10; - - for (U32 i = 0; i < numRects; i++) { - if (rects[i].point.x < minx) - minx = rects[i].point.x; - if (rects[i].point.y < miny) - miny = rects[i].point.y; - - if (rects[i].point.x + rects[i].extent.x > maxx) - maxx = rects[i].point.x + rects[i].extent.x; - if (rects[i].point.y + rects[i].extent.y > maxy) - maxy = rects[i].point.y + rects[i].extent.y; - } - - if (rZoneRect.active == false && numRects != 0) { - rZoneRect.rect = RectD(minx, miny, maxx - minx, maxy - miny); - rZoneRect.active = true; - } else { - if (rZoneRect.rect.point.x < minx) - minx = rZoneRect.rect.point.x; - if (rZoneRect.rect.point.y < miny) - miny = rZoneRect.rect.point.y; - - if (rZoneRect.rect.point.x + rZoneRect.rect.extent.x > maxx) - maxx = rZoneRect.rect.point.x + rZoneRect.rect.extent.x; - if (rZoneRect.rect.point.y + rZoneRect.rect.extent.y > maxy) - maxy = rZoneRect.rect.point.y + rZoneRect.rect.extent.y; - - rZoneRect.rect = RectD(minx, miny, maxx - minx, maxy - miny); - } -} - - - -void fixupViewport(PortalRenderInfo& rInfo) -{ - F64 widthV = rInfo.frustum[1] - rInfo.frustum[0]; - F64 heightV = rInfo.frustum[3] - rInfo.frustum[2]; - - F64 fx0 = (rInfo.frustum[0] - sgStoredFrustum[0]) / (sgStoredFrustum[1] - sgStoredFrustum[0]); - F64 fx1 = (sgStoredFrustum[1] - rInfo.frustum[1]) / (sgStoredFrustum[1] - sgStoredFrustum[0]); - - F64 dV0 = F64(sgStoredViewport.point.x) + fx0 * F64(sgStoredViewport.extent.x); - F64 dV1 = F64(sgStoredViewport.point.x + - sgStoredViewport.extent.x) - fx1 * F64(sgStoredViewport.extent.x); - - F64 fdV0 = getMax(mFloorD(dV0), F64(sgStoredViewport.point.x)); - F64 cdV1 = getMin(mCeilD(dV1), F64(sgStoredViewport.point.x + sgStoredViewport.extent.x)); - - // If the width is 1 pixel, we need to widen it up a bit... - if ((cdV1 - fdV0) <= 1.0) - cdV1 = fdV0 + 1; - AssertFatal((fdV0 >= sgStoredViewport.point.x && - cdV1 <= sgStoredViewport.point.x + sgStoredViewport.extent.x), - "Out of bounds viewport bounds"); - - F64 new0 = rInfo.frustum[0] - ((dV0 - fdV0) * (widthV / F64(sgStoredViewport.extent.x))); - F64 new1 = rInfo.frustum[1] + ((cdV1 - dV1) * (widthV / F64(sgStoredViewport.extent.x))); - - rInfo.frustum[0] = new0; - rInfo.frustum[1] = new1; - - rInfo.viewport.point.x = S32(fdV0); - rInfo.viewport.extent.x = S32(cdV1) - rInfo.viewport.point.x; - - F64 fy0 = (sgStoredFrustum[3] - rInfo.frustum[3]) / (sgStoredFrustum[3] - sgStoredFrustum[2]); - F64 fy1 = (rInfo.frustum[2] - sgStoredFrustum[2]) / (sgStoredFrustum[3] - sgStoredFrustum[2]); - - dV0 = F64(sgStoredViewport.point.y) + fy0 * F64(sgStoredViewport.extent.y); - dV1 = F64(sgStoredViewport.point.y + - sgStoredViewport.extent.y) - fy1 * F64(sgStoredViewport.extent.y); - fdV0 = getMax(mFloorD(dV0), F64(sgStoredViewport.point.y)); - cdV1 = getMin(mCeilD(dV1), F64(sgStoredViewport.point.y + sgStoredViewport.extent.y)); - - // If the width is 1 pixel, we need to widen it up a bit... - if ((cdV1 - fdV0) <= 1.0) - cdV1 = fdV0 + 1; - // GFX2_RENDER_MERGE - // Need to fix this properly but for now *HACK* -#ifndef TORQUE_OS_MAC - AssertFatal((fdV0 >= sgStoredViewport.point.y && - cdV1 <= sgStoredViewport.point.y + sgStoredViewport.extent.y), - "Out of bounds viewport bounds"); -#endif - - new0 = rInfo.frustum[2] - ((cdV1 - dV1) * (heightV / F64(sgStoredViewport.extent.y))); - new1 = rInfo.frustum[3] + ((dV0 - fdV0) * (heightV / F64(sgStoredViewport.extent.y))); - rInfo.frustum[2] = new0; - rInfo.frustum[3] = new1; - - rInfo.viewport.point.y = S32(fdV0); - rInfo.viewport.extent.y = S32(cdV1) - rInfo.viewport.point.y; -} - -RectD convertToRectD(const F64 inResult[4]) -{ - F64 minx = ((inResult[0] + 1.0f) / 2.0f) * (sgStoredFrustum[1] - sgStoredFrustum[0]) + sgStoredFrustum[0]; - F64 maxx = ((inResult[2] + 1.0f) / 2.0f) * (sgStoredFrustum[1] - sgStoredFrustum[0]) + sgStoredFrustum[0]; - - F64 miny = ((inResult[1] + 1.0f) / 2.0f) * (sgStoredFrustum[3] - sgStoredFrustum[2]) + sgStoredFrustum[2]; - F64 maxy = ((inResult[3] + 1.0f) / 2.0f) * (sgStoredFrustum[3] - sgStoredFrustum[2]) + sgStoredFrustum[2]; - - return RectD(minx, miny, (maxx - minx), (maxy - miny)); -} - -void convertToFrustum(PortalRenderInfo& zrInfo, const RectD& finalRect) -{ - zrInfo.frustum[0] = finalRect.point.x; // left - zrInfo.frustum[1] = finalRect.point.x + finalRect.extent.x; // right - zrInfo.frustum[2] = finalRect.point.y; // bottom - zrInfo.frustum[3] = finalRect.point.y + finalRect.extent.y; // top - - fixupViewport(zrInfo); -} - -} // namespace {} - - -//------------------------------------------------------------------------------ -//-------------------------------------- IMPLEMENTATION -// -Interior::Interior() -{ - mMaterialList = NULL; - - mHasTranslucentMaterials = false; - - mLMHandle = LM_HANDLE(-1); - - // By default, no alarm state, no animated light states - mHasAlarmState = false; - - mNumLightStateEntries = 0; - mNumTriggerableLights = 0; - - mPreppedForRender = false;; - mSearchTag = 0; - - mLightMapBorderSize = 0; - -#ifndef TORQUE_SHIPPING - mDebugShader = NULL; - - mDebugShaderModelViewSC = NULL; - mDebugShaderShadeColorSC = NULL; -#endif - - // Bind our vectors - VECTOR_SET_ASSOCIATION(mPlanes); - VECTOR_SET_ASSOCIATION(mPoints); - VECTOR_SET_ASSOCIATION(mBSPNodes); - VECTOR_SET_ASSOCIATION(mBSPSolidLeaves); - VECTOR_SET_ASSOCIATION(mWindings); - VECTOR_SET_ASSOCIATION(mTexGenEQs); - VECTOR_SET_ASSOCIATION(mLMTexGenEQs); - VECTOR_SET_ASSOCIATION(mWindingIndices); - VECTOR_SET_ASSOCIATION(mSurfaces); - VECTOR_SET_ASSOCIATION(mNullSurfaces); - VECTOR_SET_ASSOCIATION(mSolidLeafSurfaces); - VECTOR_SET_ASSOCIATION(mZones); - VECTOR_SET_ASSOCIATION(mZonePlanes); - VECTOR_SET_ASSOCIATION(mZoneSurfaces); - VECTOR_SET_ASSOCIATION(mZonePortalList); - VECTOR_SET_ASSOCIATION(mPortals); - //VECTOR_SET_ASSOCIATION(mSubObjects); - VECTOR_SET_ASSOCIATION(mLightmaps); - VECTOR_SET_ASSOCIATION(mLightmapKeep); - VECTOR_SET_ASSOCIATION(mNormalLMapIndices); - VECTOR_SET_ASSOCIATION(mAlarmLMapIndices); - VECTOR_SET_ASSOCIATION(mAnimatedLights); - VECTOR_SET_ASSOCIATION(mLightStates); - VECTOR_SET_ASSOCIATION(mStateData); - VECTOR_SET_ASSOCIATION(mStateDataBuffer); - VECTOR_SET_ASSOCIATION(mNameBuffer); - VECTOR_SET_ASSOCIATION(mConvexHulls); - VECTOR_SET_ASSOCIATION(mConvexHullEmitStrings); - VECTOR_SET_ASSOCIATION(mHullIndices); - VECTOR_SET_ASSOCIATION(mHullEmitStringIndices); - VECTOR_SET_ASSOCIATION(mHullSurfaceIndices); - VECTOR_SET_ASSOCIATION(mHullPlaneIndices); - VECTOR_SET_ASSOCIATION(mPolyListPlanes); - VECTOR_SET_ASSOCIATION(mPolyListPoints); - VECTOR_SET_ASSOCIATION(mPolyListStrings); - VECTOR_SET_ASSOCIATION(mCoordBinIndices); - - VECTOR_SET_ASSOCIATION(mVehicleConvexHulls); - VECTOR_SET_ASSOCIATION(mVehicleConvexHullEmitStrings); - VECTOR_SET_ASSOCIATION(mVehicleHullIndices); - VECTOR_SET_ASSOCIATION(mVehicleHullEmitStringIndices); - VECTOR_SET_ASSOCIATION(mVehicleHullSurfaceIndices); - VECTOR_SET_ASSOCIATION(mVehicleHullPlaneIndices); - VECTOR_SET_ASSOCIATION(mVehiclePolyListPlanes); - VECTOR_SET_ASSOCIATION(mVehiclePolyListPoints); - VECTOR_SET_ASSOCIATION(mVehiclePolyListStrings); - VECTOR_SET_ASSOCIATION(mVehiclePoints); - VECTOR_SET_ASSOCIATION(mVehicleNullSurfaces); - VECTOR_SET_ASSOCIATION(mVehiclePlanes); -} - -Interior::~Interior() -{ - U32 i; - delete mMaterialList; - mMaterialList = NULL; - - if(mLMHandle != LM_HANDLE(-1)) - gInteriorLMManager.removeInterior(mLMHandle); - - for(i = 0; i < mLightmaps.size(); i++) - { - delete mLightmaps[i]; - mLightmaps[i] = NULL; - } - - for(i = 0; i < mMatInstCleanupList.size(); i++) - { - delete mMatInstCleanupList[i]; - mMatInstCleanupList[i] = NULL; - } - - for(S32 i=0; i &matNames = mMaterialList->getMaterialNameList(); - Vector originalNames = matNames; - - for (U32 i = 0; i < matNames.size(); i++) - { - if (matNames[i].equal("NULL", String::NoCase) || - matNames[i].equal("ORIGIN", String::NoCase) || - matNames[i].equal("TRIGGER", String::NoCase) || - matNames[i].equal("FORCEFIELD", String::NoCase) || - matNames[i].equal("EMITTER", String::NoCase) ) - { - mMaterialList->setMaterialName(i, String()); - } - } - - String relPath = Platform::makeRelativePathName(path, Platform::getCurrentDirectory()); - - // Load the material list - mMaterialList->setTextureLookupPath(relPath); - mMaterialList->mapMaterials(); - - // Grab all the static meshes and load any textures that didn't originate - // from inside the DIF. - for(S32 i=0; imaterialList->setTextureLookupPath(relPath); - - // Now restore the material names since someone later may - // count on the special texture names being present. - for (U32 i = 0; i < originalNames.size(); i++) - mMaterialList->setMaterialName(i, originalNames[i]); - - - fillSurfaceTexMats(); - createZoneVBs(); - cloneMatInstances(); - createReflectPlanes(); - initMatInstances(); - - // lightmap manager steals the lightmaps here... - gInteriorLMManager.addInterior(mLMHandle, mLightmaps.size(), this); - AssertFatal(!mLightmaps.size(), "Failed to process lightmaps"); - - for(U32 i=0; iprepForRendering(relPath); - - GFXStateBlockDesc sh; - -#ifndef TORQUE_SHIPPING - // First create a default state block with - // texturing turned off - mInteriorDebugNoneSB = GFX->createStateBlock(sh); - - // Create a state block for portal rendering that - // doesn't have backface culling enabled - sh.cullDefined = true; - sh.cullMode = GFXCullNone; - - mInteriorDebugPortalSB = GFX->createStateBlock(sh); - - // Reset our cull mode to the default - sh.cullMode = GFXCullCCW; -#endif - - // Next turn on the first texture channel - sh.samplersDefined = true; - sh.samplers[0].textureColorOp = GFXTOPModulate; - -#ifndef TORQUE_SHIPPING - mInteriorDebugTextureSB = GFX->createStateBlock(sh); - - sh.samplers[1].textureColorOp = GFXTOPModulate; - - mInteriorDebugTwoTextureSB = GFX->createStateBlock(sh); -#endif - - // Lastly create a standard rendering state block - sh.samplers[2].textureColorOp = GFXTOPModulate; - - sh.samplers[0].magFilter = GFXTextureFilterLinear; - sh.samplers[0].minFilter = GFXTextureFilterLinear; - - mInteriorSB = GFX->createStateBlock(sh); - - mPreppedForRender = true; - - return true; -} - - -void Interior::setupAveTexGenLength() -{ -/* - F32 len = 0; - for (U32 i = 0; i < mSurfaces.size(); i++) - { - // We're going to assume that most textures don't have separate scales for - // x and y... - F32 lenx = mTexGenEQs[mSurfaces[i].texGenIndex].planeX.len(); - len += F32((*mMaterialList)[mSurfaces[i].textureIndex].getWidth()) * lenx; - } - len /= F32(mSurfaces.size()); - mAveTexGenLength = len; -*/ -} - - -//-------------------------------------------------------------------------- -bool Interior::traverseZones(SceneCullingState* state, - const Frustum& frustum, - S32 containingZone, - S32 baseZone, - U32 zoneOffset, - const MatrixF& OSToWS, - const Point3F& objScale, - const bool dontRestrictOutside, - const bool flipClipPlanes, - Frustum& outFrustum) -{ - // Store off the viewport and frustum - sgStoredViewport = state->getCameraState().getViewport(); - if( dontRestrictOutside ) - { - sgStoredFrustum[0] = state->getFrustum().getNearLeft(); - sgStoredFrustum[1] = state->getFrustum().getNearRight(); - sgStoredFrustum[2] = state->getFrustum().getNearBottom(); - sgStoredFrustum[3] = state->getFrustum().getNearTop(); - sgStoredFrustum[4] = state->getFrustum().getNearDist(); - sgStoredFrustum[5] = state->getFrustum().getFarDist(); - } - else - { - sgStoredFrustum[0] = frustum.getNearLeft(); - sgStoredFrustum[1] = frustum.getNearRight(); - sgStoredFrustum[2] = frustum.getNearBottom(); - sgStoredFrustum[3] = frustum.getNearTop(); - sgStoredFrustum[4] = frustum.getNearDist(); - sgStoredFrustum[5] = frustum.getFarDist(); - } - - sgProjMatrix = state->getCameraState().getProjectionMatrix(); - - MatrixF finalModelView = state->getCameraState().getWorldViewMatrix(); - finalModelView.mul(OSToWS); - finalModelView.scale(Point3F(objScale.x, objScale.y, objScale.z)); - sgProjMatrix.mul(finalModelView); - - finalModelView.inverse(); - finalModelView.mulP(Point3F(0, 0, 0), &sgCamPoint); - sgWSToOSMatrix = finalModelView; - - // do the zone traversal - sgZoneRenderInfo.setSize(mZones.size()); - zoneTraversal(baseZone, flipClipPlanes); - - // Copy out the information for all zones but the outside zone. - for(U32 i = 1; i < mZones.size(); i++) - { - AssertFatal(zoneOffset != 0xFFFFFFFF, "Error, this should never happen!"); - U32 globalIndex = i + zoneOffset - 1; - - if( sgZoneRenderInfo[ i ].render ) - { - state->addCullingVolumeToZone( - globalIndex, - SceneCullingVolume::Includer, - Frustum( - frustum.isOrtho(), - sgZoneRenderInfo[ i ].frustum[ 0 ], - sgZoneRenderInfo[ i ].frustum[ 1 ], - sgZoneRenderInfo[ i ].frustum[ 3 ], - sgZoneRenderInfo[ i ].frustum[ 2 ], - frustum.getNearDist(), - frustum.getFarDist(), - frustum.getTransform() - ) - ); - } - } - - destroyZoneRectVectors(); - - // If zone 0 is rendered, then we return true... - bool continueOut = sgZoneRenderInfo[ 0 ].render; - if( continueOut ) - outFrustum = Frustum( - frustum.isOrtho(), - sgZoneRenderInfo[ 0 ].frustum[ 0 ], - sgZoneRenderInfo[ 0 ].frustum[ 1 ], - sgZoneRenderInfo[ 0 ].frustum[ 3 ], - sgZoneRenderInfo[ 0 ].frustum[ 2 ], - frustum.getNearDist(), - frustum.getFarDist(), - frustum.getTransform() - ); - - return sgZoneRenderInfo[0].render; -} - - -//------------------------------------------------------------------------------ -S32 Interior::getZoneForPoint(const Point3F& rPoint) const -{ - const IBSPNode* pNode = &mBSPNodes[0]; - - while (true) { - F32 dist = getPlane(pNode->planeIndex).distToPlane(rPoint); - if (planeIsFlipped(pNode->planeIndex)) - dist = -dist; - - U32 traverseIndex; - if (dist >= 0) - traverseIndex = pNode->frontIndex; - else - traverseIndex = pNode->backIndex; - - if (isBSPLeafIndex(traverseIndex)) { - if (isBSPSolidLeaf(traverseIndex)) { - return -1; - } else { - U16 zone = getBSPEmptyLeafZone(traverseIndex); - if (zone == 0x0FFF) - return -1; - else - return zone; - } - } - - pNode = &mBSPNodes[traverseIndex]; - } -} - - -//-------------------------------------------------------------------------- -static void itrClipToPlane(Point3F* points, U32& rNumPoints, const PlaneF& rPlane) -{ - S32 start = -1; - for(U32 i = 0; i < rNumPoints; i++) - { - if(rPlane.whichSide(points[i]) == PlaneF::Front) - { - start = i; - break; - } - } - - // Nothing was in front of the plane... - if(start == -1) - { - rNumPoints = 0; - return; - } - - static Point3F finalPoints[128]; - U32 numFinalPoints = 0; - - U32 baseStart = start; - U32 end = (start + 1) % rNumPoints; - - while(end != baseStart) - { - const Point3F& rStartPoint = points[start]; - const Point3F& rEndPoint = points[end]; - - PlaneF::Side fSide = rPlane.whichSide(rStartPoint); - PlaneF::Side eSide = rPlane.whichSide(rEndPoint); - - S32 code = fSide * 3 + eSide; - switch(code) - { - case 4: // f f - case 3: // f o - case 1: // o f - case 0: // o o - // No Clipping required - finalPoints[numFinalPoints++] = points[start]; - start = end; - end = (end + 1) % rNumPoints; - break; - - - case 2: // f b - { - // In this case, we emit the front point, Insert the intersection, - // and advancing to point to first point that is in front or on... - // - finalPoints[numFinalPoints++] = points[start]; - - Point3F vector = rEndPoint - rStartPoint; - F32 t = -(rPlane.distToPlane(rStartPoint) / mDot(rPlane, vector)); - - Point3F intersection = rStartPoint + (vector * t); - finalPoints[numFinalPoints++] = intersection; - - U32 endSeek = (end + 1) % rNumPoints; - while(rPlane.whichSide(points[endSeek]) == PlaneF::Back) - endSeek = (endSeek + 1) % rNumPoints; - - end = endSeek; - start = (end + (rNumPoints - 1)) % rNumPoints; - - const Point3F& rNewStartPoint = points[start]; - const Point3F& rNewEndPoint = points[end]; - - vector = rNewEndPoint - rNewStartPoint; - t = -(rPlane.distToPlane(rNewStartPoint) / mDot(rPlane, vector)); - - intersection = rNewStartPoint + (vector * t); - points[start] = intersection; - } - break; - - case -1: // o b - { - // In this case, we emit the front point, and advance to point to first - // point that is in front or on... - // - finalPoints[numFinalPoints++] = points[start]; - - U32 endSeek = (end + 1) % rNumPoints; - while(rPlane.whichSide(points[endSeek]) == PlaneF::Back) - endSeek = (endSeek + 1) % rNumPoints; - - end = endSeek; - start = (end + (rNumPoints - 1)) % rNumPoints; - - const Point3F& rNewStartPoint = points[start]; - const Point3F& rNewEndPoint = points[end]; - - Point3F vector = rNewEndPoint - rNewStartPoint; - F32 t = -(rPlane.distToPlane(rNewStartPoint) / mDot(rPlane, vector)); - - Point3F intersection = rNewStartPoint + (vector * t); - points[start] = intersection; - } - break; - - case -2: // b f - case -3: // b o - case -4: // b b - // In the algorithm used here, this should never happen... - AssertISV(false, "CSGPlane::clipWindingToPlaneFront: error in polygon clipper"); - break; - - default: - AssertFatal(false, "CSGPlane::clipWindingToPlaneFront: bad outcode"); - break; - } - - } - - // Emit the last point. - finalPoints[numFinalPoints++] = points[start]; - AssertFatal(numFinalPoints >= 3, avar("Error, this shouldn't happen! Invalid winding in itrClipToPlane: %d", numFinalPoints)); - - // Copy the new rWinding, and we're set! - // - dMemcpy(points, finalPoints, numFinalPoints * sizeof(Point3F)); - rNumPoints = numFinalPoints; - AssertISV(rNumPoints <= 128, "Increase maxWindingPoints. Talk to DMoore"); -} - -bool Interior::projectClipAndBoundFan(U32 fanIndex, F64* pResult) -{ - const TriFan& rFan = mWindingIndices[fanIndex]; - - static Point3F windingPoints[128]; - U32 numPoints = rFan.windingCount; - U32 i; - for(i = 0; i < numPoints; i++) - windingPoints[i] = mPoints[mWindings[rFan.windingStart + i]].point; - - itrClipToPlane(windingPoints, numPoints, sgOSPlaneFar); - if(numPoints != 0) - itrClipToPlane(windingPoints, numPoints, sgOSPlaneXMin); - if(numPoints != 0) - itrClipToPlane(windingPoints, numPoints, sgOSPlaneXMax); - if(numPoints != 0) - itrClipToPlane(windingPoints, numPoints, sgOSPlaneYMin); - if(numPoints != 0) - itrClipToPlane(windingPoints, numPoints, sgOSPlaneYMax); - - if(numPoints == 0) - { - pResult[0] = - pResult[1] = - pResult[2] = - pResult[3] = 0.0f; - return false; - } - - F32 minX = 1e10; - F32 maxX = -1e10; - F32 minY = 1e10; - F32 maxY = -1e10; - static Point4F projPoints[128]; - for(i = 0; i < numPoints; i++) - { - projPoints[i].set(windingPoints[i].x, windingPoints[i].y, windingPoints[i].z, 1.0); - sgProjMatrix.mul(projPoints[i]); - - AssertFatal(projPoints[i].w != 0.0, "Error, that's bad!"); - projPoints[i].x /= projPoints[i].w; - projPoints[i].y /= projPoints[i].w; - - if(projPoints[i].x < minX) - minX = projPoints[i].x; - if(projPoints[i].x > maxX) - maxX = projPoints[i].x; - if(projPoints[i].y < minY) - minY = projPoints[i].y; - if(projPoints[i].y > maxY) - maxY = projPoints[i].y; - } - - if(minX < -1.0f) minX = -1.0f; - if(minY < -1.0f) minY = -1.0f; - if(maxX > 1.0f) maxX = 1.0f; - if(maxY > 1.0f) maxY = 1.0f; - - pResult[0] = minX; - pResult[1] = minY; - pResult[2] = maxX; - pResult[3] = maxY; - return true; -} - -void Interior::createZoneRectVectors() -{ - sgZoneRects.setSize(mZones.size()); - for(U32 i = 0; i < mZones.size(); i++) - sgZoneRects[i].active = false; -} - -void Interior::destroyZoneRectVectors() -{ - -} - -void Interior::traverseZone(const RectD* inputRects, const U32 numInputRects, U32 currZone, Vector& zoneStack) -{ - PROFILE_START(InteriorTraverseZone); - // First, we push onto our rect list all the inputRects... - insertZoneRects(sgZoneRects[currZone], inputRects, numInputRects); - - // A portal is a valid traversal if the camera point is on the - // same side of it's plane as the zone. It must then pass the - // clip/project test. - U32 i; - const Zone& rZone = mZones[currZone]; - for(i = rZone.portalStart; i < U32(rZone.portalStart + rZone.portalCount); i++) - { - const Portal& rPortal = mPortals[mZonePortalList[i]]; - AssertFatal(U32(rPortal.zoneFront) == currZone || U32(rPortal.zoneBack) == currZone, - "Portal doesn't reference this zone?"); - - S32 camSide = getPlane(rPortal.planeIndex).whichSide(sgCamPoint); - if(planeIsFlipped(rPortal.planeIndex)) - camSide = -camSide; - S32 zoneSide = (U32(rPortal.zoneFront) == currZone) ? 1 : -1; - U16 otherZone = (U32(rPortal.zoneFront) == currZone) ? rPortal.zoneBack : rPortal.zoneFront; - - // Make sure this isn't a free floating portal... - if(otherZone == currZone) - continue; - - // Make sure we haven't encountered this zone already in this traversal - bool onStack = false; - for(U32 i = 0; i < zoneStack.size(); i++) - { - if(otherZone == zoneStack[i]) - { - onStack = true; - break; - } - } - if(onStack == true) - continue; - - if(camSide == zoneSide) - { - // Can traverse. Note: special case PlaneF::On - // here to prevent possible w == 0 problems and infinite recursion -// Vector newRects; -// VECTOR_SET_ASSOCIATION(newRects); - - // We're abusing the heck out of the allocator here. - U32 waterMark = FrameAllocator::getWaterMark(); - RectD* newRects = (RectD*)FrameAllocator::alloc(1); - U32 numNewRects = 0; - - for(S32 j = 0; j < rPortal.triFanCount; j++) - { - F64 result[4]; - if(projectClipAndBoundFan(rPortal.triFanStart + j, result)) - { - // Have a good rect from this. - RectD possible = convertToRectD(result); - - for(U32 k = 0; k < numInputRects; k++) - { - RectD copy = possible; - if(copy.intersect(inputRects[k])) - newRects[numNewRects++] = copy; - } - } - } - - if(numNewRects != 0) - { - FrameAllocator::alloc((sizeof(RectD) * numNewRects) - 1); - - U32 prevStackSize = zoneStack.size(); - zoneStack.push_back(currZone); - traverseZone(newRects, numNewRects, otherZone, zoneStack); - zoneStack.pop_back(); - AssertFatal(zoneStack.size() == prevStackSize, "Error, stack size changed!"); - } - FrameAllocator::setWaterMark(waterMark); - } - else if(camSide == PlaneF::On) - { - U32 waterMark = FrameAllocator::getWaterMark(); - RectD* newRects = (RectD*)FrameAllocator::alloc(numInputRects * sizeof(RectD)); - dMemcpy(newRects, inputRects, sizeof(RectD) * numInputRects); - - U32 prevStackSize = zoneStack.size(); - zoneStack.push_back(currZone); - traverseZone(newRects, numInputRects, otherZone, zoneStack); - zoneStack.pop_back(); - AssertFatal(zoneStack.size() == prevStackSize, "Error, stack size changed!"); - FrameAllocator::setWaterMark(waterMark); - } - } - PROFILE_END(); -} - -void Interior::zoneTraversal(S32 baseZone, const bool flipClip) -{ - PROFILE_START(InteriorZoneTraversal); - // If we're in solid, render everything... - if(baseZone == -1) - { - for(U32 i = 0; i < mZones.size(); i++) - { - sgZoneRenderInfo[i].render = true; - - sgZoneRenderInfo[i].frustum[0] = sgStoredFrustum[0]; - sgZoneRenderInfo[i].frustum[1] = sgStoredFrustum[1]; - sgZoneRenderInfo[i].frustum[2] = sgStoredFrustum[2]; - sgZoneRenderInfo[i].frustum[3] = sgStoredFrustum[3]; - sgZoneRenderInfo[i].viewport = sgStoredViewport; - } - PROFILE_END(); - return; - } - - // Otherwise, we're going to have to do some work... - createZoneRectVectors(); - U32 i; - for(i = 0; i < mZones.size(); i++) - sgZoneRenderInfo[i].render = false; - - // Create the object space clipping planes... - sgComputeOSFrustumPlanes(sgStoredFrustum, - sgWSToOSMatrix, - sgCamPoint, - sgOSPlaneFar, - sgOSPlaneXMin, - sgOSPlaneXMax, - sgOSPlaneYMin, - sgOSPlaneYMax); - - if(flipClip == true) - { - sgOSPlaneXMin.neg(); - sgOSPlaneXMax.neg(); - sgOSPlaneYMin.neg(); - sgOSPlaneYMax.neg(); - } - // First, the current zone gets the full clipRect, and marked as rendering... - static const F64 fullResult[4] = { -1, -1, 1, 1}; - - static Vector zoneStack; - zoneStack.clear(); - VECTOR_SET_ASSOCIATION(zoneStack); - - RectD baseRect = convertToRectD(fullResult); - traverseZone(&baseRect, 1, baseZone, zoneStack); - - for(i = 0; i < mZones.size(); i++) - { - if(sgZoneRects[i].active == true) - { - sgZoneRenderInfo[i].render = true; - convertToFrustum(sgZoneRenderInfo[i], sgZoneRects[i].rect); - } - } - PROFILE_END(); -} - - -void mergeSurfaceVectors(const U16* from0, - const U32 size0, - const U16* from1, - const U32 size1, - U16* output, - U32* outputSize) -{ - U32 pos0 = 0; - U32 pos1 = 0; - U32 outputCount = 0; - while(pos0 < size0 && pos1 < size1) - { - if(from0[pos0] < from1[pos1]) - { - output[outputCount++] = from0[pos0++]; - } - else if(from0[pos0] == from1[pos1]) - { - // Equal, output one, and inc both counts - output[outputCount++] = from0[pos0++]; - pos1++; - } - else - { - output[outputCount++] = from1[pos1++]; - } - } - AssertFatal(pos0 == size0 || pos1 == size1, "Error, one of these must have reached the end!"); - - // Copy the dregs... - if(pos0 != size0) - { - dMemcpy(&output[outputCount], &from0[pos0], sizeof(U16) * (size0 - pos0)); - outputCount += size0 - pos0; - } - else if(pos1 != size1) - { - dMemcpy(&output[outputCount], &from1[pos1], sizeof(U16) * (size1 - pos1)); - outputCount += size1 - pos1; - } - - *outputSize = outputCount; -} - -// Remove any collision hulls, interval trees, etc... -// -void Interior::purgeLODData() -{ - mConvexHulls.clear(); - mHullIndices.clear(); - mHullEmitStringIndices.clear(); - mHullSurfaceIndices.clear(); - mCoordBinIndices.clear(); - mConvexHullEmitStrings.clear(); - for(U32 i = 0; i < NumCoordBins * NumCoordBins; i++) - { - mCoordBins[i].binStart = 0; - mCoordBins[i].binCount = 0; - } -} - -// Build an OptimizedPolyList that represents this Interior's mesh -void Interior::buildExportPolyList(OptimizedPolyList& polys, MatrixF* mat, Point3F* scale) -{ - MatrixF saveMat; - Point3F saveScale; - polys.getTransform(&saveMat, &saveScale); - - if (mat) - { - if (scale) - polys.setTransform(mat, *scale); - else - polys.setTransform(mat, Point3F(1.0f, 1.0f, 1.0f)); - } - - // Create one TSMesh per zone - for (U32 i = 0; i < mZones.size(); i++) - { - const Interior::Zone& zone = mZones[i]; - - // Gather some data - for (U32 j = 0; j < zone.surfaceCount; j++) - { - U32 sdx = mZoneSurfaces[zone.surfaceStart + j]; - - const Interior::Surface& surface = mSurfaces[sdx]; - - // Snag the MaterialInstance - BaseMatInstance *matInst = mMaterialList->getMaterialInst( surface.textureIndex ); - - // Start a poly - polys.begin(matInst, j, OptimizedPolyList::TriangleStrip); - - // Set its plane - PlaneF plane = getFlippedPlane(surface.planeIndex); - polys.plane(plane); - - // Get its texGen so that we can calculate uvs - Interior::TexGenPlanes texGens = mTexGenEQs[surface.texGenIndex]; - texGens.planeY.invert(); - - // Loop through and add the verts and uvs - for (U32 k = 0; k < surface.windingCount; k++) - { - // Get our point - U32 vdx = mWindings[surface.windingStart + k]; - const Point3F& pt = mPoints[vdx].point; - - // Get our uv - Point2F uv; - uv.x = texGens.planeX.distToPlane(pt); - uv.y = texGens.planeY.distToPlane(pt); - - Point3F normal = getPointNormal(sdx, k); - - polys.vertex(pt, normal, uv); - } - - polys.end(); - } - } - - polys.setTransform(&saveMat, saveScale); -} - - -struct TempProcSurface -{ - U32 numPoints; - U32 pointIndices[32]; - U16 planeIndex; - U8 mask; -}; - -struct PlaneGrouping -{ - U32 numPlanes; - U16 planeIndices[32]; - U8 mask; -}; - - -//-------------------------------------------------------------------------- -void Interior::processHullPolyLists() -{ - Vector planeIndices(256, __FILE__, __LINE__); - Vector pointIndices(256, __FILE__, __LINE__); - Vector pointMasks(256, __FILE__, __LINE__); - Vector planeMasks(256, __FILE__, __LINE__); - Vector tempSurfaces(128, __FILE__, __LINE__); - Vector planeGroups(32, __FILE__, __LINE__); - - // Reserve space in the vectors - { - mPolyListStrings.setSize(0); - mPolyListStrings.reserve(128 << 10); - - mPolyListPoints.setSize(0); - mPolyListPoints.reserve(32 << 10); - - mPolyListPlanes.setSize(0); - mPolyListPlanes.reserve(16 << 10); - } - - for(U32 i = 0; i < mConvexHulls.size(); i++) - { - U32 j, k, l, m; - - ConvexHull& rHull = mConvexHulls[i]; - - planeIndices.setSize(0); - pointIndices.setSize(0); - tempSurfaces.setSize(0); - - // Extract all the surfaces from this hull into our temporary processing format - { - for(j = 0; j < rHull.surfaceCount; j++) - { - tempSurfaces.increment(); - TempProcSurface& temp = tempSurfaces.last(); - - U32 surfaceIndex = mHullSurfaceIndices[j + rHull.surfaceStart]; - if(isNullSurfaceIndex(surfaceIndex)) - { - const NullSurface& rSurface = mNullSurfaces[getNullSurfaceIndex(surfaceIndex)]; - - temp.planeIndex = rSurface.planeIndex; - temp.numPoints = rSurface.windingCount; - for(k = 0; k < rSurface.windingCount; k++) - temp.pointIndices[k] = mWindings[rSurface.windingStart + k]; - } - else - { - const Surface& rSurface = mSurfaces[surfaceIndex]; - - temp.planeIndex = rSurface.planeIndex; - collisionFanFromSurface(rSurface, temp.pointIndices, &temp.numPoints); - } - } - } - - // First order of business: extract all unique planes and points from - // the list of surfaces... - { - for(j = 0; j < tempSurfaces.size(); j++) - { - const TempProcSurface& rSurface = tempSurfaces[j]; - - bool found = false; - for(k = 0; k < planeIndices.size() && !found; k++) - { - if(rSurface.planeIndex == planeIndices[k]) - found = true; - } - if(!found) - planeIndices.push_back(rSurface.planeIndex); - - for(k = 0; k < rSurface.numPoints; k++) - { - found = false; - for(l = 0; l < pointIndices.size(); l++) - { - if(pointIndices[l] == rSurface.pointIndices[k]) - found = true; - } - if(!found) - pointIndices.push_back(rSurface.pointIndices[k]); - } - } - } - - // Now that we have all the unique points and planes, remap the surfaces in - // terms of the offsets into the unique point list... - { - for(j = 0; j < tempSurfaces.size(); j++) - { - TempProcSurface& rSurface = tempSurfaces[j]; - - // Points - for(k = 0; k < rSurface.numPoints; k++) - { - bool found = false; - for(l = 0; l < pointIndices.size(); l++) - { - if(pointIndices[l] == rSurface.pointIndices[k]) - { - rSurface.pointIndices[k] = l; - found = true; - break; - } - } - AssertISV(found, "Error remapping point indices in interior collision processing"); - } - } - } - - // Ok, at this point, we have a list of unique points, unique planes, and the - // surfaces all remapped in those terms. We need to check our error conditions - // that will make sure that we can properly encode this hull: - { - AssertISV(planeIndices.size() < 256, "Error, > 256 planes on an interior hull"); - AssertISV(pointIndices.size() < 63356, "Error, > 65536 points on an interior hull"); - AssertISV(tempSurfaces.size() < 256, "Error, > 256 surfaces on an interior hull"); - } - - // Now we group the planes together, and merge the closest groups until we're left - // with <= 8 groups - { - planeGroups.setSize(planeIndices.size()); - for(j = 0; j < planeIndices.size(); j++) - { - planeGroups[j].numPlanes = 1; - planeGroups[j].planeIndices[0] = planeIndices[j]; - } - - while(planeGroups.size() > 8) - { - // Find the two closest groups. If mdp(i, j) is the value of the - // largest pairwise dot product that can be computed from the vectors - // of group i, and group j, then the closest group pair is the one - // with the smallest value of mdp. - F32 currmin = 2; - S32 firstGroup = -1; - S32 secondGroup = -1; - - for(j = 0; j < planeGroups.size(); j++) - { - PlaneGrouping& first = planeGroups[j]; - for(k = j + 1; k < planeGroups.size(); k++) - { - PlaneGrouping& second = planeGroups[k]; - - F32 max = -2; - for(l = 0; l < first.numPlanes; l++) - { - for(m = 0; m < second.numPlanes; m++) - { - Point3F firstNormal = getPlane(first.planeIndices[l]); - if(planeIsFlipped(first.planeIndices[l])) - firstNormal.neg(); - Point3F secondNormal = getPlane(second.planeIndices[m]); - if(planeIsFlipped(second.planeIndices[m])) - secondNormal.neg(); - - F32 dot = mDot(firstNormal, secondNormal); - if(dot > max) - max = dot; - } - } - - if(max < currmin) - { - currmin = max; - firstGroup = j; - secondGroup = k; - } - } - } - AssertFatal(firstGroup != -1 && secondGroup != -1, "Error, unable to find a suitable pairing?"); - - // Merge first and second - PlaneGrouping& to = planeGroups[firstGroup]; - PlaneGrouping& from = planeGroups[secondGroup]; - while(from.numPlanes != 0) - { - to.planeIndices[to.numPlanes++] = from.planeIndices[from.numPlanes - 1]; - from.numPlanes--; - } - - // And remove the merged group - planeGroups.erase(secondGroup); - } - AssertFatal(planeGroups.size() <= 8, "Error, too many plane groupings!"); - - - // Assign a mask to each of the plane groupings - for(j = 0; j < planeGroups.size(); j++) - planeGroups[j].mask = (1 << j); - } - - // Now, assign the mask to each of the temp polys - { - for(j = 0; j < tempSurfaces.size(); j++) - { - bool assigned = false; - for(k = 0; k < planeGroups.size() && !assigned; k++) - { - for(l = 0; l < planeGroups[k].numPlanes; l++) - { - if(planeGroups[k].planeIndices[l] == tempSurfaces[j].planeIndex) - { - tempSurfaces[j].mask = planeGroups[k].mask; - assigned = true; - break; - } - } - } - AssertFatal(assigned, "Error, missed a plane somewhere in the hull poly list!"); - } - } - - // Copy the appropriate group mask to the plane masks - { - planeMasks.setSize(planeIndices.size()); - dMemset(planeMasks.address(), 0, planeMasks.size() * sizeof(U8)); - - for(j = 0; j < planeIndices.size(); j++) - { - bool found = false; - for(k = 0; k < planeGroups.size() && !found; k++) - { - for(l = 0; l < planeGroups[k].numPlanes; l++) - { - if(planeGroups[k].planeIndices[l] == planeIndices[j]) - { - planeMasks[j] = planeGroups[k].mask; - found = true; - break; - } - } - } - AssertFatal(planeMasks[j] != 0, "Error, missing mask for plane!"); - } - } - - // And whip through the points, constructing the total mask for that point - { - pointMasks.setSize(pointIndices.size()); - dMemset(pointMasks.address(), 0, pointMasks.size() * sizeof(U8)); - - for(j = 0; j < pointIndices.size(); j++) - { - for(k = 0; k < tempSurfaces.size(); k++) - { - for(l = 0; l < tempSurfaces[k].numPoints; l++) - { - if(tempSurfaces[k].pointIndices[l] == j) - { - pointMasks[j] |= tempSurfaces[k].mask; - break; - } - } - } - AssertFatal(pointMasks[j] != 0, "Error, point must exist in at least one surface!"); - } - } - - // Create the emit strings, and we're done! - { - // Set the range of planes - rHull.polyListPlaneStart = mPolyListPlanes.size(); - mPolyListPlanes.setSize(rHull.polyListPlaneStart + planeIndices.size()); - for(j = 0; j < planeIndices.size(); j++) - mPolyListPlanes[j + rHull.polyListPlaneStart] = planeIndices[j]; - - // Set the range of points - rHull.polyListPointStart = mPolyListPoints.size(); - mPolyListPoints.setSize(rHull.polyListPointStart + pointIndices.size()); - for(j = 0; j < pointIndices.size(); j++) - mPolyListPoints[j + rHull.polyListPointStart] = pointIndices[j]; - - // Now the emit string. The emit string goes like: (all fields are bytes) - // NumPlanes (PLMask) * NumPlanes - // NumPointsHi NumPointsLo (PtMask) * NumPoints - // NumSurfaces - // (NumPoints SurfaceMask PlOffset (PtOffsetHi PtOffsetLo) * NumPoints) * NumSurfaces - // - U32 stringLen = 1 + planeIndices.size(); - stringLen += 2 + pointIndices.size(); - stringLen += 1; - for(j = 0; j < tempSurfaces.size(); j++) - stringLen += 1 + 1 + 1 + (tempSurfaces[j].numPoints * 2); - - rHull.polyListStringStart = mPolyListStrings.size(); - mPolyListStrings.setSize(rHull.polyListStringStart + stringLen); - - U8* pString = &mPolyListStrings[rHull.polyListStringStart]; - U32 currPos = 0; - - // Planes - pString[currPos++] = planeIndices.size(); - for(j = 0; j < planeIndices.size(); j++) - pString[currPos++] = planeMasks[j]; - - // Points - pString[currPos++] = (pointIndices.size() >> 8) & 0xFF; - pString[currPos++] = (pointIndices.size() >> 0) & 0xFF; - for(j = 0; j < pointIndices.size(); j++) - pString[currPos++] = pointMasks[j]; - - // Surfaces - pString[currPos++] = tempSurfaces.size(); - for(j = 0; j < tempSurfaces.size(); j++) - { - pString[currPos++] = tempSurfaces[j].numPoints; - pString[currPos++] = tempSurfaces[j].mask; - - bool found = false; - for(k = 0; k < planeIndices.size(); k++) - { - if(planeIndices[k] == tempSurfaces[j].planeIndex) - { - pString[currPos++] = k; - found = true; - break; - } - } - AssertFatal(found, "Error, missing planeindex!"); - - for(k = 0; k < tempSurfaces[j].numPoints; k++) - { - pString[currPos++] = (tempSurfaces[j].pointIndices[k] >> 8) & 0xFF; - pString[currPos++] = (tempSurfaces[j].pointIndices[k] >> 0) & 0xFF; - } - } - AssertFatal(currPos == stringLen, "Error, mismatched string length!"); - } - } // for (i = 0; i < mConvexHulls.size(); i++) - - // Compact the used vectors - { - mPolyListStrings.compact(); - mPolyListPoints.compact(); - mPolyListPlanes.compact(); - } -} - -//-------------------------------------------------------------------------- -void Interior::processVehicleHullPolyLists() -{ - Vector planeIndices(256, __FILE__, __LINE__); - Vector pointIndices(256, __FILE__, __LINE__); - Vector pointMasks(256, __FILE__, __LINE__); - Vector planeMasks(256, __FILE__, __LINE__); - Vector tempSurfaces(128, __FILE__, __LINE__); - Vector planeGroups(32, __FILE__, __LINE__); - - // Reserve space in the vectors - { - mVehiclePolyListStrings.setSize(0); - mVehiclePolyListStrings.reserve(128 << 10); - - mVehiclePolyListPoints.setSize(0); - mVehiclePolyListPoints.reserve(32 << 10); - - mVehiclePolyListPlanes.setSize(0); - mVehiclePolyListPlanes.reserve(16 << 10); - } - - for(U32 i = 0; i < mVehicleConvexHulls.size(); i++) - { - U32 j, k, l, m; - - ConvexHull& rHull = mVehicleConvexHulls[i]; - - planeIndices.setSize(0); - pointIndices.setSize(0); - tempSurfaces.setSize(0); - - // Extract all the surfaces from this hull into our temporary processing format - { - for(j = 0; j < rHull.surfaceCount; j++) - { - tempSurfaces.increment(); - TempProcSurface& temp = tempSurfaces.last(); - - U32 surfaceIndex = mVehicleHullSurfaceIndices[j + rHull.surfaceStart]; - const NullSurface& rSurface = mVehicleNullSurfaces[getVehicleNullSurfaceIndex(surfaceIndex)]; - - temp.planeIndex = rSurface.planeIndex; - temp.numPoints = rSurface.windingCount; - for(k = 0; k < rSurface.windingCount; k++) - temp.pointIndices[k] = mVehicleWindings[rSurface.windingStart + k]; - } - } - - // First order of business: extract all unique planes and points from - // the list of surfaces... - { - for(j = 0; j < tempSurfaces.size(); j++) - { - const TempProcSurface& rSurface = tempSurfaces[j]; - - bool found = false; - for(k = 0; k < planeIndices.size() && !found; k++) - { - if(rSurface.planeIndex == planeIndices[k]) - found = true; - } - if(!found) - planeIndices.push_back(rSurface.planeIndex); - - for(k = 0; k < rSurface.numPoints; k++) - { - found = false; - for(l = 0; l < pointIndices.size(); l++) - { - if(pointIndices[l] == rSurface.pointIndices[k]) - found = true; - } - if(!found) - pointIndices.push_back(rSurface.pointIndices[k]); - } - } - } - - // Now that we have all the unique points and planes, remap the surfaces in - // terms of the offsets into the unique point list... - { - for(j = 0; j < tempSurfaces.size(); j++) - { - TempProcSurface& rSurface = tempSurfaces[j]; - - // Points - for(k = 0; k < rSurface.numPoints; k++) - { - bool found = false; - for(l = 0; l < pointIndices.size(); l++) - { - if(pointIndices[l] == rSurface.pointIndices[k]) - { - rSurface.pointIndices[k] = l; - found = true; - break; - } - } - AssertISV(found, "Error remapping point indices in interior collision processing"); - } - } - } - - // Ok, at this point, we have a list of unique points, unique planes, and the - // surfaces all remapped in those terms. We need to check our error conditions - // that will make sure that we can properly encode this hull: - { - AssertISV(planeIndices.size() < 256, "Error, > 256 planes on an interior hull"); - AssertISV(pointIndices.size() < 63356, "Error, > 65536 points on an interior hull"); - AssertISV(tempSurfaces.size() < 256, "Error, > 256 surfaces on an interior hull"); - } - - // Now we group the planes together, and merge the closest groups until we're left - // with <= 8 groups - { - planeGroups.setSize(planeIndices.size()); - for(j = 0; j < planeIndices.size(); j++) - { - planeGroups[j].numPlanes = 1; - planeGroups[j].planeIndices[0] = planeIndices[j]; - } - - while(planeGroups.size() > 8) - { - // Find the two closest groups. If mdp(i, j) is the value of the - // largest pairwise dot product that can be computed from the vectors - // of group i, and group j, then the closest group pair is the one - // with the smallest value of mdp. - F32 currmin = 2; - S32 firstGroup = -1; - S32 secondGroup = -1; - - for(j = 0; j < planeGroups.size(); j++) - { - PlaneGrouping& first = planeGroups[j]; - for(k = j + 1; k < planeGroups.size(); k++) - { - PlaneGrouping& second = planeGroups[k]; - - F32 max = -2; - for(l = 0; l < first.numPlanes; l++) - { - for(m = 0; m < second.numPlanes; m++) - { - Point3F firstNormal = mVehiclePlanes[first.planeIndices[l]]; - Point3F secondNormal = mVehiclePlanes[second.planeIndices[m]]; - - F32 dot = mDot(firstNormal, secondNormal); - if(dot > max) - max = dot; - } - } - - if(max < currmin) - { - currmin = max; - firstGroup = j; - secondGroup = k; - } - } - } - AssertFatal(firstGroup != -1 && secondGroup != -1, "Error, unable to find a suitable pairing?"); - - // Merge first and second - PlaneGrouping& to = planeGroups[firstGroup]; - PlaneGrouping& from = planeGroups[secondGroup]; - while(from.numPlanes != 0) - { - to.planeIndices[to.numPlanes++] = from.planeIndices[from.numPlanes - 1]; - from.numPlanes--; - } - - // And remove the merged group - planeGroups.erase(secondGroup); - } - AssertFatal(planeGroups.size() <= 8, "Error, too many plane groupings!"); - - - // Assign a mask to each of the plane groupings - for(j = 0; j < planeGroups.size(); j++) - planeGroups[j].mask = (1 << j); - } - - // Now, assign the mask to each of the temp polys - { - for(j = 0; j < tempSurfaces.size(); j++) - { - bool assigned = false; - for(k = 0; k < planeGroups.size() && !assigned; k++) - { - for(l = 0; l < planeGroups[k].numPlanes; l++) - { - if(planeGroups[k].planeIndices[l] == tempSurfaces[j].planeIndex) - { - tempSurfaces[j].mask = planeGroups[k].mask; - assigned = true; - break; - } - } - } - AssertFatal(assigned, "Error, missed a plane somewhere in the hull poly list!"); - } - } - - // Copy the appropriate group mask to the plane masks - { - planeMasks.setSize(planeIndices.size()); - dMemset(planeMasks.address(), 0, planeMasks.size() * sizeof(U8)); - - for(j = 0; j < planeIndices.size(); j++) - { - bool found = false; - for(k = 0; k < planeGroups.size() && !found; k++) - { - for(l = 0; l < planeGroups[k].numPlanes; l++) - { - if(planeGroups[k].planeIndices[l] == planeIndices[j]) - { - planeMasks[j] = planeGroups[k].mask; - found = true; - break; - } - } - } - AssertFatal(planeMasks[j] != 0, "Error, missing mask for plane!"); - } - } - - // And whip through the points, constructing the total mask for that point - { - pointMasks.setSize(pointIndices.size()); - dMemset(pointMasks.address(), 0, pointMasks.size() * sizeof(U8)); - - for(j = 0; j < pointIndices.size(); j++) - { - for(k = 0; k < tempSurfaces.size(); k++) - { - for(l = 0; l < tempSurfaces[k].numPoints; l++) - { - if(tempSurfaces[k].pointIndices[l] == j) - { - pointMasks[j] |= tempSurfaces[k].mask; - break; - } - } - } - AssertFatal(pointMasks[j] != 0, "Error, point must exist in at least one surface!"); - } - } - - // Create the emit strings, and we're done! - { - // Set the range of planes - rHull.polyListPlaneStart = mVehiclePolyListPlanes.size(); - mVehiclePolyListPlanes.setSize(rHull.polyListPlaneStart + planeIndices.size()); - for(j = 0; j < planeIndices.size(); j++) - mVehiclePolyListPlanes[j + rHull.polyListPlaneStart] = planeIndices[j]; - - // Set the range of points - rHull.polyListPointStart = mVehiclePolyListPoints.size(); - mVehiclePolyListPoints.setSize(rHull.polyListPointStart + pointIndices.size()); - for(j = 0; j < pointIndices.size(); j++) - mVehiclePolyListPoints[j + rHull.polyListPointStart] = pointIndices[j]; - - // Now the emit string. The emit string goes like: (all fields are bytes) - // NumPlanes (PLMask) * NumPlanes - // NumPointsHi NumPointsLo (PtMask) * NumPoints - // NumSurfaces - // (NumPoints SurfaceMask PlOffset (PtOffsetHi PtOffsetLo) * NumPoints) * NumSurfaces - // - U32 stringLen = 1 + planeIndices.size(); - stringLen += 2 + pointIndices.size(); - stringLen += 1; - for(j = 0; j < tempSurfaces.size(); j++) - stringLen += 1 + 1 + 1 + (tempSurfaces[j].numPoints * 2); - - rHull.polyListStringStart = mVehiclePolyListStrings.size(); - mVehiclePolyListStrings.setSize(rHull.polyListStringStart + stringLen); - - U8* pString = &mVehiclePolyListStrings[rHull.polyListStringStart]; - U32 currPos = 0; - - // Planes - pString[currPos++] = planeIndices.size(); - for(j = 0; j < planeIndices.size(); j++) - pString[currPos++] = planeMasks[j]; - - // Points - pString[currPos++] = (pointIndices.size() >> 8) & 0xFF; - pString[currPos++] = (pointIndices.size() >> 0) & 0xFF; - for(j = 0; j < pointIndices.size(); j++) - pString[currPos++] = pointMasks[j]; - - // Surfaces - pString[currPos++] = tempSurfaces.size(); - for(j = 0; j < tempSurfaces.size(); j++) - { - pString[currPos++] = tempSurfaces[j].numPoints; - pString[currPos++] = tempSurfaces[j].mask; - - bool found = false; - for(k = 0; k < planeIndices.size(); k++) - { - if(planeIndices[k] == tempSurfaces[j].planeIndex) - { - pString[currPos++] = k; - found = true; - break; - } - } - AssertFatal(found, "Error, missing planeindex!"); - - for(k = 0; k < tempSurfaces[j].numPoints; k++) - { - pString[currPos++] = (tempSurfaces[j].pointIndices[k] >> 8) & 0xFF; - pString[currPos++] = (tempSurfaces[j].pointIndices[k] >> 0) & 0xFF; - } - } - AssertFatal(currPos == stringLen, "Error, mismatched string length!"); - } - } // for (i = 0; i < mConvexHulls.size(); i++) - - // Compact the used vectors - { - mVehiclePolyListStrings.compact(); - mVehiclePolyListPoints.compact(); - mVehiclePolyListPlanes.compact(); - } -} - - - - -//-------------------------------------------------------------------------- -void ZoneVisDeterminer::runFromState(SceneRenderState* state, U32 offset, U32 parentZone) -{ - mMode = FromState; - mState = state; - mZoneRangeOffset = offset; - mParentZone = parentZone; -} - -void ZoneVisDeterminer::runFromRects(SceneRenderState* state, U32 offset, U32 parentZone) -{ - mMode = FromRects; - mState = state; - mZoneRangeOffset = offset; - mParentZone = parentZone; -} - -bool ZoneVisDeterminer::isZoneVisible(const U32 zone) const -{ - if(zone == 0) - return mState->getCullingState().getZoneState(mParentZone).isZoneVisible(); - - if(mMode == FromState) - { - return mState->getCullingState().getZoneState(zone + mZoneRangeOffset - 1).isZoneVisible(); - } - else - { - return sgZoneRenderInfo[zone].render; - } -} - - - -//-------------------------------------------------------------------------- -// storeSurfaceVerts - -// Need to store the verts for every surface because the uv mapping changes -// per vertex per surface. -//-------------------------------------------------------------------------- -void Interior::storeSurfVerts( Vector &masterIndexList, - Vector &tempIndexList, - Vector &verts, - U32 numIndices, - Surface &surface, - U32 surfaceIndex ) -{ - U32 startIndex = tempIndexList.size() - numIndices; - U32 startVert = verts.size(); - - Vector vertMap; - - for( U32 i=0; i &primInfoList, - Vector &indexList, - Vector &verts, - U32 &startIndex, - U32 &startVert ) -{ - - GFXPrimitive pnfo; - - if( !node.matInst ) - { - String name = mMaterialList->getMaterialName( node.baseTexIndex ); - - if (!name.equal("NULL", String::NoCase) && - !name.equal("ORIGIN", String::NoCase) && - !name.equal("TRIGGER", String::NoCase) && - !name.equal("FORCEFIELD", String::NoCase) && - !name.equal("EMITTER", String::NoCase) ) - { - Con::errorf( "material unmapped: %s", name.c_str() ); - } - - node.matInst = MATMGR->getWarningMatInstance(); - } - - - // find min index - pnfo.minIndex = U32(-1); - - for( U32 i=startIndex; i 0 ) - { - primInfoList.push_back( pnfo ); - - node.primInfoIndex = primInfoList.size() - 1; - RNList.renderNodeList.push_back( node ); - } - -} - -//-------------------------------------------------------------------------- -// fill vertex -//-------------------------------------------------------------------------- -void Interior::fillVertex( GFXVertexPNTTB &vert, Surface &surface, U32 surfaceIndex ) -{ - TexGenPlanes texPlanes = mTexGenEQs[surface.texGenIndex]; - - vert.texCoord.x = texPlanes.planeX.x * vert.point.x + - texPlanes.planeX.y * vert.point.y + - texPlanes.planeX.z * vert.point.z + - texPlanes.planeX.d; - - - vert.texCoord.y = texPlanes.planeY.x * vert.point.x + - texPlanes.planeY.y * vert.point.y + - texPlanes.planeY.z * vert.point.z + - texPlanes.planeY.d; - - texPlanes = mLMTexGenEQs[surfaceIndex]; - - vert.texCoord2.x = texPlanes.planeX.x * vert.point.x + - texPlanes.planeX.y * vert.point.y + - texPlanes.planeX.z * vert.point.z + - texPlanes.planeX.d; - - - vert.texCoord2.y = texPlanes.planeY.x * vert.point.x + - texPlanes.planeY.y * vert.point.y + - texPlanes.planeY.z * vert.point.z + - texPlanes.planeY.d; - - // vert normal and N already set - vert.T = surface.T - vert.normal * mDot(vert.normal, surface.T); - vert.T.normalize(); - - mCross(vert.normal, vert.T, &vert.B); - vert.B *= (mDot(vert.B, surface.B) < 0.0F) ? -1.0F : 1.0F; -} - -//-------------------------------------------------------------------------- -// Create vertex (and index) buffers for each zone -//-------------------------------------------------------------------------- -void Interior::createZoneVBs() -{ - if( mVertBuff ) - { - return; - } - - // create one big-ass vertex buffer to contain all verts - // drawIndexedPrimitive() calls can render subsets of the big-ass buffer - - Vector verts; - Vector indices; - - U32 startIndex = 0; - U32 startVert = 0; - - - Vector primInfoList; - - - // fill index list first, then fill verts - for( U32 i=0; i tempIndices; - tempIndices.setSize(0); - - - - for( U32 j=0; jgetMaterialInst( surface.textureIndex ); - Material* pMat = dynamic_cast(matInst->getMaterial()); - if( pMat && pMat->mPlanarReflection ) continue; - - node.exterior = surface.surfaceFlags & SurfaceOutsideVisible; - - // fill in node info on first time through - if( j==0 ) - { - node.baseTexIndex = surface.textureIndex; - node.matInst = matInst; - curTexIndex = node.baseTexIndex; - node.lightMapIndex = mNormalLMapIndices[surfaceIndex]; - curLightMapIndex = node.lightMapIndex; - } - - // check for material change - if( surface.textureIndex != curTexIndex || - mNormalLMapIndices[surfaceIndex] != curLightMapIndex ) - { - storeRenderNode( node, RNList, primInfoList, indices, verts, startIndex, startVert ); - - tempIndices.setSize( 0 ); - - // set new material info - U16 baseTex = surface.textureIndex; - U8 lmIndex = mNormalLMapIndices[surfaceIndex]; - - if( baseTex != curTexIndex ) - { - node.baseTexIndex = baseTex; - node.matInst = mMaterialList->getMaterialInst( baseTex ); - } - else - { - node.baseTexIndex = NULL; - } - - - node.lightMapIndex = lmIndex; - - curTexIndex = baseTex; - curLightMapIndex = lmIndex; - - } - - - // NOTE, can put this in storeSurfVerts() - U32 tempStartIndex = tempIndices.size(); - - U32 nPrim = 0; - U32 last = 2; - while(last < surface.windingCount) - { - // First - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-2], getPointNormal(surfaceIndex, last-2)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-1], getPointNormal(surfaceIndex, last-1)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-0], getPointNormal(surfaceIndex, last)) ); - last++; - nPrim++; - - if(last == surface.windingCount) - break; - - // Second - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-1], getPointNormal(surfaceIndex, last-1)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-2], getPointNormal(surfaceIndex, last-2)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-0], getPointNormal(surfaceIndex, last)) ); - last++; - nPrim++; - } - - U32 dStartVert = verts.size(); - GFXPrimitive* p = &surface.surfaceInfo; - p->startIndex = indices.size(); //tempStartIndex; - - // Normal render info - storeSurfVerts( indices, tempIndices, verts, tempIndices.size() - tempStartIndex, - surface, surfaceIndex ); - - // Debug render info - p->type = GFXTriangleList; - p->numVertices = verts.size() - dStartVert; - p->numPrimitives = nPrim; - p->minIndex = indices[p->startIndex]; - for (U32 i = p->startIndex; i < p->startIndex + nPrim * 3; i++) { - if (indices[i] < p->minIndex) { - p->minIndex = indices[i]; - } - } - } - - // store remaining index list - storeRenderNode( node, RNList, primInfoList, indices, verts, startIndex, startVert ); - - mZoneRNList.push_back( RNList ); - } - - // It is possible that we have no zones or have no surfaces in our zones (static meshes only) - if (verts.size() == 0) - return; - - // create vertex buffer - mVertBuff.set(GFX, verts.size(), GFXBufferTypeStatic); - GFXVertexPNTTB *vbVerts = mVertBuff.lock(); - - dMemcpy( vbVerts, verts.address(), verts.size() * sizeof( GFXVertexPNTTB ) ); - - mVertBuff.unlock(); - - // create primitive buffer - U16 *ibIndices; - GFXPrimitive *piInput; - mPrimBuff.set(GFX, indices.size(), primInfoList.size(), GFXBufferTypeStatic); - mPrimBuff.lock(&ibIndices, &piInput); - - dMemcpy( ibIndices, indices.address(), indices.size() * sizeof(U16) ); - dMemcpy( piInput, primInfoList.address(), primInfoList.size() * sizeof(GFXPrimitive) ); - - mPrimBuff.unlock(); - -} - - -#define SMALL_FLOAT (1e-12) - -//-------------------------------------------------------------------------- -// Get the texture space matrice for a point on a surface -//-------------------------------------------------------------------------- -void Interior::getTexMat(U32 surfaceIndex, U32 pointOffset, Point3F& T, Point3F& N, Point3F& B) -{ - Surface& surface = mSurfaces[surfaceIndex]; - - if (mFileVersion >= 11) - { - // There is a one-to-one mapping of mWindings and mTexMatIndices - U32 texMatIndex = mTexMatIndices[surface.windingStart + pointOffset]; - TexMatrix& texMat = mTexMatrices[texMatIndex]; - - T = mNormals[texMat.T]; - N = mNormals[texMat.N]; - B = mNormals[texMat.B]; - } - else - { - T = surface.T - surface.N * mDot(surface.N, surface.T); - N = surface.N; - - mCross(surface.N, T, &B); - B *= (mDot(B, surface.B) < 0.0F) ? -1.0f : 1.0f; - } - - return; -} - -//-------------------------------------------------------------------------- -// Fill in texture space matrices for each surface -//-------------------------------------------------------------------------- -void Interior::fillSurfaceTexMats() -{ - for( U32 i=0; i SMALL_FLOAT ) - { - S.x = -cp.y / cp.x; - T.x = -cp.z / cp.x; - } - - edge1.set( pts[1].point.y - pts[0].point.y, pts[1].texCoord.x - pts[0].texCoord.x, pts[1].texCoord.y - pts[0].texCoord.y ); - edge2.set( pts[2].point.y - pts[0].point.y, pts[2].texCoord.x - pts[0].texCoord.x, pts[2].texCoord.y - pts[0].texCoord.y ); - - mCross( edge1, edge2, &cp ); - if( fabs(cp.x) > SMALL_FLOAT ) - { - S.y = -cp.y / cp.x; - T.y = -cp.z / cp.x; - } - - edge1.set( pts[1].point.z - pts[0].point.z, pts[1].texCoord.x - pts[0].texCoord.x, pts[1].texCoord.y - pts[0].texCoord.y ); - edge2.set( pts[2].point.z - pts[0].point.z, pts[2].texCoord.x - pts[0].texCoord.x, pts[2].texCoord.y - pts[0].texCoord.y ); - - mCross( edge1, edge2, &cp ); - if( fabs(cp.x) > SMALL_FLOAT ) - { - S.z = -cp.y / cp.x; - T.z = -cp.z / cp.x; - } - - S.normalizeSafe(); - T.normalizeSafe(); - mCross( S, T, &SxT ); - - - if( mDot( SxT, planeNorm ) < 0.0 ) - { - SxT = -SxT; - } - - surface.T = S; - surface.B = T; - surface.N = SxT; - surface.normal = planeNorm; - } - -} - -//-------------------------------------------------------------------------- -// Clone material instances - if a texture (material) exists on both the -// inside and outside of an interior, it needs to create two material -// instances - one for the inside, and one for the outside. The reason is -// that the light direction maps only exist on the inside of the interior. -//-------------------------------------------------------------------------- -void Interior::cloneMatInstances() -{ - Vector< BaseMatInstance *> outsideMats; - Vector< BaseMatInstance *> insideMats; - - // store pointers to mat lists - for( U32 i=0; i(outsideMats[i]->getMaterial()); - - if (mat) - { - BaseMatInstance *newMat = mat->createMatInstance(); - mMatInstCleanupList.push_back( newMat ); - - // go through and find the inside version and replace it - // with the new one. - for( U32 k=0; kgetFeaturesDelegate().bind( &Interior::_enableLightMapFeature ); - mat->init( MATMGR->getDefaultFeatures(), getGFXVertexFormat()); - - // We need to know if we have non-zwrite translucent materials - // so that we can make the extra renderimage pass for them. - Material* pMat = dynamic_cast(mat->getMaterial()); - if ( pMat ) - mHasTranslucentMaterials |= pMat->mTranslucent && !pMat->mTranslucentZWrite; - } - - } - - for( U32 j=0; jinit( MATMGR->getDefaultFeatures(), getGFXVertexFormat()); - - // We need to know if we have non-zwrite translucent materials - // so that we can make the extra renderimage pass for them. - Material* pMat = dynamic_cast(mat->getMaterial()); - if ( pMat ) - mHasTranslucentMaterials |= pMat->mTranslucent && !pMat->mTranslucentZWrite; - } - } - } -} - -void Interior::_enableLightMapFeature( ProcessedMaterial *mat, - U32 stageNum, - MaterialFeatureData &fd, - const FeatureSet &features ) -{ - if ( mat->getMaterial() ) - { - fd.features.addFeature( MFT_LightMap ); - fd.features.removeFeature( MFT_ToneMap ); - } -} - -//-------------------------------------------------------------------------- -// Create the reflect plane list and the nodes of geometry necessary to -// render the reflective surfaces. -//-------------------------------------------------------------------------- -void Interior::createReflectPlanes() -{ - Vector verts; - Vector primInfoList; - Vector indices; - - U32 startIndex = 0; - U32 startVert = 0; - - - - for( U32 i=0; igetMaterialInst( surface.textureIndex ); - Material* pMat = dynamic_cast(matInst->getMaterial()); - if( !pMat || !pMat->mPlanarReflection ) continue; - - U32 *surfIndices = &mWindings[surface.windingStart]; - - // create / fill in GFXPrimitve, verts, indices - // going to need a new render node - ReflectRenderNode node; - node.exterior = surface.surfaceFlags & SurfaceOutsideVisible; - node.matInst = mMaterialList->getMaterialInst( surface.textureIndex ); - node.lightMapIndex = mNormalLMapIndices[surfaceIndex]; - - - PlaneF plane; - plane = getPlane( surface.planeIndex ); - if( planeIsFlipped( surface.planeIndex ) ) - { - plane.x = -plane.x; - plane.y = -plane.y; - plane.z = -plane.z; - plane.d = -plane.d; - } - - // check if coplanar with existing reflect plane - //-------------------------------------------------- - S32 rPlaneIdx = -1; - for( U32 a=0; a 0.999 ) - { - if( fabs( plane.d - mReflectPlanes[a].d ) < 0.001 ) - { - rPlaneIdx = a; - break; - } - } - } - - PlaneF refPlane; - refPlane = plane; - - if( rPlaneIdx < 0 ) - { - mReflectPlanes.push_back( refPlane ); - node.reflectPlaneIndex = mReflectPlanes.size() - 1; - } - else - { - node.reflectPlaneIndex = rPlaneIdx; - } - - // store the indices for the surface - //-------------------------------------------------- - Vector tempIndices; - tempIndices.setSize( 0 ); - - U32 tempStartIndex = tempIndices.size(); - - U32 last = 2; - while(last < surface.windingCount) - { - // First - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-2], getPointNormal(surfaceIndex, last-2)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-1], getPointNormal(surfaceIndex, last-1)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-0], getPointNormal(surfaceIndex, last)) ); - last++; - - if(last == surface.windingCount) - break; - - // Second - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-1], getPointNormal(surfaceIndex, last-1)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-2], getPointNormal(surfaceIndex, last-2)) ); - tempIndices.push_back( VertexBufferTempIndex(surfIndices[last-0], getPointNormal(surfaceIndex, last)) ); - last++; - } - - storeSurfVerts( indices, tempIndices, verts, tempIndices.size() - tempStartIndex, - surface, surfaceIndex ); - - - // store render node and GFXPrimitive - // each node is a different reflective surface - // --------------------------------------------------- - - // find min index - GFXPrimitive pnfo; - pnfo.minIndex = U32(-1); - for( U32 k=startIndex; kgetMaterialNameList().size(); - - if(mapToNameIndex < 0 || mapToNameIndex >= targetCount) - return String::EmptyString; - - return mMaterialList->getMaterialNameList()[mapToNameIndex]; -} - -S32 Interior::getTargetCount() const -{ - if(!this) - return -1; - - return mMaterialList->getMaterialNameList().size(); - -} diff --git a/Engine/source/interior/interior.h b/Engine/source/interior/interior.h deleted file mode 100644 index b3d36ab41..000000000 --- a/Engine/source/interior/interior.h +++ /dev/null @@ -1,1172 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _INTERIOR_H_ -#define _INTERIOR_H_ - -#ifndef _COLOR_H_ -#include "core/color.h" -#endif -#ifndef _COLLISION_H_ -#include "collision/collision.h" -#endif -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif -#ifndef _MPOINT3_H_ -#include "math/mPoint3.h" -#endif -#ifndef _MPLANE_H_ -#include "math/mPlane.h" -#endif -#ifndef _MBOX_H_ -#include "math/mBox.h" -#endif -#ifndef _MSPHERE_H_ -#include "math/mSphere.h" -#endif -#ifndef _CONVEX_H_ -#include "collision/convex.h" -#endif -#ifndef _INTERIORLMMANAGER_H_ -#include "interior/interiorLMManager.h" -#endif -#ifndef _INTERIORSIMPLEMESH_H_ -#include "interior/interiorSimpleMesh.h" -#endif -#ifndef _OPTIMIZEDPOLYLIST_H_ -#include "collision/optimizedPolyList.h" -#endif -#ifndef _SCENEDATA_H_ -#include "materials/sceneData.h" -#endif - -//-------------------------------------- Forward declarations -class MatInstance; -class Stream; -class EditGeometry; -class InteriorInstance; -class GBitmap; -class RectD; -class SphereF; -class MatrixF; -class SceneRenderState; -class MaterialList; -class AbstractPolyList; -class InteriorSubObject; -class TranslucentSubObject; -class BitVector; -struct RayInfo; -struct EdgeList; -class SurfaceHash; -class InteriorPolytope; -class LightInfo; -class PlaneRange; -class EditInteriorResource; -class GFXVertexBuffer; -class GFXPrimitiveBuffer; -struct RenderInst; -struct GFXVertexPNTTB; -struct GFXPrimitiveInfo; -struct MaterialFeatureData; - - -//-------------------------------------------------------------------------- -class InteriorConvex : public Convex -{ - typedef Convex Parent; - friend class Interior; - friend class InteriorInstance; - - protected: - Interior* pInterior; - public: - S32 hullId; - Box3F box; - - public: - InteriorConvex() { mType = InteriorConvexType; } - InteriorConvex(const InteriorConvex& cv) - { - mObject = cv.mObject; - pInterior = cv.pInterior; - hullId = cv.hullId; - box = box; - } - - Box3F getBoundingBox() const; - Box3F getBoundingBox(const MatrixF& mat, const Point3F& scale) const; - Point3F support(const VectorF& v) const; - void getFeatures(const MatrixF& mat,const VectorF& n, ConvexFeature* cf); - void getPolyList(AbstractPolyList* list); -}; - -class ZoneVisDeterminer -{ - enum Mode - { - FromState, - FromRects - }; - - Mode mMode; - - SceneRenderState* mState; - U32 mZoneRangeOffset; - U32 mParentZone; - - public: - ZoneVisDeterminer() : mMode(FromRects), mState(NULL) { } - - void runFromState(SceneRenderState*, U32, U32); - void runFromRects(SceneRenderState*, U32, U32); - - bool isZoneVisible(const U32) const; -}; - - -struct ItrPaddedPoint -{ - Point3F point; - union - { - F32 fogCoord; - U8 fogColor[4]; - }; -}; - - -//------------------------------------------------------------------------------ -//-------------------------------------- CLASS NOTES -// Interior: Base for all interior geometries. Contains all lighting, poly, -// portal zone, bsp info, etc. to render an interior. -// -// Internal Structure Notes: -// IBSPNode: -// planeIndex: Obv. -// frontIndex/backIndex: Top bit indicates if children are leaves. -// Next bit indicates if leaf children are solid. -// -// IBSPLeafSolid: -// planeIndex: obv. -// surfaceIndex/surfaceCount: Polys that are on the faces of this leaf. Only -// used for collision/surface info detection. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -class Interior -{ - friend class EditGeometry; - friend class InteriorInstance; - friend class InteriorProxy; - friend class blInteriorProxy; - friend class TranslucentSubObject; - friend class MirrorSubObject; - friend class InteriorConvex; - friend class EditInteriorResource; - friend class InteriorLMManager; - friend class TSShape; - friend class SceneLighting; - - //-------------------------------------- Public interfaces - public: - Interior(); - ~Interior(); - - -private: - U32 mLightMapBorderSize; - -public: - Vector surfaceZones; - U32 getLightMapBorderSize() const {return mLightMapBorderSize;} - void setLightMapBorderSize(U32 value) {mLightMapBorderSize = value;} - void buildSurfaceZones(); - //void sgSetupLighting(InteriorInstance *intInst, SceneData &sgData); - //bool sgRenderLights(InteriorInstance *intInst, SceneData &sgData); - - // Interior Render StateBlock - GFXStateBlockRef mInteriorSB; - - MaterialList* mMaterialList; - - // Misc - U32 getDetailLevel() const; - U32 getMinPixels() const; - const Box3F& getBoundingBox() const; - S32 getNumZones() const; - - // Rendering - bool prepForRendering(const char* path); - - bool traverseZones( SceneCullingState* state, - const Frustum& frustum, - S32 containingZone, - S32 baseZone, - U32 zoneOffset, - const MatrixF& OSToWS, - const Point3F& objScale, - const bool dontRestrictOutside, - const bool flipClipPlanes, - Frustum& outFrustum ); - - void prepBatchRender( InteriorInstance *intInst, SceneRenderState *state ); - - void setupRenderStates(); - - - bool scopeZones(const S32 baseZone, - const Point3F& interiorRoot, - bool* interiorScopingState); - - ZoneVisDeterminer setupZoneVis( InteriorInstance *intInst, SceneRenderState *state ); - - SceneData setupSceneGraphInfo( InteriorInstance *intInst, - SceneRenderState *state ); - - void setupRender( InteriorInstance *intInst, - SceneRenderState *state, - MeshRenderInst *coreRi, - const MatrixF* worldToCamera); - - - //-------------------------------------- Collision Interface and zone scans - public: - bool scanZones(const Box3F&, const MatrixF&, U16* zones, U32* numZones); - bool castRay(const Point3F&, const Point3F&, RayInfo*); - bool buildPolyList(AbstractPolyList*, const Box3F&, const MatrixF&, const Point3F&); - - bool getIntersectingHulls(const Box3F&, U16* hulls, U32* numHulls); - bool getIntersectingVehicleHulls(const Box3F&, U16* hulls, U32* numHulls); - -protected: - bool castRay_r(const U32, const U16, const Point3F&, const Point3F&, RayInfo*); - void buildPolyList_r(InteriorPolytope& polytope, - SurfaceHash& hash); - void scanZone_r(const U32 node, - const Point3F& center, - const Point3F& axisx, - const Point3F& axisy, - const Point3F& axisz, - U16* zones, - U32* numZones); - void scanZoneNew(InteriorPolytope& polytope, - U16* zones, - U32* numZones); - - - /// @name Lightmap Support - /// @{ - static void _enableLightMapFeature( ProcessedMaterial *mat, - U32 stageNum, - MaterialFeatureData &fd, - const FeatureSet &features ); - /// @} - - //-------------------------------------- Global rendering control -public: - enum RenderModes - { - NormalRender = 0, - NormalRenderLines = 1, - ShowDetail = 2, - ShowAmbiguous = 3, - ShowOrphan = 4, - ShowLightmaps = 5, - ShowTexturesOnly = 6, - ShowPortalZones = 7, - ShowOutsideVisible = 8, - ShowCollisionFans = 9, - ShowStrips = 10, - ShowNullSurfaces = 11, - ShowLargeTextures = 12, - ShowHullSurfaces = 13, - ShowVehicleHullSurfaces = 14, - ShowVertexColors = 15, - ShowDetailLevel = 16 - }; - - enum Constants - { - NumCoordBins = 16, - - BinsXY = 0, - BinsXZ = 1, - BinsYZ = 2 - }; - - static U32 smRenderMode; - static bool smFocusedDebug; - static bool smUseVertexLighting; - static U32 smFileVersion; - static bool smLightingCastRays; - static bool smLightingBuildPolyList; - - //-------------------------------------- Persistence interface - public: - bool read(Stream& stream); - bool write(Stream& stream) const; - - bool readVehicleCollision(Stream& stream); - bool writeVehicleCollision(Stream& stream) const; - - private: - bool writePlaneVector(Stream&) const; - bool readPlaneVector(Stream&); - bool readLMapTexGen(Stream&, PlaneF&, PlaneF&); - bool writeLMapTexGen(Stream&, const PlaneF&, const PlaneF&) const; - void setupTexCoords(); - void setupZonePlanes(); - - //-------------------------------------- For morian only... - public: - void processHullPolyLists(); - void processVehicleHullPolyLists(); - - //-------------------------------------- BSP Structures - private: - struct IBSPNode - { - U16 planeIndex; - U32 frontIndex; - U32 backIndex; - - U16 terminalZone; // if high bit set, then the lower 15 bits are the zone - // of any of the subsidiary nodes. Note that this is - // going to overestimate some, since an object could be - // completely contained in solid, but it's probably - // going to turn out alright. - }; - struct IBSPLeafSolid - { - U32 surfaceIndex; - U16 surfaceCount; - }; - - bool isBSPLeafIndex(U32 index) const; - bool isBSPSolidLeaf(U32 index) const; - bool isBSPEmptyLeaf(U32 index) const; - U16 getBSPSolidLeafIndex(U32 index) const; - U16 getBSPEmptyLeafZone(U32 index) const; - - void setupAveTexGenLength(); - - void truncateZoneTree(); - void truncateZoneNode(const U32); - bool getUnifiedZone(const U32, S32*); - - public: - static U16 getPlaneIndex(U16 index); - static bool planeIsFlipped(U16 index); - const PlaneF& getPlane(U16 index) const; - PlaneF getFlippedPlane(const U16 index) const; - - const Point3F getPointNormal(const U32 surfaceIndex, const U32 pointOffset) const; - - private: - bool areEqualPlanes(U16, U16) const; - - bool isNullSurfaceIndex(const U32 index) const; - bool isVehicleNullSurfaceIndex(const U32 index) const; - U32 getNullSurfaceIndex(const U32 index) const; - U32 getVehicleNullSurfaceIndex(const U32 index) const; - - //-------------------------------------- Portals and Zone structures - private: - struct Zone - { - U16 portalStart; - U16 portalCount; - - U32 surfaceStart; - U32 planeStart; - - U16 surfaceCount; - U16 planeCount; - - U32 staticMeshStart; - U32 staticMeshCount; - - U16 flags; - U16 zoneId; // This is ephemeral, not persisted out. - }; - - struct Portal - { - U16 planeIndex; - - U16 triFanCount; - U32 triFanStart; // portals can have multiple windings - - U16 zoneFront; - U16 zoneBack; - }; - - //-------------------------------------- Poly/Surface structures -public: - enum SurfaceFlags - { - SurfaceDetail = BIT(0), - SurfaceAmbiguous = BIT(1), - SurfaceOrphan = BIT(2), - SurfaceSharedLMaps = BIT(3), // Indicates that the alarm and normal states share a lightmap (for mission lighter) - SurfaceOutsideVisible = BIT(4), - SurfaceStaticMesh = BIT(5), // This surface belongs to a static mesh collision hull - SurfaceFlagMask = (SurfaceDetail | - SurfaceAmbiguous | - SurfaceOrphan | - SurfaceSharedLMaps | - SurfaceOutsideVisible | - SurfaceStaticMesh) - }; - enum ZoneFlags - { - ZoneInside = BIT(0) - }; - - const bool isSurfaceOutsideVisible(U32 surface) const; - - public: - struct TexMatrix - { - S32 T; - S32 N; - S32 B; - - TexMatrix() - : T( -1 ), - N( -1 ), - B( -1 ) - {}; - }; - - struct Edge - { - S32 vertexes[2]; - S32 faces[2]; - }; - - struct TexGenPlanes - { - PlaneF planeX; - PlaneF planeY; - }; - - struct TriFan - { - U32 windingStart; - U32 windingCount; - }; - - struct Surface - { - U32 windingStart; // 1 - - U16 planeIndex; // 2 - U16 textureIndex; - - U32 texGenIndex; // 3 - - U16 lightCount; // 4 - U8 surfaceFlags; - U32 windingCount; - - U32 fanMask; // 5 - - U32 lightStateInfoStart; // 6 - - U32 mapOffsetX; // 7 - U32 mapOffsetY; - U32 mapSizeX; - U32 mapSizeY; - - Point3F T,B,N; - Point3F normal; - - //U32 VBIndexStart; - //U32 primIndex; - GFXPrimitive surfaceInfo; - - bool unused; - }; - - struct NullSurface - { - U32 windingStart; - - U16 planeIndex; - U8 surfaceFlags; - U32 windingCount; - }; - - //-------------------------------------- Animated lighting structures - enum LightFlags - { - AnimationAmbient = BIT(0), - AnimationLoop = BIT(1), - AnimationFlicker = BIT(2), - AnimationTypeMask = BIT(3) - 1, - - AlarmLight = BIT(3) - }; - - enum LightType - { - AmbientLooping = AnimationAmbient | AnimationLoop, - AmbientFlicker = AnimationAmbient | AnimationFlicker, - - TriggerableLoop = AnimationLoop, - TriggerableFlicker = AnimationFlicker, - TriggerableRamp = 0 - }; - -private: - bool readSurface(Stream&, Surface&, TexGenPlanes&, const bool); - - public: - // this is public because tools/Morian needs this defination - struct AnimatedLight { - U32 nameIndex; // Light's name - U32 stateIndex; // start point in the state list - - U16 stateCount; // number of states in this light - U16 flags; // flags (Apply AnimationTypeMask to get type) - - U32 duration; // total duration of animation (ms) - }; - private: - struct LightState { - U8 red; // state's color - U8 green; - U8 blue; - U8 _color_padding_; - - U32 activeTime; // Time (ms) at which this state becomes active - - U32 dataIndex; // StateData count and index for this state - U16 dataCount; - - U16 __32bit_padding__; - }; - struct LightStateData { - U32 surfaceIndex; // Surface affected by this data - U32 mapIndex; // Index into StateDataBuffer (0xFFFFFFFF indicates none) - U16 lightStateIndex; // Entry to modify in InteriorInstance - U16 __32bit_padding__; - }; - - // convex hull collision structures... - protected: - struct ConvexHull - { - F32 minX; - F32 maxX; - F32 minY; - F32 maxY; - - F32 minZ; - F32 maxZ; - U32 hullStart; - U32 surfaceStart; - - U32 planeStart; - U16 hullCount; - U16 surfaceCount; - U32 polyListPlaneStart; - - U32 polyListPointStart; - U32 polyListStringStart; - U16 searchTag; - bool staticMesh; - }; - - struct CoordBin - { - U32 binStart; - U32 binCount; - }; - - struct RenderNode - { - bool exterior; - U16 baseTexIndex; - U8 lightMapIndex; - S32 primInfoIndex; - BaseMatInstance *matInst; - - RenderNode() - { - exterior = true; - baseTexIndex = 0; - lightMapIndex = U8(-1); - primInfoIndex = -1; - matInst = NULL; - } - }; - - - // public because InteriorInstance needs access - public: - Vector< PlaneF > mReflectPlanes; - - protected: - struct ReflectRenderNode - { - bool exterior; - S32 reflectPlaneIndex; - S32 primInfoIndex; - U8 lightMapIndex; - - BaseMatInstance *matInst; - - - ReflectRenderNode() - { - exterior = true; - reflectPlaneIndex = -1; - lightMapIndex = U8(-1); - primInfoIndex = -1; - matInst = NULL; - } - }; - - - struct ZoneRNList - { - Vector renderNodeList; - }; - - struct ZoneReflectRNList - { - Vector reflectList; - }; - - // needs to be exposed in order for on the fly changes - public: - Vector mZoneRNList; - - private: - - // reflective plane data - GFXVertexBufferHandle mReflectVertBuff; - GFXPrimitiveBufferHandle mReflectPrimBuff; - Vector mZoneReflectRNList; - - // standard interior data - GFXVertexBufferHandle mVertBuff; - GFXPrimitiveBufferHandle mPrimBuff; - - private: - LM_HANDLE mLMHandle; - public: - LM_HANDLE getLMHandle() {return(mLMHandle);} - - public: - - // SceneLighting::InteriorProxy interface - const Surface & getSurface(const U32 surface) const; - const U32 getSurfaceCount() const; - const U32 getNormalLMapIndex(const U32 surface) const; - const U32 getAlarmLMapIndex(const U32 surface) const; - const U32 getStaticMeshCount() const; - const InteriorSimpleMesh *getStaticMesh(const U32 index) const; - const U32 getWinding(const U32 index) const; - const Point3F & getPoint(const U32 index) const; - const TexGenPlanes & getLMTexGenEQ(const U32 index) const; - const TexGenPlanes & getTexGenEQ(const U32 index) const; - bool hasAlarmState() const; - const U32 getWindingCount() const; - S32 getTargetCount() const; - const String& getTargetName( S32 mapToNameIndex ) const; - - //-------------------------------------- Instance Data Members - private: - U32 mFileVersion; - U32 mDetailLevel; - U32 mMinPixels; - F32 mAveTexGenLength; // Set in Interior::read after loading the texgen planes. - Box3F mBoundingBox; - SphereF mBoundingSphere; - - Vector mPlanes; - Vector mPoints; - Vector mPointVisibility; - - Vector mNormals; - Vector mTexMatrices; - Vector mTexMatIndices; - - ColorF mBaseAmbient; - ColorF mAlarmAmbient; - - Vector mBSPNodes; - Vector mBSPSolidLeaves; - - bool mPreppedForRender; - - bool mHasTranslucentMaterials; - - Vector mWindings; - - Vector mTexGenEQs; - Vector mLMTexGenEQs; - - Vector mWindingIndices; - Vector mSurfaces; - Vector mNullSurfaces; - Vector mSolidLeafSurfaces; - - Vector mEdges; - - // Portals and zones - Vector mZones; - Vector mZonePlanes; - Vector mZoneSurfaces; - Vector mZonePortalList; - Vector mPortals; - Vector mZoneStaticMeshes; - - // Subobjects: Doors, translucencies, mirrors, etc. - Vector mSubObjects; - - // Lighting info - bool mHasAlarmState; - U32 mNumLightStateEntries; - - Vector mLightmaps; - Vector mLightmapKeep; - Vector mNormalLMapIndices; - Vector mAlarmLMapIndices; - - U32 mNumTriggerableLights; // Note: not persisted - - // Persistent animated light structures - Vector mAnimatedLights; - Vector mLightStates; - Vector mStateData; - Vector mStateDataBuffer; - - Vector mNameBuffer; - - Vector mConvexHulls; - Vector mConvexHullEmitStrings; - Vector mHullIndices; - Vector mHullEmitStringIndices; - Vector mHullSurfaceIndices; - Vector mHullPlaneIndices; - Vector mPolyListPlanes; - Vector mPolyListPoints; - Vector mPolyListStrings; - CoordBin mCoordBins[NumCoordBins * NumCoordBins]; - Vector mCoordBinIndices; - U32 mCoordBinMode; - - Vector mVehicleConvexHulls; - Vector mVehicleConvexHullEmitStrings; - Vector mVehicleHullIndices; - Vector mVehicleHullEmitStringIndices; - Vector mVehicleHullSurfaceIndices; - Vector mVehicleHullPlaneIndices; - Vector mVehiclePolyListPlanes; - Vector mVehiclePolyListPoints; - Vector mVehiclePolyListStrings; - Vector mVehiclePoints; - Vector mVehicleNullSurfaces; - Vector mVehiclePlanes; - Vector mVehicleWindings; - Vector mVehicleWindingIndices; - - VectorPtr mStaticMeshes; - - U16 mSearchTag; - Vector mMatInstCleanupList; - - //-------------------------------------- Private interface - private: - -#ifndef TORQUE_SHIPPING - GFXShaderRef mDebugShader; - GFXTexHandle mDebugTexture; - - GFXStateBlockRef mInteriorDebugNoneSB; - GFXStateBlockRef mInteriorDebugPortalSB; - GFXStateBlockRef mInteriorDebugTextureSB; - GFXStateBlockRef mInteriorDebugTwoTextureSB; - - // Debug Render ConstantBuffers - GFXShaderConstBufferRef mDebugShaderConsts; - - GFXShaderConstHandle* mDebugShaderModelViewSC; - GFXShaderConstHandle* mDebugShaderShadeColorSC; -#endif - - const char* getName(const U32 nameIndex) const; - static const char* getLightTypeString(const LightType); - S32 getZoneForPoint(const Point3F&) const; - -#ifndef TORQUE_SHIPPING - void debugRender(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst, MatrixF& modelview); - // render debug utility functions - void preDebugRender(); - void debugDefaultRender(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst); - // show all surfaces with flag set as color c - void debugShowSurfaceFlag(const ZoneVisDeterminer& zoneVis, const U32 flag, const ColorF& c); - // render brushes - void debugNormalRenderLines(const ZoneVisDeterminer& zoneVis); - // next 4 use debugShowSurfaceFlag to show surface info - void debugShowDetail(const ZoneVisDeterminer& zoneVis); - void debugShowAmbiguous(const ZoneVisDeterminer& zoneVis); - void debugShowOrphan(const ZoneVisDeterminer& zoneVis); - void debugShowOutsideVisible(const ZoneVisDeterminer& zoneVis); - void debugShowPortalZones(const ZoneVisDeterminer& zoneVis); - void debugRenderPortals(); - void debugShowCollisionFans(const ZoneVisDeterminer& zoneVis); - void debugShowStrips(const ZoneVisDeterminer& zoneVis); - void debugShowDetailLevel(const ZoneVisDeterminer& zoneVis); - void debugShowHullSurfaces(); - void debugShowNullSurfaces(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst); - void debugShowVehicleHullSurfaces(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst); - void debugShowTexturesOnly(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst); - void debugShowLightmaps(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst); - void debugShowLargeTextures(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst); -// void debugShowVertexColors(MaterialList* pMaterials); -#endif - - public: - void collisionFanFromSurface(const Surface&, U32* fan, U32* numIndices) const; - void fillSurfaceTexMats(); - void createZoneVBs(); - void cloneMatInstances(); - void initMatInstances(); - void createReflectPlanes(); - - private: - void fullWindingFromSurface(const Surface&, U32* fan, U32* numIndices) const; - bool projectClipAndBoundFan(U32 fanIndex, F64* pResult); - void zoneTraversal(S32 baseZone, const bool flipClipPlanes); - void createZoneRectVectors(); - void destroyZoneRectVectors(); - void traverseZone(const RectD* inRects, const U32 numInputRects, U32 currZone, Vector& zoneStack); - - void fillVertex( GFXVertexPNTTB &vert, Surface &surface, U32 surfaceIndex ); - void getTexMat(U32 surfaceIndex, U32 pointOffset, Point3F& T, Point3F& N, Point3F& B); - - - void storeRenderNode( RenderNode &node, - ZoneRNList &RNList, - Vector &primInfoList, - Vector &indexList, - Vector &verts, - U32 &startIndex, - U32 &startVert ); - - void renderZoneNode( SceneRenderState *state, - RenderNode &node, - InteriorInstance *intInst, - SceneData &sgData, - MeshRenderInst *coreRi ); - - void renderReflectNode( SceneRenderState *state, - ReflectRenderNode &node, - InteriorInstance *intInst, - SceneData &sgData, - MeshRenderInst *coreRi ); - - void renderLights(SceneRenderState* state, InteriorInstance *intInst, SceneData &sgData, MeshRenderInst *coreRi, const ZoneVisDeterminer &zonevis); - - - /// Used to maintain point and normal relationship (which use - /// dissimilar index lookups) for verts when building vertex buffer. - struct VertexBufferTempIndex - { - U16 index; - Point3F normal; - - VertexBufferTempIndex() - { - index = 0; - normal.set(0.0f, 0.0f, 0.0f); - } - VertexBufferTempIndex(const U16 ind, const Point3F &norm) - { - index = ind; - normal = norm; - } - }; - - void storeSurfVerts( Vector &masterIndexList, - Vector &tempIndexList, - Vector &verts, - U32 numIndices, - Surface &surface, - U32 surfaceIndex ); - - public: - void purgeLODData(); - - void buildExportPolyList(OptimizedPolyList& polys, MatrixF* mat = NULL, Point3F* scale = NULL); -}; - -//------------------------------------------------------------------------------ -inline bool Interior::isBSPLeafIndex(U32 index) const -{ - if (mFileVersion >= 14) - return (index & 0x80000) != 0; - else - return (index & 0x8000) != 0; -} - -inline bool Interior::isBSPSolidLeaf(U32 index) const -{ - AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!"); - - if (mFileVersion >= 14) - return (index & 0x40000) != 0; - else - return (index & 0x4000) != 0; -} - -inline bool Interior::isBSPEmptyLeaf(U32 index) const -{ - AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!"); - - if (mFileVersion >= 14) - return (index & 0x40000) == 0; - else - return (index & 0x4000) == 0; -} - -inline U16 Interior::getBSPSolidLeafIndex(U32 index) const -{ - AssertFatal(isBSPSolidLeaf(index) == true, "Error, only call for leaves!"); - - if (mFileVersion >= 14) - return U16(index & ~0xC0000); - else - return U16(index & ~0xC000); -} - -inline U16 Interior::getBSPEmptyLeafZone(U32 index) const -{ - AssertFatal(isBSPEmptyLeaf(index) == true, "Error, only call for leaves!"); - - if (mFileVersion >= 14) - return U16(index & ~0xC0000); - else - return U16(index & ~0xC000); -} - -inline const PlaneF& Interior::getPlane(U16 index) const -{ - AssertFatal(U32(index & ~0x8000) < mPlanes.size(), - "Interior::getPlane: planeIndex out of range"); - - return mPlanes[index & ~0x8000]; -} - -inline PlaneF Interior::getFlippedPlane(const U16 index) const -{ - PlaneF plane = getPlane(index); - if(Interior::planeIsFlipped(index)) - plane.neg(); - - return plane; -} - -inline U16 Interior::getPlaneIndex(U16 index) -{ - return U16(index & ~0x8000); -} - -inline bool Interior::planeIsFlipped(U16 index) -{ - return (index >> 15)!=0; -} - -inline bool Interior::areEqualPlanes(U16 o, U16 t) const -{ - return (o & ~0x8000) == (t & ~0x8000); -} - -inline const Point3F Interior::getPointNormal(const U32 surfaceIndex, const U32 pointOffset) const -{ - Surface rSurface = mSurfaces[surfaceIndex]; - - Point3F normal(0.0f, 0.0f, 0.0f); - - if (mFileVersion >= 11) - { - U32 texMatIndex = mTexMatIndices[rSurface.windingStart + pointOffset]; - TexMatrix texMat = mTexMatrices[texMatIndex]; - - if (texMat.N > -1) - normal = mNormals[texMat.N]; - } - else - normal = getFlippedPlane(rSurface.planeIndex); - - return normal; -} - -inline U32 Interior::getDetailLevel() const -{ - return mDetailLevel; -} - -inline U32 Interior::getMinPixels() const -{ - return mMinPixels; -} - -inline const Box3F& Interior::getBoundingBox() const -{ - return mBoundingBox; -} - -inline S32 Interior::getNumZones() const -{ - return mZones.size(); -} - -inline bool Interior::isNullSurfaceIndex(const U32 index) const -{ - return (index & 0x80000000) != 0; -} - -inline bool Interior::isVehicleNullSurfaceIndex(const U32 index) const -{ - return (index & 0x40000000) != 0; -} - -inline U32 Interior::getNullSurfaceIndex(const U32 index) const -{ - AssertFatal(isNullSurfaceIndex(index), "Not a proper index!"); - AssertFatal(!isVehicleNullSurfaceIndex(index), "Not a proper index"); - return (index & ~0x80000000); -} - -inline U32 Interior::getVehicleNullSurfaceIndex(const U32 index) const -{ - AssertFatal(isVehicleNullSurfaceIndex(index), "Not a proper index!"); - return (index & ~(0x80000000 | 0x40000000)); -} - -inline const char* Interior::getLightTypeString(const LightType type) -{ - switch (type) { - case AmbientLooping: - return "AmbientLooping"; - case AmbientFlicker: - return "AmbientFlicker"; - case TriggerableLoop: - return "TriggerableLoop"; - case TriggerableFlicker: - return "TriggerableFlicker"; - case TriggerableRamp: - return "TriggerableRamp"; - - default: - return ""; - } -} - -inline const char* Interior::getName(const U32 nameIndex) const -{ - return &mNameBuffer[nameIndex]; -} - -inline const U32 Interior::getSurfaceCount() const -{ - return(mSurfaces.size()); -} - -inline const Interior::Surface & Interior::getSurface(const U32 surface) const -{ - AssertFatal(surface < mSurfaces.size(), "invalid index"); - return(mSurfaces[surface]); -} - -inline const U32 Interior::getStaticMeshCount() const -{ - return mStaticMeshes.size(); -} - -inline const InteriorSimpleMesh *Interior::getStaticMesh(const U32 index) const -{ - AssertFatal(index < mStaticMeshes.size(), "invalid index"); - return mStaticMeshes[index]; -} - -inline const U32 Interior::getNormalLMapIndex(const U32 surface) const -{ - AssertFatal(surface < mNormalLMapIndices.size(), "invalid index"); - return(mNormalLMapIndices[surface]); -} - -inline const U32 Interior::getAlarmLMapIndex(const U32 surface) const -{ - AssertFatal(surface < mAlarmLMapIndices.size(), "invalid index"); - return(mAlarmLMapIndices[surface]); -} - -inline const U32 Interior::getWinding(const U32 index) const -{ - AssertFatal(index < mWindings.size(), "invalid index"); - return(mWindings[index]); -} - -inline const Point3F & Interior::getPoint(const U32 index) const -{ - AssertFatal(index < mPoints.size(), "invalid index"); - return(mPoints[index].point); -} - -inline const Interior::TexGenPlanes & Interior::getLMTexGenEQ(const U32 index) const -{ - AssertFatal(index < mLMTexGenEQs.size(), "invalid index"); - return(mLMTexGenEQs[index]); -} - -inline const Interior::TexGenPlanes & Interior::getTexGenEQ(const U32 index) const -{ - AssertFatal(index < mTexGenEQs.size(), "invalid index"); - return(mTexGenEQs[index]); -} - -inline bool Interior::hasAlarmState() const -{ - return(mHasAlarmState); -} - -inline const bool Interior::isSurfaceOutsideVisible(U32 surface) const -{ - AssertFatal(surface < mSurfaces.size(), "Interior::isSurfaceOutsideVisible: Invalid surface index"); - return ((mSurfaces[surface].surfaceFlags & SurfaceOutsideVisible)!=0); -} - -inline const U32 Interior::getWindingCount() const -{ - return(mWindings.size()); -} - -#endif //_INTERIOR_H_ diff --git a/Engine/source/interior/interiorCollision.cpp b/Engine/source/interior/interiorCollision.cpp deleted file mode 100644 index 1e9260c8c..000000000 --- a/Engine/source/interior/interiorCollision.cpp +++ /dev/null @@ -1,1775 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "interior/interior.h" -#include "math/mSphere.h" -#include "scene/sceneObject.h" -#include "collision/abstractPolyList.h" - -#include "core/frameAllocator.h" -#include "platform/profiler.h" - -namespace { - -//-------------------------------------- -// Custom on plane version to reduce numerical inaccuracies in the GJK stuff. -// copied from terrCollision.cc -inline bool isOnPlane(const Point3F& p, const PlaneF& plane) -{ - F32 dist = mDot(plane,p) + plane.d; - return mFabs(dist) < 0.1f; -} - -} // namespace {} - - -//-------------------------------------------------------------------------- -//-------------------------------------- SurfaceHash -const U32 csgHashSize = 4096; -class SurfaceHash -{ - private: - U32 hash(U32 i) { return i & (csgHashSize - 1); } - - public: - U32 mSurfaceArray[csgHashSize]; - U32 mNumSurfaces; - - U32 mHashTable[csgHashSize]; - - public: - SurfaceHash() - { - AssertFatal(isPow2(csgHashSize), "Error, size must be power of 2"); - } - - void clear() - { - dMemset(mHashTable, 0xFF, sizeof(mHashTable)); - mNumSurfaces = 0; - } - - void insert(U32 surface); -}; - -inline void SurfaceHash::insert(U32 surface) -{ - AssertFatal(surface != 0xFFFFFFFF, "Hm, bad assumption. 0xFFFFFFFF is a valid surface index?"); - if (mNumSurfaces >= csgHashSize) - { - AssertFatal(false, "Error, exceeded surfaceCount restriction!"); - return; - } - - U32 probe = hash(surface); - U32 initialProbe = probe; - while (mHashTable[probe] != 0xFFFFFFFF) - { - // If it's already in the table, bail. - if (mHashTable[probe] == surface) - return; - - probe = (probe + 1) % csgHashSize; - AssertFatal(probe != initialProbe, "Hm, wraparound?"); - } - - // If we're here, then the probe failed, and the index isn't in the hash - // table - mHashTable[probe] = surface; - mSurfaceArray[mNumSurfaces++] = surface; -} - - -class InteriorPolytope -{ - // Convex Polyhedron - public: - struct Vertex - { - Point3F point; - // Temp BSP clip info - S32 side; - }; - struct Edge - { - S32 vertex[2]; - S32 face[2]; - S32 next; - }; - struct Face - { - S32 original; - // Temp BSP clip info - S32 vertex; - }; - struct Volume - { - S32 edgeList; - }; - struct StackElement - { - S32 edgeList; - U32 popCount; - U32 nodeIndex; - }; - - typedef Vector EdgeList; - typedef Vector FaceList; - typedef Vector VertexList; - typedef Vector VolumeList; - typedef Vector VolumeStack; - - // - S32 sideCount; - EdgeList mEdgeList; - FaceList mFaceList; - VertexList mVertexList; - VolumeList mVolumeList; - - public: - // - InteriorPolytope(); - void clear(); - bool intersect(const PlaneF& plane,const Point3F& sp,const Point3F& ep); - void buildBox(const Box3F& box, const MatrixF& transform, const Point3F& scale); - inline bool didIntersect() { return mVolumeList.size() > 1; } -}; - -//---------------------------------------------------------------------------- -// Box should be axis aligned in the transform space provided. - -InteriorPolytope::InteriorPolytope() -{ - mVertexList.reserve(256); - mFaceList.reserve(200); - mEdgeList.reserve(100); - mVolumeList.reserve(20); - sideCount = 0; -} - -void InteriorPolytope::clear() -{ - mVertexList.clear(); - mFaceList.clear(); - mEdgeList.clear(); - mVolumeList.clear(); - sideCount = 0; -} - -void InteriorPolytope::buildBox(const Box3F& box, const MatrixF& transform, const Point3F&) -{ - // Initial vertices - mVertexList.setSize(8); - mVertexList[0].point = Point3F(box.minExtents.x, box.minExtents.y, box.minExtents.z); - mVertexList[1].point = Point3F(box.minExtents.x, box.maxExtents.y, box.minExtents.z); - mVertexList[2].point = Point3F(box.maxExtents.x, box.maxExtents.y, box.minExtents.z); - mVertexList[3].point = Point3F(box.maxExtents.x, box.minExtents.y, box.minExtents.z); - mVertexList[4].point = Point3F(box.minExtents.x, box.minExtents.y, box.maxExtents.z); - mVertexList[5].point = Point3F(box.minExtents.x, box.maxExtents.y, box.maxExtents.z); - mVertexList[6].point = Point3F(box.maxExtents.x, box.maxExtents.y, box.maxExtents.z); - mVertexList[7].point = Point3F(box.maxExtents.x, box.minExtents.y, box.maxExtents.z); - S32 i; - for (i = 0; i < 8; i++) - { - transform.mulP(mVertexList[i].point); - mVertexList[i].side = 0; - } - - // Initial faces - mFaceList.setSize(6); - for (S32 f = 0; f < 6; f++) - { - Face& face = mFaceList[f]; - face.original = true; - face.vertex = 0; - } - - // Initial edges - mEdgeList.setSize(12); - Edge* edge = mEdgeList.begin(); - S32 nextEdge = 0; - for (i = 0; i < 4; i++) - { - S32 n = (i == 3)? 0: i + 1; - S32 p = (i == 0)? 3: i - 1; - edge->vertex[0] = i; - edge->vertex[1] = n; - edge->face[0] = i; - edge->face[1] = 4; - edge->next = ++nextEdge; - edge++; - edge->vertex[0] = 4 + i; - edge->vertex[1] = 4 + n; - edge->face[0] = i; - edge->face[1] = 5; - edge->next = ++nextEdge; - edge++; - edge->vertex[0] = i; - edge->vertex[1] = 4 + i; - edge->face[0] = i; - edge->face[1] = p; - edge->next = ++nextEdge; - edge++; - } - edge[-1].next = -1; - - // Volume - mVolumeList.setSize(1); - Volume& volume = mVolumeList.last(); - volume.edgeList = 0; - sideCount = 0; -} - -bool InteriorPolytope::intersect(const PlaneF& plane,const Point3F& sp,const Point3F& ep) -{ - // If den == 0 then the line and plane are parallel. - F32 den; - Point3F dt = ep - sp; - if ((den = plane.x * dt.x + plane.y * dt.y + plane.z * dt.z) == 0.0f) - return false; - - // Save the values in sp since the memory may go away after the increment - F32 sp_x = sp.x; - F32 sp_y = sp.y; - F32 sp_z = sp.z; - - mVertexList.increment(); - Vertex& v = mVertexList.last(); - F32 s = -(plane.x * sp_x + plane.y * sp_y + plane.z * sp_z + plane.d) / den; - v.point.x = sp_x + dt.x * s; - v.point.y = sp_y + dt.y * s; - v.point.z = sp_z + dt.z * s; - v.side = 0; - return true; -} - - -//-------------------------------------------------------------------------- -void Interior::collisionFanFromSurface(const Surface& rSurface, U32* fanIndices, U32* numIndices) const -{ - U32 tempIndices[32]; - - tempIndices[0] = 0; - U32 idx = 1; - U32 i; - - for (i = 1; i < rSurface.windingCount; i += 2) - tempIndices[idx++] = i; - - for (i = ((rSurface.windingCount - 1) & (~0x1)); i > 0; i -= 2) - tempIndices[idx++] = i; - - idx = 0; - for (i = 0; i < rSurface.windingCount; i++) - { - if (rSurface.fanMask & (1 << i)) - { - fanIndices[idx++] = mWindings[rSurface.windingStart + tempIndices[i]]; - } - } - *numIndices = idx; -} - -void Interior::fullWindingFromSurface(const Surface& rSurface, U32* fanIndices, U32* numIndices) const -{ - U32 tempIndices[32]; - - tempIndices[0] = 0; - U32 idx = 1; - U32 i; - - for (i = 1; i < rSurface.windingCount; i += 2) - tempIndices[idx++] = i; - - for (i = ((rSurface.windingCount - 1) & (~0x1)); i > 0; i -= 2) - tempIndices[idx++] = i; - - idx = 0; - for (i = 0; i < rSurface.windingCount; i++) - fanIndices[idx++] = mWindings[rSurface.windingStart + tempIndices[i]]; - - *numIndices = idx; -} - - -bool Interior::castRay_r(const U32 node, - const U16 planeIndex, - const Point3F& s, - const Point3F& e, - RayInfo* info) -{ - if (isBSPLeafIndex(node) == false) - { - const IBSPNode& rNode = mBSPNodes[node]; - const PlaneF& rPlane = getPlane(rNode.planeIndex); - - const PlaneF::Side sSide = rPlane.whichSide(s); - const PlaneF::Side eSide = rPlane.whichSide(e); - - switch (PlaneSwitchCode(sSide, eSide)) - { - case PlaneSwitchCode(PlaneF::Front, PlaneF::Front): - case PlaneSwitchCode(PlaneF::Front, PlaneF::On): - case PlaneSwitchCode(PlaneF::On, PlaneF::Front): - return castRay_r(rNode.frontIndex, planeIndex, s, e, info); - break; - - case PlaneSwitchCode(PlaneF::On, PlaneF::Back): - case PlaneSwitchCode(PlaneF::Back, PlaneF::On): - case PlaneSwitchCode(PlaneF::Back, PlaneF::Back): - return castRay_r(rNode.backIndex, planeIndex, s, e, info); - break; - - case PlaneSwitchCode(PlaneF::On, PlaneF::On): - // Line lies on the plane - if (isBSPLeafIndex(rNode.backIndex) == false) - { - if (castRay_r(rNode.backIndex, planeIndex, s, e, info)) - return true; - } - - if (isBSPLeafIndex(rNode.frontIndex) == false) - { - if (castRay_r(rNode.frontIndex, planeIndex, s, e, info)) - return true; - } - - return false; - break; - - case PlaneSwitchCode(PlaneF::Front, PlaneF::Back): - { - Point3F ip; - F32 intersectT = rPlane.intersect(s, e); - AssertFatal(intersectT != PARALLEL_PLANE, "Error, this should never happen in this case!"); - ip.interpolate(s, e, intersectT); - if (castRay_r(rNode.frontIndex, planeIndex, s, ip, info)) - return true; - return castRay_r(rNode.backIndex, rNode.planeIndex, ip, e, info); - } - break; - - case PlaneSwitchCode(PlaneF::Back, PlaneF::Front): - { - Point3F ip; - F32 intersectT = rPlane.intersect(s, e); - AssertFatal(intersectT != PARALLEL_PLANE, "Error, this should never happen in this case!"); - ip.interpolate(s, e, intersectT); - if (castRay_r(rNode.backIndex, planeIndex, s, ip, info)) - return true; - return castRay_r(rNode.frontIndex, rNode.planeIndex, ip, e, info); - } - break; - - default: - AssertFatal(false, "Misunderstood switchCode in Interior::castRay_r"); - return false; - } - } - - if (isBSPSolidLeaf(node)) - { - // DMM: Set material info here.. material info? hahaha - - info->point = s; - - if (planeIndex != U16(-1)) - { - const PlaneF& rPlane = getPlane(planeIndex); - info->normal = rPlane; - if (planeIsFlipped(planeIndex)) - { - info->normal.neg(); - if (rPlane.whichSide(e) == PlaneF::Back) - info->normal.neg(); - } - else - { - if (rPlane.whichSide(e) == PlaneF::Front) - info->normal.neg(); - } - } - else - { - // Point started in solid; - if (s == e) - { - info->normal.set(0.0f, 0.0f, 1.0f); - } - else - { - info->normal = s - e; - info->normal.normalize(); - } - } - - // ok.. let's get it on! get the face that was hit - info->face = U32(-1); - - U32 numStaticSurfaces = 0; - - const IBSPLeafSolid & rLeaf = mBSPSolidLeaves[getBSPSolidLeafIndex(node)]; - for(U32 i = 0; i < rLeaf.surfaceCount; i++) - { - U32 surfaceIndex = mSolidLeafSurfaces[rLeaf.surfaceIndex + i]; - if(isNullSurfaceIndex(surfaceIndex)) - { - const NullSurface & rSurface = mNullSurfaces[getNullSurfaceIndex(surfaceIndex)]; - if (rSurface.surfaceFlags & SurfaceStaticMesh) - numStaticSurfaces++; - - continue; - } - - const Surface & rSurface = mSurfaces[surfaceIndex]; - if(!areEqualPlanes(rSurface.planeIndex, planeIndex)) - continue; - - PlaneF plane = getPlane(rSurface.planeIndex); - if(planeIsFlipped(rSurface.planeIndex)) - plane.neg(); - - // unfan this surface - U32 winding[32]; - U32 windingCount; - collisionFanFromSurface(rSurface, winding, &windingCount); - - // inside this surface? - bool inside = true; - for(U32 j = 0; inside && (j < windingCount); j++) - { - U32 k = (j+1) % windingCount; - - Point3F vec1 = mPoints[winding[k]].point - mPoints[winding[j]].point; - Point3F vec2 = info->point - mPoints[winding[j]].point; - - Point3F cross; - mCross(vec2, vec1, &cross); - - if(mDot(plane, cross) < 0.f) - inside = false; - } - - if(inside) - { - info->face = surfaceIndex; - info->material = mMaterialList->getMaterialInst( rSurface.textureIndex ); - break; - } - } - - if (Interior::smLightingCastRays && numStaticSurfaces == rLeaf.surfaceCount && numStaticSurfaces > 0) - return false; - - return true; - } - return false; -} - -bool Interior::castRay(const Point3F& s, const Point3F& e, RayInfo* info) -{ - // DMM: Going to need normal here eventually. - bool hit = castRay_r(0, U16(-1), s, e, info); - if (hit) - { - Point3F vec = e - s; - F32 len = vec.len(); - if (len < 1e-6f) - { - info->t = 0.0f; - } - else - { - vec /= len; - info->t = mDot(info->point - s, vec) / len; - } - } - - AssertFatal(!hit || (info->normal.z == info->normal.z), "NaN returned from castRay.\n\nPlease talk to DMM if you are running this in the debugger"); - - return hit; -} - -void Interior::buildPolyList_r(InteriorPolytope& polytope, - SurfaceHash& hash) -{ - // Submit the first volume of the poly tope to the bsp tree - static InteriorPolytope::VolumeStack stack; - stack.reserve(256); - stack.setSize(1); - stack.last().edgeList = polytope.mVolumeList[0].edgeList; - stack.last().nodeIndex = 0; - stack.last().popCount = 0; - - static Vector collPlanes; - collPlanes.reserve(64); - collPlanes.clear(); - - while (stack.empty() == false) - { - InteriorPolytope::StackElement volume = stack.last(); - stack.pop_back(); - - if (isBSPLeafIndex(volume.nodeIndex)) - { - if (isBSPSolidLeaf(volume.nodeIndex)) - { - // Export the polys from this node. - const IBSPLeafSolid& rLeaf = mBSPSolidLeaves[getBSPSolidLeafIndex(volume.nodeIndex)]; - for (U32 i = 0; i < rLeaf.surfaceCount; i++) - { - U32 surfaceIndex = mSolidLeafSurfaces[rLeaf.surfaceIndex + i]; - if (isNullSurfaceIndex(surfaceIndex)) - { - // Is a NULL surface - const NullSurface& rSurface = mNullSurfaces[getNullSurfaceIndex(surfaceIndex)]; - for (U32 j = 0; j < collPlanes.size(); j++) - { - if (areEqualPlanes(rSurface.planeIndex, collPlanes[j]) == true) - { - hash.insert(surfaceIndex); - break; - } - } - } - else - { - const Surface& rSurface = mSurfaces[surfaceIndex]; - for (U32 j = 0; j < collPlanes.size(); j++) - { - if (areEqualPlanes(rSurface.planeIndex, collPlanes[j]) == true) - { - hash.insert(surfaceIndex); - break; - } - } - } - } - } - - if (volume.popCount) - for (U32 i = 0; i < volume.popCount; i++) - collPlanes.pop_back(); - - continue; - } - - const IBSPNode& rNode = mBSPNodes[volume.nodeIndex]; - - // New front and back faces - polytope.mFaceList.increment(2); - InteriorPolytope::Face& frontFace = polytope.mFaceList[polytope.mFaceList.size() - 1]; - InteriorPolytope::Face& backFace = polytope.mFaceList[polytope.mFaceList.size() - 2]; - - backFace.original = frontFace.original = false; - backFace.vertex = frontFace.vertex = 0; - - // New front and back volumes - InteriorPolytope::StackElement frontVolume,backVolume; - frontVolume.edgeList = backVolume.edgeList = -1; - - PlaneF plane = getPlane(rNode.planeIndex); - if (planeIsFlipped(rNode.planeIndex)) - plane.neg(); - - S32 startVertex = polytope.mVertexList.size(); - - // Test & clip all the edges - S32 sideBase = ++polytope.sideCount << 1; - for (S32 i = volume.edgeList; i >= 0; i = polytope.mEdgeList[i].next) - { - - // Copy into tmp first to avoid problems with the array. - InteriorPolytope::Edge edge = polytope.mEdgeList[i]; - - InteriorPolytope::Vertex& v0 = polytope.mVertexList[edge.vertex[0]]; - if (v0.side < sideBase) - v0.side = sideBase + ((plane.distToPlane(v0.point) >= 0)? 0: 1); - - InteriorPolytope::Vertex& v1 = polytope.mVertexList[edge.vertex[1]]; - if (v1.side < sideBase) - v1.side = sideBase + ((plane.distToPlane(v1.point) >= 0)? 0: 1); - - if (v0.side != v1.side) - { - S32 s = v0.side - sideBase; - polytope.intersect(plane,v0.point,v1.point); - - // Split the edge into each volume - polytope.mEdgeList.increment(2); - InteriorPolytope::Edge& e0 = polytope.mEdgeList.last(); - e0.next = frontVolume.edgeList; - frontVolume.edgeList = polytope.mEdgeList.size() - 1; - - InteriorPolytope::Edge& e1 = *(&e0 - 1); - e1.next = backVolume.edgeList; - backVolume.edgeList = frontVolume.edgeList - 1; - - e0.vertex[0] = edge.vertex[s]; - e1.vertex[0] = edge.vertex[s ^ 1]; - e0.vertex[1] = e1.vertex[1] = polytope.mVertexList.size() - 1; - e0.face[0] = e1.face[0] = edge.face[0]; - e0.face[1] = e1.face[1] = edge.face[1]; - - // Add new edges on the plane, one to each volume - for (S32 f = 0; f < 2; f++) - { - InteriorPolytope::Face& face = polytope.mFaceList[edge.face[f]]; - if (face.vertex < startVertex) - { - face.vertex = polytope.mVertexList.size() - 1; - } - else - { - polytope.mEdgeList.increment(2); - InteriorPolytope::Edge& e0 = polytope.mEdgeList.last(); - e0.next = frontVolume.edgeList; - frontVolume.edgeList = polytope.mEdgeList.size() - 1; - - InteriorPolytope::Edge& e1 = *(&e0 - 1); - e1.next = backVolume.edgeList; - backVolume.edgeList = frontVolume.edgeList - 1; - - e1.vertex[0] = e0.vertex[0] = face.vertex; - e1.vertex[1] = e0.vertex[1] = polytope.mVertexList.size() - 1; - e1.face[0] = e0.face[0] = edge.face[f]; - e1.face[1] = polytope.mFaceList.size() - 1; - e0.face[1] = e1.face[1] - 1; - } - } - } - else - { - if (v0.side == sideBase) - { - polytope.mEdgeList.push_back(edge); - InteriorPolytope::Edge& ne = polytope.mEdgeList.last(); - ne.next = frontVolume.edgeList; - frontVolume.edgeList = polytope.mEdgeList.size() - 1; - } - else - { - polytope.mEdgeList.push_back(edge); - InteriorPolytope::Edge& ne = polytope.mEdgeList.last(); - ne.next = backVolume.edgeList; - backVolume.edgeList = polytope.mEdgeList.size() - 1; - } - } - } - - // Push the front and back nodes - if (frontVolume.edgeList >= 0 && backVolume.edgeList >= 0) - { - collPlanes.push_back(rNode.planeIndex); - - frontVolume.nodeIndex = rNode.frontIndex; - frontVolume.popCount = volume.popCount + 1; - stack.push_back(frontVolume); - - backVolume.nodeIndex = rNode.backIndex; - backVolume.popCount = 0; - stack.push_back(backVolume); - } - else if (frontVolume.edgeList >= 0) - { - frontVolume.nodeIndex = rNode.frontIndex; - frontVolume.popCount = volume.popCount; - stack.push_back(frontVolume); - } - else if (backVolume.edgeList >= 0) - { - backVolume.nodeIndex = rNode.backIndex; - backVolume.popCount = volume.popCount; - stack.push_back(backVolume); - } - else - { - // Pop off our own planes... - if (volume.popCount) - for (U32 i = 0; i < volume.popCount; i++) - collPlanes.pop_back(); - } - } - - AssertFatal(collPlanes.size() == 0, "Unbalanced stack!"); -} - -bool Interior::buildPolyList(AbstractPolyList* list, - const Box3F& box, - const MatrixF& transform, - const Point3F& scale) -{ - Box3F testBox; - MatrixF toItr; - if (!list->getMapping(&toItr,&testBox)) - { - // this list doesn't do this, use world space box and transform - testBox = box; - toItr = transform; - } - - // construct an interior space box from testBox and toItr - // source space may be world space, or may be something else... - // that's up to the list - // Note: transform maps to interior, but scale is itr -> world... - // that is why we divide by scale below... - F32 * f = toItr; - - F32 xx = mFabs(f[0]); F32 xy = mFabs(f[4]); F32 xz = mFabs(f[8]); - F32 yx = mFabs(f[1]); F32 yy = mFabs(f[5]); F32 yz = mFabs(f[9]); - F32 zx = mFabs(f[2]); F32 zy = mFabs(f[6]); F32 zz = mFabs(f[10]); - - F32 xlen = testBox.maxExtents.x - testBox.minExtents.x; - F32 ylen = testBox.maxExtents.y - testBox.minExtents.y; - F32 zlen = testBox.maxExtents.z - testBox.minExtents.z; - - F32 invScalex = 1.0f/scale.x; - F32 invScaley = 1.0f/scale.y; - F32 invScalez = 1.0f/scale.z; - - F32 xrad = (xx * xlen + yx * ylen + zx * zlen) * invScalex; - F32 yrad = (xy * xlen + yy * ylen + zy * zlen) * invScaley; - F32 zrad = (xz * xlen + yz * ylen + zz * zlen) * invScalez; - - Box3F interiorBox; - testBox.getCenter(&interiorBox.minExtents); - toItr.mulP(interiorBox.minExtents); - - interiorBox.minExtents.x *= invScalex; - interiorBox.minExtents.y *= invScaley; - interiorBox.minExtents.z *= invScalez; - - interiorBox.maxExtents = interiorBox.minExtents; - - interiorBox.minExtents.x -= xrad; - interiorBox.minExtents.y -= yrad; - interiorBox.minExtents.z -= zrad; - - interiorBox.maxExtents.x += xrad; - interiorBox.maxExtents.y += yrad; - interiorBox.maxExtents.z += zrad; - - U32 waterMark = FrameAllocator::getWaterMark(); - - U16* hulls = (U16*)FrameAllocator::alloc(mConvexHulls.size() * sizeof(U16)); - U32 numHulls = 0; - - getIntersectingHulls(interiorBox,hulls, &numHulls); - - if (numHulls == 0) - { - FrameAllocator::setWaterMark(waterMark); - return false; - } - - // we've found all the hulls that intersect the lists interior space bounding box... - // now cull out those hulls which don't intersect the oriented bounding box... - - Point3F radii = testBox.maxExtents - testBox.minExtents; - radii *= 0.5f; - radii.x *= invScalex; - radii.y *= invScaley; - radii.z *= invScalez; - - // adjust toItr transform so that origin of source space is box center - // Note: center of interior box will be = to transformed center of testBox - Point3F center = interiorBox.minExtents + interiorBox.maxExtents; - center *= 0.5f; - toItr.setColumn(3,center); // (0,0,0) now goes where box center used to... - - for (S32 i=0; ibegin(0, rSurface.planeIndex); - for (U32 k = 0; k < rSurface.windingCount; k++) - { - array[k] = list->addPoint(mPoints[mWindings[rSurface.windingStart + k]].point); - list->vertex(array[k]); - } - - list->plane(getFlippedPlane(rSurface.planeIndex)); - list->end(); - } - else - { - const Interior::Surface& rSurface = mSurfaces[surfaceIndex]; - U32 array[32]; - U32 fanVerts[32]; - U32 numVerts; - - collisionFanFromSurface(rSurface, fanVerts, &numVerts); - - list->begin(0, rSurface.planeIndex); - for (U32 k = 0; k < numVerts; k++) - { - array[k] = list->addPoint(mPoints[fanVerts[k]].point); - list->vertex(array[k]); - } - list->plane(getFlippedPlane(rSurface.planeIndex)); - list->end(); - } - } - } - - FrameAllocator::setWaterMark(waterMark); - return !list->isEmpty(); -} - - -//--------------------------------------------------------------------------------- -//-------------------------------------- Zone scan. Not really collision, but hey. -// -struct Edge -{ - U16 p1; - U16 p2; - Edge(U16 o, U16 t) : p1(o), p2(t) { } -}; - -struct EdgeList -{ - - Vector points; - Vector edges; -}; - -void Interior::scanZoneNew(InteriorPolytope& polytope, - U16* zones, - U32* numZones) -{ - PROFILE_START(InteriorScanZoneNew); - // Submit the first volume of the poly tope to the bsp tree - static InteriorPolytope::VolumeStack stack; - stack.reserve(128); - stack.setSize(1); - stack.last().edgeList = polytope.mVolumeList[0].edgeList; - stack.last().nodeIndex = 0; - stack.last().popCount = 0; - - static Vector collPlanes; - collPlanes.reserve(64); - collPlanes.clear(); - - while (stack.empty() == false) - { - - InteriorPolytope::StackElement volume = stack.last(); - stack.pop_back(); - - if (isBSPLeafIndex(volume.nodeIndex)) - { - if (isBSPEmptyLeaf(volume.nodeIndex)) - { - U16 zone = getBSPEmptyLeafZone(volume.nodeIndex); - if (zone != 0x0FFF) - { - bool insert = true; - for (U32 i = 0; i < *numZones; i++) - { - if (zones[i] == zone) - { - insert = false; - break; - } - } - if (insert) - { - zones[*numZones] = zone; - (*numZones)++; - } - } - } - - if (volume.popCount) - for (U32 i = 0; i < volume.popCount; i++) - collPlanes.pop_back(); - - continue; - } - - const IBSPNode& rNode = mBSPNodes[volume.nodeIndex]; - if ((rNode.terminalZone & U16(0x8000)) != 0) - { - // Hah! we don't need to search any further - U16 zone = rNode.terminalZone & (~0x8000); - if (zone != 0x7FFF && zone != 0x0FFF) - { - bool insert = true; - for (U32 i = 0; i < *numZones; i++) - { - if (zones[i] == zone) - { - insert = false; - break; - } - } - if (insert) - { - zones[*numZones] = zone; - (*numZones)++; - } - } - - if (volume.popCount) - for (U32 i = 0; i < volume.popCount; i++) - collPlanes.pop_back(); - - continue; - } - - // New front and back faces - polytope.mFaceList.increment(2); - InteriorPolytope::Face& frontFace = polytope.mFaceList.last(); - InteriorPolytope::Face& backFace = *(&frontFace - 1); - - backFace.original = frontFace.original = false; - backFace.vertex = frontFace.vertex = 0; - - // New front and back volumes - InteriorPolytope::StackElement frontVolume,backVolume; - frontVolume.edgeList = backVolume.edgeList = -1; - - PlaneF plane = getFlippedPlane(rNode.planeIndex); - - S32 startVertex = polytope.mVertexList.size(); - - // Test & clip all the edges - S32 sideBase = ++polytope.sideCount << 1; - AssertFatal(sideBase != 0, "Well, crap."); - for (S32 i = volume.edgeList; i >= 0; i = polytope.mEdgeList[i].next) - { - // Copy into tmp first to avoid problems with the array. - InteriorPolytope::Edge edge = polytope.mEdgeList[i]; - - InteriorPolytope::Vertex& v0 = polytope.mVertexList[edge.vertex[0]]; - if (v0.side < sideBase) - v0.side = sideBase + ((plane.distToPlane(v0.point) >= 0)? 0: 1); - InteriorPolytope::Vertex& v1 = polytope.mVertexList[edge.vertex[1]]; - if (v1.side < sideBase) - v1.side = sideBase + ((plane.distToPlane(v1.point) >= 0)? 0: 1); - - if (v0.side != v1.side) - { - S32 s = v0.side - sideBase; - polytope.intersect(plane,v0.point,v1.point); - - // Split the edge into each volume - polytope.mEdgeList.increment(2); - InteriorPolytope::Edge& e0 = polytope.mEdgeList.last(); - e0.next = frontVolume.edgeList; - frontVolume.edgeList = polytope.mEdgeList.size() - 1; - - InteriorPolytope::Edge& e1 = *(&e0 - 1); - e1.next = backVolume.edgeList; - backVolume.edgeList = frontVolume.edgeList - 1; - - e0.vertex[0] = edge.vertex[s]; - e1.vertex[0] = edge.vertex[s ^ 1]; - e0.vertex[1] = e1.vertex[1] = polytope.mVertexList.size() - 1; - e0.face[0] = e1.face[0] = edge.face[0]; - e0.face[1] = e1.face[1] = edge.face[1]; - - // Add new edges on the plane, one to each volume - for (S32 f = 0; f < 2; f++) - { - InteriorPolytope::Face& face = polytope.mFaceList[edge.face[f]]; - if (face.vertex < startVertex) - { - face.vertex = polytope.mVertexList.size() - 1; - } - else - { - polytope.mEdgeList.increment(2); - InteriorPolytope::Edge& e0 = polytope.mEdgeList.last(); - e0.next = frontVolume.edgeList; - frontVolume.edgeList = polytope.mEdgeList.size() - 1; - - InteriorPolytope::Edge& e1 = *(&e0 - 1); - e1.next = backVolume.edgeList; - backVolume.edgeList = frontVolume.edgeList - 1; - - e1.vertex[0] = e0.vertex[0] = face.vertex; - e1.vertex[1] = e0.vertex[1] = polytope.mVertexList.size() - 1; - e1.face[0] = e0.face[0] = edge.face[f]; - e1.face[1] = polytope.mFaceList.size() - 1; - e0.face[1] = e1.face[1] - 1; - } - } - } - else - { - if (v0.side == sideBase) - { - polytope.mEdgeList.push_back(edge); - InteriorPolytope::Edge& ne = polytope.mEdgeList.last(); - ne.next = frontVolume.edgeList; - frontVolume.edgeList = polytope.mEdgeList.size() - 1; - } - else - { - polytope.mEdgeList.push_back(edge); - InteriorPolytope::Edge& ne = polytope.mEdgeList.last(); - ne.next = backVolume.edgeList; - backVolume.edgeList = polytope.mEdgeList.size() - 1; - } - } - } - - // Push the front and back nodes - if (frontVolume.edgeList >= 0 && backVolume.edgeList >= 0) - { - collPlanes.push_back(rNode.planeIndex); - - frontVolume.nodeIndex = rNode.frontIndex; - frontVolume.popCount = volume.popCount + 1; - stack.push_back(frontVolume); - - backVolume.nodeIndex = rNode.backIndex; - backVolume.popCount = 0; - stack.push_back(backVolume); - } - else if (frontVolume.edgeList >= 0) - { - frontVolume.nodeIndex = rNode.frontIndex; - frontVolume.popCount = volume.popCount; - stack.push_back(frontVolume); - } - else if (backVolume.edgeList >= 0) - { - backVolume.nodeIndex = rNode.backIndex; - backVolume.popCount = volume.popCount; - stack.push_back(backVolume); - } - else - { - // Pop off our own planes... - if (volume.popCount) - for (U32 i = 0; i < volume.popCount; i++) - collPlanes.pop_back(); - } - } - - AssertFatal(collPlanes.size() == 0, "Unbalanced stack!"); - PROFILE_END(); -} - -void Interior::scanZone_r(const U32 node, - const Point3F& center, - const Point3F& axisx, - const Point3F& axisy, - const Point3F& axisz, - U16* zones, - U32* numZones) -{ - if (isBSPLeafIndex(node) == false) - { - const IBSPNode& rNode = mBSPNodes[node]; - const PlaneF& rPlane = getPlane(rNode.planeIndex); - - PlaneF::Side side = rPlane.whichSideBox(center, axisx, axisy, axisz); - if (planeIsFlipped(rNode.planeIndex)) - side = PlaneF::Side(-S32(side)); - - switch (side) - { - case PlaneF::Front: - scanZone_r(rNode.frontIndex, center, axisx, axisy, axisz, zones, numZones); - break; - - case PlaneF::Back: - scanZone_r(rNode.backIndex, center, axisx, axisy, axisz, zones, numZones); - break; - - case PlaneF::On: - scanZone_r(rNode.frontIndex, center, axisx, axisy, axisz, zones, numZones); - scanZone_r(rNode.backIndex, center, axisx, axisy, axisz, zones, numZones); - break; - - default: - AssertFatal(false, "Misunderstood switchCode in Interior::zoneRay_r"); - } - - return; - } - - if (isBSPEmptyLeaf(node)) - { - U16 zone = getBSPEmptyLeafZone(node); - if (zone != 0x0FFF) - { - for (U32 i = 0; i < *numZones; i++) - { - if (zones[i] == zone) - return; - } - - zones[*numZones] = zone; - (*numZones)++; - } - } -} - -bool Interior::scanZones(const Box3F& box, - const MatrixF& transform, - U16* zones, - U32* numZones) -{ - // We don't need an exact answer, so let's just blast a box through - // the planes and see what we intersect. scanZoneNew is good if you - // have an exact volume to clip. - - Point3F center; - box.getCenter(¢er); - - Point3F xRad((box.maxExtents.x - box.minExtents.x) * 0.5f, 0.0f, 0.0f); - Point3F yRad(0.0f, (box.maxExtents.y - box.minExtents.y) * 0.5f, 0.0f); - Point3F zRad(0.0f, 0.0f, (box.maxExtents.z - box.minExtents.z) * 0.5f); - - transform.mulP(center); - transform.mulV(xRad); - transform.mulV(yRad); - transform.mulV(zRad); - - scanZone_r(0, center, xRad, yRad, zRad, zones, numZones); - - bool outsideToo = false; - if (*numZones != 0) - { - for (U32 i = 0; i < *numZones; /**/) - { - if (zones[i]) - { - i++; - continue; - } - - outsideToo = true; - - zones[i] = zones[(*numZones) - 1]; - (*numZones)--; - } - } - else - { - // If it ain't in us, it's outside us. - outsideToo = true; - } - - return outsideToo; -} - - -bool Interior::getIntersectingHulls(const Box3F& query, U16* hulls, U32* numHulls) -{ - AssertFatal(*numHulls == 0, "Error, some stuff in the hull vector already!"); - - // This is paranoia, and I probably wouldn't do it if the tag was 32 bits, but - // a possible collision every 65k searches is just a little too small for comfort - // DMM - if (mSearchTag == 0) - { - for (U32 i = 0; i < mConvexHulls.size(); i++) - mConvexHulls[i].searchTag = 0; - mSearchTag = 1; - } - else - { - mSearchTag++; - } - - F32 xBinSize = mBoundingBox.len_x() / F32(NumCoordBins); - F32 yBinSize = mBoundingBox.len_y() / F32(NumCoordBins); - - F32 queryMinX = getMax(mBoundingBox.minExtents.x, query.minExtents.x); - F32 queryMinY = getMax(mBoundingBox.minExtents.y, query.minExtents.y); - F32 queryMaxX = getMin(mBoundingBox.maxExtents.x, query.maxExtents.x); - F32 queryMaxY = getMin(mBoundingBox.maxExtents.y, query.maxExtents.y); - - S32 startX = S32(mFloor((queryMinX - mBoundingBox.minExtents.x) / xBinSize)); - S32 endX = S32( mCeil((queryMaxX - mBoundingBox.minExtents.x) / xBinSize)); - S32 startY = S32(mFloor((queryMinY - mBoundingBox.minExtents.y) / yBinSize)); - S32 endY = S32( mCeil((queryMaxY - mBoundingBox.minExtents.y) / yBinSize)); - - AssertFatal(startX >= 0, "Error, bad startx"); - AssertFatal(startY >= 0, "Error, bad starty"); - AssertFatal(endX <= NumCoordBins, "Error, bad endX"); - AssertFatal(endY <= NumCoordBins, "Error, bad endY"); - - // Handle non-debug case - startX = getMax(startX, 0); - endX = getMin(endX, NumCoordBins); - startY = getMax(startY, 0); - endY = getMin(endY, NumCoordBins); - - for (S32 i = startX; i < endX; i++) - { - for (S32 j = startY; j < endY; j++) - { - const CoordBin& rBin = mCoordBins[i * NumCoordBins + j]; - for (U32 k = rBin.binStart; k < rBin.binStart + rBin.binCount; k++) - { - U16 hullIndex = mCoordBinIndices[k]; - ConvexHull& rHull = mConvexHulls[hullIndex]; - - // Don't check twice! (We're not Santa Claus.) - if (rHull.searchTag == mSearchTag) - continue; - rHull.searchTag = mSearchTag; - - Box3F qb(rHull.minX, rHull.minY, rHull.minZ, rHull.maxX, rHull.maxY, rHull.maxZ); - if (query.isOverlapped(qb)) - { - hulls[*numHulls] = hullIndex; - (*numHulls)++; - } - } - } - } - - return *numHulls != 0; -} - - -bool Interior::getIntersectingVehicleHulls(const Box3F& query, U16* hulls, U32* numHulls) -{ - AssertFatal(*numHulls == 0, "Error, some stuff in the hull vector already!"); - - for (U16 i = 0; i < mVehicleConvexHulls.size(); i++) - { - ConvexHull& rHull = mVehicleConvexHulls[i]; - Box3F qb(rHull.minX, rHull.minY, rHull.minZ, rHull.maxX, rHull.maxY, rHull.maxZ); - if (query.isOverlapped(qb)) - { - hulls[*numHulls] = i; - (*numHulls)++; - } - } - - return *numHulls != 0; -} - -//-------------------------------------------------------------------------- -Box3F InteriorConvex::getBoundingBox() const -{ - return getBoundingBox(mObject->getTransform(), mObject->getScale()); -} - -Box3F InteriorConvex::getBoundingBox(const MatrixF& mat, const Point3F& scale) const -{ - Box3F newBox = box; - newBox.minExtents.convolve(scale); - newBox.maxExtents.convolve(scale); - mat.mul(newBox); - return newBox; -} - -Point3F InteriorConvex::support(const VectorF& v) const -{ - FrameAllocatorMarker fam; - - if (hullId >= 0) - { - AssertFatal(hullId < pInterior->mConvexHulls.size(), "Out of bounds hull!"); - - const Interior::ConvexHull& rHull = pInterior->mConvexHulls[hullId]; - - F32* pDots = (F32*)fam.alloc(sizeof(F32) * rHull.hullCount); - m_point3F_bulk_dot_indexed(&v.x, - &pInterior->mPoints[0].point.x, - rHull.hullCount, - sizeof(ItrPaddedPoint), - &pInterior->mHullIndices[rHull.hullStart], - pDots); - - U32 index = 0; - for (U32 i = 1; i < rHull.hullCount; i++) - { - if (pDots[i] > pDots[index]) - index = i; - } - - return pInterior->mPoints[pInterior->mHullIndices[rHull.hullStart + index]].point; - } - else - { - S32 actualId = -(hullId + 1); - AssertFatal(actualId < pInterior->mVehicleConvexHulls.size(), "Out of bounds hull!"); - - const Interior::ConvexHull& rHull = pInterior->mVehicleConvexHulls[actualId]; - - F32* pDots = (F32*)fam.alloc(sizeof(F32) * rHull.hullCount); - m_point3F_bulk_dot_indexed(&v.x, - &pInterior->mVehiclePoints[0].point.x, - rHull.hullCount, - sizeof(ItrPaddedPoint), - &pInterior->mVehicleHullIndices[rHull.hullStart], - pDots); - - U32 index = 0; - for (U32 i = 1; i < rHull.hullCount; i++) - { - if (pDots[i] > pDots[index]) - index = i; - } - - return pInterior->mVehiclePoints[pInterior->mVehicleHullIndices[rHull.hullStart + index]].point; - } -} - - -void InteriorConvex::getFeatures(const MatrixF& mat, const VectorF& n, ConvexFeature* cf) -{ - S32 i; - - cf->material = 0; - cf->object = mObject; - - if (hullId >= 0) - { - // We find the support ourselves here since we want the index too... - const Interior::ConvexHull& rHull = pInterior->mConvexHulls[hullId]; - U32 spIndex = 0; - F32 maxSp = mDot(pInterior->mPoints[pInterior->mHullIndices[rHull.hullStart + spIndex]].point, n); - - for (i = 1; i < rHull.hullCount; i++) - { - U32 index = pInterior->mHullIndices[rHull.hullStart + i]; - const Point3F& rPoint = pInterior->mPoints[index].point; - - F32 dot = mDot(rPoint, n); - if (dot > maxSp) - { - spIndex = i; - maxSp = dot; - } - } - - // Ok, now we have the support point, let's extract the emission string for this - // vertex... - U32 currPos = 0; - const U8* pString = &pInterior->mConvexHullEmitStrings[pInterior->mHullEmitStringIndices[rHull.hullStart + spIndex]]; - - FrameAllocatorMarker fam; - U32* pRemaps = (U32*)fam.alloc(256 * sizeof(U32)); - - // Ok, this is a piece of cake. Lets dump the points first... - U32 numPoints = pString[currPos++]; - for (i = 0; i < numPoints; i++) - { - U32 index = pString[currPos++]; - - pRemaps[i] = cf->mVertexList.size(); - cf->mVertexList.increment(); - - const Point3F& rPoint = pInterior->mPoints[pInterior->mHullIndices[rHull.hullStart + index]].point; - mat.mulP(rPoint, &cf->mVertexList.last()); - } - - // Then the edges... - U32 numEdges = pString[currPos++]; - for (i = 0; i < numEdges; i++) - { - U32 index0 = pString[currPos++]; - U32 index1 = pString[currPos++]; - - cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = pRemaps[index0]; - cf->mEdgeList.last().vertex[1] = pRemaps[index1]; - } - - // Then the polys... - U32 numPolys = pString[currPos++]; - for (i = 0; i < numPolys; i++) - { - U32 vertexCount = pString[currPos++]; - U32 planeIndex = pString[currPos++]; - - U32 verts[3]; - verts[0] = pString[currPos++]; - verts[1] = pString[currPos++]; - - AssertFatal( verts[0] < numPoints, "InteriorConvex::getFeatures verts out of range" ); - - for (U32 j = 2; j < vertexCount; j++) - { - verts[2] = pString[currPos++]; - - // Emit this poly - cf->mFaceList.increment(); - cf->mFaceList.last().normal = pInterior->getPlane(pInterior->mHullPlaneIndices[rHull.planeStart + planeIndex]); - - AssertFatal( verts[1] < numPoints, "InteriorConvex::getFeatures verts out of range" ); - AssertFatal( verts[2] < numPoints, "InteriorConvex::getFeatures verts out of range" ); - - cf->mFaceList.last().vertex[0] = pRemaps[verts[0]]; - cf->mFaceList.last().vertex[1] = pRemaps[verts[1]]; - cf->mFaceList.last().vertex[2] = pRemaps[verts[2]]; - PlaneF plane(cf->mVertexList[pRemaps[verts[0]]], - cf->mVertexList[pRemaps[verts[1]]], - cf->mVertexList[pRemaps[verts[2]]]); - cf->mFaceList.last().normal = plane; - - // Shift the fan over - verts[1] = verts[2]; - } - } - } - else - { - S32 actualId = -(hullId + 1); - // We find the support ourselves here since we want the index too... - const Interior::ConvexHull& rHull = pInterior->mVehicleConvexHulls[actualId]; - U32 spIndex = 0; - F32 maxSp = mDot(pInterior->mVehiclePoints[pInterior->mVehicleHullIndices[rHull.hullStart + spIndex]].point, n); - - for (i = 1; i < rHull.hullCount; i++) - { - U32 index = pInterior->mVehicleHullIndices[rHull.hullStart + i]; - const Point3F& rPoint = pInterior->mVehiclePoints[index].point; - - F32 dot = mDot(rPoint, n); - if (dot > maxSp) - { - spIndex = i; - maxSp = dot; - } - } - - // Ok, now we have the support point, let's extract the emission string for this - // vertex... - U32 currPos = 0; - const U8* pString = &pInterior->mVehicleConvexHullEmitStrings[ - pInterior->mVehicleHullEmitStringIndices[rHull.hullStart + spIndex] - ]; - - FrameAllocatorMarker fam; - U32* pRemaps = (U32*)fam.alloc(256 * sizeof(U32)); - - // Ok, this is a piece of cake. Lets dump the points first... - U32 numPoints = pString[currPos++]; - for (i = 0; i < numPoints; i++) - { - U32 index = pString[currPos++]; - - pRemaps[i] = cf->mVertexList.size(); - cf->mVertexList.increment(); - - const Point3F& rPoint = pInterior->mVehiclePoints[pInterior->mVehicleHullIndices[rHull.hullStart + index]].point; - mat.mulP(rPoint, &cf->mVertexList.last()); - } - - // Then the edges... - U32 numEdges = pString[currPos++]; - for (i = 0; i < numEdges; i++) - { - U32 index0 = pString[currPos++]; - U32 index1 = pString[currPos++]; - - cf->mEdgeList.increment(); - cf->mEdgeList.last().vertex[0] = pRemaps[index0]; - cf->mEdgeList.last().vertex[1] = pRemaps[index1]; - } - - // Then the polys... - U32 numPolys = pString[currPos++]; - for (i = 0; i < numPolys; i++) - { - U32 vertexCount = pString[currPos++]; - U32 planeIndex = pString[currPos++]; - - U32 verts[3]; - verts[0] = pString[currPos++]; - verts[1] = pString[currPos++]; - - for (U32 j = 2; j < vertexCount; j++) - { - verts[2] = pString[currPos++]; - - // Emit this poly - cf->mFaceList.increment(); - - cf->mFaceList.last().vertex[0] = pRemaps[verts[0]]; - cf->mFaceList.last().vertex[1] = pRemaps[verts[1]]; - cf->mFaceList.last().vertex[2] = pRemaps[verts[2]]; - cf->mFaceList.last().normal = pInterior->getPlane(planeIndex); - - // Shift the fan over - verts[1] = verts[2]; - } - } - } -} - -void InteriorConvex::getPolyList(AbstractPolyList* list) -{ - // Setup collision state data - { - list->setTransform(&mObject->getTransform(), mObject->getScale()); - list->setObject(mObject); - } - - if (hullId >= 0) - { - // Get our hull - const Interior::ConvexHull& rHull = pInterior->mConvexHulls[hullId]; - - // Build up the lists of points and strings - const U8* pString = &pInterior->mPolyListStrings[rHull.polyListStringStart]; - - U32 currPos = 0; - U32 numPlanes = pString[currPos++]; - - // It can happen that a hull has no collision surfaces. In that case, just bail out - // here... - if (numPlanes == 0) - return; - - const U8* planeString = &pString[currPos]; - currPos += numPlanes; - - U32 numPoints = pString[currPos++] << 8; - numPoints |= pString[currPos++]; - const U8* pointString = &pString[currPos]; - currPos += numPoints; - - U32 numSurfaces = pString[currPos++]; - - const U16* planeIndices = &pInterior->mPolyListPlanes[rHull.polyListPlaneStart]; - const U32* pointIndices = &pInterior->mPolyListPoints[rHull.polyListPointStart]; - - //-------------------------------------- - // At this point, currPos is pointing to the first surface in the string - //-------------------------------------- - - // First thing to do: build the interest mask, by seeing if the list is interested - // in our planes... - U8 interestMask = 0; - U32 remappedPlaneBase; - { - U16 planeIndex = planeIndices[0]; - PlaneF plane = pInterior->getPlane(planeIndex); - if (Interior::planeIsFlipped(planeIndex)) - plane.neg(); - - remappedPlaneBase = list->addPlane(plane); - - if (list->isInterestedInPlane(remappedPlaneBase)) - interestMask |= planeString[0]; - - for (U32 i = 1; i < numPlanes; i++) - { - planeIndex = planeIndices[i]; - plane = pInterior->getPlane(planeIndex); - if (Interior::planeIsFlipped(planeIndex)) - plane.neg(); - - list->addPlane(plane); - if (list->isInterestedInPlane(remappedPlaneBase + i)) - interestMask |= planeString[i]; - } - } - - // Now, whip through the points, and build up the remap table, adding only - // those points that the list is interested in. Note that we use the frameAllocator - // to get enoughMemory to deal with the variable sized remap array - FrameAllocatorMarker fam; - U32* pointRemapTable = reinterpret_cast(fam.alloc(numPoints * sizeof(U32))); - { - for (U32 i = 0; i < numPoints; i++) - { - if ((interestMask & pointString[i]) != 0) - { - const Point3F& rPoint = pInterior->mPoints[pointIndices[i]].point; - pointRemapTable[i] = list->addPoint(rPoint); - } - } - } - - // Now, whip through the surfaces, checking to make sure that we're interested in - // that poly as we go. At this point, currPos should point to the first surface. - // The format of the surface string can be found in interior.cc, in the - // processHullPolyLists function - { - for (U32 i = 0; i < numSurfaces; i++) - { - U32 snPoints = pString[currPos++]; - U32 sMask = pString[currPos++]; - U32 sPlane = pString[currPos++]; - - if ((interestMask & sMask) != 0) - { - // Add the poly - // - list->begin(0, planeIndices[sPlane]); - for (U32 j = 0; j < snPoints; j++) - { - U16 remappedIndex = pString[currPos++] << 8; - remappedIndex |= pString[currPos++]; - remappedIndex = pointRemapTable[remappedIndex]; - list->vertex(remappedIndex); - } - list->plane(remappedPlaneBase + sPlane); - - list->end(); - } - else - { - // Superflous poly, just skip past the points - currPos += snPoints * 2; - } - } - } - } - else - { - S32 actualId = -(hullId + 1); - - // Get our hull - const Interior::ConvexHull& rHull = pInterior->mVehicleConvexHulls[actualId]; - - // Build up the lists of points and strings - const U8* pString = &pInterior->mVehiclePolyListStrings[rHull.polyListStringStart]; - U32 currPos = 0; - - U32 numPlanes = pString[currPos++]; - // It can happen that a hull has no collision surfaces. In that case, just bail out - // here... - if (numPlanes == 0) - return; - - const U8* planeString = &pString[currPos]; - currPos += numPlanes; - - U32 numPoints = pString[currPos++] << 8; - numPoints |= pString[currPos++]; - const U8* pointString = &pString[currPos]; - currPos += numPoints; - - U32 numSurfaces = pString[currPos++]; - - const U16* planeIndices = &pInterior->mVehiclePolyListPlanes[rHull.polyListPlaneStart]; - const U32* pointIndices = &pInterior->mVehiclePolyListPoints[rHull.polyListPointStart]; - - //-------------------------------------- - // At this point, currPos is pointing to the first surface in the string - //-------------------------------------- - - // First thing to do: build the interest mask, by seeing if the list is interested - // in our planes... - U8 interestMask = 0; - U32 remappedPlaneBase; - { - U16 planeIndex = planeIndices[0]; - PlaneF plane = pInterior->getPlane(planeIndex); - if (Interior::planeIsFlipped(planeIndex)) - plane.neg(); - - remappedPlaneBase = list->addPlane(plane); - - if (list->isInterestedInPlane(remappedPlaneBase)) - interestMask |= planeString[0]; - - for (U32 i = 1; i < numPlanes; i++) - { - planeIndex = planeIndices[i]; - plane = pInterior->getPlane(planeIndex); - if (Interior::planeIsFlipped(planeIndex)) - plane.neg(); - - list->addPlane(plane); - if (list->isInterestedInPlane(remappedPlaneBase + i)) - interestMask |= planeString[i]; - } - } - - // Now, whip through the points, and build up the remap table, adding only - // those points that the list is interested in. Note that we use the frameAllocator - // to get enoughMemory to deal with the variable sized remap array - FrameAllocatorMarker fam; - U32* pointRemapTable = reinterpret_cast(fam.alloc(numPoints * sizeof(U32))); - { - for (U32 i = 0; i < numPoints; i++) - { - if ((interestMask & pointString[i]) != 0) - { - const Point3F& rPoint = pInterior->mVehiclePoints[pointIndices[i]].point; - pointRemapTable[i] = list->addPoint(rPoint); - } - } - } - - // Now, whip through the surfaces, checking to make sure that we're interested in - // that poly as we go. At this point, currPos should point to the first surface. - // The format of the surface string can be found in interior.cc, in the - // processHullPolyLists function - { - for (U32 i = 0; i < numSurfaces; i++) - { - U32 snPoints = pString[currPos++]; - U32 sMask = pString[currPos++]; - U32 sPlane = pString[currPos++]; - - if ((interestMask & sMask) != 0) - { - // Add the poly - // - list->begin(0, planeIndices[sPlane]); - for (U32 j = 0; j < snPoints; j++) - { - U16 remappedIndex = pString[currPos++] << 8; - remappedIndex |= pString[currPos++]; - remappedIndex = pointRemapTable[remappedIndex]; - list->vertex(remappedIndex); - } - list->plane(remappedPlaneBase + sPlane); - - list->end(); - } - else - { - // Superflous poly, just skip past the points - currPos += snPoints * 2; - } - } - } - } -} - - diff --git a/Engine/source/interior/interiorDebug.cpp b/Engine/source/interior/interiorDebug.cpp deleted file mode 100644 index 1d0db508d..000000000 --- a/Engine/source/interior/interiorDebug.cpp +++ /dev/null @@ -1,711 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "torqueConfig.h" - -#ifndef TORQUE_SHIPPING - -#include "interior/interior.h" -#include "interior/interiorInstance.h" -#include "console/console.h" -#include "core/color.h" -#include "math/mMatrix.h" -#include "gfx/bitmap/gBitmap.h" -#include "gfx/primBuilder.h" -#include "gfx/gfxShader.h" -#include "materials/matInstance.h" -#include "materials/materialList.h" -#include "materials/shaderData.h" -#include "renderInstance/renderPassManager.h" -#include "shaderGen/shaderGenVars.h" - -static U8 interiorDebugColors[14][3] = -{ - { 0xFF, 0xFF, 0xFF }, - { 0x00, 0x00, 0xFF }, - { 0x00, 0xFF, 0x00 }, - { 0xFF, 0x00, 0x00 }, - { 0xFF, 0xFF, 0x00 }, - { 0xFF, 0x00, 0xFF }, - { 0x00, 0xFF, 0xFF }, - { 0x80, 0x80, 0x80 }, - { 0xFF, 0x80, 0x80 }, - { 0x80, 0xFF, 0x80 }, - { 0x80, 0x80, 0xFF }, - { 0x80, 0xFF, 0xFF }, - { 0xFF, 0x80, 0xFF }, - { 0xFF, 0x80, 0x80 } -}; - - -namespace -{ - -void lineLoopFromStrip(Vector& points, - Vector& windings, - U32 windingStart, - U32 windingCount) -{ - PrimBuild::begin(GFXLineStrip, windingCount + 1); - PrimBuild::vertex3fv(points[windings[windingStart]].point); - S32 skip = windingStart + 1; - while (skip < (windingStart + windingCount)) - { - PrimBuild::vertex3fv(points[windings[skip]].point); - skip += 2; - } - - skip -= 1; - while (skip > windingStart) - { - if (skip < (windingStart + windingCount)) - PrimBuild::vertex3fv(points[windings[skip]].point); - - skip -= 2; - } - PrimBuild::vertex3fv(points[windings[windingStart]].point); - PrimBuild::end(); -} - -void lineStrip(Vector& points, - Vector& windings, - U32 windingStart, - U32 windingCount) -{ - U32 end = 2; - - while (end < windingCount) - { - // Even - PrimBuild::begin(GFXLineStrip, 4); - PrimBuild::vertex3fv(points[windings[windingStart + end - 2]].point); - PrimBuild::vertex3fv(points[windings[windingStart + end - 1]].point); - PrimBuild::vertex3fv(points[windings[windingStart + end - 0]].point); - PrimBuild::vertex3fv(points[windings[windingStart + end - 2]].point); - PrimBuild::end(); - - end++; - if (end >= windingCount) - break; - - // Odd - PrimBuild::begin(GFXLineStrip, 4); - PrimBuild::vertex3fv(points[windings[windingStart + end - 1]].point); - PrimBuild::vertex3fv(points[windings[windingStart + end - 2]].point); - PrimBuild::vertex3fv(points[windings[windingStart + end - 0]].point); - PrimBuild::vertex3fv(points[windings[windingStart + end - 1]].point); - PrimBuild::end(); - - end++; - } -} - -} // namespace {} - -void Interior::debugRender(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst, MatrixF& modelview) -{ - // We use this shader to color things - if ( mDebugShader == NULL ) - { - ShaderData *shaderData = NULL; - AssertFatal( Sim::findObject( "_DebugInterior_", shaderData ), "Unable to find ShaderData _DebugInterior_" ); - - mDebugShader = shaderData ? shaderData->getShader() : NULL; - - if ( mDebugShader ) - { - mDebugShaderConsts = mDebugShader->allocConstBuffer(); - mDebugShaderModelViewSC = mDebugShader->getShaderConstHandle(ShaderGenVars::modelview); - mDebugShaderShadeColorSC = mDebugShader->getShaderConstHandle("$shadeColor"); - } - } - - // We use this to override the texture that the interior defines. - if (mDebugTexture.isNull()) - { - // Allocate a small white bitmap - GBitmap temp(16, 16); - mDebugTexture.set(&temp, &GFXDefaultStaticDiffuseProfile, false, "Blank Texture"); - } - - // Set up our buffers - GFX->setVertexBuffer( mVertBuff ); - GFX->setPrimitiveBuffer( mPrimBuff ); - - // Set the modelview matrix for the shaders - mDebugShaderConsts->setSafe(mDebugShaderModelViewSC, modelview); - - GFX->disableShaders(); - - switch (smRenderMode) - { - case NormalRenderLines: - debugNormalRenderLines(zoneVis); - break; - - case ShowDetail: - debugShowDetail(zoneVis); - break; - - case ShowAmbiguous: - debugShowAmbiguous(zoneVis); - break; - - case ShowLightmaps: - debugShowLightmaps(zoneVis, sgData, intInst); - break; - - case ShowPortalZones: - debugShowPortalZones(zoneVis); - break; - - case ShowCollisionFans: - debugShowCollisionFans(zoneVis); - break; - - case ShowOrphan: - debugShowOrphan(zoneVis); - break; - - case ShowStrips: - debugShowStrips(zoneVis); - break; - - case ShowTexturesOnly: - debugShowTexturesOnly(zoneVis, sgData, intInst); - break; - - case ShowNullSurfaces: - debugShowNullSurfaces(zoneVis, sgData, intInst); - break; - - case ShowLargeTextures: - debugShowLargeTextures(zoneVis, sgData, intInst); - break; - - case ShowOutsideVisible: - debugShowOutsideVisible(zoneVis); - break; - - case ShowHullSurfaces: - debugShowHullSurfaces(); - break; - - case ShowVehicleHullSurfaces: - debugShowVehicleHullSurfaces(zoneVis, sgData, intInst); - break; - - case ShowDetailLevel: - debugShowDetailLevel(zoneVis); - break; - - case ShowVertexColors: -// debugShowVertexColors(pMaterials); - break; - - default: - AssertWarn(false, "Warning! Misunderstood debug render mode. Defaulting to ShowDetail"); - debugShowDetail(zoneVis); - break; - } -} - -void Interior::preDebugRender() -{ - // Set up our rendering states. - if( mDebugShader ) - { - // Set our shader - GFX->setShader( mDebugShader ); - - // Set a "blank" texture - GFX->setTexture( 0, mDebugTexture ); - - // Set a state block to enable our texture - GFX->setStateBlock(mInteriorDebugTextureSB); - } -} - -void Interior::debugNormalRenderLines(const ZoneVisDeterminer& zoneVis) -{ - // Set our "base debug states" (no texture) - GFX->setStateBlock(mInteriorDebugNoneSB); - - for (U32 i = 0; i < mZones.size(); i++) - { - if (zoneVis.isZoneVisible(i) == false) - continue; - - for( U32 j=0; jsetSafe(mDebugShaderShadeColorSC, col); - - GFX->setShaderConstBuffer(mDebugShaderConsts); - - GFXPrimitive* info = &rSurface.surfaceInfo; - GFX->drawIndexedPrimitive( info->type, info->startVertex, info->minIndex, info->numVertices, info->startIndex, info->numPrimitives ); - } - } - - GFX->disableShaders(); - debugNormalRenderLines(zoneVis); -} - -void Interior::debugShowDetail(const ZoneVisDeterminer& zoneVis) -{ - debugShowSurfaceFlag(zoneVis, SurfaceDetail, ColorF(1.0f, 0.0f, 0.0f)); -} - -void Interior::debugShowAmbiguous(const ZoneVisDeterminer& zoneVis) -{ - debugShowSurfaceFlag(zoneVis, SurfaceAmbiguous, ColorF(0.0f, 1.0f, 0.0f)); -} - -void Interior::debugShowOrphan(const ZoneVisDeterminer& zoneVis) -{ - debugShowSurfaceFlag(zoneVis, SurfaceOrphan, ColorF(0.0f, 0.0f, 1.0f)); -} - -void Interior::debugShowOutsideVisible(const ZoneVisDeterminer& zoneVis) -{ - debugShowSurfaceFlag(zoneVis, SurfaceOutsideVisible, ColorF(1.0f, 0.0f, 0.0f)); -} - -void Interior::debugShowPortalZones(const ZoneVisDeterminer& zoneVis) -{ - preDebugRender(); - - for (U32 i = 0; i < mZones.size(); i++) - { - U8* color; - if (i == 0) - color = interiorDebugColors[0]; - else - color = interiorDebugColors[(i % 13) + 1]; - - for (U32 j = mZones[i].surfaceStart; j < mZones[i].surfaceStart + mZones[i].surfaceCount; j++) - { - Surface& rSurface = mSurfaces[mZoneSurfaces[j]]; - ColorF c((F32) color[0] / 255.0f, (F32) color[1] / 255.0f, (F32) color[2] / 255.0f); - - mDebugShaderConsts->setSafe(mDebugShaderShadeColorSC, c); - - GFX->setShaderConstBuffer(mDebugShaderConsts); - - GFXPrimitive* info = &rSurface.surfaceInfo; - GFX->drawIndexedPrimitive( info->type, info->startVertex, info->minIndex, info->numVertices, info->startIndex, info->numPrimitives ); - } - } - - GFX->disableShaders(); - debugRenderPortals(); - debugNormalRenderLines(zoneVis); -} - -// Render portals -void Interior::debugRenderPortals() -{ - // Set our portal rendering state block - GFX->setStateBlock(mInteriorDebugPortalSB); - - for (U32 i = 0; i < mPortals.size(); i++) - { - const Portal& rPortal = mPortals[i]; - - for (U16 j = 0; j < rPortal.triFanCount; j++) - { - const TriFan& rFan = mWindingIndices[rPortal.triFanStart + j]; - U32 k; - - PrimBuild::color4f(0.75f, 0.5f, 0.75f, 0.45f); - PrimBuild::begin(GFXTriangleFan, rFan.windingCount); - - for (k = 0; k < rFan.windingCount; k++) - PrimBuild::vertex3fv(mPoints[mWindings[rFan.windingStart + k]].point); - - PrimBuild::end(); - - PrimBuild::color4f(0, 0, 1, 1); - PrimBuild::begin(GFXLineStrip, rFan.windingCount+1); - - for (k = 0; k < rFan.windingCount; k++) - PrimBuild::vertex3fv(mPoints[mWindings[rFan.windingStart + k]].point); - - PrimBuild::vertex3fv(mPoints[mWindings[rFan.windingStart]].point); - - PrimBuild::end(); - } - } -} - -void Interior::debugShowCollisionFans(const ZoneVisDeterminer& zoneVis) -{ - // Set our "base debug states" (no texture) - GFX->setStateBlock(mInteriorDebugNoneSB); - - for (U32 i = 0; i < mZones.size(); i++) - { - if (zoneVis.isZoneVisible(i) == false) - continue; - - for( U32 j=0; j 0) - PrimBuild::vertex3fv(mPoints[fanIndices[0]].point); - PrimBuild::end(); - - // Normal - PrimBuild::color3f(1, 0, 0); - PrimBuild::begin(GFXLineList, numIndices * 2); - for (U32 j = 0; j < numIndices; j++) - { - Point3F up = mPoints[fanIndices[j]].point; - Point3F norm = getPlane(rSurface.planeIndex); - if (planeIsFlipped(rSurface.planeIndex)) - up -= norm * 0.4f; - else - up += norm * 0.4f; - - PrimBuild::vertex3fv(mPoints[fanIndices[j]].point); - PrimBuild::vertex3fv(up); - } - PrimBuild::end(); - } - } -} - -// This doesn't show strip (they don't go to the card that way) -// But it does show the batches of primitives we send. -void Interior::debugShowStrips(const ZoneVisDeterminer& zoneVis) -{ - // Set up our rendering states. - preDebugRender(); - - for (U32 i = 0; i < mZones.size(); i++) - { - if (zoneVis.isZoneVisible(i) == false) - continue; - - for( U32 j=0; jsetSafe(mDebugShaderShadeColorSC, col); - - GFX->setShaderConstBuffer(mDebugShaderConsts); - - GFX->drawPrimitive(node.primInfoIndex); - } - } - - GFX->disableShaders(); - debugNormalRenderLines(zoneVis); -} - -void Interior::debugShowDetailLevel(const ZoneVisDeterminer& zoneVis) -{ - // Set up our rendering states. - preDebugRender(); - - U32 index = getDetailLevel(); - ColorF col((F32)interiorDebugColors[index][0] / 255.0f, (F32)interiorDebugColors[index][1] / 255.0f, - (F32)interiorDebugColors[index][2] / 255.0f); - - mDebugShaderConsts->setSafe(mDebugShaderShadeColorSC, col); - - GFX->setShaderConstBuffer(mDebugShaderConsts); - - for (U32 i = 0; i < mZones.size(); i++) - { - if (zoneVis.isZoneVisible(i) == false) - continue; - - for( U32 j=0; jdrawPrimitive(node.primInfoIndex); - } - } - - GFX->disableShaders(); - debugNormalRenderLines(zoneVis); -} - -void Interior::debugShowHullSurfaces() -{ - // Set our "base debug states" (no texture) - GFX->setStateBlock(mInteriorDebugNoneSB); - - for (U32 i = 0; i < mConvexHulls.size(); i++) - { - const ConvexHull& rHull = mConvexHulls[i]; - - for (U32 j = rHull.surfaceStart; j < rHull.surfaceCount + rHull.surfaceStart; j++) - { - U32 index = mHullSurfaceIndices[j]; - - if (!isNullSurfaceIndex(index)) - { - const Interior::Surface& rSurface = mSurfaces[index]; - U32 fanVerts[32]; - U32 numVerts; - collisionFanFromSurface(rSurface, fanVerts, &numVerts); - - PrimBuild::color3i(interiorDebugColors[(i%13)+1][0], interiorDebugColors[(i%13)+1][1], - interiorDebugColors[(i%13)+1][2]); - Point3F center(0, 0, 0); - PrimBuild::begin(GFXTriangleFan, numVerts); - for (U32 k = 0; k < numVerts; k++) - { - PrimBuild::vertex3fv(mPoints[fanVerts[k]].point); - center += mPoints[fanVerts[k]].point; - } - PrimBuild::end(); - center /= F32(numVerts); - PrimBuild::color3f(0, 0, 0); - lineLoopFromStrip(mPoints, mWindings, rSurface.windingStart, rSurface.windingCount); - - PlaneF plane; - plane.set(mPoints[fanVerts[0]].point, mPoints[fanVerts[1]].point, mPoints[fanVerts[2]].point); - PrimBuild::begin(GFXLineList, 2); - PrimBuild::vertex3fv(center); - PrimBuild::vertex3fv(center + (plane * 0.25)); - PrimBuild::end(); - } - } - } -} - -void Interior::debugDefaultRender(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst) -{ - // Set up a state block with two textures enabled - GFX->setStateBlock(mInteriorDebugTwoTextureSB); - - for( U32 i=0; igetLMHandle(), node.lightMapIndex ); - - GFX->setTexture( 0, mMaterialList->getDiffuseTexture( curBaseTexIndex )); - GFX->setTexture(1, sgData.lightmap); - GFX->drawPrimitive( node.primInfoIndex ); - } - } -} - -void Interior::debugShowNullSurfaces(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst) -{ - debugDefaultRender(zoneVis, sgData, intInst); - - PrimBuild::color3f(1.0f, 0.0f, 0.0f); - for (U32 i = 0; i < mNullSurfaces.size(); i++) - { - const NullSurface& rSurface = mNullSurfaces[i]; - - PrimBuild::begin(GFXTriangleFan, rSurface.windingCount); - for (U32 k = 0; k < rSurface.windingCount; k++) - { - PrimBuild::vertex3fv(mPoints[mWindings[rSurface.windingStart+k]].point); - } - PrimBuild::end(); - } -} - -void Interior::debugShowVehicleHullSurfaces(const ZoneVisDeterminer& zoneVis, SceneData &sgData, - InteriorInstance *intInst) -{ - debugDefaultRender(zoneVis, sgData, intInst); - - PrimBuild::color3f(1.0f, 0.0f, 0.0f); - for (U32 i = 0; i < mVehicleNullSurfaces.size(); i++) - { - const NullSurface& rSurface = mNullSurfaces[i]; - PrimBuild::begin(GFXTriangleFan, rSurface.windingCount); - for (U32 k = 0; k < rSurface.windingCount; k++) - { - PrimBuild::vertex3fv(mPoints[mWindings[rSurface.windingStart+k]].point); - } - } -} - -void Interior::debugShowTexturesOnly(const ZoneVisDeterminer& zoneVis, SceneData &sgData, - InteriorInstance *intInst) -{ - // Set up a state block with one texture unit enabled - GFX->setStateBlock(mInteriorDebugTextureSB); - - for( U32 i=0; isetTexture( 0, mMaterialList->getDiffuseTexture( curBaseTexIndex )); - GFX->drawPrimitive( node.primInfoIndex ); - } - } -} - -void Interior::debugShowLargeTextures(const ZoneVisDeterminer& zoneVis, SceneData &sgData, - InteriorInstance *intInst) -{ - preDebugRender(); - - for( U32 i=0; igetDiffuseTexture( curBaseTexIndex ); - ColorF texSizeColor(1.0f, 1.0f, 1.0f, 1.0f); - if (t) - { - U32 width = t.getWidth(); - U32 height = t.getHeight(); - - if (width <= 256 && height <= 256) - texSizeColor = ColorF(0.25f, 0.25f, 1.0f); // small texture - else if (width <= 512 && height <= 512) - texSizeColor = ColorF(0.25f, 1.0f, 0.25f); // medium texture - else - texSizeColor = ColorF(1.0f, 0.25f, 0.25f); // large texture - } - - mDebugShaderConsts->setSafe(mDebugShaderShadeColorSC, texSizeColor); - - GFX->setShaderConstBuffer(mDebugShaderConsts); - - GFX->setTexture( 0, t); - GFX->drawPrimitive( node.primInfoIndex ); - } - } -} - -void Interior::debugShowLightmaps(const ZoneVisDeterminer& zoneVis, SceneData &sgData, InteriorInstance *intInst) -{ - GFX->setTexture(0, mDebugTexture); - - // Set up a state block with two textures enabled - GFX->setStateBlock(mInteriorDebugTwoTextureSB); - - for( U32 i=0; igetLMHandle(), node.lightMapIndex ); - - GFX->setTexture(1, sgData.lightmap); - GFX->drawPrimitive( node.primInfoIndex ); - } - } -} - -#endif diff --git a/Engine/source/interior/interiorIO.cpp b/Engine/source/interior/interiorIO.cpp deleted file mode 100644 index 323951cba..000000000 --- a/Engine/source/interior/interiorIO.cpp +++ /dev/null @@ -1,1669 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "interior/interior.h" -#include "core/bitVector.h" -#include "core/stream/stream.h" -#include "math/mathIO.h" -#include "gfx/bitmap/gBitmap.h" -#include "interior/interiorSubObject.h" -#include "console/console.h" -#include "core/frameAllocator.h" -#include "materials/materialList.h" - -int QSORT_CALLBACK cmpU32(const void* p1, const void* p2) -{ - return S32(*((U32*)p1)) - S32(*((U32*)p2)); -} - -//------------------------------------------------------------------------------ -//-------------------------------------- PERSISTENCE IMPLEMENTATION -// -U32 Interior::smFileVersion = 14; - -bool Interior::read(Stream& stream) -{ - AssertFatal(stream.hasCapability(Stream::StreamRead), "Interior::read: non-read capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::read: Error, stream in inconsistent state"); - - S32 i; - - // Version this stream. We only load stream of the current version - U32 fileVersion; - stream.read(&fileVersion); - - // We need to store the version in case there is any post processing that - // needs to take place that is dependent on the file version - mFileVersion = fileVersion; - - if (fileVersion > smFileVersion) - { - Con::errorf(ConsoleLogEntry::General, "Interior::read: incompatible file version found."); - return false; - } - - // Geometry factors... - stream.read(&mDetailLevel); - - stream.read(&mMinPixels); - mathRead(stream, &mBoundingBox); - mathRead(stream, &mBoundingSphere); - stream.read(&mHasAlarmState); - stream.read(&mNumLightStateEntries); - - // Now read in our data vectors. - S32 vectorSize; - - // mPlanes - readPlaneVector(stream); - - // mPoints - stream.read(&vectorSize); - mPoints.setSize(vectorSize); - for (i = 0; i < mPoints.size(); i++) - mathRead(stream, &mPoints[i].point); - - // mPointVisibility - stream.read(&vectorSize); - mPointVisibility.setSize(vectorSize); - stream.read(vectorSize, mPointVisibility.address()); - - // mTexGenEQs - stream.read(&vectorSize); - mTexGenEQs.setSize(vectorSize); - for(i = 0; i < mTexGenEQs.size(); i++) - { - mathRead(stream, &mTexGenEQs[i].planeX); - mathRead(stream, &mTexGenEQs[i].planeY); - } - - // mBSPNodes; - stream.read(&vectorSize); - mBSPNodes.setSize(vectorSize); - for(i = 0; i < mBSPNodes.size(); i++) - { - stream.read(&mBSPNodes[i].planeIndex); - - if (fileVersion >= 14) - { - stream.read(&mBSPNodes[i].frontIndex); - stream.read(&mBSPNodes[i].backIndex); - } - else - { - U16 frontIndex, backIndex; - stream.read(&frontIndex); - stream.read(&backIndex); - - mBSPNodes[i].frontIndex = U32(frontIndex); - mBSPNodes[i].backIndex = U32(backIndex); - } - } - - // mBSPSolidLeaves - stream.read(&vectorSize); - mBSPSolidLeaves.setSize(vectorSize); - for(i = 0; i < mBSPSolidLeaves.size(); i++) - { - stream.read(&mBSPSolidLeaves[i].surfaceIndex); - stream.read(&mBSPSolidLeaves[i].surfaceCount); - } - - // MaterialList - if(mMaterialList != NULL) - delete mMaterialList; - mMaterialList = new MaterialList; - mMaterialList->read(stream); - - - // mWindings - stream.read(&vectorSize); - mWindings.setSize(vectorSize); - for(i = 0; i < mWindings.size(); i++) - { - stream.read(&mWindings[i]); - } - - // mWindingIndices - stream.read(&vectorSize); - mWindingIndices.setSize(vectorSize); - for(i = 0; i < mWindingIndices.size(); i++) - { - stream.read(&mWindingIndices[i].windingStart); - stream.read(&mWindingIndices[i].windingCount); - } - - // mEdges - if (fileVersion >= 12) - { - stream.read(&vectorSize); - - mEdges.setSize(vectorSize); - for (i = 0; i < mEdges.size(); i++) - { - stream.read(&mEdges[i].vertexes[0]); - stream.read(&mEdges[i].vertexes[1]); - stream.read(&mEdges[i].faces[0]); - stream.read(&mEdges[i].faces[1]); - } - } - - // mZones - stream.read(&vectorSize); - mZones.setSize(vectorSize); - for(i = 0; i < mZones.size(); i++) - { - stream.read(&mZones[i].portalStart); - stream.read(&mZones[i].portalCount); - stream.read(&mZones[i].surfaceStart); - stream.read(&mZones[i].surfaceCount); - - if (fileVersion >= 12) - { - stream.read(&mZones[i].staticMeshStart); - stream.read(&mZones[i].staticMeshCount); - } - else - { - mZones[i].staticMeshStart = 0; - mZones[i].staticMeshCount = 0; - } - - stream.read(&mZones[i].flags); - mZones[i].zoneId = 0; - } - - // Zone surfaces - stream.read(&vectorSize); - mZoneSurfaces.setSize(vectorSize); - for(i = 0; i < mZoneSurfaces.size(); i++) - stream.read(&mZoneSurfaces[i]); - - // Zone static meshes - if (fileVersion >= 12) - { - stream.read(&vectorSize); - - mZoneStaticMeshes.setSize(vectorSize); - for (i = 0; i < mZoneStaticMeshes.size(); i++) - stream.read(&mZoneStaticMeshes[i]); - } - - // mZonePortalList; - stream.read(&vectorSize); - mZonePortalList.setSize(vectorSize); - for(i = 0; i < mZonePortalList.size(); i++) - stream.read(&mZonePortalList[i]); - - // mPortals - stream.read(&vectorSize); - mPortals.setSize(vectorSize); - for(i = 0; i < mPortals.size(); i++) - { - stream.read(&mPortals[i].planeIndex); - stream.read(&mPortals[i].triFanCount); - stream.read(&mPortals[i].triFanStart); - stream.read(&mPortals[i].zoneFront); - stream.read(&mPortals[i].zoneBack); - } - - // mSurfaces - stream.read(&vectorSize); - mSurfaces.setSize(vectorSize); - mLMTexGenEQs.setSize(vectorSize); - - // Couple of hoops to *attempt* to detect that we are loading - // a TGE version 0 Interior and not a TGEA verison 0 - U32 surfacePos = stream.getPosition(); - bool tgeInterior = false; - - // First attempt to read this as though it isn't a TGE version 0 Interior - for(i = 0; i < mSurfaces.size(); i++) - { - // If we end up reading any invalid data in this loop then odds - // are that we are no longer correctly reading from the stream - // and have gotten off because this is a TGE version 0 Interior - - Surface& surface = mSurfaces[i]; - - if (readSurface(stream, surface, mLMTexGenEQs[i], false) == false) - { - tgeInterior = true; - break; - } - } - - // If this is a version 0 Interior and we failed to read it as a - // TGEA version 0 Interior then attempt to read it as a TGE version 0 - if (fileVersion == 0 && tgeInterior) - { - // Set our stream position back to the start of the surfaces - stream.setPosition(surfacePos); - - // Try reading in the surfaces again - for(i = 0; i < mSurfaces.size(); i++) - { - Surface& surface = mSurfaces[i]; - - // If we fail on any of the surfaces then bail - if (readSurface(stream, surface, mLMTexGenEQs[i], true) == false) - return false; - } - } - // If we failed to read but this isn't a version 0 Interior - // then something has gone horribly wrong - else if (fileVersion != 0 && tgeInterior) - return false; - - // Edges - if (fileVersion == 5) - { - stream.read(&vectorSize); - mEdges.setSize(vectorSize); - for (i = 0; i < mEdges.size(); i++) - { - stream.read(&mEdges[i].vertexes[0]); - stream.read(&mEdges[i].vertexes[1]); - U32 normals[2]; - stream.read(&normals[0]); - stream.read(&normals[1]); - - if (fileVersion > 2) // version 3 is where surface id's get added - { - stream.read(&mEdges[i].faces[0]); - stream.read(&mEdges[i].faces[1]); - } - } - } - - // mNormals - if (fileVersion == 5) - { - stream.read(&vectorSize); - Vector normals; - normals.setSize(vectorSize); - for(i = 0; i < normals.size(); i++) - mathRead(stream, &normals[i]); - - // mNormalIndices - stream.read(&vectorSize); - Vector normalIndices; - normalIndices.setSize(vectorSize); - for (i = 0; i < normalIndices.size(); i++) - stream.read(&normalIndices[i]); - } - - // NormalLMapIndices - stream.read(&vectorSize); - mNormalLMapIndices.setSize(vectorSize); - for (U32 i = 0; i < mNormalLMapIndices.size(); i++) - { - if (fileVersion >= 13) - stream.read(&mNormalLMapIndices[i]); - else - { - U8 index = 0; - stream.read(&index); - - mNormalLMapIndices[i] = (U32)index; - } - } - - // AlarmLMapIndices - stream.read(&vectorSize); - mAlarmLMapIndices.setSize(vectorSize); - for (U32 i = 0; i < mAlarmLMapIndices.size(); i++) - { - if (fileVersion >= 13) - stream.read(&mAlarmLMapIndices[i]); - else - { - U8 index = 0; - stream.read(&index); - - mAlarmLMapIndices[i] = (U32)index; - } - } - - // mNullSurfaces - stream.read(&vectorSize); - mNullSurfaces.setSize(vectorSize); - for(i = 0; i < mNullSurfaces.size(); i++) - { - stream.read(&mNullSurfaces[i].windingStart); - stream.read(&mNullSurfaces[i].planeIndex); - stream.read(&mNullSurfaces[i].surfaceFlags); - - if (fileVersion >= 13) - stream.read(&mNullSurfaces[i].windingCount); - else - { - U8 count; - stream.read(&count); - mNullSurfaces[i].windingCount = (U32)count; - } - } - - // mLightmaps - stream.read(&vectorSize); - mLightmaps.setSize(vectorSize); - mLightmapKeep.setSize(vectorSize); - GBitmap dummyBmp; - for(i = 0; i < mLightmaps.size(); i++) - { - mLightmaps[i] = new GBitmap; - mLightmaps[i]->readBitmap("png",stream); - - if (!tgeInterior && (fileVersion == 0 || fileVersion == 5 || fileVersion >= 12)) - { - // The "light normal maps" or "light direction maps" were - // removed from Torque 3D... this just reads and throws - // them away. - dummyBmp.readBitmap("png",stream); - } - - stream.read(&mLightmapKeep[i]); - } - - // mSolidLeafSurfaces - stream.read(&vectorSize); - mSolidLeafSurfaces.setSize(vectorSize); - for(i = 0; i < mSolidLeafSurfaces.size(); i++) - { - stream.read(&mSolidLeafSurfaces[i]); - } - - // mAnimatedLights - mNumTriggerableLights = 0; - stream.read(&vectorSize); - mAnimatedLights.setSize(vectorSize); - for(i = 0; i < mAnimatedLights.size(); i++) - { - stream.read(&mAnimatedLights[i].nameIndex); - stream.read(&mAnimatedLights[i].stateIndex); - stream.read(&mAnimatedLights[i].stateCount); - stream.read(&mAnimatedLights[i].flags); - stream.read(&mAnimatedLights[i].duration); - - if((mAnimatedLights[i].flags & AnimationAmbient) == 0) - mNumTriggerableLights++; - } - - // mLightStates - stream.read(&vectorSize); - mLightStates.setSize(vectorSize); - for(i = 0; i < mLightStates.size(); i++) - { - stream.read(&mLightStates[i].red); - stream.read(&mLightStates[i].green); - stream.read(&mLightStates[i].blue); - stream.read(&mLightStates[i].activeTime); - stream.read(&mLightStates[i].dataIndex); - stream.read(&mLightStates[i].dataCount); - } - - // mStateData - stream.read(&vectorSize); - mStateData.setSize(vectorSize); - for(i = 0; i < mStateData.size(); i++) - { - stream.read(&mStateData[i].surfaceIndex); - stream.read(&mStateData[i].mapIndex); - stream.read(&mStateData[i].lightStateIndex); - } - - // mStateDataBuffer - stream.read(&vectorSize); - mStateDataBuffer.setSize(vectorSize); - U32 flags; - stream.read(&flags); - stream.read(mStateDataBuffer.size(), mStateDataBuffer.address()); - - // mNameBuffer - stream.read(&vectorSize); - mNameBuffer.setSize(vectorSize); - stream.read(mNameBuffer.size(), mNameBuffer.address()); - - // mSubObjects - stream.read(&vectorSize); - mSubObjects.setSize(vectorSize); - for (i = 0; i < mSubObjects.size(); i++) - { - InteriorSubObject* iso = InteriorSubObject::readISO(stream); - AssertFatal(iso != NULL, "Error, bad sub object in stream!"); - mSubObjects[i] = iso; - } - - // Convex hulls - stream.read(&vectorSize); - mConvexHulls.setSize(vectorSize); - for(i = 0; i < mConvexHulls.size(); i++) - { - stream.read(&mConvexHulls[i].hullStart); - stream.read(&mConvexHulls[i].hullCount); - stream.read(&mConvexHulls[i].minX); - stream.read(&mConvexHulls[i].maxX); - stream.read(&mConvexHulls[i].minY); - stream.read(&mConvexHulls[i].maxY); - stream.read(&mConvexHulls[i].minZ); - stream.read(&mConvexHulls[i].maxZ); - stream.read(&mConvexHulls[i].surfaceStart); - stream.read(&mConvexHulls[i].surfaceCount); - stream.read(&mConvexHulls[i].planeStart); - stream.read(&mConvexHulls[i].polyListPlaneStart); - stream.read(&mConvexHulls[i].polyListPointStart); - stream.read(&mConvexHulls[i].polyListStringStart); - - if (fileVersion >= 12) - stream.read(&mConvexHulls[i].staticMesh); - else - mConvexHulls[i].staticMesh = false; - } - - // Convex hull emit strings - stream.read(&vectorSize); - mConvexHullEmitStrings.setSize(vectorSize); - stream.read(mConvexHullEmitStrings.size(), mConvexHullEmitStrings.address()); - - // Hull indices - stream.read(&vectorSize); - mHullIndices.setSize(vectorSize); - for(i = 0; i < mHullIndices.size(); i++) - stream.read(&mHullIndices[i]); - - // Hull plane indices - stream.read(&vectorSize); - mHullPlaneIndices.setSize(vectorSize); - for(i = 0; i < mHullPlaneIndices.size(); i++) - stream.read(&mHullPlaneIndices[i]); - - // Hull emit string indices - stream.read(&vectorSize); - mHullEmitStringIndices.setSize(vectorSize); - for(i = 0; i < mHullEmitStringIndices.size(); i++) - stream.read(&mHullEmitStringIndices[i]); - - // Hull surface indices - stream.read(&vectorSize); - mHullSurfaceIndices.setSize(vectorSize); - for(i = 0; i < mHullSurfaceIndices.size(); i++) - stream.read(&mHullSurfaceIndices[i]); - - // PolyList planes - stream.read(&vectorSize); - mPolyListPlanes.setSize(vectorSize); - for(i = 0; i < mPolyListPlanes.size(); i++) - stream.read(&mPolyListPlanes[i]); - - // PolyList points - stream.read(&vectorSize); - mPolyListPoints.setSize(vectorSize); - for(i = 0; i < mPolyListPoints.size(); i++) - stream.read(&mPolyListPoints[i]); - - // PolyList strings - stream.read(&vectorSize); - mPolyListStrings.setSize(vectorSize); - for(i = 0; i < mPolyListStrings.size(); i++) - stream.read(&mPolyListStrings[i]); - - // Coord bins - for(i = 0; i < NumCoordBins * NumCoordBins; i++) - { - stream.read(&mCoordBins[i].binStart); - stream.read(&mCoordBins[i].binCount); - } - - // Coord bin indices - stream.read(&vectorSize); - mCoordBinIndices.setSize(vectorSize); - for(i = 0; i < mCoordBinIndices.size(); i++) - stream.read(&mCoordBinIndices[i]); - - // Coord bin mode - stream.read(&mCoordBinMode); - - // Ambient colors - stream.read(&mBaseAmbient); - stream.read(&mAlarmAmbient); - - if (fileVersion >= 10) - { - // Static meshes - stream.read(&vectorSize); - - mStaticMeshes.setSize(vectorSize); - for (i = 0; i < mStaticMeshes.size(); i++) - { - mStaticMeshes[i] = new InteriorSimpleMesh; - mStaticMeshes[i]->read(stream); - } - } - - if (fileVersion >= 11) - { - // Normals - stream.read(&vectorSize); - - mNormals.setSize(vectorSize); - for (i = 0; i < mNormals.size(); i++) - mathRead(stream, &mNormals[i]); - - // TexMatrices - stream.read(&vectorSize); - - mTexMatrices.setSize(vectorSize); - for (i = 0; i < mTexMatrices.size(); i++) - { - stream.read(&mTexMatrices[i].T); - stream.read(&mTexMatrices[i].N); - stream.read(&mTexMatrices[i].B); - } - - // TexMatIndices - stream.read(&vectorSize); - - mTexMatIndices.setSize(vectorSize); - for (i = 0; i < mTexMatIndices.size(); i++) - stream.read(&mTexMatIndices[i]); - } - - // For future expandability - U32 dummy; - if (fileVersion < 10) - { - stream.read(&dummy); if (dummy != 0) return false; - } - if (fileVersion < 11) - { - stream.read(&dummy); if (dummy != 0) return false; - stream.read(&dummy); if (dummy != 0) return false; - } - - // - // Support for interior light map border sizes. - // - U32 extendedlightmapdata; - stream.read(&extendedlightmapdata); - if(extendedlightmapdata == 1) - { - stream.read(&mLightMapBorderSize); - - //future expansion under current block (avoid using too - //many of the above expansion slots by allowing nested - //blocks)... - stream.read(&dummy); if (dummy != 0) return false; - } - - // Setup the zone planes - setupZonePlanes(); - truncateZoneTree(); - - buildSurfaceZones(); - - return (stream.getStatus() == Stream::Ok); -} - -bool Interior::write(Stream& stream) const -{ - AssertFatal(stream.hasCapability(Stream::StreamWrite), "Interior::write: non-write capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::write: Error, stream in inconsistent state"); - - U32 i; - - // Version this stream - stream.write(smFileVersion); - - stream.write(mDetailLevel); - stream.write(mMinPixels); - mathWrite(stream, mBoundingBox); - mathWrite(stream, mBoundingSphere); - - stream.write(mHasAlarmState); - stream.write(mNumLightStateEntries); - - // Now write out our data vectors. Remember, for cross-platform capability, no - // structure writing is allowed... - - // mPlanes - writePlaneVector(stream); - - // mPoints - stream.write(mPoints.size()); - for (i = 0; i < mPoints.size(); i++) - mathWrite(stream, mPoints[i].point); - - // mPointVisibility - stream.write(mPointVisibility.size()); - stream.write(mPointVisibility.size(), mPointVisibility.address()); - - // mTexGenEQs - stream.write(mTexGenEQs.size()); - for (i = 0; i < mTexGenEQs.size(); i++) - { - mathWrite(stream, mTexGenEQs[i].planeX); - mathWrite(stream, mTexGenEQs[i].planeY); - } - - // mBSPNodes; - stream.write(mBSPNodes.size()); - for (i = 0; i < mBSPNodes.size(); i++) - { - stream.write(mBSPNodes[i].planeIndex); - - if (smFileVersion < 14) - { - stream.write(U16(mBSPNodes[i].frontIndex)); - stream.write(U16(mBSPNodes[i].backIndex)); - } - else - { - stream.write(mBSPNodes[i].frontIndex); - stream.write(mBSPNodes[i].backIndex); - } - } - - // mBSPSolidLeaves - stream.write(mBSPSolidLeaves.size()); - for (i = 0; i < mBSPSolidLeaves.size(); i++) - { - stream.write(mBSPSolidLeaves[i].surfaceIndex); - stream.write(mBSPSolidLeaves[i].surfaceCount); - } - - // MaterialList - mMaterialList->write(stream); - - // mWindings - stream.write(mWindings.size()); - for (i = 0; i < mWindings.size(); i++) - { - stream.write(mWindings[i]); - } - - // mWindingIndices - stream.write(mWindingIndices.size()); - for (i = 0; i < mWindingIndices.size(); i++) - { - stream.write(mWindingIndices[i].windingStart); - stream.write(mWindingIndices[i].windingCount); - } - - // mEdges - if (smFileVersion >= 12) - { - stream.write(mEdges.size()); - for (i = 0; i < mEdges.size(); i++) - { - stream.write(mEdges[i].vertexes[0]); - stream.write(mEdges[i].vertexes[1]); - stream.write(mEdges[i].faces[0]); - stream.write(mEdges[i].faces[1]); - } - } - - // mZones - stream.write(mZones.size()); - for (i = 0; i < mZones.size(); i++) - { - stream.write(mZones[i].portalStart); - stream.write(mZones[i].portalCount); - stream.write(mZones[i].surfaceStart); - stream.write(mZones[i].surfaceCount); - - if (smFileVersion >= 12) - { - stream.write(mZones[i].staticMeshStart); - stream.write(mZones[i].staticMeshCount); - } - - stream.write(mZones[i].flags); - } - - // Zone surfaces - stream.write(mZoneSurfaces.size()); - for (i = 0; i < mZoneSurfaces.size(); i++) - stream.write(mZoneSurfaces[i]); - - // Zone static meshes - if (smFileVersion >= 12) - { - stream.write(mZoneStaticMeshes.size()); - for (i = 0; i < mZoneStaticMeshes.size(); i++) - stream.write(mZoneStaticMeshes[i]); - } - - // mZonePortalList; - stream.write(mZonePortalList.size()); - for (i = 0; i < mZonePortalList.size(); i++) - stream.write(mZonePortalList[i]); - - // mPortals - stream.write(mPortals.size()); - for (i = 0; i < mPortals.size(); i++) - { - stream.write(mPortals[i].planeIndex); - stream.write(mPortals[i].triFanCount); - stream.write(mPortals[i].triFanStart); - stream.write(mPortals[i].zoneFront); - stream.write(mPortals[i].zoneBack); - } - - // mSurfaces - stream.write(mSurfaces.size()); - for (i = 0; i < mSurfaces.size(); i++) - { - stream.write(mSurfaces[i].windingStart); - - if (smFileVersion >= 13) - stream.write(mSurfaces[i].windingCount); - else - { - U8 count = (U8)mSurfaces[i].windingCount; - stream.write(count); - } - - stream.write(mSurfaces[i].planeIndex); - stream.write(mSurfaces[i].textureIndex); - stream.write(mSurfaces[i].texGenIndex); - stream.write(mSurfaces[i].surfaceFlags); - stream.write(mSurfaces[i].fanMask); - writeLMapTexGen(stream, mLMTexGenEQs[i].planeX, mLMTexGenEQs[i].planeY); - - stream.write(mSurfaces[i].lightCount); - stream.write(mSurfaces[i].lightStateInfoStart); - - if (smFileVersion >= 13) - { - stream.write(mSurfaces[i].mapOffsetX); - stream.write(mSurfaces[i].mapOffsetY); - stream.write(mSurfaces[i].mapSizeX); - stream.write(mSurfaces[i].mapSizeY); - } - else - { - U8 offX, offY, sizeX, sizeY; - offX = (U8)mSurfaces[i].mapOffsetX; - offY = (U8)mSurfaces[i].mapOffsetY; - sizeX = (U8)mSurfaces[i].mapSizeX; - sizeY = (U8)mSurfaces[i].mapSizeY; - - stream.write(offX); - stream.write(offY); - stream.write(sizeX); - stream.write(sizeY); - } - - if (smFileVersion == 0 || smFileVersion >= 12) - stream.write(mSurfaces[i].unused); - } - // NormalLMapIndices - stream.write(mNormalLMapIndices.size()); - for (U32 i = 0; i < mNormalLMapIndices.size(); i++) - { - if (smFileVersion >= 13) - stream.write(mNormalLMapIndices[i]); - else - { - U8 index = (U8)mNormalLMapIndices[i]; - stream.write(index); - } - } - - // AlarmLMapIndices - stream.write(mAlarmLMapIndices.size()); - for (U32 i = 0; i < mAlarmLMapIndices.size(); i++) - { - if (smFileVersion >= 13) - stream.write(mAlarmLMapIndices[i]); - else - { - U8 index = (U8)mAlarmLMapIndices[i]; - stream.write(index); - } - } - - - // mNullSurfaces - stream.write(mNullSurfaces.size()); - for(i = 0; i < mNullSurfaces.size(); i++) - { - stream.write(mNullSurfaces[i].windingStart); - stream.write(mNullSurfaces[i].planeIndex); - stream.write(mNullSurfaces[i].surfaceFlags); - - if (smFileVersion >= 13) - stream.write(mNullSurfaces[i].windingCount); - else - { - U8 count = (U8)mNullSurfaces[i].windingCount; - stream.write(count); - } - } - - // mLightmaps - stream.write(mLightmaps.size()); - for(i = 0; i < mLightmaps.size(); i++) - { - mLightmaps[i]->writeBitmap("png",stream); - - if (smFileVersion == 0 || smFileVersion >= 12) - { - // The "light normal maps" or "light direction maps" were - // removed from Torque 3D... this just writes a dummy 2x2 - // texture so that the read/write functions don't change. - GBitmap dummyBmp( 2, 2 ); - dummyBmp.writeBitmap("png",stream); - } - - stream.write(mLightmapKeep[i]); - } - - // mSolidLeafSurfaces - stream.write(mSolidLeafSurfaces.size()); - for(i = 0; i < mSolidLeafSurfaces.size(); i++) - { - stream.write(mSolidLeafSurfaces[i]); - } - - - // Animated lights - stream.write(mAnimatedLights.size()); - for(i = 0; i < mAnimatedLights.size(); i++) - { - stream.write(mAnimatedLights[i].nameIndex); - stream.write(mAnimatedLights[i].stateIndex); - stream.write(mAnimatedLights[i].stateCount); - stream.write(mAnimatedLights[i].flags); - stream.write(mAnimatedLights[i].duration); - } - - stream.write(mLightStates.size()); - for(i = 0; i < mLightStates.size(); i++) - { - stream.write(mLightStates[i].red); - stream.write(mLightStates[i].green); - stream.write(mLightStates[i].blue); - stream.write(mLightStates[i].activeTime); - stream.write(mLightStates[i].dataIndex); - stream.write(mLightStates[i].dataCount); - } - - // mStateData - stream.write(mStateData.size()); - for(i = 0; i < mStateData.size(); i++) - { - stream.write(mStateData[i].surfaceIndex); - stream.write(mStateData[i].mapIndex); - stream.write(mStateData[i].lightStateIndex); - } - - // mStateDataBuffer: Note: superfluous 0 is for flags in future versions. - // that may add compression. This way, we can maintain - // compatability with previous versions. - stream.write(mStateDataBuffer.size()); - stream.write(U32(0)); - stream.write(mStateDataBuffer.size(), mStateDataBuffer.address()); - - // mNameBuffer - stream.write(mNameBuffer.size()); - stream.write(mNameBuffer.size(), mNameBuffer.address()); - - // mSubObjects - stream.write(mSubObjects.size()); - for (i = 0; i < mSubObjects.size(); i++) - { - bool writeSuccess = mSubObjects[i]->writeISO(stream); - AssertFatal(writeSuccess == true, "Error writing sub object to stream!"); - } - - // Convex hulls - stream.write(mConvexHulls.size()); - for(i = 0; i < mConvexHulls.size(); i++) - { - stream.write(mConvexHulls[i].hullStart); - stream.write(mConvexHulls[i].hullCount); - stream.write(mConvexHulls[i].minX); - stream.write(mConvexHulls[i].maxX); - stream.write(mConvexHulls[i].minY); - stream.write(mConvexHulls[i].maxY); - stream.write(mConvexHulls[i].minZ); - stream.write(mConvexHulls[i].maxZ); - stream.write(mConvexHulls[i].surfaceStart); - stream.write(mConvexHulls[i].surfaceCount); - stream.write(mConvexHulls[i].planeStart); - stream.write(mConvexHulls[i].polyListPlaneStart); - stream.write(mConvexHulls[i].polyListPointStart); - stream.write(mConvexHulls[i].polyListStringStart); - - if (smFileVersion >= 12) - stream.write(mConvexHulls[i].staticMesh); - } - - stream.write(mConvexHullEmitStrings.size()); - stream.write(mConvexHullEmitStrings.size(), mConvexHullEmitStrings.address()); - - stream.write(mHullIndices.size()); - for(i = 0; i < mHullIndices.size(); i++) - stream.write(mHullIndices[i]); - - stream.write(mHullPlaneIndices.size()); - for(i = 0; i < mHullPlaneIndices.size(); i++) - stream.write(mHullPlaneIndices[i]); - - stream.write(mHullEmitStringIndices.size()); - for(i = 0; i < mHullEmitStringIndices.size(); i++) - stream.write(mHullEmitStringIndices[i]); - - stream.write(mHullSurfaceIndices.size()); - for(i = 0; i < mHullSurfaceIndices.size(); i++) - stream.write(mHullSurfaceIndices[i]); - - stream.write(mPolyListPlanes.size()); - for(i = 0; i < mPolyListPlanes.size(); i++) - stream.write(mPolyListPlanes[i]); - - stream.write(mPolyListPoints.size()); - for(i = 0; i < mPolyListPoints.size(); i++) - stream.write(mPolyListPoints[i]); - - stream.write(mPolyListStrings.size()); - for(i = 0; i < mPolyListStrings.size(); i++) - stream.write(mPolyListStrings[i]); - - // Coord bins - for(i = 0; i < NumCoordBins * NumCoordBins; i++) - { - stream.write(mCoordBins[i].binStart); - stream.write(mCoordBins[i].binCount); - } - stream.write(mCoordBinIndices.size()); - for(i = 0; i < mCoordBinIndices.size(); i++) - stream.write(mCoordBinIndices[i]); - stream.write(mCoordBinMode); - - // Ambient colors... - stream.write(mBaseAmbient); - stream.write(mAlarmAmbient); - - if (smFileVersion >= 10) - { - // Static meshes - stream.write(mStaticMeshes.size()); - for (i = 0; i < mStaticMeshes.size(); i++) - mStaticMeshes[i]->write(stream); - } - else - stream.write(U32(0)); - - if (smFileVersion >= 11) - { - // Normals - stream.write(mNormals.size()); - for (i = 0; i < mNormals.size(); i++) - mathWrite(stream, mNormals[i]); - - // TexMatrices - stream.write(mTexMatrices.size()); - for (i = 0; i < mTexMatrices.size(); i++) - { - stream.write(mTexMatrices[i].T); - stream.write(mTexMatrices[i].N); - stream.write(mTexMatrices[i].B); - } - - // TexMatIndices - stream.write(mTexMatIndices.size()); - for (i = 0; i < mTexMatIndices.size(); i++) - stream.write(mTexMatIndices[i]); - } - else - { - stream.write(U32(0)); - stream.write(U32(0)); - } - - // - // Support for interior light map border sizes. - // - if(mLightMapBorderSize > 0) - { - stream.write(U32(1));//flag new block... - stream.write(U32(mLightMapBorderSize));//new block data.. - - //future expansion under current block (avoid using too - //many of the above expansion slots by allowing nested - //blocks)... - stream.write(U32(0)); - } - else - { - stream.write(U32(0)); - } - - return stream.getStatus() == Stream::Ok; -} - -bool Interior::readVehicleCollision(Stream& stream) -{ - AssertFatal(stream.hasCapability(Stream::StreamRead), "Interior::read: non-read capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::read: Error, stream in inconsistent state"); - - S32 i; - - // Version this stream. We only load stream of the current version - U32 fileVersion; - stream.read(&fileVersion); - if (fileVersion > smFileVersion) - { - Con::errorf(ConsoleLogEntry::General, "Interior::read: incompatible file version found."); - return false; - } - - U32 vectorSize; - - // Convex hulls - stream.read(&vectorSize); - mVehicleConvexHulls.setSize(vectorSize); - for(i = 0; i < mVehicleConvexHulls.size(); i++) - { - stream.read(&mVehicleConvexHulls[i].hullStart); - stream.read(&mVehicleConvexHulls[i].hullCount); - stream.read(&mVehicleConvexHulls[i].minX); - stream.read(&mVehicleConvexHulls[i].maxX); - stream.read(&mVehicleConvexHulls[i].minY); - stream.read(&mVehicleConvexHulls[i].maxY); - stream.read(&mVehicleConvexHulls[i].minZ); - stream.read(&mVehicleConvexHulls[i].maxZ); - stream.read(&mVehicleConvexHulls[i].surfaceStart); - stream.read(&mVehicleConvexHulls[i].surfaceCount); - stream.read(&mVehicleConvexHulls[i].planeStart); - stream.read(&mVehicleConvexHulls[i].polyListPlaneStart); - stream.read(&mVehicleConvexHulls[i].polyListPointStart); - stream.read(&mVehicleConvexHulls[i].polyListStringStart); - } - - stream.read(&vectorSize); - mVehicleConvexHullEmitStrings.setSize(vectorSize); - stream.read(mVehicleConvexHullEmitStrings.size(), mVehicleConvexHullEmitStrings.address()); - - stream.read(&vectorSize); - mVehicleHullIndices.setSize(vectorSize); - for(i = 0; i < mVehicleHullIndices.size(); i++) - stream.read(&mVehicleHullIndices[i]); - - stream.read(&vectorSize); - mVehicleHullPlaneIndices.setSize(vectorSize); - for(i = 0; i < mVehicleHullPlaneIndices.size(); i++) - stream.read(&mVehicleHullPlaneIndices[i]); - - stream.read(&vectorSize); - mVehicleHullEmitStringIndices.setSize(vectorSize); - for(i = 0; i < mVehicleHullEmitStringIndices.size(); i++) - stream.read(&mVehicleHullEmitStringIndices[i]); - - stream.read(&vectorSize); - mVehicleHullSurfaceIndices.setSize(vectorSize); - for(i = 0; i < mVehicleHullSurfaceIndices.size(); i++) - stream.read(&mVehicleHullSurfaceIndices[i]); - - stream.read(&vectorSize); - mVehiclePolyListPlanes.setSize(vectorSize); - for(i = 0; i < mVehiclePolyListPlanes.size(); i++) - stream.read(&mVehiclePolyListPlanes[i]); - - stream.read(&vectorSize); - mVehiclePolyListPoints.setSize(vectorSize); - for(i = 0; i < mVehiclePolyListPoints.size(); i++) - stream.read(&mVehiclePolyListPoints[i]); - - stream.read(&vectorSize); - mVehiclePolyListStrings.setSize(vectorSize); - for(i = 0; i < mVehiclePolyListStrings.size(); i++) - stream.read(&mVehiclePolyListStrings[i]); - - stream.read(&vectorSize); - mVehicleNullSurfaces.setSize(vectorSize); - for(i = 0; i < mVehicleNullSurfaces.size(); i++) - { - stream.read(&mVehicleNullSurfaces[i].windingStart); - stream.read(&mVehicleNullSurfaces[i].planeIndex); - stream.read(&mVehicleNullSurfaces[i].surfaceFlags); - stream.read(&mVehicleNullSurfaces[i].windingCount); - } - - stream.read(&vectorSize); - mVehiclePoints.setSize(vectorSize); - for(i = 0; i < mVehiclePoints.size(); i++) - mathRead(stream, &mVehiclePoints[i].point); - - stream.read(&vectorSize); - mVehiclePlanes.setSize(vectorSize); - for(i = 0; i < mVehiclePlanes.size(); i++) - mathRead(stream, &mVehiclePlanes[i]); - - stream.read(&vectorSize); - mVehicleWindings.setSize(vectorSize); - for(i = 0; i < mVehicleWindings.size(); i++) - { - stream.read(&mVehicleWindings[i]); - } - - stream.read(&vectorSize); - mVehicleWindingIndices.setSize(vectorSize); - for(i = 0; i < mVehicleWindingIndices.size(); i++) - { - stream.read(&mVehicleWindingIndices[i].windingStart); - stream.read(&mVehicleWindingIndices[i].windingCount); - } - - return true; -} - -bool Interior::writeVehicleCollision(Stream& stream) const -{ - AssertFatal(stream.hasCapability(Stream::StreamWrite), "Interior::write: non-write capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::write: Error, stream in inconsistent state"); - - U32 i; - - // Version this stream - stream.write(smFileVersion); - - // Convex hulls - stream.write(mVehicleConvexHulls.size()); - for(i = 0; i < mVehicleConvexHulls.size(); i++) - { - stream.write(mVehicleConvexHulls[i].hullStart); - stream.write(mVehicleConvexHulls[i].hullCount); - stream.write(mVehicleConvexHulls[i].minX); - stream.write(mVehicleConvexHulls[i].maxX); - stream.write(mVehicleConvexHulls[i].minY); - stream.write(mVehicleConvexHulls[i].maxY); - stream.write(mVehicleConvexHulls[i].minZ); - stream.write(mVehicleConvexHulls[i].maxZ); - stream.write(mVehicleConvexHulls[i].surfaceStart); - stream.write(mVehicleConvexHulls[i].surfaceCount); - stream.write(mVehicleConvexHulls[i].planeStart); - stream.write(mVehicleConvexHulls[i].polyListPlaneStart); - stream.write(mVehicleConvexHulls[i].polyListPointStart); - stream.write(mVehicleConvexHulls[i].polyListStringStart); - } - - stream.write(mVehicleConvexHullEmitStrings.size()); - stream.write(mVehicleConvexHullEmitStrings.size(), mVehicleConvexHullEmitStrings.address()); - - stream.write(mVehicleHullIndices.size()); - for(i = 0; i < mVehicleHullIndices.size(); i++) - stream.write(mVehicleHullIndices[i]); - - stream.write(mVehicleHullPlaneIndices.size()); - for(i = 0; i < mVehicleHullPlaneIndices.size(); i++) - stream.write(mVehicleHullPlaneIndices[i]); - - stream.write(mVehicleHullEmitStringIndices.size()); - for(i = 0; i < mVehicleHullEmitStringIndices.size(); i++) - stream.write(mVehicleHullEmitStringIndices[i]); - - stream.write(mVehicleHullSurfaceIndices.size()); - for(i = 0; i < mVehicleHullSurfaceIndices.size(); i++) - stream.write(mVehicleHullSurfaceIndices[i]); - - stream.write(mVehiclePolyListPlanes.size()); - for(i = 0; i < mVehiclePolyListPlanes.size(); i++) - stream.write(mVehiclePolyListPlanes[i]); - - stream.write(mVehiclePolyListPoints.size()); - for(i = 0; i < mVehiclePolyListPoints.size(); i++) - stream.write(mVehiclePolyListPoints[i]); - - stream.write(mVehiclePolyListStrings.size()); - for(i = 0; i < mVehiclePolyListStrings.size(); i++) - stream.write(mVehiclePolyListStrings[i]); - - stream.write(mVehicleNullSurfaces.size()); - for(i = 0; i < mVehicleNullSurfaces.size(); i++) - { - stream.write(mVehicleNullSurfaces[i].windingStart); - stream.write(mVehicleNullSurfaces[i].planeIndex); - stream.write(mVehicleNullSurfaces[i].surfaceFlags); - stream.write(mVehicleNullSurfaces[i].windingCount); - } - - stream.write(mVehiclePoints.size()); - for(i = 0; i < mVehiclePoints.size(); i++) - mathWrite(stream, mVehiclePoints[i].point); - - stream.write(mVehiclePlanes.size()); - for(i = 0; i < mVehiclePlanes.size(); i++) - mathWrite(stream, mVehiclePlanes[i]); - - stream.write(mVehicleWindings.size()); - for(i = 0; i < mVehicleWindings.size(); i++) - stream.write(mVehicleWindings[i]); - - stream.write(mVehicleWindingIndices.size()); - for(i = 0; i < mVehicleWindingIndices.size(); i++) - { - stream.write(mVehicleWindingIndices[i].windingStart); - stream.write(mVehicleWindingIndices[i].windingCount); - } - - return true; -} - -bool Interior::readSurface(Stream& stream, Surface& surface, TexGenPlanes& texgens, const bool tgeInterior) -{ - // If we end up reading any invalid data then odds are that we - // are no longer correctly reading from the stream and have gotten - // off because this is a TGE version 0 Interior so we bail. - // That is why you will see checks all the way through - stream.read(&surface.windingStart); - - if (surface.windingStart >= mWindings.size()) - return false; - - if (mFileVersion >= 13) - stream.read(&surface.windingCount); - else - { - U8 count; - stream.read(&count); - surface.windingCount = (U32)count; - } - - if (surface.windingStart + surface.windingCount > mWindings.size()) - return false; - - stream.read(&surface.planeIndex); - - if (U32(surface.planeIndex & ~0x8000) >= mPlanes.size()) - return false; - - stream.read(&surface.textureIndex); - - if (surface.textureIndex >= mMaterialList->size()) - return false; - - stream.read(&surface.texGenIndex); - - if (surface.texGenIndex >= mTexGenEQs.size()) - return false; - - stream.read(&surface.surfaceFlags); - stream.read(&surface.fanMask); - - // If reading the lightmap texgen fails then most likely this is a - // TGE version 0 Interior (it gets offset by the "unused" read below - if (readLMapTexGen(stream, texgens.planeX, texgens.planeY) == false) - return false; - - stream.read(&surface.lightCount); - stream.read(&surface.lightStateInfoStart); - - if (mFileVersion >= 13) - { - stream.read(&surface.mapOffsetX); - stream.read(&surface.mapOffsetY); - stream.read(&surface.mapSizeX); - stream.read(&surface.mapSizeY); - } - else - { - U8 offX, offY, sizeX, sizeY; - stream.read(&offX); - stream.read(&offY); - stream.read(&sizeX); - stream.read(&sizeY); - - surface.mapOffsetX = (U32)offX; - surface.mapOffsetY = (U32)offY; - surface.mapSizeX = (U32)sizeX; - surface.mapSizeY = (U32)sizeY; - } - - if (!tgeInterior && (mFileVersion == 0 || mFileVersion == 5 || mFileVersion >= 12)) - stream.read(&surface.unused); - - if (mFileVersion == 5) - { - U32 brushId; - stream.read(&brushId); - } - - return true; -} - -bool Interior::readLMapTexGen(Stream& stream, PlaneF& planeX, PlaneF& planeY) -{ - F32 genX[4]; - F32 genY[4]; - - for(U32 i = 0; i < 4; i++) - { - genX[i] = 0.0f; - genY[i] = 0.0f; - } - - U16 finalWord; - stream.read(&finalWord); - stream.read(&genX[3]); - stream.read(&genY[3]); - - // Unpack the final word. - U32 logScaleY = (finalWord >> 0) & ((1 << 6) - 1); - U32 logScaleX = (finalWord >> 6) & ((1 << 6) - 1); - U16 stEnc = (finalWord >> 13) & 7; - - S32 sc, tc; - switch(stEnc) - { - case 0: sc = 0; tc = 1; break; - case 1: sc = 0; tc = 2; break; - case 2: sc = 1; tc = 0; break; - case 3: sc = 1; tc = 2; break; - case 4: sc = 2; tc = 0; break; - case 5: sc = 2; tc = 1; break; - - default: - sc = tc = -1; - // This is potentially an invalid st coord encoding however *most* times - // this is caused by attempting to load a TGE version 0 Interior - return false; - } - - U32 invScaleX = 1 << logScaleX; - U32 invScaleY = 1 << logScaleY; - - genX[sc] = F32(1.0 / F64(invScaleX)); - genY[tc] = F32(1.0 / F64(invScaleY)); - - planeX.x = genX[0]; - planeX.y = genX[1]; - planeX.z = genX[2]; - planeX.d = genX[3]; - planeY.x = genY[0]; - planeY.y = genY[1]; - planeY.z = genY[2]; - planeY.d = genY[3]; - - return stream.getStatus() == Stream::Ok; -} - -bool Interior::writeLMapTexGen(Stream& stream, const PlaneF& planeX, const PlaneF& planeY) const -{ - F32 genX[4], genY[4]; - - genX[0] = planeX.x; - genX[1] = planeX.y; - genX[2] = planeX.z; - genX[3] = planeX.d; - genY[0] = planeY.x; - genY[1] = planeY.y; - genY[2] = planeY.z; - genY[3] = planeY.d; - - // The tex gen for lmaps is a special case. - // there are only 4 parameters that matter, - // an inverse power of 2 in the x and y, and the - // fp offsets in x and y. We can encode the - // scales completely in U16 and we'll just write out - // the offsets. First, determine which coords we're - // writing... - // - S32 sc = -1; - S32 tc = -1; - if(genX[0] != 0.0) sc = 0; - else if(genX[1] != 0.0) sc = 1; - else if(genX[2] != 0.0) sc = 2; - - if(genY[0] != 0.0) tc = 0; - else if(genY[1] != 0.0) tc = 1; - else if(genY[2] != 0.0) tc = 2; - AssertFatal(sc != -1 && tc != -1 && sc != tc, "Hm, something wrong here."); - - U32 invScaleX = U32((1.0f / genX[sc]) + 0.5); - U32 invScaleY = U32((1.0f / genY[tc]) + 0.5); - AssertISV(invScaleX && isPow2(invScaleX) && invScaleY && isPow2(invScaleY), "Not a power of 2? Something wrong"); - - U32 logScaleX = getBinLog2(invScaleX); - U32 logScaleY = getBinLog2(invScaleY); - AssertFatal(logScaleX < 63 && logScaleY < 63, "Error, you've set the lightmap scale WAAYYY to high!"); - - // We need 3 bits to encode sc and tc, which leaves us 6 bits for logScaleX - // and logScaleY - S16 stEnc = -1; - if(sc == 0 && tc == 1) stEnc = 0; - else if(sc == 0 && tc == 2) stEnc = 1; - else if(sc == 1 && tc == 0) stEnc = 2; - else if(sc == 1 && tc == 2) stEnc = 3; - else if(sc == 2 && tc == 0) stEnc = 4; - else if(sc == 2 && tc == 1) stEnc = 5; - AssertFatal(stEnc != -1, avar("Hm. This should never happen. (%d, %d)", sc, tc)); - - U16 finalWord = U16(stEnc) << 13; - finalWord |= logScaleX << 6; - finalWord |= logScaleY << 0; - - stream.write(finalWord); - stream.write(genX[3]); - stream.write(genY[3]); - - return stream.getStatus() == Stream::Ok; -} - -bool Interior::writePlaneVector(Stream& stream) const -{ - // This is pretty slow, but who cares? - // - Vector uniqueNormals(mPlanes.size()); - Vector uniqueIndices(mPlanes.size()); - - U32 i; - - for(i = 0; i < mPlanes.size(); i++) - { - bool inserted = false; - for(U32 j = 0; j < uniqueNormals.size(); j++) - { - if(mPlanes[i] == uniqueNormals[j]) - { - // Hah! Already have this one... - uniqueIndices.push_back(j); - inserted = true; - break; - } - } - - if(inserted == false) - { - // Gotta do it ourselves... - uniqueIndices.push_back(uniqueNormals.size()); - uniqueNormals.push_back(Point3F(mPlanes[i].x, mPlanes[i].y, mPlanes[i].z)); - } - } - - // Ok, what we have now, is a list of unique normals, a set of indices into - // that vector, and the distances that we still have to write out by hand. - // Hop to it! - stream.write(uniqueNormals.size()); - for(i = 0; i < uniqueNormals.size(); i++) - mathWrite(stream, uniqueNormals[i]); - - stream.write(mPlanes.size()); - for(i = 0; i < mPlanes.size(); i++) - { - stream.write(uniqueIndices[i]); - stream.write(mPlanes[i].d); - } - - return(stream.getStatus() == Stream::Ok); -} - -bool Interior::readPlaneVector(Stream& stream) -{ - U32 vectorSize; - - stream.read(&vectorSize); - Point3F* normals = new Point3F[vectorSize]; - U32 i; - for(i = 0; i < vectorSize; i++) - mathRead(stream, &normals[i]); - - U16 index; - stream.read(&vectorSize); - mPlanes.setSize(vectorSize); - for(i = 0; i < mPlanes.size(); i++) - { - stream.read(&index); - stream.read(&mPlanes[i].d); - mPlanes[i].x = normals[index].x; - mPlanes[i].y = normals[index].y; - mPlanes[i].z = normals[index].z; - } - - delete [] normals; - - return(stream.getStatus() == Stream::Ok); -} - - -bool Interior::getUnifiedZone(const U32 index, S32* zone) -{ - if(isBSPLeafIndex(index)) - { - if(isBSPSolidLeaf(index)) - *zone = -1; - else - *zone = S32(getBSPEmptyLeafZone(index)); - return true; - } - else - { - S32 frontZone, backZone; - bool frontUnified = getUnifiedZone(mBSPNodes[index].frontIndex, &frontZone); - bool backUnified = getUnifiedZone(mBSPNodes[index].backIndex, &backZone); - if(frontUnified && backUnified) - { - if(frontZone == backZone) - { - *zone = frontZone; - return true; - } - else - { - if(frontZone == -1 || backZone == -1) - { - // DMMFIX: Once the interior file format is able to distinguish - // between structural and detail nodes in the runtime bsp, - // we can make this work a little better. - return false; - } - else - { - // Not equal, and neither is -1, no unified zone possible - return false; - } - } - } - else - { - return false; - } - } -} - -void Interior::truncateZoneNode(const U32 index) -{ - S32 unifiedZone; - bool unified = getUnifiedZone(index, &unifiedZone); - if(unified) - { - // Aha! - if(isBSPLeafIndex(index)) - return; - - if(unifiedZone == -1) - mBSPNodes[index].terminalZone = U16(0xFFFF); - else - mBSPNodes[index].terminalZone = U16(0x8000) | U16(unifiedZone); - } - else - { - // Sigh. - if(isBSPLeafIndex(mBSPNodes[index].frontIndex) == false) - truncateZoneNode(mBSPNodes[index].frontIndex); - if(isBSPLeafIndex(mBSPNodes[index].backIndex) == false) - truncateZoneNode(mBSPNodes[index].backIndex); - } -} - -void Interior::truncateZoneTree() -{ - for(U32 i = 0; i < mBSPNodes.size(); i++) - { - mBSPNodes[i].terminalZone = 0; - } - - if(mBSPNodes.size() > 0) - truncateZoneNode(0); -} - - -void Interior::setupZonePlanes() -{ - U16* temp = new U16[mPlanes.size() * mZones.size()]; - U32 tempSize = 0; - - for(U32 i = 0; i < mZones.size(); i++) - { - Zone& rZone = mZones[i]; - - BitVector usedPlanes; - usedPlanes.setSize(mPlanes.size()); - usedPlanes.clear(); - - U32 j; - for(j = 0; j < rZone.surfaceCount; j++) - { - Surface& rSurface = mSurfaces[mZoneSurfaces[rZone.surfaceStart + j]]; - usedPlanes.set(getPlaneIndex(rSurface.planeIndex)); - } - - rZone.planeStart = tempSize; - for(j = 0; j < mPlanes.size(); j++) - { - if(usedPlanes.test(j)) - { - AssertFatal(tempSize < mPlanes.size() * mZones.size(), "Error, out of bounds plane list!"); - temp[tempSize++] = j; - } - } - rZone.planeCount = tempSize - rZone.planeStart; - } - - mZonePlanes.setSize(tempSize); - for(U32 j = 0; j < tempSize; j++) - mZonePlanes[j] = temp[j]; - - delete [] temp; -} diff --git a/Engine/source/interior/interiorInstance.cpp b/Engine/source/interior/interiorInstance.cpp deleted file mode 100644 index 3bacfde4a..000000000 --- a/Engine/source/interior/interiorInstance.cpp +++ /dev/null @@ -1,1547 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "interior/interiorInstance.h" - -#include "interior/interior.h" -#include "console/consoleTypes.h" -#include "scene/sceneManager.h" -#include "scene/sceneRenderState.h" -#include "scene/zones/sceneTraversalState.h" -#include "scene/zones/sceneRootZone.h" -#include "core/stream/bitStream.h" -#include "core/stream/fileStream.h" -#include "gfx/bitmap/gBitmap.h" -#include "math/mathIO.h" -#include "gui/worldEditor/editor.h" -#include "interior/interiorResObjects.h" -#include "scene/simPath.h" -#include "interior/forceField.h" -#include "lighting/lightManager.h" -#include "collision/convex.h" -#include "sfx/sfxProfile.h" -#include "sfx/sfxEnvironment.h" -#include "core/frameAllocator.h" -#include "sim/netConnection.h" -#include "platform/profiler.h" -#include "gui/3d/guiTSControl.h" -#include "math/mathUtils.h" -#include "renderInstance/renderPassManager.h" -#include "core/resourceManager.h" -#include "materials/materialManager.h" -#include "materials/materialFeatureTypes.h" -#include "materials/matInstance.h" -#include "collision/concretePolyList.h" -#include "T3D/physics/physicsPlugin.h" -#include "T3D/physics/physicsBody.h" -#include "T3D/physics/physicsCollision.h" -#include "console/engineAPI.h" - -#ifdef TORQUE_COLLADA -#include "ts/collada/colladaUtils.h" -#endif - - -IMPLEMENT_CO_NETOBJECT_V1(InteriorInstance); - -ConsoleDocClass( InteriorInstance, - "@brief Object used to represent buildings and other architectural structures (legacy).\n\n" - - "Interiors are made up entirely from convex hulls or, as they are more commonly known as by game " - "artists, brushes. So what you see is what you collide against. There is no difference between the " - "visible meshes and the collision meshes.\n\n" - - "Unlike a DTS or COLLADA mesh, interiors do not support any animation. They also do not support " - "transparent textures. If you need animation or transparency then you are forced to use other model objects.\n\n" - - "It is important to note that interiors are no longer the preferred format for large structures. It is an " - "old format, which does not have much to offer above DTS or COLLADA. They are still included in Torque 3D " - "for the sake of backwards compatibility for developers porting older TGE or TGEA projects. It will be " - "deprecated soon.\n\n" - - "@ingroup gameObjects" -); - - -static const U32 csgMaxZoneSize = 256; -static bool sgScopeBoolArray[256]; - - -bool InteriorInstance::smDontRestrictOutside = false; -F32 InteriorInstance::smDetailModification = 1.0f; - - - -//----------------------------------------------------------------------------- - -InteriorInstance::InteriorInstance() -{ - mAlarmState = false; - - mInteriorFileName = NULL; - mTypeMask |= InteriorObjectType | StaticObjectType | StaticShapeObjectType; - mZoneFlags.clear( ZoneFlag_IsClosedOffSpace ); // Interiors are open spaces. - - mForcedDetailLevel = -1; - - mConvexList = new Convex; - mCRC = 0; - - mPhysicsRep = NULL; -} - -//----------------------------------------------------------------------------- - -InteriorInstance::~InteriorInstance() -{ - delete mConvexList; - mConvexList = NULL; - - // GFX2_RENDER_MERGE - //for (U32 i = 0; i < mReflectPlanes.size(); i++) - // mReflectPlanes[i].clearTextures(); -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::inspectPostApply() -{ - // Apply any transformations set in the editor - Parent::inspectPostApply(); - - // Update the Transform on Editor Apply. - setMaskBits(TransformMask); -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::initPersistFields() -{ - addGroup("Media"); - - addProtectedField( "interiorFile", TypeFilename, Offset( mInteriorFileName, InteriorInstance ), - &_setInteriorFile, &defaultProtectedGetFn, - "Path and filename of the Interior file (.DIF) to load for this InteriorInstance."); - - endGroup("Media"); - - Parent::initPersistFields(); -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::consoleInit() -{ - //-------------------------------------- Class level variables - Con::addVariable( "pref::Interior::VertexLighting", TypeBool, &Interior::smUseVertexLighting, - "Forces all InteriorInstances to not render their lightmaps.\n" - "@ingroup Interior" ); - Con::addVariable( "pref::Interior::detailAdjust", TypeF32, &InteriorInstance::smDetailModification, - "Forces all InteriorInstance rendering to a particular detail level.\n" - "@ingroup Interior" ); - - // DEBUG ONLY!!! -#ifndef TORQUE_SHIPPING - Con::addVariable( "Interior::DontRestrictOutside", TypeBool, &smDontRestrictOutside, - "Render only the outside zone of all InteriorInstances.\n" - "@ingroup Interior" ); -#endif -} - -//----------------------------------------------------------------------------- - -#ifdef TORQUE_COLLADA - -void InteriorInstance::exportToCollada(bool bakeTransform) -{ - if (mInteriorRes->getNumDetailLevels() == 0) - { - Con::errorf("InteriorInstance::exportToCollada() called an InteriorInstance with no Interior"); - return; - } - - // For now I am only worrying about the highest lod - Interior* pInterior = mInteriorRes->getDetailLevel(0); - - if (!pInterior) - { - Con::errorf("InteriorInstance::exportToCollada() called an InteriorInstance with an invalid Interior"); - return; - } - - // Get an optimized version of our mesh - OptimizedPolyList interiorMesh; - - if (bakeTransform) - { - MatrixF mat = getTransform(); - Point3F scale = getScale(); - - pInterior->buildExportPolyList(interiorMesh, &mat, &scale); - } - else - pInterior->buildExportPolyList(interiorMesh); - - // Get our export path - Torque::Path colladaFile = mInteriorRes.getPath(); - - // Make sure to set our Collada extension - colladaFile.setExtension("dae"); - - // Use the InteriorInstance name if possible - String meshName = getName(); - - // Otherwise use the DIF's file name - if (meshName.isEmpty()) - meshName = colladaFile.getFileName(); - - // If we are baking the transform then append - // a CRC version of the transform to the mesh/file name - if (bakeTransform) - { - F32 trans[19]; - - const MatrixF& mat = getTransform(); - const Point3F& scale = getScale(); - - // Copy in the transform - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 4; j++) - { - trans[i * 4 + j] = mat(i, j); - } - } - - // Copy in the scale - trans[16] = scale.x; - trans[17] = scale.y; - trans[18] = scale.z; - - U32 crc = CRC::calculateCRC(trans, sizeof(F32) * 19); - - meshName += String::ToString("_%x", crc); - } - - // Set the file name as the meshName - colladaFile.setFileName(meshName); - - // Use a ColladaUtils function to do the actual export to a Collada file - ColladaUtils::exportToCollada(colladaFile, interiorMesh, meshName); -} -#endif - -//----------------------------------------------------------------------------- - -bool InteriorInstance::onAdd() -{ - if(! _loadInterior()) - return false; - - if(!Parent::onAdd()) - return false; - - addToScene(); - - if ( PHYSICSMGR && mInteriorRes && mInteriorRes->getNumDetailLevels() > 0 ) - { - // TODO: We need to cache the collision by resource name - // and reuse it across multiple instances. - - // Get the interior collision geometry. - ConcretePolyList polylist; - mInteriorRes->getDetailLevel(0)->buildPolyList( &polylist, Box3F(999999.0f), MatrixF::Identity, getScale() ); - polylist.triangulate(); - - // Look out... this could possibly happen! - if ( !polylist.isEmpty() ) - { - // Use a triangle mesh for collision. - PhysicsCollision *colShape = PHYSICSMGR->createCollision(); - colShape->addTriangleMesh( polylist.mVertexList.address(), - polylist.mVertexList.size(), - polylist.mIndexList.address(), - polylist.mIndexList.size() / 3, - MatrixF::Identity ); - - PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ); - mPhysicsRep = PHYSICSMGR->createBody(); - mPhysicsRep->init( colShape, 0, 0, this, world ); - mPhysicsRep->setTransform( getTransform() ); - } - } - - return true; -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::onRemove() -{ - SAFE_DELETE( mPhysicsRep ); - - _unloadInterior(); - - removeFromScene(); - - Parent::onRemove(); -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::_loadInterior() -{ - U32 i; - - // Load resource - mInteriorRes = ResourceManager::get().load(mInteriorFileName); - if (bool(mInteriorRes) == false) { - Con::errorf(ConsoleLogEntry::General, "Unable to load interior: %s", mInteriorFileName); - NetConnection::setLastError("Unable to load interior: %s", mInteriorFileName); - return false; - } - if(isClientObject()) - { - if(mCRC != mInteriorRes.getChecksum()) - { - NetConnection::setLastError("Local interior file '%s' does not match version on server.", mInteriorFileName); - return false; - } - for (i = 0; i < mInteriorRes->getNumDetailLevels(); i++) { - // ok, if the material list load failed... - // if this is a local connection, we'll assume that's ok - // and just have white textures... - // otherwise we want to return false. - Interior* pInterior = mInteriorRes->getDetailLevel(i); - if(!pInterior->prepForRendering(mInteriorRes.getPath().getFullPath().c_str()) ) - { - if(!bool(mServerObject)) - { - return false; - } - } - } - - // copy planar reflect list from top detail level - for now - Interior* pInterior = mInteriorRes->getDetailLevel(0); - if( pInterior->mReflectPlanes.size() ) - { - for ( i = 0; i < pInterior->mReflectPlanes.size(); i++ ) - { - mPlaneReflectors.increment(); - PlaneReflector &plane = mPlaneReflectors.last(); - - plane.refplane = pInterior->mReflectPlanes[i]; - plane.objectSpace = true; - plane.registerReflector( this, &mReflectorDesc ); - } - } - - } - else - mCRC = mInteriorRes.getChecksum(); - - // Ok, everything's groovy! Let's cache our hashed filename for renderimage sorting... - mInteriorFileHash = _StringTable::hashString(mInteriorFileName); - - // Setup bounding information - mObjBox = mInteriorRes->getDetailLevel(0)->getBoundingBox(); - resetWorldBox(); - setRenderTransform(mObjToWorld); - - - // Do any handle loading, etc. required. - - if (isClientObject()) { - - for (i = 0; i < mInteriorRes->getNumDetailLevels(); i++) { - Interior* pInterior = mInteriorRes->getDetailLevel(i); - - // Force the lightmap manager to download textures if we're - // running the mission editor. Normally they are only - // downloaded after the whole scene is lit. - gInteriorLMManager.addInstance(pInterior->getLMHandle(), mLMHandle, this); - if (gEditingMission) { - gInteriorLMManager.useBaseTextures(pInterior->getLMHandle(), mLMHandle); - gInteriorLMManager.downloadGLTextures(pInterior->getLMHandle()); - } - - // Install material list - // mMaterialMaps.push_back(new MaterialList(pInterior->mMaterialList)); - } - - } else { - - } - - setMaskBits(0xffffffff); - return true; -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::_unloadInterior() -{ - mConvexList->nukeList(); - delete mConvexList; - mConvexList = new Convex; - - if(isClientObject()) - { - if(bool(mInteriorRes) && mLMHandle != 0xFFFFFFFF) - { - for(U32 i = 0; i < mInteriorRes->getNumDetailLevels(); i++) - { - Interior * pInterior = mInteriorRes->getDetailLevel(i); - if (pInterior->getLMHandle() != 0xFFFFFFFF) - gInteriorLMManager.removeInstance(pInterior->getLMHandle(), mLMHandle); - } - } - - if( mPlaneReflectors.size() ) - { - for ( U32 i = 0; i < mPlaneReflectors.size(); i++ ) - { - mPlaneReflectors[i].unregisterReflector(); - } - mPlaneReflectors.clear(); - } - } -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::onSceneAdd() -{ - AssertFatal(mInteriorRes, "Error, should not have been added to the scene if there's no interior!"); - - if (Parent::onSceneAdd() == false) - return false; - - U32 maxNumZones = 0; - - for (U32 i = 0; i < mInteriorRes->getNumDetailLevels(); i++) - { - if (mInteriorRes->getDetailLevel(i)->mZones.size() > maxNumZones) - maxNumZones = mInteriorRes->getDetailLevel(i)->mZones.size(); - } - - if( maxNumZones > 1 ) - { - SceneZoneSpaceManager* zoneManager = getSceneManager()->getZoneManager(); - if( zoneManager ) - { - zoneManager->registerZones(this, (maxNumZones - 1)); - - // Connect to outdoor zone. - zoneManager->getRootZone()->connectZoneSpace( this ); - connectZoneSpace( zoneManager->getRootZone() ); - } - } - - return true; -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::onSceneRemove() -{ - // Disconnect from root zone in case we have connected. - - SceneZoneSpaceManager* zoneManager = getSceneManager()->getZoneManager(); - if( zoneManager ) - zoneManager->getRootZone()->disconnectZoneSpace( this ); - - Parent::onSceneRemove(); -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::_getOverlappingZones( const Box3F& aabb, const MatrixF& transform, const Point3F& scale, U32* outZones, U32& outNumZones ) -{ - MatrixF xForm(true); - Point3F invScale(1.0f / getScale().x, - 1.0f / getScale().y, - 1.0f / getScale().z); - xForm.scale(invScale); - xForm.mul(getWorldTransform()); - xForm.mul(transform); - xForm.scale(scale); - - U32 waterMark = FrameAllocator::getWaterMark(); - - U16* zoneVector = (U16*)FrameAllocator::alloc(mInteriorRes->getDetailLevel(0)->mZones.size() * sizeof(U16)); - U32 numRetZones = 0; - - bool outsideToo = mInteriorRes->getDetailLevel(0)->scanZones(aabb, - xForm, - zoneVector, - &numRetZones - ); - - if (numRetZones > SceneObject::MaxObjectZones) - { - Con::warnf(ConsoleLogEntry::General, "Too many zones returned for query on %s. Returning first %d", - mInteriorFileName, SceneObject::MaxObjectZones); - } - - for (U32 i = 0; i < getMin(numRetZones, U32(SceneObject::MaxObjectZones)); i++) - outZones[i] = zoneVector[i] + mZoneRangeStart - 1; - outNumZones = numRetZones; - - FrameAllocator::setWaterMark(waterMark); - - return outsideToo; -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::getOverlappingZones( const Box3F& aabb, U32* outZones, U32& outNumZones ) -{ - return _getOverlappingZones( aabb, MatrixF::Identity, Point3F( 1.f, 1.f, 1.f ), outZones, outNumZones ); -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::getOverlappingZones( SceneObject* obj, U32* outZones, U32& outNumZones ) -{ - return _getOverlappingZones( obj->getObjBox(), obj->getTransform(), obj->getScale(), outZones, outNumZones ); -} - -//----------------------------------------------------------------------------- - -U32 InteriorInstance::getPointZone(const Point3F& p) -{ - AssertFatal(mInteriorRes, "Error, no interior!"); - - Point3F osPoint = p; - mWorldToObj.mulP(osPoint); - osPoint.convolveInverse(mObjScale); - - S32 zone = mInteriorRes->getDetailLevel(0)->getZoneForPoint(osPoint); - - // If we're in solid (-1) or outside, we need to return 0 - if (zone == -1 || zone == 0) - return SceneZoneSpaceManager::InvalidZoneId; - - return (zone-1) + mZoneRangeStart; -} - -//----------------------------------------------------------------------------- - -// does a hack check to determine how much a point is 'inside'.. should have -// portals prebuilt with the transfer energy to each other portal in the zone -// from the neighboring zone.. these values can be used to determine the factor -// from within an individual zone.. also, each zone could be marked with -// average material property for eax environment audio -// ~0: outside -> 1: inside -bool InteriorInstance::getPointInsideScale(const Point3F & pos, F32 * pScale) -{ - AssertFatal(mInteriorRes, "InteriorInstance::getPointInsideScale: no interior"); - - Interior * interior = mInteriorRes->getDetailLevel(0); - - Point3F p = pos; - mWorldToObj.mulP(p); - p.convolveInverse(mObjScale); - - U32 zoneIndex = interior->getZoneForPoint(p); - if(zoneIndex == -1) // solid? - { - *pScale = 1.f; - return(true); - } - else if(zoneIndex == 0) // outside? - { - *pScale = 0.f; - return(true); - } - - U32 waterMark = FrameAllocator::getWaterMark(); - const Interior::Portal** portals = (const Interior::Portal**)FrameAllocator::alloc(256 * sizeof(const Interior::Portal*)); - U32 numPortals = 0; - - Interior::Zone & zone = interior->mZones[zoneIndex]; - - U32 i; - for(i = 0; i < zone.portalCount; i++) - { - const Interior::Portal & portal = interior->mPortals[interior->mZonePortalList[zone.portalStart + i]]; - if(portal.zoneBack == 0 || portal.zoneFront == 0) { - AssertFatal(numPortals < 256, "Error, overflow in temporary portal buffer!"); - portals[numPortals++] = &portal; - } - } - - // inside? - if(numPortals == 0) - { - *pScale = 1.f; - - FrameAllocator::setWaterMark(waterMark); - return(true); - } - - Point3F* portalCenters = (Point3F*)FrameAllocator::alloc(numPortals * sizeof(Point3F)); - U32 numPortalCenters = 0; - - // scale using the distances to the portals in this zone... - for(i = 0; i < numPortals; i++) - { - const Interior::Portal * portal = portals[i]; - if(!portal->triFanCount) - continue; - - Point3F center(0, 0, 0); - for(U32 j = 0; j < portal->triFanCount; j++) - { - const Interior::TriFan & fan = interior->mWindingIndices[portal->triFanStart + j]; - U32 numPoints = fan.windingCount; - - if(!numPoints) - continue; - - for(U32 k = 0; k < numPoints; k++) - { - const Point3F & a = interior->mPoints[interior->mWindings[fan.windingStart + k]].point; - center += a; - } - - center /= (F32)numPoints; - portalCenters[numPortalCenters++] = center; - } - } - - // 'magic' check here... - F32 magic = Con::getFloatVariable("Interior::insideDistanceFalloff", 10.f); - - F32 val = 0.f; - for(i = 0; i < numPortalCenters; i++) - val += 1.f - mClampF(Point3F(portalCenters[i] - p).len() / magic, 0.f, 1.f); - - *pScale = 1.f - mClampF(val, 0.f, 1.f); - - FrameAllocator::setWaterMark(waterMark); - return(true); -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* overrideMat ) -{ -#ifndef TORQUE_SHIPPING - if (Interior::smRenderMode == 0) - return; - - if (overrideMat) - return; - - if(gEditingMission && isHidden()) - return; - - U32 detailLevel = 0; - detailLevel = _calcDetailLevel(state, state->getCameraPosition()); - - Interior* pInterior = mInteriorRes->getDetailLevel( detailLevel ); - - if (!pInterior) - return; - - PROFILE_START( IRO_DebugRender ); - - GFX->pushWorldMatrix(); - - // setup world matrix - for fixed function - MatrixF world = GFX->getWorldMatrix(); - world.mul( getRenderTransform() ); - world.scale( getScale() ); - GFX->setWorldMatrix( world ); - - // setup world matrix - for shaders - MatrixF proj = GFX->getProjectionMatrix(); - proj.mul(world); - - SceneData sgData; - - sgData = pInterior->setupSceneGraphInfo( this, state ); - ZoneVisDeterminer zoneVis = pInterior->setupZoneVis( this, state ); - pInterior->debugRender( zoneVis, sgData, this, proj ); - - GFX->popWorldMatrix(); - - PROFILE_END(); -#endif -} - -//----------------------------------------------------------------------------- - -U32 InteriorInstance::_calcDetailLevel(SceneRenderState* state, const Point3F& wsPoint) -{ - AssertFatal(mInteriorRes, "Error, should not try to calculate the deatil level without a resource to work with!"); - AssertFatal(_getNumCurrZones() > 0, "Error, must belong to a zone for this to work"); - - if (smDetailModification < 0.3f) - smDetailModification = 0.3f; - if (smDetailModification > 1.0f) - smDetailModification = 1.0f; - - // Early out for simple interiors - if (mInteriorRes->getNumDetailLevels() == 1) - return 0; - - if((mForcedDetailLevel >= 0) && (mForcedDetailLevel < mInteriorRes->getNumDetailLevels())) - return(mForcedDetailLevel); - - Point3F osPoint = wsPoint; - mRenderWorldToObj.mulP(osPoint); - osPoint.convolveInverse(mObjScale); - - // First, see if the point is in the object space bounding box of the highest detail - // If it is, then the detail level is zero. - if (mObjBox.isContained(osPoint)) - return 0; - - // Otherwise, we're going to have to do some ugly trickery to get the projection. - // I've stolen the worldToScreenScale from dglMatrix, we'll have to calculate the - // projection of the bounding sphere of the lowest detail level. - // worldToScreenScale = (near * view.extent.x) / (right - left) - F32 worldToScreenScale = state->getWorldToScreenScale().x; - const SphereF& lowSphere = mInteriorRes->getDetailLevel(mInteriorRes->getNumDetailLevels() - 1)->mBoundingSphere; - F32 dist = (lowSphere.center - osPoint).len(); - F32 projRadius = (lowSphere.radius / dist) * worldToScreenScale; - - // Scale the projRadius based on the objects maximum scale axis - projRadius *= getMax(mFabs(mObjScale.x), getMax(mFabs(mObjScale.y), mFabs(mObjScale.z))); - - // Multiply based on detail preference... - projRadius *= smDetailModification; - - // Ok, now we have the projected radius, we need to search through the interiors to - // find the largest interior that will support this projection. - U32 final = mInteriorRes->getNumDetailLevels() - 1; - for (U32 i = 0; i< mInteriorRes->getNumDetailLevels() - 1; i++) { - Interior* pDetail = mInteriorRes->getDetailLevel(i); - - if (pDetail->mMinPixels < projRadius) { - final = i; - break; - } - } - - // Ok, that's it. - return final; -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::traverseZones( SceneTraversalState* state ) -{ - U32 startZone = getPointZone( state->getCullingState()->getCameraState().getViewPosition() ); - if( startZone != SceneZoneSpaceManager::InvalidZoneId ) - startZone = startZone - mZoneRangeStart + 1; - else - startZone = SceneZoneSpaceManager::RootZoneId; - - traverseZones( state, startZone ); -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::traverseZones( SceneTraversalState* state, U32 startZoneId ) -{ - PROFILE_SCOPE( InteriorInstance_traverseZones ); - - SceneCullingState* cullingState = state->getCullingState(); - - // [rene, 23-Mar-11] This is a really gross hack. It effectively renders all zoning in interiors - // ineffective and just lets them render with the root frustum. It's just that after untangling - // DMM's mess in the sceneGraph system, I just don't have the energy anymore to also dig through - // the ungodly mess that is the interior code and since this is all quasi-deprecated-and-soon-to-die - // anyway it would just be wasted effort. - - for( U32 i = getZoneRangeStart(); i < ( getZoneRangeStart() + getZoneRange() ); ++ i ) - cullingState->addCullingVolumeToZone( i, state->getCurrentCullingVolume() ); - -#if 0 - U32 baseZoneForPrep = getCurrZone( 0 ); - bool multipleZones = ( getNumCurrZones() > 1 ); - - Frustum outFrustum; - bool continueOut = mInteriorRes->getDetailLevel( 0 )->traverseZones( - renderState, - frustum, - baseZoneForPrep, - startZoneId, - mZoneRangeStart, - mRenderObjToWorld, - mObjScale, - smDontRestrictOutside | multipleZones, - renderState->isInvertedWorld(), - outFrustum - ); - - if( smDontRestrictOutside ) - continueOut = true; -#endif - - if( true )// continueOut ) - { - state->pushZone( startZoneId ); - _traverseConnectedZoneSpaces( state ); - state->popZone(); - } -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::prepRenderImage( SceneRenderState* state ) -{ - PROFILE_SCOPE( InteriorInstance_prepRenderImage ); - - U32 detailLevel = _calcDetailLevel( state, state->getCameraPosition() ); - Interior* pInterior = getResource()->getDetailLevel( detailLevel ); - pInterior->prepBatchRender( this, state ); -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::castRay(const Point3F& s, const Point3F& e, RayInfo* info) -{ - info->object = this; - return mInteriorRes->getDetailLevel(0)->castRay(s, e, info); -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::buildPolyList(PolyListContext context, AbstractPolyList* list, const Box3F& wsBox, const SphereF&) -{ - if (bool(mInteriorRes) == false) - return false; - - // Setup collision state data - list->setTransform(&getTransform(), getScale()); - list->setObject(this); - - return mInteriorRes->getDetailLevel(0)->buildPolyList(list, wsBox, mWorldToObj, getScale()); -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::buildConvex(const Box3F& box, Convex* convex) -{ - if (bool(mInteriorRes) == false) - return; - - mConvexList->collectGarbage(); - - Box3F realBox = box; - mWorldToObj.mul(realBox); - realBox.minExtents.convolveInverse(mObjScale); - realBox.maxExtents.convolveInverse(mObjScale); - - if (realBox.isOverlapped(getObjBox()) == false) - return; - - U32 waterMark = FrameAllocator::getWaterMark(); - - if ((convex->getObject()->getTypeMask() & VehicleObjectType) && - mInteriorRes->getDetailLevel(0)->mVehicleConvexHulls.size() > 0) - { - // Can never have more hulls than there are hulls in the interior... - U16* hulls = (U16*)FrameAllocator::alloc(mInteriorRes->getDetailLevel(0)->mVehicleConvexHulls.size() * sizeof(U16)); - U32 numHulls = 0; - - Interior* pInterior = mInteriorRes->getDetailLevel(0); - if (pInterior->getIntersectingVehicleHulls(realBox, hulls, &numHulls) == false) { - FrameAllocator::setWaterMark(waterMark); - return; - } - - for (U32 i = 0; i < numHulls; i++) { - // See if this hull exists in the working set already... - Convex* cc = 0; - CollisionWorkingList& wl = convex->getWorkingList(); - for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext) { - if (itr->mConvex->getType() == InteriorConvexType && - (static_cast(itr->mConvex)->getObject() == this && - static_cast(itr->mConvex)->hullId == -S32(hulls[i] + 1))) { - cc = itr->mConvex; - break; - } - } - if (cc) - continue; - - // Create a new convex. - InteriorConvex* cp = new InteriorConvex; - mConvexList->registerObject(cp); - convex->addToWorkingList(cp); - cp->mObject = this; - cp->pInterior = pInterior; - cp->hullId = -S32(hulls[i] + 1); - cp->box.minExtents.x = pInterior->mVehicleConvexHulls[hulls[i]].minX; - cp->box.minExtents.y = pInterior->mVehicleConvexHulls[hulls[i]].minY; - cp->box.minExtents.z = pInterior->mVehicleConvexHulls[hulls[i]].minZ; - cp->box.maxExtents.x = pInterior->mVehicleConvexHulls[hulls[i]].maxX; - cp->box.maxExtents.y = pInterior->mVehicleConvexHulls[hulls[i]].maxY; - cp->box.maxExtents.z = pInterior->mVehicleConvexHulls[hulls[i]].maxZ; - } - } - else - { - // Can never have more hulls than there are hulls in the interior... - U16* hulls = (U16*)FrameAllocator::alloc(mInteriorRes->getDetailLevel(0)->mConvexHulls.size() * sizeof(U16)); - U32 numHulls = 0; - - Interior* pInterior = mInteriorRes->getDetailLevel(0); - if (pInterior->getIntersectingHulls(realBox, hulls, &numHulls) == false) { - FrameAllocator::setWaterMark(waterMark); - return; - } - - for (U32 i = 0; i < numHulls; i++) { - // See if this hull exists in the working set already... - Convex* cc = 0; - CollisionWorkingList& wl = convex->getWorkingList(); - for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext) { - if (itr->mConvex->getType() == InteriorConvexType && - (static_cast(itr->mConvex)->getObject() == this && - static_cast(itr->mConvex)->hullId == hulls[i])) { - cc = itr->mConvex; - break; - } - } - if (cc) - continue; - - // Create a new convex. - InteriorConvex* cp = new InteriorConvex; - mConvexList->registerObject(cp); - convex->addToWorkingList(cp); - cp->mObject = this; - cp->pInterior = pInterior; - cp->hullId = hulls[i]; - cp->box.minExtents.x = pInterior->mConvexHulls[hulls[i]].minX; - cp->box.minExtents.y = pInterior->mConvexHulls[hulls[i]].minY; - cp->box.minExtents.z = pInterior->mConvexHulls[hulls[i]].minZ; - cp->box.maxExtents.x = pInterior->mConvexHulls[hulls[i]].maxX; - cp->box.maxExtents.y = pInterior->mConvexHulls[hulls[i]].maxY; - cp->box.maxExtents.z = pInterior->mConvexHulls[hulls[i]].maxZ; - } - } - FrameAllocator::setWaterMark(waterMark); -} - -//----------------------------------------------------------------------------- - -U32 InteriorInstance::packUpdate(NetConnection* c, U32 mask, BitStream* stream) -{ - U32 retMask = Parent::packUpdate(c, mask, stream); - - if (stream->writeFlag((mask & InitMask) != 0)) { - // Initial update, write the whole kit and kaboodle - stream->write(mCRC); - - stream->writeString(mInteriorFileName); - - // Write the alarm state - stream->writeFlag(mAlarmState); - } - else - { - stream->writeFlag(mAlarmState); - } - - return retMask; -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::unpackUpdate(NetConnection* c, BitStream* stream) -{ - Parent::unpackUpdate(c, stream); - - MatrixF temp; - Point3F tempScale; - - if (stream->readFlag()) { - bool isNewUpdate(mInteriorRes); - - if(isNewUpdate) - _unloadInterior(); - - // Initial Update - // CRC - stream->read(&mCRC); - - // File - mInteriorFileName = stream->readSTString(); - - // Alarm state: Note that we handle this ourselves on the initial update - // so that the state is always full on or full off... - mAlarmState = stream->readFlag(); - - if(isNewUpdate) - { - if(! _loadInterior()) - Con::errorf("InteriorInstance::unpackUpdate - Unable to load new interior"); - } - } - else - { - setAlarmMode(stream->readFlag()); - } -} - -//----------------------------------------------------------------------------- - -Interior* InteriorInstance::getDetailLevel(const U32 level) -{ - return mInteriorRes->getDetailLevel(level); -} - -//----------------------------------------------------------------------------- - -U32 InteriorInstance::getNumDetailLevels() -{ - return mInteriorRes->getNumDetailLevels(); -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::setAlarmMode(const bool alarm) -{ - if (mInteriorRes->getDetailLevel(0)->mHasAlarmState == false) - return; - - if (mAlarmState == alarm) - return; - - mAlarmState = alarm; - if (isServerObject()) - { - setMaskBits(AlarmMask); - } - else - { - // DMMTODO: Invalidate current light state - } -} - -//----------------------------------------------------------------------------- - -void InteriorInstance::_createTriggerTransform(const InteriorResTrigger* trigger, MatrixF* transform) -{ - Point3F offset; - MatrixF xform = getTransform(); - xform.getColumn(3, &offset); - - Point3F triggerOffset = trigger->mOffset; - triggerOffset.convolve(mObjScale); - getTransform().mulV(triggerOffset); - offset += triggerOffset; - xform.setColumn(3, offset); - - *transform = xform; -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::readLightmaps(GBitmap**** lightmaps) -{ - AssertFatal(mInteriorRes, "Error, no interior loaded!"); - AssertFatal(lightmaps, "Error, no lightmaps or numdetails result pointers"); - AssertFatal(*lightmaps == NULL, "Error, already have a pointer in the lightmaps result field!"); - - // Load resource - FileStream* pStream; - if((pStream = FileStream::createAndOpen( mInteriorFileName, Torque::FS::File::Read )) == NULL) - { - Con::errorf(ConsoleLogEntry::General, "Unable to load interior: %s", mInteriorFileName); - return false; - } - - InteriorResource* pResource = new InteriorResource; - bool success = pResource->read(*pStream); - delete pStream; - - if (success == false) - { - delete pResource; - return false; - } - AssertFatal(pResource->getNumDetailLevels() == mInteriorRes->getNumDetailLevels(), - "Mismatched detail levels!"); - - *lightmaps = new GBitmap**[mInteriorRes->getNumDetailLevels()]; - - for (U32 i = 0; i < pResource->getNumDetailLevels(); i++) - { - Interior* pInterior = pResource->getDetailLevel(i); - (*lightmaps)[i] = new GBitmap*[pInterior->mLightmaps.size()]; - for (U32 j = 0; j < pInterior->mLightmaps.size(); j++) - { - ((*lightmaps)[i])[j] = pInterior->mLightmaps[j]; - pInterior->mLightmaps[j] = NULL; - } - pInterior->mLightmaps.clear(); - } - - delete pResource; - return true; -} - -//----------------------------------------------------------------------------- - -S32 InteriorInstance::getSurfaceZone(U32 surfaceindex, Interior *detail) -{ - AssertFatal(((surfaceindex >= 0) && (surfaceindex < detail->surfaceZones.size())), "Bad surface index!"); - S32 zone = detail->surfaceZones[surfaceindex]; - if(zone > -1) - return zone + mZoneRangeStart; - return _getCurrZone(0); -} - -//----------------------------------------------------------------------------- - -bool InteriorInstance::_setInteriorFile( void *object, const char *, const char *data ) -{ - if(data == NULL) - return true; - - InteriorInstance *inst = static_cast(object); - - if(inst->isProperlyAdded()) - inst->_unloadInterior(); - - inst->mInteriorFileName = StringTable->insert(data); - - if(inst->isProperlyAdded()) - { - if(! inst->_loadInterior()) - Con::errorf("InteriorInstance::setInteriorFile - Unable to load new interior"); - } - - return false; -} - -//============================================================================= -// Console API. -//============================================================================= -// MARK: ---- Console API ---- - -ConsoleFunctionGroupBegin(Interiors, ""); - -//----------------------------------------------------------------------------- - -#ifndef TORQUE_SHIPPING - -DefineEngineFunction( setInteriorRenderMode, void, ( S32 mode ),, - "Globally changes how InteriorInstances are rendered. Useful for debugging geometry and rendering artifacts\n" - - "@note This does not work in shipping mode\n\n" - - "@param mode The render mode can be one of the following numbers:\n\n" - "NormalRender = 0,\n\n" - "NormalRenderLines = 1,\n\n" - "ShowDetail = 2,\n\n" - "ShowAmbiguous = 3,\n\n" - "ShowOrphan = 4,\n\n" - "ShowLightmaps = 5,\n\n" - "ShowTexturesOnly = 6,\n\n" - "ShowPortalZones = 7,\n\n" - "ShowOutsideVisible = 8,\n\n" - "ShowCollisionFans = 9,\n\n" - "ShowStrips = 10,\n\n" - "ShowNullSurfaces = 11,\n\n" - "ShowLargeTextures = 12,\n\n" - "ShowHullSurfaces = 13,\n\n" - "ShowVehicleHullSurfaces = 14,\n\n" - "ShowVertexColors = 15,\n\n" - "ShowDetailLevel = 16\n\n" - - "@ingroup Game" ) -{ - if (mode < 0 || mode > Interior::ShowDetailLevel) - mode = 0; - - Interior::smRenderMode = mode; -} - -//----------------------------------------------------------------------------- - -ConsoleFunction( setInteriorFocusedDebug, void, 2, 2, "(bool enable)" - "@brief No longer properly supported\n\n" - "@internal") -{ - if (dAtob(argv[1])) { - Interior::smFocusedDebug = true; - } else { - Interior::smFocusedDebug = false; - } -} - -#endif - -//----------------------------------------------------------------------------- - -ConsoleDocFragment _isPointInside1( - "@brief Check to see if a point in world space is inside of an interior.\n\n" - - "@param position The position to check in world space.\n\n" - - "@tsexample\n" - "// Check to see if a point is inside any interior\n" - "%point = \"100 100 100\";\n" - "%isInside = isPointInside(%point);\n" - "@endtsexample\n\n" - - "@ingroup Game", - NULL, - "bool isPointInside( Point3F position );" -); -ConsoleDocFragment _isPointInside2( - "Check to see if a set of coordinates in world space are inside of an interior.\n\n" - "@param x X-coordinate for position in world space.\n" - "@param y Y-coordinate for position in world space.\n" - "@param z Z-coordinate for position in world space.\n" - "@tsexample\n\n" - "// Check to see if a point is inside any interior\n" - "%isInside = isPointInside(100, 100, 100);\n" - "@endtsexample\n\n" - "@ingroup Game", - NULL, - "bool isPointInside( F32 x, F32 y, F32 z );" -); - -ConsoleFunction( isPointInside, bool, 2, 4, "Check to see if a point in world space is inside of an interior." - "@hide") -{ - static bool lastValue = false; - - if(!(argc == 2 || argc == 4)) - { - Con::errorf(ConsoleLogEntry::General, "cIsPointInside: invalid parameters"); - return(lastValue); - } - - Point3F pos; - if(argc == 2) - dSscanf(argv[1], "%g %g %g", &pos.x, &pos.y, &pos.z); - else - { - pos.x = dAtof(argv[1]); - pos.y = dAtof(argv[2]); - pos.z = dAtof(argv[3]); - } - - RayInfo collision; - if(gClientContainer.castRay(pos, Point3F(pos.x, pos.y, pos.z - 2000.f), InteriorObjectType, &collision)) - { - if(collision.face == -1) - Con::errorf(ConsoleLogEntry::General, "cIsPointInside: failed to find hit face on interior"); - else - { - InteriorInstance * interior = dynamic_cast(collision.object); - if(interior) - lastValue = !interior->getDetailLevel(0)->isSurfaceOutsideVisible(collision.face); - else - Con::errorf(ConsoleLogEntry::General, "cIsPointInside: invalid interior on collision"); - } - } - - return(lastValue); -} - - -ConsoleFunctionGroupEnd(Interiors); - -//----------------------------------------------------------------------------- - -#ifdef TORQUE_COLLADA - -DefineEngineMethod( InteriorInstance, exportToCollada, void, ( bool bakeTransform ),, - "@brief Exports the Interior to a Collada file\n\n" - - "@param bakeTransform Bakes the InteriorInstance's transform into the vertex positions\n\n" - - "@tsexample\n" - "// Export to COLLADA, do not bakeTransform\n" - "%interiorObject.exportToCollada(0);\n" - "@endtsexample\n\n") -{ - object->exportToCollada(bakeTransform); -} -#endif - -//----------------------------------------------------------------------------- - -DefineEngineMethod( InteriorInstance, setAlarmMode, void, ( const char* alarmMode),, - "@brief This sets the alarm mode of the interior\n\n" - - "The alarm mode is used when debugging bad geometry for an interior. When on, the the bad verties " - "will be rendered a different color.\n\n" - - "@param alarmMode If true the interior will be in an alarm state next frame. Options are \'On\' or \'Off\'.\n\n" - - "@tsexample\n" - "// Turn on alarm mode debugging for interior\n" - "%interiorObject.setAlarmMode(\"On\");\n" - "@endtsexample\n\n") -{ - AssertFatal(dynamic_cast(object) != NULL, - "Error, how did a non-interior get here?"); - - bool alarm; - if (dStricmp(alarmMode, "On") == 0) - alarm = true; - else - alarm = false; - - InteriorInstance* interior = static_cast(object); - if (interior->isClientObject()) { - Con::errorf(ConsoleLogEntry::General, "InteriorInstance: client objects may not receive console commands. Ignored"); - return; - } - - interior->setAlarmMode(alarm); -} - -//----------------------------------------------------------------------------- - -DefineEngineMethod( InteriorInstance, getNumDetailLevels, S32, (),, - "@brief Get the number of detail levels interior was created with\n\n" - - "@tsexample\n" - "%numLODs = %interiorObject.getNumDetailLevels();\n" - "echo(%numLODs);\n" - "@endtsexample\n\n") -{ - InteriorInstance * instance = static_cast(object); - return(instance->getNumDetailLevels()); -} - -//----------------------------------------------------------------------------- - -DefineEngineMethod( InteriorInstance, setDetailLevel, void, (S32 level),, - "@brief Manually changes the current detail level, rather than automatically via view distance\n\n" - - "@param level Detail level to force.\n\n" - - "@tsexample\n" - "%interiorObject.setDetailLevel(2);\n" - "@endtsexample\n\n") -{ - InteriorInstance * instance = static_cast(object); - if(instance->isServerObject()) - { - NetConnection * toServer = NetConnection::getConnectionToServer(); - NetConnection * toClient = NetConnection::getLocalClientConnection(); - if(!toClient || !toServer) - return; - - S32 index = toClient->getGhostIndex(instance); - if(index == -1) - return; - - InteriorInstance * clientInstance = dynamic_cast(toServer->resolveGhost(index)); - if(clientInstance) - clientInstance->setDetailLevel(level); - } - else - instance->setDetailLevel(level); -} - -//----------------------------------------------------------------------------- - -//These functions are duplicated in tsStatic, shapeBase, and interiorInstance. -//They each function a little differently; but achieve the same purpose of gathering -//target names/counts without polluting simObject. - -DefineEngineMethod( InteriorInstance, getTargetName, const char*, (S32 detailLevel, S32 targetNum),, - "@brief Get the name of the indexed shape material\n\n" - - "@param detailLevel Target LOD\n" - "@param targetNum Index mapped to the target\n\n" - - "@return The name of the target (material) at the specified detail level and index\n\n" - - "@tsexample\n" - "// First level of detail, top of the index map\n" - "%targetName = %interiorObject.getTargetName(1, 0);\n" - "echo(%targetName);\n" - "@endtsexample\n\n") -{ - Interior* obj = object->getDetailLevel(detailLevel); - - if(obj) - return obj->getTargetName(targetNum); - - return ""; -} - -//----------------------------------------------------------------------------- - -DefineEngineMethod( InteriorInstance, getTargetCount, S32, (U32 detailLevel),, - "@brief Get the number of materials used by interior\n\n" - - "@param detailLevel Interior level of detail to scan\n" - - "@return The number of materials used by the interior at a specified detail level\n\n" - - "@tsexample\n" - "// Find materials used at first level of detail\n" - "%targetCount = %interiorObject.getTargetCount(1);\n" - "echo(%targetCount);\n" - "@endtsexample\n\n") -{ - Interior* obj = object->getDetailLevel(detailLevel); - if(obj) - return obj->getTargetCount(); - - return -1; -} - -//----------------------------------------------------------------------------- - -DefineEngineMethod( InteriorInstance, changeMaterial, void, (const char* mapTo, Material* oldMat, Material* newMat),, - "@brief Change one of the materials on the shape.\n\n" - - "This method changes materials per mapTo with others. The material that " - "is being replaced is mapped to unmapped_mat as a part of this transition.\n\n" - - "@note Warning, right now this only sort of works. It doesn't do a live " - "update like it should.\n\b" - - "@param mapTo The name of the material target to remap (from getTargetName)\n" - "@param oldMat The old Material that was mapped \n" - "@param newMat The new Material to map\n\n" - - "@tsexample\n" - "// remap the first material in the shape\n" - "%mapTo = %interiorObject.getTargetName( 0 );\n" - "%interiorObject.changeMaterial( %mapTo, 0, MyMaterial );\n" - "@endtsexample\n" ) -{ - // if no valid new material, theres no reason for doing this - if( !newMat ) - { - Con::errorf("InteriorInstance::changeMaterial failed: New material does not exist!"); - return; - } - - // simple parsing through the interiors detail levels looking for the correct mapto. - // break when we find the correct detail level to depend on. - U32 level; - S32 matIndex = -1; - for( level = 0; level < object->getNumDetailLevels(); level++ ) - { - matIndex = object->getDetailLevel(level)->mMaterialList->getMaterialNameList().find_next(String(mapTo)); - if (matIndex >= 0) - break; - } - - if (matIndex == -1) - { - Con::errorf("InteriorInstance::changeMaterial failed: Invalid mapTo name '%s'", mapTo); - return; - } - - // initilize server/client versions - Interior *serverObj = object->getDetailLevel( level ); - - InteriorInstance * instanceClientObj = dynamic_cast< InteriorInstance* > ( object->getClientObject() ); - Interior *clientObj = instanceClientObj ? instanceClientObj->getDetailLevel( level ) : NULL; - - if(serverObj) - { - // Lets remap the old material off, so as to let room for our current material room to claim its spot - if( oldMat ) - oldMat->mMapTo = String("unmapped_mat"); - - newMat->mMapTo = mapTo; - - // Map the material in the in the matmgr - MATMGR->mapMaterial( mapTo, newMat->mMapTo ); - - // Replace instances with the new material being traded in. Lets make sure that we only - // target the specific targets per inst. This technically is only done here for interiors for - // safe keeping. The remapping that truly matters most (for on the fly changes) are done in the node lists - delete serverObj->mMaterialList->mMatInstList[matIndex]; - serverObj->mMaterialList->mMatInstList[matIndex] = newMat->createMatInstance(); - - // Finishing the safekeeping - const GFXVertexFormat *flags = getGFXVertexFormat(); - FeatureSet features = MATMGR->getDefaultFeatures(); - serverObj->mMaterialList->getMaterialInst(matIndex)->init( features, flags ); - - if (clientObj) - { - delete clientObj->mMaterialList->mMatInstList[matIndex]; - clientObj->mMaterialList->mMatInstList[matIndex] = newMat->createMatInstance(); - clientObj->mMaterialList->getMaterialInst(matIndex)->init( features, flags ); - - // These loops are referenced in interior.cpp's initMatInstances - // Made a couple of alterations to tailor specifically towards one changing one instance - for( U32 i=0; igetNumZones(); i++ ) - { - for( U32 j=0; jmZoneRNList[i].renderNodeList.size(); j++ ) - { - BaseMatInstance *matInst = clientObj->mZoneRNList[i].renderNodeList[j].matInst; - Material* refMat = dynamic_cast(matInst->getMaterial()); - - if(refMat == oldMat) - { - clientObj->mZoneRNList[i].renderNodeList[j].matInst = newMat->createMatInstance(); - clientObj->mZoneRNList[i].renderNodeList[j].matInst->init(MATMGR->getDefaultFeatures(), getGFXVertexFormat()); - - //if ( pMat ) - //mHasTranslucentMaterials |= pMat->mTranslucent && !pMat->mTranslucentZWrite; - } - } - } - - // Lets reset the clientObj settings in order to accomodate the new material - clientObj->fillSurfaceTexMats(); - clientObj->createZoneVBs(); - clientObj->cloneMatInstances(); - clientObj->createReflectPlanes(); - clientObj->initMatInstances(); - } - } -} - -//----------------------------------------------------------------------------- - -DefineEngineMethod( InteriorInstance, getModelFile, const char*, (),, - "@brief Get the interior file name\n\n" - - - "@return The name of the interior's model file in .DIF.\n\n" - - "@tsexample\n" - "%interiorObject.getModelFile();\n" - "@endtsexample\n\n") -{ - return object->getInteriorFileName(); -} diff --git a/Engine/source/interior/interiorInstance.h b/Engine/source/interior/interiorInstance.h deleted file mode 100644 index 69f0d27c3..000000000 --- a/Engine/source/interior/interiorInstance.h +++ /dev/null @@ -1,254 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _INTERIORINSTANCE_H_ -#define _INTERIORINSTANCE_H_ - -#ifndef _SCENEZONESPACE_H_ -#include "scene/zones/sceneZoneSpace.h" -#endif - -#ifndef _INTERIORRES_H_ -#include "interior/interiorRes.h" -#endif - -#ifndef _INTERIORLMMANAGER_H_ -#include "interior/interiorLMManager.h" -#endif - -#ifndef _BITVECTOR_H_ -#include "core/bitVector.h" -#endif - -#ifndef _COLOR_H_ -#include "core/color.h" -#endif - -#ifndef _INTERIOR_H_ -#include "interior.h" -#endif - -#ifndef _REFLECTOR_H_ -#include "scene/reflector.h" -#endif - -#ifndef __RESOURCE_H__ -#include "core/resource.h" -#endif - - -class AbstractPolyList; -class InteriorSubObject; -class InteriorResTrigger; -class MaterialList; -class TextureObject; -class Convex; -class SFXProfile; -class SFXEnvironment; -class PhysicsBody; - - -/// Instance of a DIF interior. -class InteriorInstance : public SceneZoneSpace -{ - public: - - friend class Interior; - - typedef SceneZoneSpace Parent; - - static bool smDontRestrictOutside; - static F32 smDetailModification; - - protected: - - enum UpdateMaskBits - { - InitMask = Parent::NextFreeMask << 0, - AlarmMask = Parent::NextFreeMask << 1, - - // Reserved for light updates (8 bits for now) - _lightupdate0 = Parent::NextFreeMask << 2, - _lightupdate1 = Parent::NextFreeMask << 3, - _lightupdate2 = Parent::NextFreeMask << 4, - _lightupdate3 = Parent::NextFreeMask << 5, - _lightupdate4 = Parent::NextFreeMask << 6, - _lightupdate5 = Parent::NextFreeMask << 7, - _lightupdate6 = Parent::NextFreeMask << 8, - _lightupdate7 = Parent::NextFreeMask << 9, - - SkinBaseMask = Parent::NextFreeMask << 10, - NextFreeMask = Parent::NextFreeMask << 11, - }; - - enum - { - LightUpdateBitStart = 3, - LightUpdateBitEnd = 10 - }; - - enum AlarmState { - Normal = 0, - Alarm = 1 - }; - - /// Alarm state of the interior - bool mAlarmState; - - /// File name of the interior this instance encapuslates - StringTableEntry mInteriorFileName; - - /// Hash for interior file name, used for sorting - U32 mInteriorFileHash; - - /// Interior managed by resource manager - Resource mInteriorRes; - - /// Forced LOD, if -1 auto LOD - S32 mForcedDetailLevel; - - /// CRC for the interior - U32 mCRC; - - /// Handle to the light manager - LM_HANDLE mLMHandle; - - Convex* mConvexList; - - PhysicsBody* mPhysicsRep; - - Vector< PlaneReflector > mPlaneReflectors; - ReflectorDesc mReflectorDesc; - - U32 _calcDetailLevel( SceneRenderState* state, const Point3F& wsPoint ); - bool _loadInterior(); - void _unloadInterior(); - void _renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* ); - bool _getOverlappingZones( const Box3F& aabb, const MatrixF& transform, const Point3F& scale, U32* outZones, U32& outNumZones ); - - /// Creates a transform based on an trigger area - /// @param trigger Trigger to create a transform for - /// @param transform Transform generated (out) - void _createTriggerTransform(const InteriorResTrigger *trigger, MatrixF *transform); - - // SceneObject. - virtual bool onSceneAdd(); - virtual void onSceneRemove(); - - public: - - InteriorInstance(); - virtual ~InteriorInstance(); - - StringTableEntry getInteriorFileName() { return mInteriorFileName; } - - S32 getSurfaceZone(U32 surfaceindex, Interior *detail); - - /// Exports the interior to a Collada file - /// @param bakeTransform Bakes the InteriorInstance's transform into the vertex positions - void exportToCollada(bool bakeTransform = false); - - /// Returns the Light Manager handle - LM_HANDLE getLMHandle() { return(mLMHandle); } - - /// Reads the lightmaps of the interior into the provided pointer - /// @param lightmaps Lightmaps in the interior (out) - bool readLightmaps(GBitmap ****lightmaps); - - /// This is used to determine just how 'inside' a point is in an interior. - /// This is used by the environmental audio code for audio properties and the - /// function always returns true. - /// @param pos Point to test - /// @param pScale How inside is the point 0 = totally outside, 1 = totally inside (out) - bool getPointInsideScale(const Point3F & pos, F32 * pScale); // ~0: outside -> 1: inside - - /// Returns the interior resource - Resource & getResource() {return(mInteriorRes);} // SceneLighting::InteriorProxy interface - - /// Returns the CRC for validation - U32 getCRC() { return(mCRC); } - - /// @name Alarm States - /// @{ - - /// This returns true if the interior is in an alarm state. Alarm state - /// will put different lighting into the interior and also possibly - /// have an audio element also. - bool inAlarmState() {return(mAlarmState);} - - /// This sets the alarm mode of the interior. - /// @param alarm If true the interior will be in an alarm state next frame - void setAlarmMode(const bool alarm); - - /// @} - - /// @name Subobject access interface - /// @{ - - /// Returns the number of detail levels for an object - U32 getNumDetailLevels(); - - /// Gets the interior associated with a particular detail level - /// @param level Detail level - Interior* getDetailLevel(const U32 level); - - /// Sets the detail level to render manually - /// @param level Detail level to force - void setDetailLevel(S32 level = -1) { mForcedDetailLevel = level; } - - /// @} - - // SimObject. - DECLARE_CONOBJECT( InteriorInstance ); - - virtual bool onAdd(); - virtual void onRemove(); - virtual void inspectPostApply(); - - static void initPersistFields(); - static void consoleInit(); - - // NetObject. - virtual U32 packUpdate( NetConnection* conn, U32 mask, BitStream* stream ); - virtual void unpackUpdate( NetConnection* conn, BitStream* stream ); - - // SceneObject. - virtual bool buildPolyList(PolyListContext context, AbstractPolyList *polyList, const Box3F &box, const SphereF &sphere); - virtual bool castRay(const Point3F &start, const Point3F &end, RayInfo *info); - virtual void buildConvex(const Box3F& box,Convex* convex); - virtual void prepRenderImage( SceneRenderState *state ); - - // SceneZoneSpace. - virtual void traverseZones( SceneTraversalState* state ); - virtual void traverseZones( SceneTraversalState* state, U32 startZoneId ); - virtual U32 getPointZone( const Point3F& p ); - virtual bool getOverlappingZones( const Box3F& aabb, U32* outZones, U32& outNumZones ); - virtual bool getOverlappingZones( SceneObject* obj, U32* outZones, U32& outNumZones ); - - private: - - // Protected field accessors - static bool _setInteriorFile( void *object, const char *, const char *data ); -}; - -#endif //_INTERIORBLOCK_H_ - diff --git a/Engine/source/interior/interiorLMManager.cpp b/Engine/source/interior/interiorLMManager.cpp deleted file mode 100644 index 93f465756..000000000 --- a/Engine/source/interior/interiorLMManager.cpp +++ /dev/null @@ -1,384 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "interior/interiorLMManager.h" -#include "gfx/gfxTextureManager.h" -#include "gfx/bitmap/gBitmap.h" -#include "interior/interiorRes.h" -#include "interior/interiorInstance.h" -#include "interior/interior.h" - -//------------------------------------------------------------------------------ -// Globals -InteriorLMManager gInteriorLMManager; - -//------------------------------------------------------------------------------ - -InteriorLMManager::InteriorLMManager() -{ - VECTOR_SET_ASSOCIATION( mInteriors ); -} - -InteriorLMManager::~InteriorLMManager() -{ - for(U32 i = 0; i < mInteriors.size(); i++) - removeInterior(LM_HANDLE(i)); -} - -//------------------------------------------------------------------------------ -void InteriorLMManager::addInterior(LM_HANDLE & interiorHandle, U32 numLightmaps, Interior * interior) -{ - interiorHandle = mInteriors.size(); - mInteriors.increment(); - mInteriors.last() = new InteriorLMInfo; - - mInteriors.last()->mInterior = interior; - mInteriors.last()->mHandlePtr = &interiorHandle; - mInteriors.last()->mNumLightmaps = numLightmaps; - - // create base instance - addInstance(interiorHandle, mInteriors.last()->mBaseInstanceHandle, 0); - AssertFatal(mInteriors.last()->mBaseInstanceHandle == LM_HANDLE(0), "InteriorLMManager::addInterior: invalid base instance handle"); - - // steal the lightmaps from the interior - Vector& texHandles = getHandles(interiorHandle, 0); - for(U32 i = 0; i < interior->mLightmaps.size(); i++) - { - AssertFatal(interior->mLightmaps[i], "InteriorLMManager::addInterior: interior missing lightmap"); - texHandles[i].set(interior->mLightmaps[i], &GFXDefaultPersistentProfile, true, String("Interior Lightmap")); - } - - interior->mLightmaps.clear(); -} - -void InteriorLMManager::removeInterior(LM_HANDLE interiorHandle) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::removeInterior: invalid interior handle"); - AssertFatal(mInteriors[interiorHandle]->mInstances.size() == 1, "InteriorLMManager::removeInterior: cannot remove base interior"); - - // remove base instance - removeInstance(interiorHandle, 0); - - *mInteriors[interiorHandle]->mHandlePtr = LM_HANDLE(-1); - - delete mInteriors[interiorHandle]; - - // last one? otherwise move it - if((mInteriors.size()-1) != interiorHandle) - { - mInteriors[interiorHandle] = mInteriors.last(); - *(mInteriors[interiorHandle]->mHandlePtr) = interiorHandle; - } - - mInteriors.decrement(); -} - -//------------------------------------------------------------------------------ -void InteriorLMManager::addInstance(LM_HANDLE interiorHandle, LM_HANDLE & instanceHandle, InteriorInstance * instance) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::addInstance: invalid interior handle"); - AssertFatal(interiorHandle == *(mInteriors[interiorHandle]->mHandlePtr), "InteriorLMManager::addInstance: invalid handle value"); - - InteriorLMInfo * interiorInfo = mInteriors[interiorHandle]; - - // create the instance info and fill - InstanceLMInfo * instanceInfo = new InstanceLMInfo; - - instanceInfo->mInstance = instance; - instanceInfo->mHandlePtr = &instanceHandle; - instanceHandle = interiorInfo->mInstances.size(); - - interiorInfo->mInstances.push_back(instanceInfo); - - // create/clear list - instanceInfo->mLightmapHandles.setSize(interiorInfo->mNumLightmaps); - - for(U32 i = 0; i < instanceInfo->mLightmapHandles.size(); i++) - instanceInfo->mLightmapHandles[i] = NULL; -} - -void InteriorLMManager::removeInstance(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::removeInstance: invalid interior handle"); - AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::removeInstance: invalid instance handle"); - AssertFatal(!(instanceHandle == mInteriors[interiorHandle]->mBaseInstanceHandle && - mInteriors[interiorHandle]->mInstances.size() > 1), "InteriorLMManager::removeInstance: invalid base instance"); - - InteriorLMInfo * itrInfo = mInteriors[interiorHandle]; - - // kill it - InstanceLMInfo * instInfo = itrInfo->mInstances[instanceHandle]; - for(U32 i = 0; i < instInfo->mLightmapHandles.size(); i++) - instInfo->mLightmapHandles[i] = NULL; - - // reset on last instance removal only (multi detailed shapes share the same instance handle) - if(itrInfo->mInstances.size() == 1) - *instInfo->mHandlePtr = LM_HANDLE(-1); - - delete instInfo; - - // last one? otherwise move it - if((itrInfo->mInstances.size()-1) != instanceHandle) - { - itrInfo->mInstances[instanceHandle] = itrInfo->mInstances.last(); - *(itrInfo->mInstances[instanceHandle]->mHandlePtr) = instanceHandle; - } - - itrInfo->mInstances.decrement(); -} - -void InteriorLMManager::useBaseTextures(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::useBaseTextures: invalid interior handle"); - AssertFatal(interiorHandle == *(mInteriors[interiorHandle]->mHandlePtr), "InteriorLMManager::useBaseTextures: invalid handle value"); - - // Make sure the base light maps are loaded - loadBaseLightmaps(interiorHandle,instanceHandle); - - // Install base lightmaps for this instance... - Vector& baseHandles = getHandles(interiorHandle, 0); - Vector& texHandles = getHandles(interiorHandle, instanceHandle); - for(U32 i = 0; i < baseHandles.size(); i++) - texHandles[i] = baseHandles[i]; -} - -//------------------------------------------------------------------------------ -void InteriorLMManager::destroyBitmaps() -{ - for(S32 i = mInteriors.size() - 1; i >= 0; i--) - { - InteriorLMInfo * interiorInfo = mInteriors[i]; - for(S32 j = interiorInfo->mInstances.size() - 1; j >= 0; j--) - { - InstanceLMInfo * instanceInfo = interiorInfo->mInstances[j]; - for(S32 k = instanceInfo->mLightmapHandles.size() - 1; k >= 0; k--) - { - if(!instanceInfo->mLightmapHandles[k]) - continue; - - GFXTextureObject * texObj = instanceInfo->mLightmapHandles[k]; - if(!texObj || !texObj->mBitmap) - continue; - - // don't remove 'keep' bitmaps - if(!interiorInfo->mInterior->mLightmapKeep[k]) - { -// SAFE_DELETE(texObj->mBitmap); -// texObj->bitmap = 0; - } - } - } - } -} - -void InteriorLMManager::destroyTextures() -{ - for(S32 i = mInteriors.size() - 1; i >= 0; i--) - { - InteriorLMInfo * interiorInfo = mInteriors[i]; - for(S32 j = interiorInfo->mInstances.size() - 1; j >= 0; j--) - { - InstanceLMInfo * instanceInfo = interiorInfo->mInstances[j]; - for(S32 k = interiorInfo->mNumLightmaps - 1; k >= 0; k--) - { - // will want to remove the vector here eventually... so dont clear - instanceInfo->mLightmapHandles[k] = NULL; - } - } - } -} - -void InteriorLMManager::downloadGLTextures() -{ - for(S32 i = mInteriors.size() - 1; i >= 0; i--) - downloadGLTextures(i); -} - -void InteriorLMManager::downloadGLTextures(LM_HANDLE interiorHandle) -{ - - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::downloadGLTextures: invalid interior handle"); - InteriorLMInfo * interiorInfo = mInteriors[interiorHandle]; - - // The bit vector is used to keep track of which lightmap sets need - // to be loaded from the shared "base" instance. Every instance - // can have it's own lightmap set due to mission lighting. - BitVector needTexture; - needTexture.setSize(interiorInfo->mNumLightmaps); - needTexture.clear(); - - for(S32 j = interiorInfo->mInstances.size() - 1; j >= 0; j--) - { - InstanceLMInfo * instanceInfo = interiorInfo->mInstances[j]; - for(S32 k = instanceInfo->mLightmapHandles.size() - 1; k >= 0; k--) - { - // All instances can share the base instances static lightmaps. - // Test here to see if we need to load those lightmaps. - if ((j == 0) && !needTexture.test(k)) - continue; - if (!instanceInfo->mLightmapHandles[k]) - { - needTexture.set(k); - continue; - } - GFXTexHandle texObj = instanceInfo->mLightmapHandles[k]; - if (!texObj || !texObj->mBitmap) - { - needTexture.set(k); - continue; - } - - instanceInfo->mLightmapHandles[k].set( texObj->mBitmap, &GFXDefaultPersistentProfile, false, String("Interior Lightmap Handle") ); - } - } -} - -bool InteriorLMManager::loadBaseLightmaps(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::loadBaseLightmaps: invalid interior handle"); - AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::loadBaseLightmaps: invalid instance handle"); - - // must use a valid instance handle - if(!instanceHandle) - return(false); - - InteriorLMInfo * interiorInfo = mInteriors[interiorHandle]; - if(!interiorInfo->mNumLightmaps) - return(false); - - InstanceLMInfo * baseInstanceInfo = interiorInfo->mInstances[0]; - - // already loaded? (if any bitmap is present, then assumed that all will be) - GFXTexHandle texture (baseInstanceInfo->mLightmapHandles[0]); - if(texture.isValid() && texture.getBitmap()) - return(true); - - InstanceLMInfo * instanceInfo = interiorInfo->mInstances[instanceHandle]; - - Resource & interiorRes = instanceInfo->mInstance->getResource(); - if(!bool(interiorRes)) - return(false); - - GBitmap *** pBitmaps = 0; - if(!instanceInfo->mInstance->readLightmaps(&pBitmaps)) - return(false); - - for(U32 i = 0; i < interiorRes->getNumDetailLevels(); i++) - { - Interior * interior = interiorRes->getDetailLevel(i); - AssertFatal(interior, "InteriorLMManager::loadBaseLightmaps: invalid detail level in resource"); - AssertFatal(interior->getLMHandle() != LM_HANDLE(-1), "InteriorLMManager::loadBaseLightmaps: interior not added to manager"); - AssertFatal(interior->getLMHandle() < mInteriors.size(), "InteriorLMManager::loadBaseLightmaps: invalid interior"); - - InteriorLMInfo * interiorInfo = mInteriors[interior->getLMHandle()]; - InstanceLMInfo * baseInstanceInfo = interiorInfo->mInstances[0]; - - for(U32 j = 0; j < interiorInfo->mNumLightmaps; j++) - { - AssertFatal(pBitmaps[i][j], "InteriorLMManager::loadBaseLightmaps: invalid bitmap"); - - if (baseInstanceInfo->mLightmapHandles[j]) - { - GFXTextureObject * texObj = baseInstanceInfo->mLightmapHandles[j]; - texObj->mBitmap = pBitmaps[i][j]; - } - else - baseInstanceInfo->mLightmapHandles[j].set( pBitmaps[i][j], &GFXDefaultPersistentProfile, false, String("Interior Lightmap Handle") ); - } - } - - delete [] pBitmaps; - return(true); -} - -//------------------------------------------------------------------------------ -GFXTexHandle &InteriorLMManager::getHandle(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::getHandle: invalid interior handle"); - AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::getHandle: invalid instance handle"); - AssertFatal(index < mInteriors[interiorHandle]->mNumLightmaps, "InteriorLMManager::getHandle: invalid texture index"); - - // valid? if not, then get base lightmap handle - if(!mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]) - { - AssertFatal(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index], "InteriorLMManager::getHandle: invalid base texture handle"); - return(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index]); - } - return(mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]); -} - -GBitmap * InteriorLMManager::getBitmap(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::getBitmap: invalid interior handle"); - AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::getBitmap: invalid instance handle"); - AssertFatal(index < mInteriors[interiorHandle]->mNumLightmaps, "InteriorLMManager::getBitmap: invalid texture index"); - - if(!mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]) - { - AssertFatal(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index], "InteriorLMManager::getBitmap: invalid base texture handle"); - return(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index]->getBitmap()); - } - - return(mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]->getBitmap()); -} - -Vector & InteriorLMManager::getHandles(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::getHandles: invalid interior handle"); - AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::getHandles: invalid instance handle"); - return(mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles); -} - -//------------------------------------------------------------------------------ - -void InteriorLMManager::clearLightmaps(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::clearLightmaps: invalid interior handle"); - AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::clearLightmaps: invalid instance handle"); - - for(U32 i = 0; i < mInteriors[interiorHandle]->mNumLightmaps; i++) - mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[i] = 0; -} - -//------------------------------------------------------------------------------ -GFXTexHandle &InteriorLMManager::duplicateBaseLightmap(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index) -{ - AssertFatal(interiorHandle < mInteriors.size(), "InteriorLMManager::duplicateBaseLightmap: invalid interior handle"); - AssertFatal(instanceHandle < mInteriors[interiorHandle]->mInstances.size(), "InteriorLMManager::duplicateBaseLightmap: invalid instance handle"); - AssertFatal(index < mInteriors[interiorHandle]->mNumLightmaps, "InteriorLMManager::duplicateBaseLightmap: invalid texture index"); - - // already exists? - GFXTexHandle texHandle = mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]; - if(texHandle && texHandle->getBitmap() ) - return mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]; - - AssertFatal(mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index], "InteriorLMManager::duplicateBaseLightmap: invalid base handle"); - - // copy it - GBitmap * src = mInteriors[interiorHandle]->mInstances[0]->mLightmapHandles[index]->getBitmap(); - GBitmap * dest = new GBitmap(*src); - - // don't want this texture to be downloaded yet (SceneLighting will take care of that) - GFXTexHandle tHandle( dest, &GFXDefaultPersistentProfile, true, String("Interior Lightmap Handle 2") ); - mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index] = tHandle; - return mInteriors[interiorHandle]->mInstances[instanceHandle]->mLightmapHandles[index]; -} diff --git a/Engine/source/interior/interiorLMManager.h b/Engine/source/interior/interiorLMManager.h deleted file mode 100644 index 09a50b827..000000000 --- a/Engine/source/interior/interiorLMManager.h +++ /dev/null @@ -1,92 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _INTERIORLMMANAGER_H_ -#define _INTERIORLMMANAGER_H_ - -#ifndef _PLATFORM_H_ -#include "platform/platform.h" -#endif -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif - -#include "gfx/gfxTextureHandle.h" - -class GBitmap; -class Interior; -class InteriorInstance; - -typedef U32 LM_HANDLE; - -class InteriorLMManager -{ - private: - - struct InstanceLMInfo { - InteriorInstance * mInstance; - LM_HANDLE * mHandlePtr; - Vector mLightmapHandles; - }; - - struct InteriorLMInfo { - Interior * mInterior; - LM_HANDLE * mHandlePtr; - U32 mNumLightmaps; - LM_HANDLE mBaseInstanceHandle; - Vector mInstances; - }; - - Vector mInteriors; - - public: - - InteriorLMManager(); - ~InteriorLMManager(); - - void destroyBitmaps(); - void destroyTextures(); - - void downloadGLTextures(); - void downloadGLTextures(LM_HANDLE interiorHandle); - bool loadBaseLightmaps(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle); - - void addInterior(LM_HANDLE & interiorHandle, U32 numLightmaps, Interior * interior); - void removeInterior(LM_HANDLE interiorHandle); - - void addInstance(LM_HANDLE interiorHandle, LM_HANDLE & instanceHandle, InteriorInstance * instance); - void removeInstance(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle); - void useBaseTextures(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle); - - void clearLightmaps(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle); - - GFXTexHandle &getHandle(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index); - Vector & getHandles(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle); - - // helper's - GFXTexHandle &duplicateBaseLightmap(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index); - GBitmap * getBitmap(LM_HANDLE interiorHandle, LM_HANDLE instanceHandle, U32 index); -}; - -extern InteriorLMManager gInteriorLMManager; - -#endif diff --git a/Engine/source/interior/interiorRender.cpp b/Engine/source/interior/interiorRender.cpp deleted file mode 100644 index 9f0309b8b..000000000 --- a/Engine/source/interior/interiorRender.cpp +++ /dev/null @@ -1,359 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "interior/interior.h" -#include "scene/sceneRenderState.h" -#include "scene/sceneManager.h" -#include "lighting/lightManager.h" - -#include "gfx/bitmap/gBitmap.h" -#include "math/mMatrix.h" -#include "math/mRect.h" -#include "core/bitVector.h" -#include "platform/profiler.h" -#include "gfx/gfxDevice.h" -#include "interior/interiorInstance.h" -#include "gfx/gfxTextureHandle.h" -#include "materials/materialList.h" -#include "materials/sceneData.h" -#include "materials/matInstance.h" -#include "materials/materialFeatureTypes.h" -#include "math/mathUtils.h" -#include "renderInstance/renderPassManager.h" -#include "core/frameAllocator.h" - -extern bool sgFogActive; -extern U16* sgActivePolyList; -extern U32 sgActivePolyListSize; -extern U16* sgFogPolyList; -extern U32 sgFogPolyListSize; -extern U16* sgEnvironPolyList; -extern U32 sgEnvironPolyListSize; - -Point3F sgOSCamPosition; - - -U32 sgRenderIndices[2048]; -U32 csgNumAllowedPoints = 256; - -extern "C" { - F32 texGen0[8]; - F32 texGen1[8]; - Point2F *fogCoordinatePointer; -} - - -//------------------------------------------------------------------------------ -// Set up render states for interor rendering -//------------------------------------------------------------------------------ -void Interior::setupRenderStates() -{ - // GFX2_RENDER_MERGE - // I suspect we don't need this anymore - MDF - GFX->setStateBlock(mInteriorSB); -} - -//------------------------------------------------------------------------------ -// Setup zone visibility -//------------------------------------------------------------------------------ -ZoneVisDeterminer Interior::setupZoneVis( InteriorInstance *intInst, SceneRenderState *state ) -{ - - U32 zoneOffset = intInst->getZoneRangeStart() != 0xFFFFFFFF ? intInst->getZoneRangeStart() : 0; - - U32 baseZone = 0xFFFFFFFF; - - if (intInst->_getNumCurrZones() == 1) - { - baseZone = intInst->_getCurrZone(0); - } - else - { - for (U32 i = 0; i < intInst->_getNumCurrZones(); i++) - { - if (state->getCullingState().getZoneState(intInst->_getCurrZone(i)).isZoneVisible()) - { - if (baseZone == 0xFFFFFFFF) { - baseZone = intInst->_getCurrZone(i); - break; - } - } - } - if (baseZone == 0xFFFFFFFF) - { - baseZone = intInst->_getCurrZone(0); - } - } - - ZoneVisDeterminer zoneVis; - zoneVis.runFromState(state, zoneOffset, baseZone); - return zoneVis; -} - -//------------------------------------------------------------------------------ -// Setup scenegraph data structure for materials -//------------------------------------------------------------------------------ -SceneData Interior::setupSceneGraphInfo( InteriorInstance *intInst, - SceneRenderState *state ) -{ - SceneData sgData; - sgData.init( state ); - - // TODO: This sucks... interiors only get sunlight? - sgData.lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType ); - sgData.objTrans = &intInst->getTransform(); - //sgData.backBuffTex = GFX->getSfxBackBuffer(); // NOTICE: SFXBB is removed and refraction is disabled! - - return sgData; -} - -//------------------------------------------------------------------------------ -// Render zone RenderNode -//------------------------------------------------------------------------------ -void Interior::renderZoneNode( SceneRenderState *state, - RenderNode &node, - InteriorInstance *intInst, - SceneData &sgData, - MeshRenderInst *coreRi ) -{ - BaseMatInstance *matInst = state->getOverrideMaterial( node.matInst ); - if ( !matInst ) - return; - - MeshRenderInst *ri = state->getRenderPass()->allocInst(); - *ri = *coreRi; - - ri->lights[0] = LIGHTMGR->getSpecialLight( LightManager::slSunLightType ); - - // setup lightmap - if (dStricmp(LIGHTMGR->getId(), "BLM") == 0) - { - if ( node.lightMapIndex != U8(-1) && - matInst->getFeatures().hasFeature( MFT_LightMap ) ) - ri->lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), node.lightMapIndex ); - } - - ri->matInst = matInst; - ri->primBuffIndex = node.primInfoIndex; - - if ( matInst->getMaterial()->isTranslucent() ) - { - ri->type = RenderPassManager::RIT_Translucent; - ri->translucentSort = true; - ri->sortDistSq = intInst->getRenderWorldBox().getSqDistanceToPoint( state->getCameraPosition() ); - } - - // Sort by the material then the normal map or vertex buffer! - ri->defaultKey = matInst->getStateHint(); - ri->defaultKey2 = ri->lightmap ? (U32)ri->lightmap : (U32)ri->vertBuff; - - state->getRenderPass()->addInst( ri ); -} - -//------------------------------------------------------------------------------ -// Render zone RenderNode -//------------------------------------------------------------------------------ -void Interior::renderReflectNode( SceneRenderState *state, - ReflectRenderNode &node, - InteriorInstance *intInst, - SceneData &sgData, - MeshRenderInst *coreRi ) -{ - BaseMatInstance *matInst = state->getOverrideMaterial( node.matInst ); - if ( !matInst ) - return; - - MeshRenderInst *ri = state->getRenderPass()->allocInst(); - *ri = *coreRi; - - ri->vertBuff = &mReflectVertBuff; - ri->primBuff = &mReflectPrimBuff; - - // use sgData.backBuffer to transfer the reflect texture to the materials - PlaneReflector *rp = &intInst->mPlaneReflectors[ node.reflectPlaneIndex ]; - ri->reflectTex = rp->reflectTex; - ri->reflective = true; - - // setup lightmap - if (dStricmp(LIGHTMGR->getId(), "BLM") == 0) - { - if ( node.lightMapIndex != U8(-1) && - matInst->getFeatures().hasFeature( MFT_LightMap ) ) - ri->lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), node.lightMapIndex ); - } - - ri->matInst = matInst; - ri->primBuffIndex = node.primInfoIndex; - - // Sort by the material then the normal map or vertex buffer! - ri->defaultKey = matInst->getStateHint(); - ri->defaultKey2 = ri->lightmap ? (U32)ri->lightmap : (U32)ri->vertBuff; - - state->getRenderPass()->addInst( ri ); -} - - -//------------------------------------------------------------------------------ -// Setup the rendering -//------------------------------------------------------------------------------ -void Interior::setupRender( InteriorInstance *intInst, - SceneRenderState *state, - MeshRenderInst *coreRi, const MatrixF* worldToCamera ) -{ - // Set the vertex and primitive buffers - coreRi->vertBuff = &mVertBuff; - coreRi->primBuff = &mPrimBuff; - - // Grab our render transform and scale it - MatrixF objectToWorld = intInst->getRenderTransform(); - objectToWorld.scale( intInst->getScale() ); - - coreRi->objectToWorld = state->getRenderPass()->allocUniqueXform(objectToWorld); - coreRi->worldToCamera = state->getRenderPass()->allocUniqueXform(*worldToCamera); // This is handed down from SceneRenderState::renderCurrentImages() - coreRi->projection = state->getRenderPass()->allocSharedXform(RenderPassManager::Projection); - - coreRi->type = RenderPassManager::RIT_Interior; - - // NOTICE: SFXBB is removed and refraction is disabled! - //coreRi->backBuffTex = GFX->getSfxBackBuffer(); -} - - -//------------------------------------------------------------------------------ -// Render -//------------------------------------------------------------------------------ -void Interior::prepBatchRender( InteriorInstance *intInst, SceneRenderState *state ) -{ - // coreRi - used as basis for subsequent interior ri allocations - MeshRenderInst *coreRi = state->getRenderPass()->allocInst(); - SceneData sgData; - sgData.init( state ); - setupRender( intInst, state, coreRi, &state->getWorldViewMatrix() ); - ZoneVisDeterminer zoneVis = setupZoneVis( intInst, state ); - -// GFX2_RENDER_MERGE -#ifndef TORQUE_SHIPPING - if( smRenderMode != 0 ) - { - ObjectRenderInst *ri = state->getRenderPass()->allocInst(); - ri->renderDelegate.bind(intInst, &InteriorInstance::_renderObject); - ri->type = RenderPassManager::RIT_Object; - state->getRenderPass()->addInst( ri ); - return; - } -#endif - - // render zones - for( U32 i=0; iisReflectPass() ) - continue; - - for( U32 j=0; jrender( state, *coreRi, getLMHandle(), - intInst->getLMHandle(), intInst ); - - // render reflective surfaces - if ( !state->isReflectPass() ) - { - renderLights(state, intInst, sgData, coreRi, zoneVis); - - for( U32 i=0; iinteriorInstInit(intInst)) - return; - - // build the render instances... - for(U32 z=0; z -1) - zoneid += intInst->getZoneRangeStart();// only zone managers... - else - zoneid = intInst->_getCurrZone(0);// if not what zone is it in... - - if (!smLightPlugin->zoneInit(zoneid)) - continue; - - static Vector sRenderList; - sRenderList.clear(); - - for(U32 j=0; jgetRenderPass()->allocInst(); - *ri = *coreRi; - ri->type = RenderPassManager::RIT_InteriorDynamicLighting; - ri->matInst = node.matInst; - ri->primBuffIndex = node.primInfoIndex; - - sRenderList.push_back(ri); - } - smLightPlugin->processRI(state, sRenderList); - } - */ -} - - diff --git a/Engine/source/interior/interiorRes.cpp b/Engine/source/interior/interiorRes.cpp deleted file mode 100644 index 4e1d2cb3a..000000000 --- a/Engine/source/interior/interiorRes.cpp +++ /dev/null @@ -1,355 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - - -#include "platform/platform.h" -#include "interior/interiorRes.h" - -#include "console/console.h" -#include "core/stream/fileStream.h" -#include "interior/interior.h" -#include "interior/interiorResObjects.h" -#include "gfx/bitmap/gBitmap.h" -#include "interior/forceField.h" - - -const U32 InteriorResource::smFileVersion = 44; - -//-------------------------------------------------------------------------- -InteriorResource::InteriorResource() -{ - VECTOR_SET_ASSOCIATION(mDetailLevels); - VECTOR_SET_ASSOCIATION(mSubObjects); - VECTOR_SET_ASSOCIATION(mTriggers); - //VECTOR_SET_ASSOCIATION(mPaths); - VECTOR_SET_ASSOCIATION(mInteriorPathFollowers); - VECTOR_SET_ASSOCIATION(mForceFields); - VECTOR_SET_ASSOCIATION(mAISpecialNodes); - - mPreviewBitmap = NULL; -} - -InteriorResource::~InteriorResource() -{ - U32 i; - - for (i = 0; i < mDetailLevels.size(); i++) - delete mDetailLevels[i]; - for (i = 0; i < mSubObjects.size(); i++) - delete mSubObjects[i]; - for (i = 0; i < mTriggers.size(); i++) - delete mTriggers[i]; - for (i = 0; i < mInteriorPathFollowers.size(); i++) - delete mInteriorPathFollowers[i]; - for (i = 0; i < mForceFields.size(); i++) - delete mForceFields[i]; - for (i = 0; i < mAISpecialNodes.size(); i++) - delete mAISpecialNodes[i]; - for (i = 0; i < mGameEntities.size(); i++) - delete mGameEntities[i]; - - delete mPreviewBitmap; - mPreviewBitmap = NULL; -} - -bool InteriorResource::read(Stream& stream) -{ - AssertFatal(stream.hasCapability(Stream::StreamRead), "Interior::read: non-read capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::read: Error, stream in inconsistent state"); - - U32 i; - - // Version this stream - U32 fileVersion; - stream.read(&fileVersion); - if (fileVersion != smFileVersion) { - Con::errorf(ConsoleLogEntry::General, "InteriorResource::read: incompatible file version found."); - return false; - } - - // Handle preview - bool previewIncluded = false; - stream.read(&previewIncluded); - if (previewIncluded) { - GBitmap bmp; - bmp.readBitmap("png",stream); - } - - // Details - U32 numDetailLevels; - stream.read(&numDetailLevels); - mDetailLevels.setSize(numDetailLevels); - for (i = 0; i < mDetailLevels.size(); i++) - mDetailLevels[i] = NULL; - - for (i = 0; i < mDetailLevels.size(); i++) { - mDetailLevels[i] = new Interior; - if (mDetailLevels[i]->read(stream) == false) { - Con::errorf(ConsoleLogEntry::General, "Unable to read detail level %d in interior resource", i); - return false; - } - } - - // Subobjects: mirrors, translucencies - U32 numSubObjects; - stream.read(&numSubObjects); - mSubObjects.setSize(numSubObjects); - for (i = 0; i < mSubObjects.size(); i++) - mSubObjects[i] = NULL; - - for (i = 0; i < mSubObjects.size(); i++) { - mSubObjects[i] = new Interior; - if (mSubObjects[i]->read(stream) == false) { - AssertISV(false, avar("Unable to read subobject %d in interior resource", i)); - return false; - } - } - - // Triggers - U32 numTriggers; - stream.read(&numTriggers); - mTriggers.setSize(numTriggers); - for (i = 0; i < mTriggers.size(); i++) - mTriggers[i] = NULL; - - for (i = 0; i < mTriggers.size(); i++) { - mTriggers[i] = new InteriorResTrigger; - if (mTriggers[i]->read(stream) == false) { - AssertISV(false, avar("Unable to read trigger %d in interior resource", i)); - return false; - } - } - - U32 numChildren; - stream.read(&numChildren); - mInteriorPathFollowers.setSize(numChildren); - for (i = 0; i < mInteriorPathFollowers.size(); i++) - mInteriorPathFollowers[i] = NULL; - - for (i = 0; i < mInteriorPathFollowers.size(); i++) { - mInteriorPathFollowers[i] = new InteriorPathFollower; - if (mInteriorPathFollowers[i]->read(stream) == false) { - AssertISV(false, avar("Unable to read child %d in interior resource", i)); - return false; - } - } - - U32 numFields; - stream.read(&numFields); - mForceFields.setSize(numFields); - for (i = 0; i < mForceFields.size(); i++) - mForceFields[i] = NULL; - - for (i = 0; i < mForceFields.size(); i++) { - mForceFields[i] = new ForceField; - if (mForceFields[i]->read(stream) == false) { - AssertISV(false, avar("Unable to read field %d in interior resource", i)); - return false; - } - } - - U32 numSpecNodes; - stream.read(&numSpecNodes); - mAISpecialNodes.setSize(numSpecNodes); - for (i = 0; i < mAISpecialNodes.size(); i++) - mAISpecialNodes[i] = NULL; - - for (i = 0; i < mAISpecialNodes.size(); i++) { - mAISpecialNodes[i] = new AISpecialNode; - if (mAISpecialNodes[i]->read(stream) == false) { - AssertISV(false, avar("Unable to read SpecNode %d in interior resource", i)); - return false; - } - } - - U32 dummyInt; - stream.read(&dummyInt); - if (dummyInt == 1) - { - if (mDetailLevels.size() != 0) - getDetailLevel(0)->readVehicleCollision(stream); - } - - // For expansion purposes - stream.read(&dummyInt); - if(dummyInt == 2) - { - U32 numGameEnts; - stream.read(&numGameEnts); - mGameEntities.setSize(numGameEnts); - for (i = 0; i < numGameEnts; i++) - mGameEntities[i] = new ItrGameEntity; - - for (i = 0; i < numGameEnts; i++) { - if (mGameEntities[i]->read(stream) == false) { - AssertISV(false, avar("Unable to read SpecNode %d in interior resource", i)); - return false; - } - } - stream.read(&dummyInt); - } - - return (stream.getStatus() == Stream::Ok); -} - -bool InteriorResource::write(Stream& stream) const -{ - AssertFatal(stream.hasCapability(Stream::StreamWrite), "Interior::write: non-write capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::write: Error, stream in inconsistent state"); - - // Version the stream - stream.write(smFileVersion); - - // Handle preview - // - if (mPreviewBitmap != NULL) { - stream.write(bool(true)); - mPreviewBitmap->writeBitmap("png",stream); - } else { - stream.write(bool(false)); - } - - // Write out the interiors - stream.write(mDetailLevels.size()); - U32 i; - for (i = 0; i < mDetailLevels.size(); i++) { - if (mDetailLevels[i]->write(stream) == false) { - AssertISV(false, "Unable to write detail level to stream"); - return false; - } - } - - stream.write(mSubObjects.size()); - for (i = 0; i < mSubObjects.size(); i++) { - if (mSubObjects[i]->write(stream) == false) { - AssertISV(false, "Unable to write subobject to stream"); - return false; - } - } - - stream.write(mTriggers.size()); - for (i = 0; i < mTriggers.size(); i++) { - if (mTriggers[i]->write(stream) == false) { - AssertISV(false, "Unable to write trigger to stream"); - return false; - } - } - - stream.write(mInteriorPathFollowers.size()); - for (i = 0; i < mInteriorPathFollowers.size(); i++) { - if (mInteriorPathFollowers[i]->write(stream) == false) { - AssertISV(false, avar("Unable to write child %d in interior resource", i)); - return false; - } - } - - stream.write(mForceFields.size()); - for (i = 0; i < mForceFields.size(); i++) { - if (mForceFields[i]->write(stream) == false) { - AssertISV(false, avar("Unable to write field %d in interior resource", i)); - return false; - } - } - - stream.write(mAISpecialNodes.size()); - for (i = 0; i < mAISpecialNodes.size(); i++) { - if (mAISpecialNodes[i]->write(stream) == false) { - AssertISV(false, avar("Unable to write SpecNode %d in interior resource", i)); - return false; - } - } - - stream.write(U32(1)); - if (mDetailLevels.size() != 0) - const_cast(mDetailLevels[0])->writeVehicleCollision(stream); - - // For expansion purposes - if (mGameEntities.size()) - { - stream.write(U32(2)); - stream.write(mGameEntities.size()); - for(i = 0; i < mGameEntities.size(); i++) - { - if (mGameEntities[i]->write(stream) == false) { - AssertISV(false, avar("Unable to write GameEnt %d in interior resource", i)); - return false; - } - } - } - stream.write(U32(0)); - - return (stream.getStatus() == Stream::Ok); -} - -GBitmap* InteriorResource::extractPreview(Stream& stream) -{ - AssertFatal(stream.hasCapability(Stream::StreamRead), "Interior::read: non-read capable stream passed"); - AssertFatal(stream.getStatus() == Stream::Ok, "Interior::read: Error, stream in inconsistent state"); - - // Version this stream - U32 fileVersion; - stream.read(&fileVersion); - if (fileVersion != smFileVersion) { - Con::errorf(ConsoleLogEntry::General, "InteriorResource::read: incompatible file version found."); - return NULL; - } - - // Handle preview - bool previewIncluded = false; - stream.read(&previewIncluded); - if (previewIncluded) { - GBitmap* pBmp = new GBitmap; - if (pBmp->readBitmap("png",stream) == true) - return pBmp; - - delete pBmp; - } - - return NULL; -} - -//------------------------------------------------------------------------------ -//-------------------------------------- Interior Resource constructor -template<> void *Resource::create(const Torque::Path &path) -{ - FileStream stream; - - stream.open( path.getFullPath(), Torque::FS::File::Read ); - - if ( stream.getStatus() != Stream::Ok ) - return NULL; - - InteriorResource* pResource = new InteriorResource; - - if (pResource->read(stream) == true) - return pResource; - else - { - delete pResource; - return NULL; - } -} - -template<> ResourceBase::Signature Resource::signature() -{ - return MakeFourCC('t','d','i','f'); -} diff --git a/Engine/source/interior/interiorRes.h b/Engine/source/interior/interiorRes.h deleted file mode 100644 index 27f57bc39..000000000 --- a/Engine/source/interior/interiorRes.h +++ /dev/null @@ -1,170 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _INTERIORRES_H_ -#define _INTERIORRES_H_ - -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif - - -class Stream; -class Interior; -class GBitmap; -class InteriorResTrigger; -class InteriorPath; -class InteriorPathFollower; -class ForceField; -class AISpecialNode; -class ItrGameEntity; - -class InteriorResource -{ - static const U32 smFileVersion; - - protected: - Vector mDetailLevels; - Vector mSubObjects; - Vector mTriggers; - Vector mInteriorPathFollowers; - Vector mForceFields; - Vector mAISpecialNodes; - Vector mGameEntities; - - GBitmap* mPreviewBitmap; - - public: - InteriorResource(); - ~InteriorResource(); - - bool read(Stream& stream); - bool write(Stream& stream) const; - static GBitmap* extractPreview(Stream&); - - S32 getNumDetailLevels() const; - S32 getNumSubObjects() const; - S32 getNumTriggers() const; - S32 getNumInteriorPathFollowers() const; - S32 getNumForceFields() const; - S32 getNumSpecialNodes() const; - S32 getNumGameEntities() const; - - Interior* getDetailLevel(const U32); - Interior* getSubObject(const U32); - InteriorResTrigger* getTrigger(const U32); - InteriorPathFollower* getInteriorPathFollower(const U32); - ForceField* getForceField(const U32); - AISpecialNode* getSpecialNode(const U32); - ItrGameEntity* getGameEntity(const U32); -}; - -//-------------------------------------------------------------------------- -inline S32 InteriorResource::getNumDetailLevels() const -{ - return mDetailLevels.size(); -} - -inline S32 InteriorResource::getNumSubObjects() const -{ - return mSubObjects.size(); -} - -inline S32 InteriorResource::getNumTriggers() const -{ - return mTriggers.size(); -} - -inline S32 InteriorResource::getNumSpecialNodes() const -{ - return mAISpecialNodes.size(); -} - -inline S32 InteriorResource::getNumGameEntities() const -{ - return mGameEntities.size(); -} - -inline S32 InteriorResource::getNumInteriorPathFollowers() const -{ - return mInteriorPathFollowers.size(); -} - -inline S32 InteriorResource::getNumForceFields() const -{ - return mForceFields.size(); -} - -inline Interior* InteriorResource::getDetailLevel(const U32 idx) -{ - AssertFatal(idx < getNumDetailLevels(), "Error, out of bounds detail level!"); - - if (idx < getNumDetailLevels()) - return mDetailLevels[idx]; - else - return NULL; -} - -inline Interior* InteriorResource::getSubObject(const U32 idx) -{ - AssertFatal(idx < getNumSubObjects(), "Error, out of bounds subObject!"); - - return mSubObjects[idx]; -} - -inline InteriorResTrigger* InteriorResource::getTrigger(const U32 idx) -{ - AssertFatal(idx < getNumTriggers(), "Error, out of bounds trigger!"); - - return mTriggers[idx]; -} - -inline InteriorPathFollower* InteriorResource::getInteriorPathFollower(const U32 idx) -{ - AssertFatal(idx < getNumInteriorPathFollowers(), "Error, out of bounds path follower!"); - - return mInteriorPathFollowers[idx]; -} - -inline ForceField* InteriorResource::getForceField(const U32 idx) -{ - AssertFatal(idx < getNumForceFields(), "Error, out of bounds force field!"); - - return mForceFields[idx]; -} - -inline AISpecialNode* InteriorResource::getSpecialNode(const U32 idx) -{ - AssertFatal(idx < getNumSpecialNodes(), "Error, out of bounds Special Nodes!"); - - return mAISpecialNodes[idx]; -} - -inline ItrGameEntity* InteriorResource::getGameEntity(const U32 idx) -{ - AssertFatal(idx < getNumGameEntities(), "Error, out of bounds Game ENts!"); - - return mGameEntities[idx]; -} - -#endif // _H_INTERIORRES_ - diff --git a/Engine/source/interior/interiorResObjects.cpp b/Engine/source/interior/interiorResObjects.cpp deleted file mode 100644 index 591dc4517..000000000 --- a/Engine/source/interior/interiorResObjects.cpp +++ /dev/null @@ -1,246 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "interior/interiorResObjects.h" -#include "core/stream/stream.h" -#include "math/mathIO.h" - -//-------------------------------------------------------------------------- -//-------------------------------------- -// - -void InteriorDict::read(Stream &stream) -{ - U32 sz; - stream.read(&sz); - setSize(sz); - for(U32 i = 0; i < sz; i++) - { - InteriorDictEntry e; - stream.readString(e.name); - stream.readString(e.value); - (*this)[i] = e; - } -} - -void InteriorDict::write(Stream &stream) const -{ - U32 sz = size(); - stream.write(sz); - for(U32 i = 0; i < sz; i++) - { - stream.writeString((*this)[i].name); - stream.writeString((*this)[i].value); - } -} - -bool InteriorResTrigger::read(Stream& stream) -{ - U32 i, size; - stream.readString(mName); - mDataBlock = stream.readSTString(); - mDictionary.read(stream); - - // Read the polyhedron - stream.read(&size); - mPolyhedron.pointList.setSize(size); - for (i = 0; i < mPolyhedron.pointList.size(); i++) - mathRead(stream, &mPolyhedron.pointList[i]); - - stream.read(&size); - mPolyhedron.planeList.setSize(size); - for (i = 0; i < mPolyhedron.planeList.size(); i++) - mathRead(stream, &mPolyhedron.planeList[i]); - - stream.read(&size); - mPolyhedron.edgeList.setSize(size); - for (i = 0; i < mPolyhedron.edgeList.size(); i++) { - Polyhedron::Edge& rEdge = mPolyhedron.edgeList[i]; - - stream.read(&rEdge.face[0]); - stream.read(&rEdge.face[1]); - stream.read(&rEdge.vertex[0]); - stream.read(&rEdge.vertex[1]); - } - - // And the offset - mathRead(stream, &mOffset); - - return (stream.getStatus() == Stream::Ok); -} - -bool InteriorResTrigger::write(Stream& stream) const -{ - U32 i; - - stream.writeString(mName); - stream.writeString(mDataBlock); - mDictionary.write(stream); - - // Write the polyhedron - stream.write(mPolyhedron.pointList.size()); - for (i = 0; i < mPolyhedron.pointList.size(); i++) - mathWrite(stream, mPolyhedron.pointList[i]); - - stream.write(mPolyhedron.planeList.size()); - for (i = 0; i < mPolyhedron.planeList.size(); i++) - mathWrite(stream, mPolyhedron.planeList[i]); - - stream.write(mPolyhedron.edgeList.size()); - for (i = 0; i < mPolyhedron.edgeList.size(); i++) { - const Polyhedron::Edge& rEdge = mPolyhedron.edgeList[i]; - - stream.write(rEdge.face[0]); - stream.write(rEdge.face[1]); - stream.write(rEdge.vertex[0]); - stream.write(rEdge.vertex[1]); - } - - // And the offset - mathWrite(stream, mOffset); - - return (stream.getStatus() == Stream::Ok); -} - -InteriorPathFollower::InteriorPathFollower() -{ - VECTOR_SET_ASSOCIATION( mTriggerIds ); - VECTOR_SET_ASSOCIATION( mWayPoints ); - - mName = ""; - mPathIndex = 0; - mOffset.set(0, 0, 0); -} - -InteriorPathFollower::~InteriorPathFollower() -{ - -} - -bool InteriorPathFollower::read(Stream& stream) -{ - mName = stream.readSTString(); - mDataBlock = stream.readSTString(); - stream.read(&mInteriorResIndex); - mathRead(stream, &mOffset); - mDictionary.read(stream); - - U32 numTriggers; - stream.read(&numTriggers); - mTriggerIds.setSize(numTriggers); - for (U32 i = 0; i < mTriggerIds.size(); i++) - stream.read(&mTriggerIds[i]); - - U32 numWayPoints; - stream.read(&numWayPoints); - mWayPoints.setSize(numWayPoints); - for(U32 i = 0; i < numWayPoints; i++) - { - mathRead(stream, &mWayPoints[i].pos); - mathRead(stream, &mWayPoints[i].rot); - stream.read(&mWayPoints[i].msToNext); - stream.read(&mWayPoints[i].smoothingType); - } - stream.read(&mTotalMS); - return (stream.getStatus() == Stream::Ok); -} - -bool InteriorPathFollower::write(Stream& stream) const -{ - stream.writeString(mName); - stream.writeString(mDataBlock); - stream.write(mInteriorResIndex); - mathWrite(stream, mOffset); - mDictionary.write(stream); - - stream.write(mTriggerIds.size()); - for (U32 i = 0; i < mTriggerIds.size(); i++) - stream.write(mTriggerIds[i]); - - stream.write(U32(mWayPoints.size())); - for (U32 i = 0; i < mWayPoints.size(); i++) { - mathWrite(stream, mWayPoints[i].pos); - mathWrite(stream, mWayPoints[i].rot); - stream.write(mWayPoints[i].msToNext); - stream.write(mWayPoints[i].smoothingType); - } - stream.write(mTotalMS); - - return (stream.getStatus() == Stream::Ok); -} - -AISpecialNode::AISpecialNode() -{ - mName = ""; - mPos.set(0, 0, 0); -} - -AISpecialNode::~AISpecialNode() -{ -} - -bool AISpecialNode::read(Stream& stream) -{ - mName = stream.readSTString(); - mathRead(stream, &mPos); - - return (stream.getStatus() == Stream::Ok); -} - -bool AISpecialNode::write(Stream& stream) const -{ - stream.writeString(mName); - mathWrite(stream, mPos); - - return (stream.getStatus() == Stream::Ok); -} - -ItrGameEntity::ItrGameEntity() -{ - mDataBlock = ""; - mGameClass = ""; - mPos.set(0, 0, 0); -} - -ItrGameEntity::~ItrGameEntity() -{ -} - -bool ItrGameEntity::read(Stream& stream) -{ - mDataBlock = stream.readSTString(); - mGameClass = stream.readSTString(); - mathRead(stream, &mPos); - mDictionary.read(stream); - - return (stream.getStatus() == Stream::Ok); -} - -bool ItrGameEntity::write(Stream& stream) const -{ - stream.writeString(mDataBlock); - stream.writeString(mGameClass); - mathWrite(stream, mPos); - mDictionary.write(stream); - - return (stream.getStatus() == Stream::Ok); -} diff --git a/Engine/source/interior/interiorResObjects.h b/Engine/source/interior/interiorResObjects.h deleted file mode 100644 index 0307dd99f..000000000 --- a/Engine/source/interior/interiorResObjects.h +++ /dev/null @@ -1,151 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _INTERIORRESOBJECTS_H_ -#define _INTERIORRESOBJECTS_H_ - -#ifndef _PLATFORM_H_ -#include "platform/platform.h" -#endif -#ifndef _MPOINT3_H_ -#include "math/mPoint3.h" -#endif -#ifndef _MBOX_H_ -#include "math/mBox.h" -#endif -#ifndef _MMATRIX_H_ -#include "math/mMatrix.h" -#endif -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif -#ifndef _MPOLYHEDRON_H_ -#include "math/mPolyhedron.h" -#endif -#ifndef _MQUAT_H_ -#include "math/mQuat.h" -#endif - -class Stream; - -struct InteriorDictEntry -{ - char name[256]; - char value[256]; -}; - -class InteriorDict : public Vector -{ -public: - void read(Stream& stream); - void write(Stream& stream) const; -}; - -class InteriorResTrigger -{ - public: - enum Constants { - MaxNameChars = 255 - }; - - char mName[MaxNameChars+1]; - StringTableEntry mDataBlock; - InteriorDict mDictionary; - - Point3F mOffset; - Polyhedron mPolyhedron; - - public: - InteriorResTrigger() { } - - bool read(Stream& stream); - bool write(Stream& stream) const; -}; - -class InteriorPathFollower -{ - public: - struct WayPoint { - Point3F pos; - QuatF rot; - U32 msToNext; - U32 smoothingType; - }; - StringTableEntry mName; - StringTableEntry mDataBlock; - U32 mInteriorResIndex; - U32 mPathIndex; - Point3F mOffset; - Vector mTriggerIds; - Vector mWayPoints; - U32 mTotalMS; - InteriorDict mDictionary; - - public: - InteriorPathFollower(); - ~InteriorPathFollower(); - - bool read(Stream& stream); - bool write(Stream& stream) const; -}; - - -class AISpecialNode -{ - public: - enum - { - chute = 0, - }; - - public: - StringTableEntry mName; - Point3F mPos; - //U32 mType; - - public: - AISpecialNode(); - ~AISpecialNode(); - - bool read(Stream& stream); - bool write(Stream& stream) const; - -}; - -class ItrGameEntity -{ - public: - StringTableEntry mDataBlock; - StringTableEntry mGameClass; - Point3F mPos; - InteriorDict mDictionary; - - public: - ItrGameEntity(); - ~ItrGameEntity(); - - bool read(Stream& stream); - bool write(Stream& stream) const; - -}; - -#endif // _H_INTERIORRESOBJECTS_ diff --git a/Engine/source/interior/interiorSimpleMesh.cpp b/Engine/source/interior/interiorSimpleMesh.cpp deleted file mode 100644 index d8684acc5..000000000 --- a/Engine/source/interior/interiorSimpleMesh.cpp +++ /dev/null @@ -1,644 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "interior/interiorSimpleMesh.h" - -#include "interior/interiorLMManager.h" -#include "interior/interior.h" -#include "console/console.h" -#include "scene/sceneObject.h" -#include "math/mathIO.h" -#include "materials/matInstance.h" -#include "materials/materialManager.h" -#include "scene/sceneManager.h" -#include "scene/sceneRenderState.h" -#include "ts/tsShape.h" -#include "gfx/bitmap/gBitmap.h" - - -Vector *InteriorSimpleMesh::renderInstList = new Vector(); - - -// Checks for polygon level collision with given planes -U32 _whichSide(PlaneF pln, Point3F* verts) -{ - Point3F currv, nextv; - S32 csd, nsd; - - // Find out which side the first vert is on - U32 side = PlaneF::On; - currv = verts[0]; - csd = pln.whichSide(currv); - if(csd != PlaneF::On) - side = csd; - - for(U32 k = 1; k < 3; k++) - { - nextv = verts[k]; - nsd = pln.whichSide(nextv); - if((csd == PlaneF::Back && nsd == PlaneF::Front) || - (csd == PlaneF::Front && nsd == PlaneF::Back)) - return 2; - else if (nsd != PlaneF::On) - side = nsd; - currv = nextv; - csd = nsd; - } - - // Loop back to the first vert - nextv = verts[0]; - nsd = pln.whichSide(nextv); - if((csd == PlaneF::Back && nsd == PlaneF::Front) || - (csd == PlaneF::Front && nsd == PlaneF::Back)) - return 2; - else if(nsd != PlaneF::On) - side = nsd; - return side; - -} - - -//bool InteriorSimpleMesh::castRay(const Point3F &start, const Point3F &end, RayInfo* info) -//{ -// bool found = false; -// F32 best_t = F32_MAX; -// Point3F best_normal = Point3F(0, 0, 1); -// Point3F dir = end - start; -// -// for(U32 p=0; pt = best_t; -// info->normal = best_normal; -// info->material = 0; -// } -// -// return found; -//} - -bool InteriorSimpleMesh::castPlanes(PlaneF left, PlaneF right, PlaneF top, PlaneF bottom) -{ - for(U32 p=0; pmPrimitiveCount == packedPrimitives.size()), "Primitive mismatch"); - - renderInstList->clear(); - - for(S32 i=0; igetRenderPass()->allocInst(); - *inst = copyinst; - - inst->matInst = materialList->getMaterialInst(draw.diffuseIndex); - if(!inst->matInst) - inst->matInst = MATMGR->getWarningMatInstance(); - if(!inst->matInst) - continue; - - inst->primBuffIndex = i; - inst->primBuff = &primBuff; - inst->vertBuff = &vertBuff; - - if(draw.alpha) - { - inst->translucentSort = true; - inst->type = RenderPassManager::RIT_Translucent; - } - - inst->lightmap = gInteriorLMManager.getHandle(interiorlmhandle, instancelmhandle, draw.lightMapIndex); - - state->getRenderPass()->addInst(inst); - renderInstList->push_back(inst); - } - - if(lightingplugin && renderInstList->size() > 0) - { - if(lightingplugin->interiorInstInit(intInst, this)) - { - if(lightingplugin->allZoneInit()) - { - Vector &list = *renderInstList; - - // clone the origial instances to avoid damaging the originals' data - for(int i=0; isize(); i++) - { - MeshRenderInst *inst = state->getRenderPass()->allocInst(); - const MeshRenderInst *oldinst = list[i]; - *inst = *oldinst; - list[i] = inst; - } - - lightingplugin->processRI(state, list); - } - } - } - */ -} - -bool InteriorSimpleMesh::read(Stream& stream) -{ - // Simple serialization - S32 vectorSize = 0; - - // Primitives - stream.read(&vectorSize); - primitives.setSize(vectorSize); - for (U32 i = 0; i < primitives.size(); i++) - { - stream.read(&primitives[i].alpha); - stream.read(&primitives[i].texS); - stream.read(&primitives[i].texT); - stream.read(&primitives[i].diffuseIndex); - stream.read(&primitives[i].lightMapIndex); - stream.read(&primitives[i].start); - stream.read(&primitives[i].count); - - mathRead(stream, &primitives[i].lightMapEquationX); - mathRead(stream, &primitives[i].lightMapEquationY); - mathRead(stream, &primitives[i].lightMapOffset); - mathRead(stream, &primitives[i].lightMapSize); - } - - // Indices - stream.read(&vectorSize); - indices.setSize(vectorSize); - for (U32 i = 0; i < indices.size(); i++) - stream.read(&indices[i]); - - // Vertices - stream.read(&vectorSize); - verts.setSize(vectorSize); - for (U32 i = 0; i < verts.size(); i++) - mathRead(stream, &verts[i]); - - // Normals - stream.read(&vectorSize); - norms.setSize(vectorSize); - for (U32 i = 0; i < norms.size(); i++) - mathRead(stream, &norms[i]); - - // Diffuse UVs - stream.read(&vectorSize); - diffuseUVs.setSize(vectorSize); - for (U32 i = 0; i < diffuseUVs.size(); i++) - mathRead(stream, &diffuseUVs[i]); - - // Lightmap UVs - stream.read(&vectorSize); - lightmapUVs.setSize(vectorSize); - for (U32 i = 0; i < lightmapUVs.size(); i++) - mathRead(stream, &lightmapUVs[i]); - - // Material list - bool hasMaterialList = false; - stream.read(&hasMaterialList); - if (hasMaterialList) - { - // Since we are doing this externally to a TSShape read we need to - // make sure that our read version is the same as our write version. - // It is possible that it was changed along the way by a loaded TSShape. - TSShape::smReadVersion = 25; - - if (materialList) - delete materialList; - - materialList = new TSMaterialList; - materialList->read(stream); - } - else - materialList = NULL; - - // Diffuse bitmaps - stream.read(&vectorSize); - for (U32 i = 0; i < vectorSize; i++) - { - // need to read these - bool hasBitmap = false; - stream.read(&hasBitmap); - if(hasBitmap) - { - GBitmap* bitMap = new GBitmap; - bitMap->readBitmap("png",stream); - delete bitMap; - } - } - - // Misc data - stream.read(&hasSolid); - stream.read(&hasTranslucency); - mathRead(stream, &bounds); - mathRead(stream, &transform); - mathRead(stream, &scale); - - calculateBounds(); - buildBuffers(); - - return true; -} - -bool InteriorSimpleMesh::write(Stream& stream) const -{ - // Simple serialization - // Primitives - stream.write(primitives.size()); - for (U32 i = 0; i < primitives.size(); i++) - { - stream.write(primitives[i].alpha); - stream.write(primitives[i].texS); - stream.write(primitives[i].texT); - stream.write(primitives[i].diffuseIndex); - stream.write(primitives[i].lightMapIndex); - stream.write(primitives[i].start); - stream.write(primitives[i].count); - - mathWrite(stream, primitives[i].lightMapEquationX); - mathWrite(stream, primitives[i].lightMapEquationY); - mathWrite(stream, primitives[i].lightMapOffset); - mathWrite(stream, primitives[i].lightMapSize); - } - - // Indices - stream.write(indices.size()); - for (U32 i = 0; i < indices.size(); i++) - stream.write(indices[i]); - - // Vertices - stream.write(verts.size()); - for (U32 i = 0; i < verts.size(); i++) - mathWrite(stream, verts[i]); - - // Normals - stream.write(norms.size()); - for (U32 i = 0; i < norms.size(); i++) - mathWrite(stream, norms[i]); - - // Diffuse UVs - stream.write(diffuseUVs.size()); - for (U32 i = 0; i < diffuseUVs.size(); i++) - mathWrite(stream, diffuseUVs[i]); - - // Lightmap UVs - stream.write(lightmapUVs.size()); - for (U32 i = 0; i < lightmapUVs.size(); i++) - mathWrite(stream, lightmapUVs[i]); - - // Material list - if (materialList) - { - stream.write(true); - materialList->write(stream); - } - else - stream.write(false); - - // Diffuse bitmaps - if (!materialList) - stream.write(0); - else - { - stream.write(materialList->size()); - - for (U32 i = 0; i < materialList->size(); i++) - { - GFXTexHandle handle(materialList->getDiffuseTexture(i)); - - if (handle.isValid()) - { - GBitmap* bitMap = handle.getBitmap(); - - if (bitMap) - { - stream.write(true); - bitMap->writeBitmap("png",stream); - } - else - stream.write(false); - } - else - stream.write(false); - } - } - - // Misc data - stream.write(hasSolid); - stream.write(hasTranslucency); - mathWrite(stream, bounds); - mathWrite(stream, transform); - mathWrite(stream, scale); - - return true; -} - -void InteriorSimpleMesh::buildBuffers() -{ - bool flipped = false; - - MatrixF trans = transform; - trans.scale(scale); - - Point3F r0, r1, r2; - trans.getRow(0, &r0); - trans.getRow(1, &r1); - trans.getRow(2, &r2); - F32 det = r0.x * (r1.y * r2.z - r1.z * r2.y) - - r0.y * (r1.x * r2.z - r1.z * r2.x) + - r0.z * (r1.x * r2.y - r1.y * r2.x); - flipped = det < 0.0f; - - // setup the repack vectors - packedIndices.clear(); - packedPrimitives.clear(); - packedIndices.reserve(indices.size() * 2); - packedPrimitives.reserve(primitives.size()); - - Vector addedprim; - addedprim.setSize(primitives.size()); - dMemset(addedprim.address(), 0, (addedprim.size() * sizeof(bool))); - - Vector tang; - Vector binorm; - tang.setSize(verts.size()); - binorm.setSize(verts.size()); - dMemset(tang.address(), 0, (tang.size() * sizeof(Point3F))); - dMemset(binorm.address(), 0, (binorm.size() * sizeof(Point3F))); - - // fill the repack vectors - for(U32 p=0; p packedprims; - packedprims.setSize(packedPrimitives.size()); - - for(U32 i=0; i packedIndices[prim.start + ii]) - p.minIndex = packedIndices[prim.start + ii]; - if(maxindex < packedIndices[prim.start + ii]) - maxindex = packedIndices[prim.start + ii]; - } - - // D3D voodoo - not the actual numverts, only the max span (maxindex - minindex) - this needs a better variable name... - p.numVertices = (maxindex - p.minIndex) + 1; - } - - // create vb style sysmem buffer - Vector packedverts; - packedverts.setSize(verts.size()); - - // fill it - for(U32 i=0; i &tang, Vector &binorm) -{ - const Point3F& va = verts[i0]; - const Point3F& vb = verts[i1]; - const Point3F& vc = verts[i2]; - const Point2F& uva = diffuseUVs[i0]; - const Point2F& uvb = diffuseUVs[i1]; - const Point2F& uvc = diffuseUVs[i2]; - - float x1 = vb.x - va.x; - float x2 = vc.x - va.x; - float y1 = vb.y - va.y; - float y2 = vc.y - va.y; - float z1 = vb.z - va.z; - float z2 = vc.z - va.z; - float s1 = uvb.x - uva.x; - float s2 = uvc.x - uva.x; - float t1 = uvb.y - uva.y; - float t2 = uvc.y - uva.y; - - F32 denom = (s1 * t2 - s2 * t1); - if(fabs(denom) < 0.0001) - return; - - float r = 1.0F / denom; - Point3F s((t2 * x1 - t1 * x2) * r, - (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); - Point3F t((s1 * x2 - s2 * x1) * r, - (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); - - tang[i0] += s; - tang[i1] += s; - tang[i2] += s; - binorm[i0] += t; - binorm[i1] += t; - binorm[i2] += t; -} - -void InteriorSimpleMesh::packPrimitive(primitive &primnew, const primitive &primold, Vector &indicesnew, - bool flipped, Vector &tang, Vector &binorm) -{ - // convert from strip to list and add to primnew - for(U32 p=2; pload(InteriorTexture, path, false); - materialList->mapMaterials(); - - // GFX2_RENDER_MERGE - materialList->initMatInstances( MATMGR->getDefaultFeatures(), getGFXVertexFormat() ); - - return true; -} diff --git a/Engine/source/interior/interiorSimpleMesh.h b/Engine/source/interior/interiorSimpleMesh.h deleted file mode 100644 index 762074d3c..000000000 --- a/Engine/source/interior/interiorSimpleMesh.h +++ /dev/null @@ -1,208 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _INTERIORSIMPLEMESH_H_ -#define _INTERIORSIMPLEMESH_H_ - -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif -#ifndef _MBOX_H_ -#include "math/mBox.h" -#endif -#ifndef _TSMATERIALLIST_H_ -#include "ts/tsMaterialList.h" -#endif -#ifndef _RENDERPASSMANAGER_H_ -#include "renderInstance/renderPassManager.h" -#endif -#ifndef _GFXPRIMITIVEBUFFER_H_ -#include "gfx/gfxPrimitiveBuffer.h" -#endif -#ifndef _GFXVERTEXBUFFER_H_ -#include "gfx/gfxVertexBuffer.h" -#endif - -class InteriorInstance; - - -class InteriorSimpleMesh -{ -public: - class primitive - { - public: - bool alpha; - U32 texS; - U32 texT; - S32 diffuseIndex; - S32 lightMapIndex; - U32 start; - U32 count; - - // used to relight the surface in-engine... - PlaneF lightMapEquationX; - PlaneF lightMapEquationY; - Point2I lightMapOffset; - Point2I lightMapSize; - - primitive() - { - alpha = false; - texS = GFXAddressWrap; - texT = GFXAddressWrap; - diffuseIndex = 0; - lightMapIndex = 0; - start = 0; - count = 0; - - lightMapEquationX = PlaneF(0, 0, 0, 0); - lightMapEquationY = PlaneF(0, 0, 0, 0); - lightMapOffset = Point2I(0, 0); - lightMapSize = Point2I(0, 0); - } - }; - - InteriorSimpleMesh() - { - VECTOR_SET_ASSOCIATION( packedIndices ); - VECTOR_SET_ASSOCIATION( packedPrimitives ); - VECTOR_SET_ASSOCIATION( indices ); - VECTOR_SET_ASSOCIATION( verts ); - VECTOR_SET_ASSOCIATION( norms ); - VECTOR_SET_ASSOCIATION( diffuseUVs ); - VECTOR_SET_ASSOCIATION( lightmapUVs ); - - materialList = NULL; - clear(); - } - ~InteriorSimpleMesh(){clear();} - void clear(bool wipeMaterials = true) - { - vertBuff = NULL; - primBuff = NULL; - packedIndices.clear(); - packedPrimitives.clear(); - - hasSolid = false; - hasTranslucency = false; - bounds = Box3F(-1, -1, -1, 1, 1, 1); - transform.identity(); - scale.set(1.0f, 1.0f, 1.0f); - - primitives.clear(); - indices.clear(); - verts.clear(); - norms.clear(); - diffuseUVs.clear(); - lightmapUVs.clear(); - - if(wipeMaterials && materialList) - delete materialList; - - if (wipeMaterials) - materialList = NULL; - } - - void render( SceneRenderState* state, - const MeshRenderInst ©inst, - U32 interiorlmhandle, - U32 instancelmhandle, - InteriorInstance* intInst ); - - void calculateBounds() - { - bounds = Box3F(F32_MAX, F32_MAX, F32_MAX, -F32_MAX, -F32_MAX, -F32_MAX); - for(U32 i=0; i packedIndices; - Vector packedPrimitives;/// tri-list instead of strips - GFXVertexBufferHandle vertBuff; - GFXPrimitiveBufferHandle primBuff; - void buildBuffers(); - void buildTangent(U32 i0, U32 i1, U32 i2, Vector &tang, Vector &binorm); - void packPrimitive(primitive &primnew, const primitive &primold, Vector &indicesnew, - bool flipped, Vector &tang, Vector &binorm); - bool prepForRendering(const char *path); - - bool hasSolid; - bool hasTranslucency; - Box3F bounds; - MatrixF transform; - Point3F scale; - - Vector primitives; - - // same index relationship... - Vector indices; - Vector verts; - Vector norms; - Vector diffuseUVs; - Vector lightmapUVs; - - TSMaterialList *materialList; - - bool containsPrimitiveType(bool translucent) - { - for(U32 i=0; i *renderInstList; -}; - -#endif //_INTERIORSIMPLEMESH_H_ - diff --git a/Engine/source/interior/interiorSubObject.cpp b/Engine/source/interior/interiorSubObject.cpp deleted file mode 100644 index 6cd003aea..000000000 --- a/Engine/source/interior/interiorSubObject.cpp +++ /dev/null @@ -1,108 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "core/stream/stream.h" -#include "interior/interiorInstance.h" - -#include "interior/interiorSubObject.h" -#include "interior/mirrorSubObject.h" - - -InteriorSubObject::InteriorSubObject() -{ - mInteriorInstance = NULL; -} - -InteriorSubObject::~InteriorSubObject() -{ - mInteriorInstance = NULL; -} - -InteriorSubObject* InteriorSubObject::readISO(Stream& stream) -{ - U32 soKey; - stream.read(&soKey); - - InteriorSubObject* pObject = NULL; - switch (soKey) { - case MirrorSubObjectKey: - pObject = new MirrorSubObject; - break; - - default: - Con::errorf(ConsoleLogEntry::General, "Bad key in subObject stream!"); - return NULL; - }; - - if (pObject) { - bool readSuccess = pObject->_readISO(stream); - if (readSuccess == false) { - delete pObject; - pObject = NULL; - } - } - - return pObject; -} - -bool InteriorSubObject::writeISO(Stream& stream) const -{ - stream.write(getSubObjectKey()); - return _writeISO(stream); -} - -bool InteriorSubObject::_readISO(Stream& stream) -{ - return (stream.getStatus() == Stream::Ok); -} - -bool InteriorSubObject::_writeISO(Stream& stream) const -{ - return (stream.getStatus() == Stream::Ok); -} - -const MatrixF& InteriorSubObject::getSOTransform() const -{ - static const MatrixF csBadMatrix(true); - - if (mInteriorInstance != NULL) { - return mInteriorInstance->getTransform(); - } else { - AssertWarn(false, "Returning bad transform for subobject"); - return csBadMatrix; - } -} - -const Point3F& InteriorSubObject::getSOScale() const -{ - return mInteriorInstance->getScale(); -} - -InteriorInstance* InteriorSubObject::getInstance() -{ - return mInteriorInstance; -} - -void InteriorSubObject::noteTransformChange() -{ - // -} diff --git a/Engine/source/interior/interiorSubObject.h b/Engine/source/interior/interiorSubObject.h deleted file mode 100644 index 51588150c..000000000 --- a/Engine/source/interior/interiorSubObject.h +++ /dev/null @@ -1,80 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _INTERIORSUBOBJECT_H_ -#define _INTERIORSUBOBJECT_H_ - -#ifndef _SCENERENDERSTATE_H_ -#include "scene/sceneRenderState.h" -#endif -#ifndef _SCENEOBJECT_H_ -#include "scene/sceneObject.h" -#endif - -class InteriorInstance; - -//class SubObjectRenderImage : public SceneRenderImage -//{ -// public: -// U32 mDetailLevel; -//}; - -class InteriorSubObject : public SceneObject -{ - typedef SceneObject Parent; - - protected: - InteriorInstance* mInteriorInstance; // Should NOT be set by derived except in clone - - protected: - enum SubObjectKeys { - TranslucentSubObjectKey = 0, - MirrorSubObjectKey = 1 - }; - - virtual U32 getSubObjectKey() const = 0; - virtual bool _readISO(Stream&); - virtual bool _writeISO(Stream&) const; - - InteriorInstance* getInstance(); - const MatrixF& getSOTransform() const; - const Point3F& getSOScale() const; - - public: - InteriorSubObject(); - virtual ~InteriorSubObject(); - - // Render control. A sub-object should return false from renderDetailDependant if - // it exists only at the level-0 detail level, ie, doors, elevators, etc., true - // if should only render at the interiors detail, ie, translucencies. - //virtual SubObjectRenderImage* getRenderImage(SceneState*, const Point3F& osPoint) = 0; - virtual bool renderDetailDependant() const = 0; - virtual U32 getZone() const = 0; - - virtual void noteTransformChange(); - virtual InteriorSubObject* clone(InteriorInstance*) const = 0; - - static InteriorSubObject* readISO(Stream&); - bool writeISO(Stream&) const; -}; - -#endif // _H_INTERIORSUBOBJECT_ diff --git a/Engine/source/interior/mirrorSubObject.cpp b/Engine/source/interior/mirrorSubObject.cpp deleted file mode 100644 index f503fa93b..000000000 --- a/Engine/source/interior/mirrorSubObject.cpp +++ /dev/null @@ -1,286 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "interior/mirrorSubObject.h" -#include "interior/interiorInstance.h" -#include "interior/interior.h" -#include "materials/materialList.h" -#include "core/stream/stream.h" -#include "scene/sgUtil.h" - -IMPLEMENT_CONOBJECT(MirrorSubObject); - -ConsoleDocClass( MirrorSubObject, - "@deprecated Dysfunctional" - "@internal" -); - -//-------------------------------------------------------------------------- -MirrorSubObject::MirrorSubObject() -{ - mTypeMask = StaticObjectType; - - mInitialized = false; - mWhite = NULL; -} - -MirrorSubObject::~MirrorSubObject() -{ - delete mWhite; - mWhite = NULL; -} - -//-------------------------------------------------------------------------- -void MirrorSubObject::initPersistFields() -{ - Parent::initPersistFields(); - - // -} - -//-------------------------------------------------------------------------- -/* -void MirrorSubObject::renderObject(SceneRenderState* state, SceneRenderImage* image) -{ -} -*/ - -//-------------------------------------------------------------------------- -void MirrorSubObject::transformModelview(const U32 portalIndex, const MatrixF& oldMV, MatrixF* pNewMV) -{ - AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!"); - AssertFatal(portalIndex == 0, "Error, we only have one portal!"); - - *pNewMV = oldMV; - pNewMV->mul(mReflectionMatrix); -} - - -//-------------------------------------------------------------------------- -void MirrorSubObject::transformPosition(const U32 portalIndex, Point3F& ioPosition) -{ - AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!"); - AssertFatal(portalIndex == 0, "Error, we only have one portal!"); - - mReflectionMatrix.mulP(ioPosition); -} - - -//-------------------------------------------------------------------------- -bool MirrorSubObject::computeNewFrustum(const U32 portalIndex, - const Frustum &oldFrustum, - const F64 nearPlane, - const F64 farPlane, - const RectI& oldViewport, - F64 *newFrustum, - RectI& newViewport, - const bool flippedMatrix) -{ - AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!"); - AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!"); - - Interior* interior = getInstance()->getDetailLevel(mDetailLevel); - - static Vector mirrorWindings; - mirrorWindings.setSize(surfaceCount); - - for (U32 i = 0; i < surfaceCount; i++) { - SGWinding& rSGWinding = mirrorWindings[i]; - const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart + i]; - - U32 fanIndices[32]; - U32 numFanIndices = 0; - interior->collisionFanFromSurface(rSurface, fanIndices, &numFanIndices); - - for (U32 j = 0; j < numFanIndices; j++) - rSGWinding.points[j] = interior->mPoints[fanIndices[j]].point; - rSGWinding.numPoints = numFanIndices; - } - - MatrixF finalModelView; - finalModelView.mul(getSOTransform()); - finalModelView.scale(getSOScale()); - - return sgComputeNewFrustum(oldFrustum, nearPlane, farPlane, - oldViewport, - mirrorWindings.address(), mirrorWindings.size(), - finalModelView, - newFrustum, newViewport, - flippedMatrix); -} - - -//-------------------------------------------------------------------------- -void MirrorSubObject::openPortal(const U32 portalIndex, - SceneRenderState* pCurrState, - SceneRenderState* pParentState) -{ - -} - - -//-------------------------------------------------------------------------- -void MirrorSubObject::closePortal(const U32 portalIndex, - SceneRenderState* pCurrState, - SceneRenderState* pParentState) -{ -} - - -//-------------------------------------------------------------------------- -void MirrorSubObject::getWSPortalPlane(const U32 portalIndex, PlaneF* pPlane) -{ - AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!"); - - Interior* interior = getInstance()->getDetailLevel(mDetailLevel); - const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart]; - - PlaneF temp = interior->getPlane(rSurface.planeIndex); - if (Interior::planeIsFlipped(rSurface.planeIndex)) - temp.neg(); - - mTransformPlane(getSOTransform(), getSOScale(), temp, pPlane); -} - - -//-------------------------------------------------------------------------- -U32 MirrorSubObject::getSubObjectKey() const -{ - return InteriorSubObject::MirrorSubObjectKey; -} - - -bool MirrorSubObject::_readISO(Stream& stream) -{ - AssertFatal(isInitialized() == false, "Error, should not be initialized here!"); - - if (Parent::_readISO(stream) == false) - return false; - - stream.read(&mDetailLevel); - stream.read(&mZone); - stream.read(&mAlphaLevel); - stream.read(&surfaceCount); - stream.read(&surfaceStart); - - stream.read(&mCentroid.x); - stream.read(&mCentroid.y); - stream.read(&mCentroid.z); - - return true; -} - - -bool MirrorSubObject::_writeISO(Stream& stream) const -{ - if (Parent::_writeISO(stream) == false) - return false; - - stream.write(mDetailLevel); - stream.write(mZone); - stream.write(mAlphaLevel); - stream.write(surfaceCount); - stream.write(surfaceStart); - - stream.write(mCentroid.x); - stream.write(mCentroid.y); - stream.write(mCentroid.z); - - return true; -} - -bool MirrorSubObject::renderDetailDependant() const -{ - return true; -} - - -U32 MirrorSubObject::getZone() const -{ - return mZone; -} - - -void MirrorSubObject::setupTransforms() -{ - mInitialized = true; - - // This is really bad, but it's just about the only good place for this... - if (getInstance()->isClientObject() && mWhite == NULL) - mWhite = new GFXTexHandle("special/whiteAlpha0", &GFXDefaultStaticDiffuseProfile, avar("%s() - mWhite (line %d)", __FUNCTION__, __LINE__)); - - Interior* interior = getInstance()->getDetailLevel(mDetailLevel); - const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart]; - - PlaneF plane = interior->getPlane(rSurface.planeIndex); - if (Interior::planeIsFlipped(rSurface.planeIndex)) - plane.neg(); - - Point3F n(plane.x, plane.y, plane.z); - Point3F q = n; - q *= -plane.d; - - MatrixF t(true); - t.scale(getSOScale()); - t.mul(getSOTransform()); - - t.mulV(n); - t.mulP(q); - - F32* ra = mReflectionMatrix; - - ra[0] = 1.0f - 2.0f*(n.x*n.x); ra[1] = 0.0f - 2.0f*(n.x*n.y); ra[2] = 0.0f - 2.0f*(n.x*n.z); ra[3] = 0.0f; - ra[4] = 0.0f - 2.0f*(n.y*n.x); ra[5] = 1.0f - 2.0f*(n.y*n.y); ra[6] = 0.0f - 2.0f*(n.y*n.z); ra[7] = 0.0f; - ra[8] = 0.0f - 2.0f*(n.z*n.x); ra[9] = 0.0f - 2.0f*(n.z*n.y); ra[10] = 1.0f - 2.0f*(n.z*n.z); ra[11] = 0.0f; - - Point3F qnn = n * mDot(n, q); - - ra[12] = qnn.x * 2.0f; - ra[13] = qnn.y * 2.0f; - ra[14] = qnn.z * 2.0f; - ra[15] = 1.0f; - - // Now, the GGems series (as of v1) uses row vectors (arg) - mReflectionMatrix.transpose(); -} - -void MirrorSubObject::noteTransformChange() -{ - setupTransforms(); - Parent::noteTransformChange(); -} - -InteriorSubObject* MirrorSubObject::clone(InteriorInstance* instance) const -{ - MirrorSubObject* pClone = new MirrorSubObject; - - pClone->mDetailLevel = mDetailLevel; - pClone->mZone = mZone; - pClone->mAlphaLevel = mAlphaLevel; - pClone->mCentroid = mCentroid; - pClone->surfaceCount = surfaceCount; - pClone->surfaceStart = surfaceStart; - - pClone->mInteriorInstance = instance; - - return pClone; -} diff --git a/Engine/source/interior/mirrorSubObject.h b/Engine/source/interior/mirrorSubObject.h deleted file mode 100644 index 59b345ee4..000000000 --- a/Engine/source/interior/mirrorSubObject.h +++ /dev/null @@ -1,104 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _MIRRORSUBOBJECT_H_ -#define _MIRRORSUBOBJECT_H_ - -#ifndef _INTERIORSUBOBJECT_H_ -#include "interior/interiorSubObject.h" -#endif - -#include "gfx/gfxTextureHandle.h" - -class TextureHandle; - -class MirrorSubObject : public InteriorSubObject -{ - typedef InteriorSubObject Parent; - - public: - U32 mDetailLevel; - U32 mZone; - - F32 mAlphaLevel; - Point3F mCentroid; - - U32 surfaceCount; - U32 surfaceStart; - - private: - bool mInitialized; - GFXTexHandle* mWhite; - MatrixF mReflectionMatrix; - - bool isInitialized() const { return mInitialized; } - void setupTransforms(); - - - // ISO overrides - protected: - U32 getSubObjectKey() const; - bool _readISO(Stream&); - bool _writeISO(Stream&) const; - - // Render control. A sub-object should return false from renderDetailDependant if - // it exists only at the level-0 detail level, ie, doors, elevators, etc., true - // if should only render at the interiors detail, ie, translucencies. - //SubObjectRenderImage* getRenderImage(SceneRenderState*, const Point3F&); - bool renderDetailDependant() const; - U32 getZone() const; - void noteTransformChange(); - - InteriorSubObject* clone(InteriorInstance*) const; - - // Rendering - protected: - //void renderObject(SceneRenderState*, SceneRenderImage*); - void transformModelview(const U32, const MatrixF&, MatrixF*); - void transformPosition(const U32, Point3F&); - bool computeNewFrustum( const U32 portalIndex, - const Frustum &oldFrustum, - const F64 nearPlane, - const F64 farPlane, - const RectI& oldViewport, - F64 *newFrustum, - RectI& newViewport, - const bool flippedMatrix ); - void openPortal(const U32 portalIndex, - SceneRenderState* pCurrState, - SceneRenderState* pParentState); - void closePortal(const U32 portalIndex, - SceneRenderState* pCurrState, - SceneRenderState* pParentState); - void getWSPortalPlane(const U32 portalIndex, PlaneF*); - - - public: - MirrorSubObject(); - ~MirrorSubObject(); - - DECLARE_CONOBJECT(MirrorSubObject); - static void initPersistFields(); -}; - -#endif // _H_MIRRORSUBOBJECT - diff --git a/Engine/source/interior/pathedInterior.cpp b/Engine/source/interior/pathedInterior.cpp deleted file mode 100644 index 081fd0c2f..000000000 --- a/Engine/source/interior/pathedInterior.cpp +++ /dev/null @@ -1,586 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "interior/pathedInterior.h" -#include "core/stream/stream.h" -#include "console/consoleTypes.h" -#include "scene/sceneRenderState.h" -#include "math/mathIO.h" -#include "core/stream/bitStream.h" -#include "interior/interior.h" -#include "scene/simPath.h" -#include "scene/pathManager.h" -#include "core/frameAllocator.h" -#include "scene/sceneManager.h" -#include "sfx/sfxSystem.h" -#include "sfx/sfxProfile.h" -#include "sfx/sfxSource.h" -#include "core/resourceManager.h" - -IMPLEMENT_CO_NETOBJECT_V1(PathedInterior); -IMPLEMENT_CO_DATABLOCK_V1(PathedInteriorData); - -ConsoleDocClass( PathedInterior, - "@brief Legacy interior related class, soon to be deprecated.\n\n" - "Not intended for game development, for editors or internal use only.\n\n " - "@internal"); - -ConsoleDocClass( PathedInteriorData, - "@brief Legacy interior related class, soon to be deprecated.\n\n" - "Not intended for game development, for editors or internal use only.\n\n " - "@internal"); - -//-------------------------------------------------------------------------- - -PathedInteriorData::PathedInteriorData() -{ - for(U32 i = 0; i < MaxSounds; i++) - sound[i] = NULL; -} - -void PathedInteriorData::initPersistFields() -{ - addField("StartSound", TYPEID< SFXProfile >(), Offset(sound[StartSound], PathedInteriorData)); - addField("SustainSound", TYPEID< SFXProfile >(), Offset(sound[SustainSound], PathedInteriorData)); - addField("StopSound", TYPEID< SFXProfile >(), Offset(sound[StopSound], PathedInteriorData)); - - Parent::initPersistFields(); -} - -void PathedInteriorData::packData(BitStream *stream) -{ - for (S32 i = 0; i < MaxSounds; i++) - { - if (stream->writeFlag(sound[i])) - stream->writeRangedU32(packed? SimObjectId(sound[i]): - sound[i]->getId(),DataBlockObjectIdFirst,DataBlockObjectIdLast); - } - Parent::packData(stream); -} - -void PathedInteriorData::unpackData(BitStream* stream) -{ - for (S32 i = 0; i < MaxSounds; i++) { - sound[i] = NULL; - if (stream->readFlag()) - sound[i] = (SFXProfile*)stream->readRangedU32(DataBlockObjectIdFirst, - DataBlockObjectIdLast); - } - Parent::unpackData(stream); -} - -bool PathedInteriorData::preload(bool server, String &errorStr) -{ - if(!Parent::preload(server, errorStr)) - return false; - - // Resolve objects transmitted from server - if (!server) - { - for (S32 i = 0; i < MaxSounds; i++) - if (sound[i]) - Sim::findObject(SimObjectId(sound[i]),sound[i]); - } - return true; -} - -PathedInterior::PathedInterior() -{ - mNetFlags.set(Ghostable); - mTypeMask = InteriorObjectType; - - mCurrentPosition = 0; - mTargetPosition = 0; - mPathKey = 0xFFFFFFFF; - mStopped = false; - - mSustainSound = NULL; -} - -PathedInterior::~PathedInterior() -{ - // -} - -PathedInterior *PathedInterior::mClientPathedInteriors = NULL; -//-------------------------------------------------------------------------- -void PathedInterior::initPersistFields() -{ - addField("interiorResource", TypeFilename, Offset(mInteriorResName, PathedInterior)); - addField("interiorIndex", TypeS32, Offset(mInteriorResIndex, PathedInterior)); - addField("basePosition", TypeMatrixPosition, Offset(mBaseTransform, PathedInterior)); - addField("baseRotation", TypeMatrixRotation, Offset(mBaseTransform, PathedInterior)); - addField("baseScale", TypePoint3F, Offset(mBaseScale, PathedInterior)); - - Parent::initPersistFields(); -} - - -//-------------------------------------------------------------------------- -bool PathedInterior::onAdd() -{ - if(!Parent::onAdd()) - return false; - - // Load the interior resource and extract the interior that is us. - mInteriorRes = ResourceManager::get().load(mInteriorResName); - if (bool(mInteriorRes) == false) - return false; - mInterior = mInteriorRes->getSubObject(mInteriorResIndex); - if (mInterior == NULL) - return false; - - // Setup bounding information - mObjBox = mInterior->getBoundingBox(); - resetWorldBox(); - - setScale(mBaseScale); - setTransform(mBaseTransform); - - if (isClientObject()) { - mNextClientPI = mClientPathedInteriors; - mClientPathedInteriors = this; - mInterior->prepForRendering(mInteriorRes.getPath().getFullPath().c_str()); -// gInteriorLMManager.addInstance(mInterior->getLMHandle(), mLMHandle, NULL, this); - } - - if(isClientObject()) - { - Point3F initialPos( 0.0, 0.0, 0.0 ); - mBaseTransform.getColumn(3, &initialPos); - Point3F pathPos( 0.0, 0.0, 0.0 ); - //gClientPathManager->getPathPosition(mPathKey, 0, pathPos); - mOffset = initialPos - pathPos; - //gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, pathPos); - MatrixF mat = getTransform(); - mat.setColumn(3, pathPos + mOffset); - setTransform(mat); - } - - addToScene(); - - return true; -} - -bool PathedInterior::onNewDataBlock( GameBaseData *dptr, bool reload ) -{ - mDataBlock = dynamic_cast(dptr); - - if ( isClientObject() ) - { - SFX_DELETE( mSustainSound ); - - if ( mDataBlock->sound[PathedInteriorData::SustainSound] ) - mSustainSound = SFX->createSource( mDataBlock->sound[PathedInteriorData::SustainSound], &getTransform() ); - - if ( mSustainSound ) - mSustainSound->play(); - } - - return Parent::onNewDataBlock(dptr,reload); -} - -void PathedInterior::onRemove() -{ - if(isClientObject()) - { - SFX_DELETE( mSustainSound ); - - PathedInterior **walk = &mClientPathedInteriors; - while(*walk) - { - if(*walk == this) - { - *walk = mNextClientPI; - break; - } - walk = &((*walk)->mNextClientPI); - } -/* if(bool(mInteriorRes) && mLMHandle != 0xFFFFFFFF) - { - if (mInterior->getLMHandle() != 0xFFFFFFFF) - gInteriorLMManager.removeInstance(mInterior->getLMHandle(), mLMHandle); - }*/ - } - removeFromScene(); - Parent::onRemove(); -} - -//------------------------------------------------------------------------------ -bool PathedInterior::buildPolyList(AbstractPolyList* list, const Box3F& wsBox, const SphereF&) -{ - if (bool(mInteriorRes) == false) - return false; - - // Setup collision state data - list->setTransform(&getTransform(), getScale()); - list->setObject(this); - - return mInterior->buildPolyList(list, wsBox, mWorldToObj, getScale()); -} - - -//-------------------------------------------------------------------------- -void PathedInterior::prepRenderImage( SceneRenderState* state ) -{ - if (mPathKey == SimPath::Path::NoPathIndex) - return; - -/* - SceneRenderImage* image = new SceneRenderImage; - image->obj = this; - state->insertRenderImage(image); -*/ -} - -extern ColorF gInteriorFogColor; - -void PathedInterior::renderObject(SceneRenderState* state) -{ -} - -void PathedInterior::resolvePathKey() -{ - if(mPathKey == 0xFFFFFFFF && !isGhost()) - { - mPathKey = getPathKey(); - Point3F pathPos( 0.0, 0.0, 0.0 ); - Point3F initialPos( 0.0, 0.0, 0.0 ); - mBaseTransform.getColumn(3, &initialPos); - //gServerPathManager->getPathPosition(mPathKey, 0, pathPos); - mOffset = initialPos - pathPos; - } -} - - -//-------------------------------------------------------------------------- -U32 PathedInterior::packUpdate(NetConnection* con, U32 mask, BitStream* stream) -{ - U32 retMask = Parent::packUpdate(con, mask, stream); - resolvePathKey(); - - if (stream->writeFlag(mask & InitialUpdateMask)) - { - // Inital update... - stream->writeString(mInteriorResName); - stream->write(mInteriorResIndex); - - stream->writeAffineTransform(mBaseTransform); - mathWrite(*stream, mBaseScale); - - stream->write(mPathKey); - } - if(stream->writeFlag((mask & NewPositionMask) && mPathKey != SimPath::Path::NoPathIndex)) - stream->writeInt(S32(mCurrentPosition), gServerPathManager->getPathTimeBits(mPathKey)); - if(stream->writeFlag((mask & NewTargetMask) && mPathKey != SimPath::Path::NoPathIndex)) - { - if(stream->writeFlag(mTargetPosition < 0)) - { - stream->writeFlag(mTargetPosition == -1); - } - else - stream->writeInt(S32(mTargetPosition), gServerPathManager->getPathTimeBits(mPathKey)); - } - return retMask; -} - -void PathedInterior::unpackUpdate(NetConnection* con, BitStream* stream) -{ - Parent::unpackUpdate(con, stream); - - MatrixF tempXForm; - Point3F tempScale; - - if (stream->readFlag()) - { - // Initial - mInteriorResName = stream->readSTString(); - stream->read(&mInteriorResIndex); - - stream->readAffineTransform(&tempXForm); - mathRead(*stream, &tempScale); - mBaseTransform = tempXForm; - mBaseScale = tempScale; - - stream->read(&mPathKey); - } - if(stream->readFlag()) - { - Point3F pathPos(0.0f, 0.0f, 0.0f); - mCurrentPosition = stream->readInt(gClientPathManager->getPathTimeBits(mPathKey)); - if(isProperlyAdded()) - { - //gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, pathPos); - MatrixF mat = getTransform(); - mat.setColumn(3, pathPos + mOffset); - setTransform(mat); - } - } - if(stream->readFlag()) - { - if(stream->readFlag()) - { - mTargetPosition = stream->readFlag() ? -1 : -2; - } - else - mTargetPosition = stream->readInt(gClientPathManager->getPathTimeBits(mPathKey)); - } -} - -void PathedInterior::processTick(const Move* move) -{ - if(isServerObject()) - { - S32 timeMs = 32; - if(mCurrentPosition != mTargetPosition) - { - S32 delta; - if(mTargetPosition == -1) - delta = timeMs; - else if(mTargetPosition == -2) - delta = -timeMs; - else - { - delta = mTargetPosition - (S32)mCurrentPosition; - if(delta < -timeMs) - delta = -timeMs; - else if(delta > timeMs) - delta = timeMs; - } - mCurrentPosition += delta; - U32 totalTime = gClientPathManager->getPathTotalTime(mPathKey); - while(mCurrentPosition > totalTime) - mCurrentPosition -= totalTime; - while(mCurrentPosition < 0) - mCurrentPosition += totalTime; - } - } -} - -void PathedInterior::computeNextPathStep(U32 timeDelta) -{ - S32 timeMs = timeDelta; - mStopped = false; - - if(mCurrentPosition == mTargetPosition) - { - mExtrudedBox = getWorldBox(); - mCurrentVelocity.set(0,0,0); - } - else - { - S32 delta = 0; - if(mTargetPosition < 0) - { - if(mTargetPosition == -1) - delta = timeMs; - else if(mTargetPosition == -2) - delta = -timeMs; - - mCurrentPosition += delta; - - U32 totalTime = gClientPathManager->getPathTotalTime(mPathKey); - - while(mCurrentPosition >= totalTime) - mCurrentPosition -= totalTime; - - while(mCurrentPosition < 0) - mCurrentPosition += totalTime; - } - else - { - delta = mTargetPosition - (S32)mCurrentPosition; - if(delta < -timeMs) - delta = -timeMs; - else if(delta > timeMs) - delta = timeMs; - mCurrentPosition += delta; - } - - Point3F curPoint; - Point3F newPoint( 0.0, 0.0, 0.0 ); - MatrixF mat = getTransform(); - mat.getColumn(3, &curPoint); - //gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, newPoint); - newPoint += mOffset; - - Point3F displaceDelta = newPoint - curPoint; - mExtrudedBox = getWorldBox(); - - if(displaceDelta.x < 0) - mExtrudedBox.minExtents.x += displaceDelta.x; - else - mExtrudedBox.maxExtents.x += displaceDelta.x; - if(displaceDelta.y < 0) - mExtrudedBox.minExtents.y += displaceDelta.y; - else - mExtrudedBox.maxExtents.y += displaceDelta.y; - if(displaceDelta.z < 0) - mExtrudedBox.minExtents.z += displaceDelta.z; - else - mExtrudedBox.maxExtents.z += displaceDelta.z; - - mCurrentVelocity = displaceDelta * 1000 / F32(timeDelta); - } - Point3F pos; - mExtrudedBox.getCenter(&pos); - MatrixF mat = getTransform(); - mat.setColumn(3, pos); - - if ( mSustainSound ) - { - mSustainSound->setTransform( mat ); - mSustainSound->setVelocity( getVelocity() ); - } -} - -Point3F PathedInterior::getVelocity() -{ - return mCurrentVelocity; -} - -void PathedInterior::advance(F64 timeDelta) -{ - if(mStopped) - return; - - if(mCurrentVelocity.len() == 0) - { -// if(mSustainHandle) -// { -// alxStop(mSustainHandle); -// mSustainHandle = 0; -// } - return; - } - MatrixF mat = getTransform(); - Point3F newPoint; - mat.getColumn(3, &newPoint); - newPoint += mCurrentVelocity * timeDelta / 1000.0f; - //gClientPathManager->getPathPosition(mPathKey, mCurrentPosition, newPoint); - mat.setColumn(3, newPoint);// + mOffset); - setTransform(mat); - setRenderTransform(mat); -} - -U32 PathedInterior::getPathKey() -{ - AssertFatal(isServerObject(), "Error, must be a server object to call this..."); - - SimGroup* myGroup = getGroup(); - AssertFatal(myGroup != NULL, "No group for this object?"); - - for (SimGroup::iterator itr = myGroup->begin(); itr != myGroup->end(); itr++) { - SimPath::Path* pPath = dynamic_cast(*itr); - if (pPath != NULL) { - U32 pathKey = pPath->getPathIndex(); - AssertFatal(pathKey != SimPath::Path::NoPathIndex, "Error, path must have event over at this point..."); - return pathKey; - } - } - - return SimPath::Path::NoPathIndex; -} - -void PathedInterior::setPathPosition(S32 newPosition) -{ - resolvePathKey(); - if(newPosition < 0) - newPosition = 0; - if(newPosition > S32(gServerPathManager->getPathTotalTime(mPathKey))) - newPosition = S32(gServerPathManager->getPathTotalTime(mPathKey)); - mCurrentPosition = mTargetPosition = newPosition; - setMaskBits(NewPositionMask | NewTargetMask); -} - -void PathedInterior::setTargetPosition(S32 newPosition) -{ - resolvePathKey(); - if(newPosition < -2) - newPosition = 0; - if(newPosition > S32(gServerPathManager->getPathTotalTime(mPathKey))) - newPosition = gServerPathManager->getPathTotalTime(mPathKey); - if(mTargetPosition != newPosition) - { - mTargetPosition = newPosition; - setMaskBits(NewTargetMask); - } -} - -ConsoleMethod(PathedInterior, setPathPosition, void, 3, 3, "") -{ - ((PathedInterior *) object)->setPathPosition(dAtoi(argv[2])); -} - -ConsoleMethod(PathedInterior, setTargetPosition, void, 3, 3, "") -{ - ((PathedInterior *) object)->setTargetPosition(dAtoi(argv[2])); -} - - -//-------------------------------------------------------------------------- -bool PathedInterior::readPI(Stream& stream) -{ - mName = stream.readSTString(); - mInteriorResName = stream.readSTString(); - stream.read(&mInteriorResIndex); - stream.read(&mPathIndex); - mathRead(stream, &mOffset); - - U32 numTriggers; - stream.read(&numTriggers); - mTriggers.setSize(numTriggers); - for (S32 i = 0; i < mTriggers.size(); i++) - mTriggers[i] = stream.readSTString(); - - return (stream.getStatus() == Stream::Ok); -} - -bool PathedInterior::writePI(Stream& stream) const -{ - stream.writeString(mName); - stream.writeString(mInteriorResName); - stream.write(mInteriorResIndex); - stream.write(mPathIndex); - mathWrite(stream, mOffset); - - stream.write(mTriggers.size()); - for (S32 i = 0; i < mTriggers.size(); i++) - stream.writeString(mTriggers[i]); - - return (stream.getStatus() == Stream::Ok); -} - -PathedInterior* PathedInterior::clone() const -{ - PathedInterior* pClone = new PathedInterior; - - pClone->mName = mName; - pClone->mInteriorResName = mInteriorResName; - pClone->mInteriorResIndex = mInteriorResIndex; - pClone->mPathIndex = mPathIndex; - pClone->mOffset = mOffset; - - return pClone; -} - - diff --git a/Engine/source/interior/pathedInterior.h b/Engine/source/interior/pathedInterior.h deleted file mode 100644 index 1f8b3672c..000000000 --- a/Engine/source/interior/pathedInterior.h +++ /dev/null @@ -1,157 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _H_PATHEDINTERIOR -#define _H_PATHEDINTERIOR - -#ifndef _INTERIOR_H_ -#include "interior/interior.h" -#endif -#ifndef _GAMEBASE_H_ -#include "T3D/gameBase/gameBase.h" -#endif -#ifndef _INTERIORRES_H_ -#include "interior/interiorRes.h" -#endif -#ifndef __RESOURCE_H__ -#include "core/resource.h" -#endif - -class InteriorInstance; -class EditGeometry; -class EditInteriorResource; -class SFXProfile; -class SFXSource; - -struct PathedInteriorData : public GameBaseData { - typedef GameBaseData Parent; -public: - enum Sounds { - StartSound, - SustainSound, - StopSound, - MaxSounds - }; - SFXProfile *sound[MaxSounds]; - static void initPersistFields(); - virtual void packData(BitStream* stream); - virtual void unpackData(BitStream* stream); - bool preload(bool server, String &errorStr); - PathedInteriorData(); - - DECLARE_CONOBJECT(PathedInteriorData); -}; - -class PathedInterior : public GameBase -{ - typedef GameBase Parent; - friend class InteriorInstance; - friend class EditGeometry; - friend class EditInteriorResource; - - PathedInteriorData *mDataBlock; - -public: - enum UpdateMasks { - NewTargetMask = Parent::NextFreeMask, - NewPositionMask = Parent::NextFreeMask << 1, - NextFreeMask = Parent::NextFreeMask << 2, - }; -private: - - U32 getPathKey(); // only used on the server - - // Persist fields - protected: - StringTableEntry mName; - S32 mPathIndex; - Vector mTriggers; - Point3F mOffset; - Box3F mExtrudedBox; - bool mStopped; - - // Loaded resources and fields - protected: - static PathedInterior *mClientPathedInteriors; - - SFXSource* mSustainSound; - - StringTableEntry mInteriorResName; - S32 mInteriorResIndex; - Resource mInteriorRes; - Interior* mInterior; - Vector mVertexColorsNormal; - Vector mVertexColorsAlarm; - - MatrixF mBaseTransform; - Point3F mBaseScale; - - U32 mPathKey; // only used on the client - F64 mCurrentPosition; - S32 mTargetPosition; - Point3F mCurrentVelocity; - - PathedInterior *mNextClientPI; - - // Rendering - protected: - void prepRenderImage( SceneRenderState *state ); - void renderObject( SceneRenderState *state ); - void renderShadowVolumes( SceneRenderState *state ); - - protected: - bool onAdd(); - void onRemove(); - - public: - PathedInterior(); - ~PathedInterior(); - - PathedInterior *getNext() { return mNextClientPI; } - - static PathedInterior *getClientPathedInteriors() { return mClientPathedInteriors; } - - void processTick(const Move* move); - void setStopped() { mStopped = true; } - void resolvePathKey(); - - bool onNewDataBlock( GameBaseData *dptr, bool reload ); - bool buildPolyList(AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere); - bool readPI(Stream&); - bool writePI(Stream&) const; - PathedInterior* clone() const; - - DECLARE_CONOBJECT(PathedInterior); - static void initPersistFields(); - void setPathPosition(S32 newPosition); - void setTargetPosition(S32 targetPosition); - void computeNextPathStep(U32 timeDelta); - Box3F getExtrudedBox() { return mExtrudedBox; } - Point3F getVelocity(); - void advance(F64 timeDelta); - - U32 packUpdate(NetConnection *conn, U32 mask, BitStream* stream); - void unpackUpdate(NetConnection *conn, BitStream* stream); -}; - -#endif // _H_PATHEDINTERIOR - diff --git a/Engine/source/lighting/basic/basicLightManager.cpp b/Engine/source/lighting/basic/basicLightManager.cpp index 0ca0e0bde..04d8b1dc7 100644 --- a/Engine/source/lighting/basic/basicLightManager.cpp +++ b/Engine/source/lighting/basic/basicLightManager.cpp @@ -44,7 +44,6 @@ #include "shaderGen/HLSL/shaderFeatureHLSL.h" #include "shaderGen/HLSL/bumpHLSL.h" #include "shaderGen/HLSL/pixSpecularHLSL.h" -#include "lighting/basic/blInteriorSystem.h" #include "lighting/basic/blTerrainSystem.h" #include "lighting/common/projectedShadow.h" @@ -95,10 +94,8 @@ BasicLightManager::BasicLightManager() { mTimer = PlatformTimer::create(); - mInteriorSystem = new blInteriorSystem; mTerrainSystem = new blTerrainSystem; - getSceneLightingInterface()->registerSystem( mInteriorSystem ); getSceneLightingInterface()->registerSystem( mTerrainSystem ); Con::addVariable( "$BasicLightManagerStats::activePlugins", @@ -152,7 +149,6 @@ BasicLightManager::~BasicLightManager() SAFE_DELETE( mTimer ); SAFE_DELETE( mTerrainSystem ); - SAFE_DELETE( mInteriorSystem ); } bool BasicLightManager::isCompatible() const diff --git a/Engine/source/lighting/basic/basicLightManager.h b/Engine/source/lighting/basic/basicLightManager.h index 4da1972be..705cb0e77 100644 --- a/Engine/source/lighting/basic/basicLightManager.h +++ b/Engine/source/lighting/basic/basicLightManager.h @@ -44,7 +44,6 @@ class GFXShaderConstHandle; class RenderPrePassMgr; class PlatformTimer; -class blInteriorSystem; class blTerrainSystem; class BasicLightManager : public LightManager @@ -121,7 +120,6 @@ protected: /// A timer used for tracking update time. PlatformTimer *mTimer; - blInteriorSystem* mInteriorSystem; blTerrainSystem* mTerrainSystem; public: diff --git a/Engine/source/lighting/basic/blInteriorSystem.cpp b/Engine/source/lighting/basic/blInteriorSystem.cpp deleted file mode 100644 index 041f1ec8e..000000000 --- a/Engine/source/lighting/basic/blInteriorSystem.cpp +++ /dev/null @@ -1,1472 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "lighting/basic/blInteriorSystem.h" -#include "lighting/lightingInterfaces.h" -#include "lighting/common/shadowVolumeBSP.h" -#include "interior/interiorInstance.h" -#include "lighting/common/sceneLightingGlobals.h" -#include "lighting/basic/basicLightManager.h" -#include "gfx/bitmap/gBitmap.h" - -//#define SET_COLORS - - -bool blInteriorSystem::smUseVertexLighting = false; - - -//------------------------------------------------------------------------------ -// Class SceneLighting::PersistInfo::InteriorChunk -//------------------------------------------------------------------------------ -struct blInteriorChunk : public PersistInfo::PersistChunk -{ - typedef PersistChunk Parent; - - blInteriorChunk(); - ~blInteriorChunk(); - - Vector sgNormalLightMaps; - - Vector mDetailLightmapCount; - Vector mDetailLightmapIndices; - Vector mLightmaps; - - bool mHasAlarmState; - Vector mDetailVertexCount; - Vector mVertexColorsNormal; - Vector mVertexColorsAlarm; - - bool read(Stream &); - bool write(Stream &); -}; - -blInteriorChunk::blInteriorChunk() -{ - mChunkType = PersistChunk::InteriorChunkType; -} - -blInteriorChunk::~blInteriorChunk() -{ - for(U32 i = 0; i < mLightmaps.size(); i++) - delete mLightmaps[i]; -} - -//------------------------------------------------------------------------------ -// - always read in vertex lighting, lightmaps may not be needed -bool blInteriorChunk::read(Stream & stream) -{ - if(!Parent::read(stream)) - return(false); - - U32 size; - U32 i; - - // lightmaps->vertex-info - // BTRTODO: FIX ME - if (true) - //if(!SceneLighting::smUseVertexLighting) - { - // size of this minichunk - if(!stream.read(&size)) - return(false); - - // lightmaps - stream.read(&size); - mDetailLightmapCount.setSize(size); - for(i = 0; i < size; i++) - if(!stream.read(&mDetailLightmapCount[i])) - return(false); - - stream.read(&size); - mDetailLightmapIndices.setSize(size); - for(i = 0; i < size; i++) - if(!stream.read(&mDetailLightmapIndices[i])) - return(false); - - if(!stream.read(&size)) - return(false); - mLightmaps.setSize(size); - - for(i = 0; i < size; i++) - { - mLightmaps[i] = new GBitmap; - if(!mLightmaps[i]->readBitmap("png",stream)) - return(false); - } - } - else - { - // step past the lightmaps - if(!stream.read(&size)) - return(false); - if(!stream.setPosition(stream.getPosition() + size)) - return(false); - } - - // size of the vertex lighting: need to reset stream position after zipStream reading - U32 zipStreamEnd; - if(!stream.read(&zipStreamEnd)) - return(false); - zipStreamEnd += stream.getPosition(); - - /* - // vertex lighting - ZipSubRStream zipStream; - if(!zipStream.attachStream(&stream)) - return(false); - - if(!zipStream.read(&size)) - return(false); - mHasAlarmState = bool(size); - - if(!zipStream.read(&size)) - return(false); - mDetailVertexCount.setSize(size); - for(i = 0; i < size; i++) - if(!zipStream.read(&mDetailVertexCount[i])) - return(false); - - size = 0; - for(i = 0; i < mDetailVertexCount.size(); i++) - size += mDetailVertexCount[i]; - - mVertexColorsNormal.setSize(size); - - if(mHasAlarmState) - mVertexColorsAlarm.setSize(size); - - U32 curPos = 0; - for(i = 0; i < mDetailVertexCount.size(); i++) - { - U32 count = mDetailVertexCount[i]; - for(U32 j = 0; j < count; j++) - if(!zipStream.read(&mVertexColorsNormal[curPos + j])) - return(false); - - // read in the alarm info - if(mHasAlarmState) - { - // same? - if(!zipStream.read(&size)) - return(false); - if(bool(size)) - dMemcpy(&mVertexColorsAlarm[curPos], &mVertexColorsNormal[curPos], count * sizeof(ColorI)); - else - { - for(U32 j = 0; j < count; j++) - if(!zipStream.read(&mVertexColorsAlarm[curPos + j])) - return(false); - } - } - - curPos += count; - } - - zipStream.detachStream(); - */ - - // since there is no resizeFilterStream the zipStream happily reads - // off the end of the compressed block... reset the position - stream.setPosition(zipStreamEnd); - - return(true); -} - -bool blInteriorChunk::write(Stream & stream) -{ - if(!Parent::write(stream)) - return(false); - - // lightmaps - U32 startPos = stream.getPosition(); - if(!stream.write(U32(0))) - return(false); - - U32 i; - if(!stream.write(U32(mDetailLightmapCount.size()))) - return(false); - for(i = 0; i < mDetailLightmapCount.size(); i++) - if(!stream.write(mDetailLightmapCount[i])) - return(false); - - if(!stream.write(U32(mDetailLightmapIndices.size()))) - return(false); - for(i = 0; i < mDetailLightmapIndices.size(); i++) - if(!stream.write(mDetailLightmapIndices[i])) - return(false); - - if(!stream.write(U32(mLightmaps.size()))) - return(false); - for(i = 0; i < mLightmaps.size(); i++) - { - AssertFatal(mLightmaps[i], "SceneLighting::blInteriorChunk::Write: Invalid bitmap!"); - if(!mLightmaps[i]->writeBitmap("png",stream)) - return(false); - } - - // write out the lightmap portions size - U32 endPos = stream.getPosition(); - if(!stream.setPosition(startPos)) - return(false); - - // don't include the offset in the size - if(!stream.write(U32(endPos - startPos - sizeof(U32)))) - return(false); - if(!stream.setPosition(endPos)) - return(false); - - - // vertex lighting: needs the size of the vertex info because the - // zip stream may read off the end of the chunk - startPos = stream.getPosition(); - if(!stream.write(U32(0))) - return(false); - - // write out the vertex lighting portions size - endPos = stream.getPosition(); - if(!stream.setPosition(startPos)) - return(false); - - // don't include the offset in the size - if(!stream.write(U32(endPos - startPos - sizeof(U32)))) - return(false); - if(!stream.setPosition(endPos)) - return(false); - - return(true); -} - -// -// InteriorProxy (definition) -// -class blInteriorProxy : public SceneLighting::ObjectProxy -{ -private: - typedef ObjectProxy Parent; - - bool isShadowedBy(blInteriorProxy *); - ShadowVolumeBSP::SVPoly * buildInteriorPoly(ShadowVolumeBSP * shadowVolumeBSP, - Interior * detail, U32 surfaceIndex, LightInfo * light, - bool createSurfaceInfo); -public: - - blInteriorProxy(SceneObject * obj); - ~blInteriorProxy(); - InteriorInstance * operator->() {return(static_cast(static_cast(mObj)));} - InteriorInstance * getObject() {return(static_cast(static_cast(mObj)));} - - // current light info - ShadowVolumeBSP * mBoxShadowBSP; - Vector mLitBoxSurfaces; - Vector mOppositeBoxPlanes; - Vector mTerrainTestPlanes; - - - struct sgSurfaceInfo - { - const Interior::Surface *sgSurface; - U32 sgIndex; - Interior *sgDetail; - bool sgHasAlarm; - }; - U32 sgCurrentSurfaceIndex; - U32 sgSurfacesPerPass; - InteriorInstance *sgInterior; - Vector sgLights; - Vector sgSurfaces; - - void sgAddLight(LightInfo *light, InteriorInstance *interior); - //void sgLightUniversalPoint(LightInfo *light); - void sgProcessSurface(const Interior::Surface &surface, U32 i, Interior *detail, bool hasAlarm); - - - // lighting interface - bool loadResources(); - void init(); - //bool tgePreLight(LightInfo* light); - bool preLight(LightInfo *); - void light(LightInfo *); - void postLight(bool lastLight); - - //virtual void processLightingStart(); - //virtual bool processStartObjectLightingEvent(SceneLighting::ObjectProxy* objproxy, U32 current, U32 max); - //virtual void processTGELightProcessEvent(U32 curr, U32 max, LightInfo*); - - virtual bool supportsShadowVolume(); - virtual void getClipPlanes(Vector& planes); - virtual void addToShadowVolume(ShadowVolumeBSP * shadowVolume, LightInfo * light, S32 level); - - // persist - U32 getResourceCRC(); - bool setPersistInfo(PersistInfo::PersistChunk *); - bool getPersistInfo(PersistInfo::PersistChunk *); -}; - -//------------------------------------------------------------------------------ -// Class SceneLighting::InteriorProxy: -//------------------------------------------------------------------------------ -blInteriorProxy::blInteriorProxy(SceneObject * obj) : -Parent(obj) -{ - mBoxShadowBSP = 0; -} - -blInteriorProxy::~blInteriorProxy() -{ - delete mBoxShadowBSP; -} - -bool blInteriorProxy::loadResources() -{ - InteriorInstance * interior = getObject(); - if(!interior) - return(false); - - Resource & interiorRes = interior->getResource(); - if(!bool(interiorRes)) - return(false); - - return(true); -} - -void blInteriorProxy::init() -{ - InteriorInstance * interior = getObject(); - if(!interior) - return; -} - -bool blInteriorProxy::supportsShadowVolume() -{ - return true; -} - -void blInteriorProxy::getClipPlanes(Vector& planes) -{ - for(U32 i = 0; i < mLitBoxSurfaces.size(); i++) - planes.push_back(mLitBoxSurfaces[i]->mPlane); -} - -ShadowVolumeBSP::SVPoly * blInteriorProxy::buildInteriorPoly(ShadowVolumeBSP * shadowVolumeBSP, - Interior * detail, U32 surfaceIndex, LightInfo * light, - bool createSurfaceInfo) -{ - InteriorInstance* interior = dynamic_cast(getObject()); - if (!interior) - return NULL; - - // transform and add the points... - const MatrixF & transform = interior->getTransform(); - const VectorF & scale = interior->getScale(); - - const Interior::Surface & surface = detail->mSurfaces[surfaceIndex]; - - ShadowVolumeBSP::SVPoly * poly = shadowVolumeBSP->createPoly(); - - poly->mWindingCount = surface.windingCount; - - // project these points - for(U32 j = 0; j < poly->mWindingCount; j++) - { - Point3F iPnt = detail->mPoints[detail->mWindings[surface.windingStart + j]].point; - Point3F tPnt; - iPnt.convolve(scale); - transform.mulP(iPnt, &tPnt); - poly->mWinding[j] = tPnt; - } - - // convert from fan - U32 tmpIndices[ShadowVolumeBSP::SVPoly::MaxWinding]; - Point3F fanIndices[ShadowVolumeBSP::SVPoly::MaxWinding]; - - tmpIndices[0] = 0; - - U32 idx = 1; - U32 i; - for(i = 1; i < poly->mWindingCount; i += 2) - tmpIndices[idx++] = i; - for(i = ((poly->mWindingCount - 1) & (~0x1)); i > 0; i -= 2) - tmpIndices[idx++] = i; - - idx = 0; - for(i = 0; i < poly->mWindingCount; i++) - if(surface.fanMask & (1 << i)) - fanIndices[idx++] = poly->mWinding[tmpIndices[i]]; - - // set the data - poly->mWindingCount = idx; - for(i = 0; i < poly->mWindingCount; i++) - poly->mWinding[i] = fanIndices[i]; - - // flip the plane - shadow volumes face inwards - PlaneF plane = detail->getPlane(surface.planeIndex); - if(!Interior::planeIsFlipped(surface.planeIndex)) - plane.neg(); - - // transform the plane - mTransformPlane(transform, scale, plane, &poly->mPlane); - shadowVolumeBSP->buildPolyVolume(poly, light); - - // do surface info? - if(createSurfaceInfo) - { - ShadowVolumeBSP::SurfaceInfo * surfaceInfo = new ShadowVolumeBSP::SurfaceInfo; - shadowVolumeBSP->mSurfaces.push_back(surfaceInfo); - - // fill it - surfaceInfo->mSurfaceIndex = surfaceIndex; - surfaceInfo->mShadowVolume = shadowVolumeBSP->getShadowVolume(poly->mShadowVolume); - - // POLY and POLY node gets it too - ShadowVolumeBSP::SVNode * traverse = shadowVolumeBSP->getShadowVolume(poly->mShadowVolume); - while(traverse->mFront) - { - traverse->mSurfaceInfo = surfaceInfo; - traverse = traverse->mFront; - } - - // get some info from the poly node - poly->mSurfaceInfo = traverse->mSurfaceInfo = surfaceInfo; - surfaceInfo->mPlaneIndex = traverse->mPlaneIndex; - } - - return(poly); -} - - -void blInteriorProxy::addToShadowVolume(ShadowVolumeBSP * shadowVolume, LightInfo * light, S32 level) -{ - if(light->getType() != LightInfo::Vector) - return; - - ColorF ambient = light->getAmbient(); - - bool shadowedTree = true; - - InteriorInstance* interior = dynamic_cast(getObject()); - if (!interior) - return; - Resource mInteriorRes = interior->getResource(); - - // check if just getting shadow detail - if(level == SceneLighting::SHADOW_DETAIL) - { - shadowedTree = false; - level = mInteriorRes->getNumDetailLevels() - 1; - } - - Interior * detail = mInteriorRes->getDetailLevel(level); - bool hasAlarm = detail->hasAlarmState(); - - // make sure surfaces do not get processed more than once - BitVector surfaceProcessed; - surfaceProcessed.setSize(detail->mSurfaces.size()); - surfaceProcessed.clear(); - - ColorI color = light->getAmbient(); - - // go through the zones of the interior and grab outside visible surfaces - for(U32 i = 0; i < detail->getNumZones(); i++) - { - Interior::Zone & zone = detail->mZones[i]; - for(U32 j = 0; j < zone.surfaceCount; j++) - { - U32 surfaceIndex = detail->mZoneSurfaces[zone.surfaceStart + j]; - - // dont reprocess a surface - if(surfaceProcessed.test(surfaceIndex)) - continue; - surfaceProcessed.set(surfaceIndex); - - Interior::Surface & surface = detail->mSurfaces[surfaceIndex]; - - // outside visible? - if(!(surface.surfaceFlags & Interior::SurfaceOutsideVisible)) - continue; - - // good surface? - PlaneF plane = detail->getPlane(surface.planeIndex); - if(Interior::planeIsFlipped(surface.planeIndex)) - plane.neg(); - - // project the plane - PlaneF projPlane; - mTransformPlane(interior->getTransform(), interior->getScale(), plane, &projPlane); - - // fill with ambient? (need to do here, because surface will not be - // added to the SVBSP tree) - F32 dot = mDot(projPlane, light->getDirection()); - if(dot > -gParellelVectorThresh)// && !(GFX->getPixelShaderVersion() > 0.0) ) - { - if(shadowedTree) - { - // alarm lighting - GFXTexHandle normHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getNormalLMapIndex(surfaceIndex)); - GFXTexHandle alarmHandle; - - GBitmap * normLightmap = normHandle->getBitmap(); - GBitmap * alarmLightmap = 0; - - // check if they share the lightmap - if(hasAlarm) - { - if(detail->getNormalLMapIndex(surfaceIndex) != detail->getAlarmLMapIndex(surfaceIndex)) - { - alarmHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getAlarmLMapIndex(surfaceIndex)); - alarmLightmap = alarmHandle->getBitmap(); - } - } - - // - // Support for interior light map border sizes. - // - U32 xlen, ylen, xoff, yoff; - U32 lmborder = detail->getLightMapBorderSize(); - xlen = surface.mapSizeX + (lmborder * 2); - ylen = surface.mapSizeY + (lmborder * 2); - xoff = surface.mapOffsetX - lmborder; - yoff = surface.mapOffsetY - lmborder; - - // attemp to light normal and alarm lighting - for(U32 c = 0; c < 2; c++) - { - GBitmap * lightmap = (c == 0) ? normLightmap : alarmLightmap; - if(!lightmap) - continue; - - // fill it - for(U32 y = 0; y < ylen; y++) - { - for(U32 x = 0; x < xlen; x++) - { - ColorI outColor(255, 0, 0, 255); - -#ifndef SET_COLORS - ColorI lmColor(0, 0, 0, 255); - lightmap->getColor(xoff + x, yoff + y, lmColor); - - U32 _r = static_cast( color.red ) + static_cast( lmColor.red ); - U32 _g = static_cast( color.green ) + static_cast( lmColor.green ); - U32 _b = static_cast( color.blue ) + static_cast( lmColor.blue ); - - outColor.red = mClamp(_r, 0, 255); - outColor.green = mClamp(_g, 0, 255); - outColor.blue = mClamp(_b, 0, 255); -#endif - - lightmap->setColor(xoff + x, yoff + y, outColor); - } - } - } - } - continue; - } - - ShadowVolumeBSP::SVPoly * poly = buildInteriorPoly(shadowVolume, detail, - surfaceIndex, light, shadowedTree); - - // insert it into the SVBSP tree - shadowVolume->insertPoly(poly); - } - } -} - -bool blInteriorProxy::preLight(LightInfo * light) -{ - // create shadow volume of the bounding box of this object - InteriorInstance * interior = getObject(); - if(!interior) - return(false); - - if(light->getType() != LightInfo::Vector) - return(false); - - // reset - mLitBoxSurfaces.clear(); - - const Box3F & objBox = interior->getObjBox(); - const MatrixF & objTransform = interior->getTransform(); - const VectorF & objScale = interior->getScale(); - - // grab the surfaces which form the shadow volume - U32 numPlanes = 0; - PlaneF testPlanes[3]; - U32 planeIndices[3]; - - // grab the bounding planes which face the light - U32 i; - for(i = 0; (i < 6) && (numPlanes < 3); i++) - { - PlaneF plane; - plane.x = BoxNormals[i].x; - plane.y = BoxNormals[i].y; - plane.z = BoxNormals[i].z; - - if(i&1) - plane.d = (((const float*)objBox.minExtents)[(i-1)>>1]); - else - plane.d = -(((const float*)objBox.maxExtents)[i>>1]); - - // project - mTransformPlane(objTransform, objScale, plane, &testPlanes[numPlanes]); - - planeIndices[numPlanes] = i; - - if(mDot(testPlanes[numPlanes], light->getDirection()) < gParellelVectorThresh) - numPlanes++; - } - AssertFatal(numPlanes, "blInteriorProxy::preLight: no planes found"); - - // project the points - Point3F projPnts[8]; - for(i = 0; i < 8; i++) - { - Point3F pnt; - pnt.set(BoxPnts[i].x ? objBox.maxExtents.x : objBox.minExtents.x, - BoxPnts[i].y ? objBox.maxExtents.y : objBox.minExtents.y, - BoxPnts[i].z ? objBox.maxExtents.z : objBox.minExtents.z); - - // scale it - pnt.convolve(objScale); - objTransform.mulP(pnt, &projPnts[i]); - } - - mBoxShadowBSP = new ShadowVolumeBSP; - - // insert the shadow volumes for the surfaces - for(i = 0; i < numPlanes; i++) - { - ShadowVolumeBSP::SVPoly * poly = mBoxShadowBSP->createPoly(); - poly->mWindingCount = 4; - - U32 j; - for(j = 0; j < 4; j++) - poly->mWinding[j] = projPnts[BoxVerts[planeIndices[i]][j]]; - - testPlanes[i].neg(); - poly->mPlane = testPlanes[i]; - - mBoxShadowBSP->buildPolyVolume(poly, light); - mLitBoxSurfaces.push_back(mBoxShadowBSP->copyPoly(poly)); - mBoxShadowBSP->insertPoly(poly); - - // create the opposite planes for testing against terrain - Point3F pnts[3]; - for(j = 0; j < 3; j++) - pnts[j] = projPnts[BoxVerts[planeIndices[i]^1][j]]; - PlaneF plane(pnts[2], pnts[1], pnts[0]); - mOppositeBoxPlanes.push_back(plane); - } - - // grab the unique planes for terrain checks - for(i = 0; i < numPlanes; i++) - { - U32 mask = 0; - for(U32 j = 0; j < numPlanes; j++) - mask |= BoxSharedEdgeMask[planeIndices[i]][planeIndices[j]]; - - ShadowVolumeBSP::SVNode * traverse = mBoxShadowBSP->getShadowVolume(mLitBoxSurfaces[i]->mShadowVolume); - while(traverse->mFront) - { - if(!(mask & 1)) - mTerrainTestPlanes.push_back(mBoxShadowBSP->getPlane(traverse->mPlaneIndex)); - - mask >>= 1; - traverse = traverse->mFront; - } - } - - // there will be 2 duplicate node planes if there were only 2 planes lit - if(numPlanes == 2) - { - for(S32 i = 0; i < mTerrainTestPlanes.size(); i++) - for(U32 j = 0; j < mTerrainTestPlanes.size(); j++) - { - if(i == j) - continue; - - if((mDot(mTerrainTestPlanes[i], mTerrainTestPlanes[j]) > gPlaneNormThresh) && - (mFabs(mTerrainTestPlanes[i].d - mTerrainTestPlanes[j].d) < gPlaneDistThresh)) - { - mTerrainTestPlanes.erase(i); - i--; - break; - } - } - } - - return(true); -} - -bool blInteriorProxy::isShadowedBy(blInteriorProxy * test) -{ - // add if overlapping world box - if((*this)->getWorldBox().isOverlapped((*test)->getWorldBox())) - return(true); - - // test the box shadow volume - for(U32 i = 0; i < mLitBoxSurfaces.size(); i++) - { - ShadowVolumeBSP::SVPoly * poly = mBoxShadowBSP->copyPoly(mLitBoxSurfaces[i]); - if(test->mBoxShadowBSP->testPoly(poly)) - return(true); - } - - return(false); -} - -void blInteriorProxy::light(LightInfo * light) -{ - Platform::setMathControlStateKnown(); - - InteriorInstance * interior = getObject(); - if(!interior) - return; - - ColorF ambient = light->getAmbient(); - - S32 time = Platform::getRealMilliseconds(); - - // create own shadow volume - ShadowVolumeBSP shadowVolume; - - // add the other objects lit surfaces into shadow volume - for(ObjectProxy ** itr = gLighting->mLitObjects.begin(); itr != gLighting->mLitObjects.end(); itr++) - { - if(!(*itr)->getObject()) - continue; - - ObjectProxy* obj = *itr; - if (obj != this) - { - if (obj->supportsShadowVolume()) - obj->addToShadowVolume(&shadowVolume, light, SceneLighting::SHADOW_DETAIL); - } - -/* - // insert the terrain squares - if(gLighting->isTerrain((*itr)->mObj)) - { - TerrainProxy * terrain = static_cast(*itr); - - Vector clipPlanes; - clipPlanes = mTerrainTestPlanes; - for(U32 i = 0; i < mOppositeBoxPlanes.size(); i++) - clipPlanes.push_back(mOppositeBoxPlanes[i]); - - Vector shadowList; - if(terrain->getShadowedSquares(clipPlanes, shadowList)) - { - TerrainBlock * block = static_cast((*itr)->getObject()); - Point3F offset; - block->getTransform().getColumn(3, &offset); - - F32 squareSize = block->getSquareSize(); - - for(U32 j = 0; j < shadowList.size(); j++) - { - Point2I pos(shadowList[j] & TerrainBlock::BlockMask, shadowList[j] >> TerrainBlock::BlockShift); - Point2F wPos(pos.x * squareSize + offset.x, - pos.y * squareSize + offset.y); - - Point3F pnts[4]; - pnts[0].set(wPos.x, wPos.y, fixedToFloat(block->getHeight(pos.x, pos.y))); - pnts[1].set(wPos.x + squareSize, wPos.y, fixedToFloat(block->getHeight(pos.x + 1, pos.y))); - pnts[2].set(wPos.x + squareSize, wPos.y + squareSize, fixedToFloat(block->getHeight(pos.x + 1, pos.y + 1))); - pnts[3].set(wPos.x, wPos.y + squareSize, fixedToFloat(block->getHeight(pos.x, pos.y + 1))); - - GridSquare * gs = block->findSquare(0, pos); - - U32 squareIdx = (gs->flags & GridSquare::Split45) ? 0 : 2; - - for(U32 k = squareIdx; k < (squareIdx + 2); k++) - { - // face plane inwards - PlaneF plane(pnts[TerrainSquareIndices[k][2]], - pnts[TerrainSquareIndices[k][1]], - pnts[TerrainSquareIndices[k][0]]); - - if(mDot(plane, light->mDirection) > gParellelVectorThresh) - { - ShadowVolumeBSP::SVPoly * poly = shadowVolume.createPoly(); - poly->mWindingCount = 3; - - poly->mWinding[0] = pnts[TerrainSquareIndices[k][0]]; - poly->mWinding[1] = pnts[TerrainSquareIndices[k][1]]; - poly->mWinding[2] = pnts[TerrainSquareIndices[k][2]]; - poly->mPlane = plane; - - // create the shadow volume for this and insert - shadowVolume.buildPolyVolume(poly, light); - shadowVolume.insertPoly(poly); - } - } - } - } - }*/ - } - - // light all details - for(U32 i = 0; i < interior->getResource()->getNumDetailLevels(); i++) - { - // clear lightmaps - Interior * detail = interior->getResource()->getDetailLevel(i); - gInteriorLMManager.clearLightmaps(detail->getLMHandle(), interior->getLMHandle()); - - // clear out the last inserted interior - shadowVolume.removeLastInterior(); - - bool hasAlarm = detail->hasAlarmState(); - - addToShadowVolume(&shadowVolume, light, i); - - //gLighting->addInterior(&shadowVolume, *this, light, i); - - for(U32 j = 0; j < shadowVolume.mSurfaces.size(); j++) - { - ShadowVolumeBSP::SurfaceInfo * surfaceInfo = shadowVolume.mSurfaces[j]; - - U32 surfaceIndex = surfaceInfo->mSurfaceIndex; - - const Interior::Surface & surface = detail->getSurface(surfaceIndex); - - // alarm lighting - GFXTexHandle normHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getNormalLMapIndex(surfaceIndex)); - GFXTexHandle alarmHandle; - - GBitmap * normLightmap = normHandle->getBitmap(); - GBitmap * alarmLightmap = 0; - - // check if the lightmaps are shared - if(hasAlarm) - { - if(detail->getNormalLMapIndex(surfaceIndex) != detail->getAlarmLMapIndex(surfaceIndex)) - { - alarmHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getAlarmLMapIndex(surfaceIndex)); - alarmLightmap = alarmHandle->getBitmap(); - } - } - - // points right way? - PlaneF plane = detail->getPlane(surface.planeIndex); - if(Interior::planeIsFlipped(surface.planeIndex)) - plane.neg(); - - const MatrixF & transform = interior->getTransform(); - const Point3F & scale = interior->getScale(); - - // - PlaneF projPlane; - mTransformPlane(transform, scale, plane, &projPlane); - - F32 dot = mDot(projPlane, -light->getDirection()); - - // cancel out lambert dot product and ambient lighting on hardware - // with pixel shaders - if( GFX->getPixelShaderVersion() > 0.0 ) - { - dot = 1.0f; - ambient.set( 0.0f, 0.0f, 0.0f ); - } - - // shadowed? - if(!surfaceInfo->mShadowed.size()) - { - // calc the color and convert to U8 rep - ColorF tmp = (light->getColor() * dot) + ambient; - tmp.clamp(); - ColorI color = tmp; - - // attempt to light both the normal and the alarm states - for(U32 c = 0; c < 2; c++) - { - GBitmap * lightmap = (c == 0) ? normLightmap : alarmLightmap; - if(!lightmap) - continue; - - // - // Support for interior light map border sizes. - // - U32 xlen, ylen, xoff, yoff; - U32 lmborder = detail->getLightMapBorderSize(); - xlen = surface.mapSizeX + (lmborder * 2); - ylen = surface.mapSizeY + (lmborder * 2); - xoff = surface.mapOffsetX - lmborder; - yoff = surface.mapOffsetY - lmborder; - - // fill it - for(U32 y = 0; y < ylen; y++) - { - for(U32 x = 0; x < xlen; x++) - { - ColorI outColor(0, 255, 0, 255); - -#ifndef SET_COLORS - ColorI lmColor(0, 0, 0, 255); - lightmap->getColor(xoff + x, yoff + y, lmColor); - - U32 _r = static_cast( color.red ) + static_cast( lmColor.red ); - U32 _g = static_cast( color.green ) + static_cast( lmColor.green ); - U32 _b = static_cast( color.blue ) + static_cast( lmColor.blue ); - - outColor.red = mClamp(_r, 0, 255); - outColor.green = mClamp(_g, 0, 255); - outColor.blue = mClamp(_b, 0, 255); -#endif - - lightmap->setColor(xoff + x, yoff + y, outColor); - } - } - } - if(!surfaceInfo->mShadowed.size()) - continue; - } - - // - // Support for interior light map border sizes. - // - U32 xlen, ylen, xoff, yoff; - U32 lmborder = detail->getLightMapBorderSize(); - xlen = surface.mapSizeX + (lmborder * 2); - ylen = surface.mapSizeY + (lmborder * 2); - xoff = surface.mapOffsetX - lmborder; - yoff = surface.mapOffsetY - lmborder; - - // get the lmagGen... - const Interior::TexGenPlanes & lmTexGenEQ = detail->getLMTexGenEQ(surfaceIndex); - - const F32 * const lGenX = lmTexGenEQ.planeX; - const F32 * const lGenY = lmTexGenEQ.planeY; - - AssertFatal((lGenX[0] * lGenX[1] == 0.f) && - (lGenX[0] * lGenX[2] == 0.f) && - (lGenX[1] * lGenX[2] == 0.f), "Bad lmTexGen!"); - AssertFatal((lGenY[0] * lGenY[1] == 0.f) && - (lGenY[0] * lGenY[2] == 0.f) && - (lGenY[1] * lGenY[2] == 0.f), "Bad lmTexGen!"); - - // get the axis index for the texgens (could be swapped) - S32 si=0; - S32 ti=0; - S32 axis = -1; - - // - if(lGenX[0] == 0.f && lGenY[0] == 0.f) // YZ - { - axis = 0; - if(lGenX[1] == 0.f) { // swapped? - si = 2; - ti = 1; - } else { - si = 1; - ti = 2; - } - } - else if(lGenX[1] == 0.f && lGenY[1] == 0.f) // XZ - { - axis = 1; - if(lGenX[0] == 0.f) { // swapped? - si = 2; - ti = 0; - } else { - si = 0; - ti = 2; - } - } - else if(lGenX[2] == 0.f && lGenY[2] == 0.f) // XY - { - axis = 2; - if(lGenX[0] == 0.f) { // swapped? - si = 1; - ti = 0; - } else { - si = 0; - ti = 1; - } - } - AssertFatal(!(axis == -1), "SceneLighting::lightInterior: bad TexGen!"); - - const F32 * pNormal = ((const F32*)plane); - - Point3F start; - F32 * pStart = ((F32*)start); - - F32 lumelScale = 1.0 / (lGenX[si] * normLightmap->getWidth()); - - // get the start point on the lightmap - pStart[si] = (((xoff * lumelScale) / (1.0 / lGenX[si])) - lGenX[3] ) / lGenX[si]; - pStart[ti] = (((yoff * lumelScale) / (1.0 / lGenY[ti])) - lGenY[3] ) / lGenY[ti]; - pStart[axis] = ((pNormal[si] * pStart[si]) + (pNormal[ti] * pStart[ti]) + plane.d) / -pNormal[axis]; - - start.convolve(scale); - transform.mulP(start); - - // get the s/t vecs oriented on the surface - Point3F sVec; - Point3F tVec; - - F32 * pSVec = ((F32*)sVec); - F32 * pTVec = ((F32*)tVec); - - F32 angle; - Point3F planeNormal; - - // s - pSVec[si] = 1.f; - pSVec[ti] = 0.f; - - planeNormal = plane; - ((F32*)planeNormal)[ti] = 0.f; - planeNormal.normalize(); - - angle = mAcos(mClampF(((F32*)planeNormal)[axis], -1.f, 1.f)); - pSVec[axis] = (((F32*)planeNormal)[si] < 0.f) ? mTan(angle) : -mTan(angle); - - // t - pTVec[ti] = 1.f; - pTVec[si] = 0.f; - - planeNormal = plane; - ((F32*)planeNormal)[si] = 0.f; - planeNormal.normalize(); - - angle = mAcos(mClampF(((F32*)planeNormal)[axis], -1.f, 1.f)); - pTVec[axis] = (((F32*)planeNormal)[ti] < 0.f) ? mTan(angle) : -mTan(angle); - - // scale the vectors - - sVec *= lumelScale; - tVec *= lumelScale; - - // project vecs - transform.mulV(sVec); - sVec.convolve(scale); - - transform.mulV(tVec); - tVec.convolve(scale); - - Point3F & curPos = start; - Point3F sRun = sVec * xlen; - - // get the lexel area - Point3F cross; - mCross(sVec, tVec, &cross); - F32 maxLexelArea = cross.len(); - - const PlaneF & surfacePlane = shadowVolume.getPlane(surfaceInfo->mPlaneIndex); - - // get the world coordinate for each lexel - for(U32 y = 0; y < ylen; y++) - { - for(U32 x = 0; x < xlen; x++) - { - ShadowVolumeBSP::SVPoly * poly = shadowVolume.createPoly(); - poly->mPlane = surfacePlane; - poly->mWindingCount = 4; - - // set the poly indices - poly->mWinding[0] = curPos; - poly->mWinding[1] = curPos + sVec; - poly->mWinding[2] = curPos + sVec + tVec; - poly->mWinding[3] = curPos + tVec; - - //// insert poly which has been clipped to own shadow volume - //ShadowVolumeBSP::SVPoly * store = 0; - //shadowVolume.clipToSelf(surfaceInfo->mShadowVolume, &store, poly); - - //if(!store) - // continue; - - //F32 lexelArea = shadowVolume.getPolySurfaceArea(store); - //F32 area = shadowVolume.getLitSurfaceArea(store, surfaceInfo); - - F32 area = shadowVolume.getLitSurfaceArea(poly, surfaceInfo); - F32 shadowScale = mClampF(area / maxLexelArea, 0.f, 1.f); - - // get the color into U8 - ColorF tmp = (light->getColor() * dot * shadowScale) + ambient; - tmp.clamp(); - ColorI color = tmp; - - // attempt to light both normal and alarm lightmaps - for(U32 c = 0; c < 2; c++) - { - GBitmap * lightmap = (c == 0) ? normLightmap : alarmLightmap; - if(!lightmap) - continue; - - ColorI outColor(0, 0, 255, 255); - -#ifndef SET_COLORS - ColorI lmColor(0, 0, 0, 255); - lightmap->getColor(xoff + x, yoff + y, lmColor); - - U32 _r = static_cast( color.red ) + static_cast( lmColor.red ); - U32 _g = static_cast( color.green ) + static_cast( lmColor.green ); - U32 _b = static_cast( color.blue ) + static_cast( lmColor.blue ); - - outColor.red = mClamp(_r, 0, 255); - outColor.green = mClamp(_g, 0, 255); - outColor.blue = mClamp(_b, 0, 255); -#endif - - lightmap->setColor(xoff + x, yoff + y, outColor); - } - - curPos += sVec; - } - - curPos -= sRun; - curPos += tVec; - } - } - } - - Con::printf(" = interior lit in %3.3f seconds", (Platform::getRealMilliseconds()-time)/1000.f); -} - -void blInteriorProxy::postLight(bool lastLight) -{ - delete mBoxShadowBSP; - mBoxShadowBSP = 0; - - InteriorInstance * interior = getObject(); - if(!interior) - return; -} - -//------------------------------------------------------------------------------ -U32 blInteriorProxy::getResourceCRC() -{ - InteriorInstance * interior = getObject(); - if(!interior) - return(0); - return(interior->getCRC()); -} - -//------------------------------------------------------------------------------ -bool blInteriorProxy::setPersistInfo(PersistInfo::PersistChunk * info) -{ - - if(!Parent::setPersistInfo(info)) - return(false); - - blInteriorChunk * chunk = dynamic_cast(info); - AssertFatal(chunk, "blInteriorProxy::setPersistInfo: invalid info chunk!"); - - InteriorInstance * interior = getObject(); - if(!interior) - return(false); - - U32 numDetails = interior->getNumDetailLevels(); - - // check the lighting method -// BTRTODO: Restore -// AssertFatal(SceneLighting::smUseVertexLighting == Interior::smUseVertexLighting, "blInteriorProxy::setPersistInfo: invalid vertex lighting state"); -// if(SceneLighting::smUseVertexLighting != Interior::smUseVertexLighting) -// return(false); - - /* - // process the vertex lighting... - if(chunk->mDetailVertexCount.size() != numDetails) - return(false); - - AssertFatal(chunk->mVertexColorsNormal.size(), "blInteriorProxy::setPersistInfo: invalid chunk info"); - AssertFatal(!chunk->mHasAlarmState || chunk->mVertexColorsAlarm.size(), "blInteriorProxy::setPersistInfo: invalid chunk info"); - AssertFatal(!(chunk->mHasAlarmState ^ interior->getDetailLevel(0)->hasAlarmState()), "blInteriorProxy::setPersistInfo: invalid chunk info"); - - - U32 curPos = 0; - for(U32 i = 0; i < numDetails; i++) - { - U32 count = chunk->mDetailVertexCount[i]; - Vector* normal = interior->getVertexColorsNormal(i); - Vector* alarm = interior->getVertexColorsAlarm(i); - AssertFatal(normal != NULL && alarm != NULL, "Error, bad vectors returned!"); - - normal->setSize(count); - dMemcpy(normal->address(), &chunk->mVertexColorsNormal[curPos], count * sizeof(ColorI)); - - if(chunk->mHasAlarmState) - { - alarm->setSize(count); - dMemcpy(alarm->address(), &chunk->mVertexColorsAlarm[curPos], count * sizeof(ColorI)); - } - - curPos += count; - } - */ - // need lightmaps? - //if(!SceneLighting::smUseVertexLighting) - // BTRTODO: Fix me - if (!false) - { - if(chunk->mDetailLightmapCount.size() != numDetails) - return(false); - - LM_HANDLE instanceHandle = interior->getLMHandle(); - U32 idx = 0; - - for(U32 i = 0; i < numDetails; i++) - { - Interior * detail = interior->getDetailLevel(i); - - LM_HANDLE interiorHandle = detail->getLMHandle(); - Vector & baseHandles = gInteriorLMManager.getHandles(interiorHandle, 0); - - if(chunk->mDetailLightmapCount[i] > baseHandles.size()) - return(false); - - for(U32 j = 0; j < chunk->mDetailLightmapCount[i]; j++) - { - U32 baseIndex = chunk->mDetailLightmapIndices[idx]; - if(baseIndex >= baseHandles.size()) - return(false); - - AssertFatal(chunk->mLightmaps[idx], "blInteriorProxy::setPersistInfo: bunk bitmap!"); - if(chunk->mLightmaps[idx]->getWidth() != baseHandles[baseIndex]->getWidth() || - chunk->mLightmaps[idx]->getHeight() != baseHandles[baseIndex]->getHeight()) - return(false); - - GFXTexHandle tHandle = gInteriorLMManager.duplicateBaseLightmap(interiorHandle, instanceHandle, baseIndex); - - // create the diff bitmap - tHandle->getBitmap()->combine( baseHandles[baseIndex]->getBitmap(), - chunk->mLightmaps[idx], - GFXTOPAdd ); - - idx++; - } - } - } - - return(true); -} - -bool blInteriorProxy::getPersistInfo(PersistInfo::PersistChunk * info) -{ - if(!Parent::getPersistInfo(info)) - return(false); - - blInteriorChunk* chunk = dynamic_cast(info); - AssertFatal(chunk, "blInteriorProxy::getPersistInfo: invalid info chunk!"); - - InteriorInstance * interior = getObject(); - if(!interior) - return(false); - - LM_HANDLE instanceHandle = interior->getLMHandle(); - - AssertFatal(!chunk->mDetailLightmapCount.size(), "blInteriorProxy::getPersistInfo: invalid array!"); - AssertFatal(!chunk->mDetailLightmapIndices.size(), "blInteriorProxy::getPersistInfo: invalid array!"); - AssertFatal(!chunk->mLightmaps.size(), "blInteriorProxy::getPersistInfo: invalid array!"); - - U32 numDetails = interior->getNumDetailLevels(); - U32 i; - for(i = 0; i < numDetails; i++) - { - Interior * detail = interior->getDetailLevel(i); - LM_HANDLE interiorHandle = detail->getLMHandle(); - - Vector & baseHandles = gInteriorLMManager.getHandles(interiorHandle, 0); - Vector & instanceHandles = gInteriorLMManager.getHandles(interiorHandle, instanceHandle); - - U32 litCount = 0; - - // walk all the instance lightmaps and grab diff lighting from them - for(U32 j = 0; j < instanceHandles.size(); j++) - { - if(!instanceHandles[j]) - continue; - - litCount++; - chunk->mDetailLightmapIndices.push_back(j); - - GBitmap * baseBitmap = baseHandles[j]->getBitmap(); - GBitmap * instanceBitmap = instanceHandles[j]->getBitmap(); - - Point2I extent(baseBitmap->getWidth(), baseBitmap->getHeight()); - - GBitmap * diffLightmap = new GBitmap(extent.x, extent.y, false); - - // diffLightmap = instanceBitmap - baseBitmap - diffLightmap->combine( instanceBitmap, baseBitmap, GFXTOPSubtract ); - - chunk->mLightmaps.push_back(diffLightmap); - } - - chunk->mDetailLightmapCount.push_back(litCount); - } - - // process the vertex lighting... - AssertFatal(!chunk->mDetailVertexCount.size(), "blInteriorProxy::getPersistInfo: invalid chunk info"); - AssertFatal(!chunk->mVertexColorsNormal.size(), "blInteriorProxy::getPersistInfo: invalid chunk info"); - AssertFatal(!chunk->mVertexColorsAlarm.size(), "blInteriorProxy::getPersistInfo: invalid chunk info"); - - chunk->mHasAlarmState = interior->getDetailLevel(0)->hasAlarmState(); - chunk->mDetailVertexCount.setSize(numDetails); - - U32 size = 0; - for(i = 0; i < numDetails; i++) - { - Interior * detail = interior->getDetailLevel(i); - - U32 count = detail->getWindingCount(); - chunk->mDetailVertexCount[i] = count; - size += count; - } - - /* - chunk->mVertexColorsNormal.setSize(size); - if(chunk->mHasAlarmState) - chunk->mVertexColorsAlarm.setSize(size); - - U32 curPos = 0; - for(i = 0; i < numDetails; i++) - { - Vector* normal = interior->getVertexColorsNormal(i); - Vector* alarm = interior->getVertexColorsAlarm(i); - AssertFatal(normal != NULL && alarm != NULL, "Error, no normal or alarm vertex colors!"); - - U32 count = chunk->mDetailVertexCount[i]; - dMemcpy(&chunk->mVertexColorsNormal[curPos], normal->address(), count * sizeof(ColorI)); - - if(chunk->mHasAlarmState) - dMemcpy(&chunk->mVertexColorsAlarm[curPos], alarm->address(), count * sizeof(ColorI)); - - curPos += count; - } - */ - - return(true); -} - - -SceneLighting::ObjectProxy* blInteriorSystem::createObjectProxy(SceneObject* obj, SceneLighting::ObjectProxyList* sceneObjects) -{ - if ((obj->getTypeMask() & InteriorObjectType) != 0) - { - return new blInteriorProxy(obj); - } else { - return NULL; - } -} - -PersistInfo::PersistChunk* blInteriorSystem::createPersistChunk(const U32 chunkType) -{ - if (chunkType == PersistInfo::PersistChunk::InteriorChunkType) - { - return new blInteriorChunk; - } else { - return NULL; - } -} - -bool blInteriorSystem::createPersistChunkFromProxy(SceneLighting::ObjectProxy* objproxy, PersistInfo::PersistChunk **ret) -{ - if ((objproxy->mObj->getTypeMask() & InteriorObjectType) != 0) - { - *ret = new blInteriorChunk; - return true; - } else { - return false; - } -} - -void blInteriorSystem::init() -{ - -} - -U32 blInteriorSystem::addObjectType() -{ - return InteriorObjectType; -} - -U32 blInteriorSystem::addToClippingMask() -{ - return InteriorObjectType; -} - -void blInteriorSystem::processLightingBegin() -{ - // Store the vertex lighting state when we being lighting, we compare this when we finish lighting - smUseVertexLighting = Interior::smUseVertexLighting; -} - -void blInteriorSystem::processLightingCompleted(bool success) -{ - if(success) - { - AssertFatal(smUseVertexLighting == Interior::smUseVertexLighting, "SceneLighting::completed: vertex lighting state changed during scene light"); - - // cannot do anything if vertex state has changed (since we only load in what is needed) - if(smUseVertexLighting == Interior::smUseVertexLighting) - { - if(!smUseVertexLighting) - { - gInteriorLMManager.downloadGLTextures(); - gInteriorLMManager.destroyBitmaps(); - } - else - gInteriorLMManager.destroyTextures(); - } - } -} - -// Given a ray, this will return the color from the lightmap of this object, return true if handled -bool blInteriorSystem::getColorFromRayInfo(RayInfo collision, ColorF& result) -{ - InteriorInstance* interior = dynamic_cast(collision.object); - if (interior == NULL) - return false; - - interior->getRenderWorldTransform().mulP(collision.point); - Interior *detail = interior->getDetailLevel(0); - AssertFatal((detail), "SceneObject::getLightingAmbientColor: invalid interior"); - if(collision.face < detail->getSurfaceCount()) - { - const Interior::Surface &surface = detail->getSurface(collision.face); - const Interior::TexGenPlanes &texgen = detail->getLMTexGenEQ(collision.face); - - GBitmap* lightmap = gInteriorLMManager.getHandle(detail->getLMHandle(), - interior->getLMHandle(), detail->getNormalLMapIndex(collision.face)).getBitmap(); - if (!lightmap) - return false; - - Point2F uv; - uv.x = mDot(texgen.planeX, collision.point) + texgen.planeX.d; - uv.y = mDot(texgen.planeY, collision.point) + texgen.planeY.d; - - U32 size = (U32)(uv.x * F32(lightmap->getWidth())); - size = mClamp(size, surface.mapOffsetX, (surface.mapOffsetX + surface.mapSizeX)); - uv.x = F32(size) / F32(lightmap->getWidth()); - - size = (U32)(uv.y * F32(lightmap->getHeight())); - size = mClamp(size, surface.mapOffsetY, (surface.mapOffsetY + surface.mapSizeY)); - uv.y = F32(size) / F32(lightmap->getHeight()); - - result = lightmap->sampleTexel(uv.x, uv.y); - return true; - } - return false; -} diff --git a/Engine/source/lighting/basic/blInteriorSystem.h b/Engine/source/lighting/basic/blInteriorSystem.h deleted file mode 100644 index 604963d88..000000000 --- a/Engine/source/lighting/basic/blInteriorSystem.h +++ /dev/null @@ -1,57 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _BLINTERIOSYSTEM_H_ -#define _BLINTERIOSYSTEM_H_ - -#ifndef _SCENELIGHTING_H_ - #include "lighting/common/sceneLighting.h" -#endif -#ifndef _SG_SYSTEM_INTERFACE_H - #include "lighting/lightingInterfaces.h" -#endif - - -// -// Lighting system interface -// -class blInteriorSystem : public SceneLightingInterface -{ -public: - static bool smUseVertexLighting; - - virtual SceneLighting::ObjectProxy* createObjectProxy(SceneObject* obj, SceneLighting::ObjectProxyList* sceneObjects); - virtual PersistInfo::PersistChunk* createPersistChunk(const U32 chunkType); - virtual bool createPersistChunkFromProxy(SceneLighting::ObjectProxy* objproxy, PersistInfo::PersistChunk **ret); - - virtual void init(); - virtual U32 addObjectType(); - virtual U32 addToClippingMask(); - - virtual void processLightingBegin(); - virtual void processLightingCompleted(bool success); - - // Given a ray, this will return the color from the lightmap of this object, return true if handled - virtual bool getColorFromRayInfo(RayInfo collision, ColorF& result); -}; - -#endif // !_BLINTERIOSYSTEM_H_ diff --git a/Engine/source/lighting/common/blobShadow.cpp b/Engine/source/lighting/common/blobShadow.cpp index ce1397cd1..0dfce8b15 100644 --- a/Engine/source/lighting/common/blobShadow.cpp +++ b/Engine/source/lighting/common/blobShadow.cpp @@ -37,7 +37,7 @@ DepthSortList BlobShadow::smDepthSortList; GFXTexHandle BlobShadow::smGenericShadowTexture = NULL; S32 BlobShadow::smGenericShadowDim = 32; -U32 BlobShadow::smShadowMask = TerrainObjectType | InteriorObjectType; +U32 BlobShadow::smShadowMask = TerrainObjectType; F32 BlobShadow::smGenericRadiusSkew = 0.4f; // shrink radius of shape when it always uses generic shadow... Box3F gBlobShadowBox; diff --git a/Engine/source/lighting/common/sceneLighting.cpp b/Engine/source/lighting/common/sceneLighting.cpp index fe73f0086..f542753ab 100644 --- a/Engine/source/lighting/common/sceneLighting.cpp +++ b/Engine/source/lighting/common/sceneLighting.cpp @@ -40,14 +40,6 @@ #include "core/stream/fileStream.h" #include "core/crc.h" -//#define DUMP_LIGHTMAPS - -#ifdef DUMP_LIGHTMAPS -#include "interior/interiorInstance.h" -#include "core/volume.h" -#endif - - namespace { bool gTerminateLighting = false; @@ -394,23 +386,6 @@ void SceneLighting::sgSGObjectCompleteEvent(S32 object) // only the last light does something mLitObjects[object]->postLight(true); -#ifdef DUMP_LIGHTMAPS - InteriorInstance *interiorinst = dynamic_cast(mLitObjects[object]->getObject()); - if(interiorinst) - { - Interior *detail = interiorinst->getDetailLevel(0); - for(U32 i=0; imNormalLMapIndices.size(); i++) - { - GFXTexHandle normHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), - interiorinst->getLMHandle(), detail->getNormalLMapIndex(i)); - GBitmap *normLightmap = normHandle->getBitmap(); - - FileStream output; - output.open(avar("lightmaps/lm_%d_%d.png", object, i), Torque::FS::File::Write); - normLightmap->writeBitmap("png",output); - } - } -#endif /*ObjectProxy *obj = mLitObjects[object]; for(U32 i=0; iaddManager( new RenderMeshMgr(RenderPassManager::RIT_Mesh, 0.3f, 0.3f) ); - mShadowRPM->addManager( new RenderMeshMgr( RenderPassManager::RIT_Interior, 0.4f, 0.4f ) ); //mShadowRPM->addManager( new RenderObjectMgr() ); mShadowRPM->addManager( new RenderTerrainMgr( 0.5f, 0.5f ) ); mShadowRPM->addManager( new RenderImposterMgr( 0.6f, 0.6f ) ); @@ -231,7 +230,7 @@ void ShadowRenderPassManager::addInst( RenderInst *inst ) { PROFILE_SCOPE(ShadowRenderPassManager_addInst); - if ( inst->type == RIT_Mesh || inst->type == RIT_Interior ) + if ( inst->type == RIT_Mesh ) { MeshRenderInst *meshRI = static_cast( inst ); if ( !meshRI->matInst ) diff --git a/Engine/source/renderInstance/renderBinManager.h b/Engine/source/renderInstance/renderBinManager.h index c906eeaf8..cc5bbe6c3 100644 --- a/Engine/source/renderInstance/renderBinManager.h +++ b/Engine/source/renderInstance/renderBinManager.h @@ -159,7 +159,6 @@ inline bool RenderBinManager::newPassNeeded( MeshRenderInst *ri, MeshRenderInst* inline BaseMatInstance* RenderBinManager::getMaterial( RenderInst *inst ) const { if ( inst->type == RenderPassManager::RIT_Mesh || - inst->type == RenderPassManager::RIT_Interior || inst->type == RenderPassManager::RIT_Decal || inst->type == RenderPassManager::RIT_Translucent ) return static_cast(inst)->matInst; diff --git a/Engine/source/renderInstance/renderGlowMgr.cpp b/Engine/source/renderInstance/renderGlowMgr.cpp index 58fd8843c..547d20a7f 100644 --- a/Engine/source/renderInstance/renderGlowMgr.cpp +++ b/Engine/source/renderInstance/renderGlowMgr.cpp @@ -86,7 +86,6 @@ RenderGlowMgr::RenderGlowMgr() GFXFormatR8G8B8A8, Point2I( 512, 512 ) ) { - notifyType( RenderPassManager::RIT_Interior ); notifyType( RenderPassManager::RIT_Decal ); notifyType( RenderPassManager::RIT_Translucent ); diff --git a/Engine/source/renderInstance/renderPassManager.cpp b/Engine/source/renderInstance/renderPassManager.cpp index 8a2e44c11..33e74839e 100644 --- a/Engine/source/renderInstance/renderPassManager.cpp +++ b/Engine/source/renderInstance/renderPassManager.cpp @@ -44,7 +44,6 @@ const RenderInstType RenderInstType::Invalid( "" ); -const RenderInstType RenderPassManager::RIT_Interior("Interior"); const RenderInstType RenderPassManager::RIT_Mesh("Mesh"); const RenderInstType RenderPassManager::RIT_Shadow("Shadow"); const RenderInstType RenderPassManager::RIT_Sky("Sky"); diff --git a/Engine/source/renderInstance/renderPassManager.h b/Engine/source/renderInstance/renderPassManager.h index d80964866..5547b723c 100644 --- a/Engine/source/renderInstance/renderPassManager.h +++ b/Engine/source/renderInstance/renderPassManager.h @@ -96,7 +96,6 @@ public: // Default bin types. Not necessarily the only bin types in the system. // RIT = "R"ender "I"nstance "T"ype - static const RenderInstType RIT_Interior; static const RenderInstType RIT_Mesh; static const RenderInstType RIT_Shadow; static const RenderInstType RIT_Sky; diff --git a/Engine/source/renderInstance/renderPrePassMgr.cpp b/Engine/source/renderInstance/renderPrePassMgr.cpp index f82bc09f2..bb64d1dd7 100644 --- a/Engine/source/renderInstance/renderPrePassMgr.cpp +++ b/Engine/source/renderInstance/renderPrePassMgr.cpp @@ -80,7 +80,6 @@ RenderPrePassMgr::RenderPrePassMgr( bool gatherDepth, { notifyType( RenderPassManager::RIT_Decal ); notifyType( RenderPassManager::RIT_Mesh ); - notifyType( RenderPassManager::RIT_Interior ); notifyType( RenderPassManager::RIT_Terrain ); notifyType( RenderPassManager::RIT_Object ); @@ -194,8 +193,7 @@ void RenderPrePassMgr::addElement( RenderInst *inst ) // First what type of render instance is it? const bool isDecalMeshInst = inst->type == RenderPassManager::RIT_Decal; - const bool isMeshInst = inst->type == RenderPassManager::RIT_Mesh || - inst->type == RenderPassManager::RIT_Interior; + const bool isMeshInst = inst->type == RenderPassManager::RIT_Mesh; const bool isTerrainInst = inst->type == RenderPassManager::RIT_Terrain; diff --git a/Engine/source/scene/pathManager.cpp b/Engine/source/scene/pathManager.cpp index 2ed41d17a..1bb263765 100644 --- a/Engine/source/scene/pathManager.cpp +++ b/Engine/source/scene/pathManager.cpp @@ -25,7 +25,6 @@ #include "sim/netConnection.h" #include "core/stream/bitStream.h" #include "scene/simPath.h" -#include "interior/interiorInstance.h" #include "math/mathIO.h" #include "scene/sceneRenderState.h" #include "scene/sceneManager.h" diff --git a/Engine/source/ts/collada/colladaUtils.cpp b/Engine/source/ts/collada/colladaUtils.cpp index c816f2e98..7bd5b2e9d 100644 --- a/Engine/source/ts/collada/colladaUtils.cpp +++ b/Engine/source/ts/collada/colladaUtils.cpp @@ -946,7 +946,7 @@ void ColladaUtils::exportColladaHeader(TiXmlElement* rootNode) TiXmlElement* authoringToolNode = new TiXmlElement("authoring_tool"); contributorNode->LinkEndChild(authoringToolNode); - TiXmlText* authorText = new TiXmlText(avar("%s %s Interior Exporter", getEngineProductString(), getVersionString())); + TiXmlText* authorText = new TiXmlText(avar("%s %s Object Exporter", getEngineProductString(), getVersionString())); authoringToolNode->LinkEndChild(authorText); TiXmlElement* commentsNode = new TiXmlElement("comments"); diff --git a/Templates/Empty/game/core/scripts/client/metrics.cs b/Templates/Empty/game/core/scripts/client/metrics.cs index 75f8c8972..339dc5fad 100644 --- a/Templates/Empty/game/core/scripts/client/metrics.cs +++ b/Templates/Empty/game/core/scripts/client/metrics.cs @@ -142,8 +142,6 @@ function decalMetricsCallback() function renderMetricsCallback() { return " | Render |" @ - " Int: " @ $RenderMetrics::RIT_Interior @ - " IntDL: " @ $RenderMetrics::RIT_InteriorDynamicLighting @ " Mesh: " @ $RenderMetrics::RIT_Mesh @ " MeshDL: " @ $RenderMetrics::RIT_MeshDynamicLighting @ " Shadow: " @ $RenderMetrics::RIT_Shadow @ diff --git a/Templates/Empty/game/core/scripts/client/renderManager.cs b/Templates/Empty/game/core/scripts/client/renderManager.cs index 672451f2d..dcd1628fe 100644 --- a/Templates/Empty/game/core/scripts/client/renderManager.cs +++ b/Templates/Empty/game/core/scripts/client/renderManager.cs @@ -55,7 +55,6 @@ function initRenderManager() DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Begin"; renderOrder = 0.2; processAddOrder = 0.2; } ); // Normal mesh rendering. - DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Interior"; renderOrder = 0.3; processAddOrder = 0.3; } ); DiffuseRenderPassManager.addManager( new RenderTerrainMgr() { renderOrder = 0.4; processAddOrder = 0.4; } ); DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Mesh"; renderOrder = 0.5; processAddOrder = 0.5; } ); DiffuseRenderPassManager.addManager( new RenderImposterMgr() { renderOrder = 0.56; processAddOrder = 0.56; } ); diff --git a/Templates/Empty/game/core/scripts/client/shaders.cs b/Templates/Empty/game/core/scripts/client/shaders.cs index bf6744fa4..76b35884c 100644 --- a/Templates/Empty/game/core/scripts/client/shaders.cs +++ b/Templates/Empty/game/core/scripts/client/shaders.cs @@ -25,19 +25,6 @@ //----------------------------------------------------------------------------- -singleton ShaderData( _DebugInterior_ ) -{ - DXVertexShaderFile = "shaders/common/debugInteriorsV.hlsl"; - DXPixelShaderFile = "shaders/common/debugInteriorsP.hlsl"; - - OGLVertexShaderFile = "shaders/common/gl/debugInteriorsV.glsl"; - OGLPixelShaderFile = "shaders/common/gl/debugInteriorsP.glsl"; - - samplerNames[0] = "$diffuseMap"; - - pixVersion = 1.1; -}; - singleton ShaderData( ParticlesShaderData ) { DXVertexShaderFile = "shaders/common/particlesV.hlsl"; diff --git a/Templates/Empty/game/scripts/client/default.bind.cs b/Templates/Empty/game/scripts/client/default.bind.cs index 5ea30d8f0..fa7455271 100644 --- a/Templates/Empty/game/scripts/client/default.bind.cs +++ b/Templates/Empty/game/scripts/client/default.bind.cs @@ -442,70 +442,6 @@ GlobalActionMap.bind(keyboard, "ctrl o", bringUpOptions); // Debugging Functions //------------------------------------------------------------------------------ -$MFDebugRenderMode = 0; -function cycleDebugRenderMode(%val) -{ - if (!%val) - return; - - $MFDebugRenderMode++; - - if ($MFDebugRenderMode > 16) - $MFDebugRenderMode = 0; - if ($MFDebugRenderMode == 15) - $MFDebugRenderMode = 16; - - setInteriorRenderMode($MFDebugRenderMode); - - if (isObject(ChatHud)) - { - %message = "Setting Interior debug render mode to "; - %debugMode = "Unknown"; - - switch($MFDebugRenderMode) - { - case 0: - %debugMode = "NormalRender"; - case 1: - %debugMode = "NormalRenderLines"; - case 2: - %debugMode = "ShowDetail"; - case 3: - %debugMode = "ShowAmbiguous"; - case 4: - %debugMode = "ShowOrphan"; - case 5: - %debugMode = "ShowLightmaps"; - case 6: - %debugMode = "ShowTexturesOnly"; - case 7: - %debugMode = "ShowPortalZones"; - case 8: - %debugMode = "ShowOutsideVisible"; - case 9: - %debugMode = "ShowCollisionFans"; - case 10: - %debugMode = "ShowStrips"; - case 11: - %debugMode = "ShowNullSurfaces"; - case 12: - %debugMode = "ShowLargeTextures"; - case 13: - %debugMode = "ShowHullSurfaces"; - case 14: - %debugMode = "ShowVehicleHullSurfaces"; - // Depreciated - //case 15: - // %debugMode = "ShowVertexColors"; - case 16: - %debugMode = "ShowDetailLevel"; - } - - ChatHud.addLine(%message @ %debugMode); - } -} - -GlobalActionMap.bind(keyboard, "F9", cycleDebugRenderMode); //------------------------------------------------------------------------------ // diff --git a/Templates/Empty/game/shaders/common/debugInteriorsP.hlsl b/Templates/Empty/game/shaders/common/debugInteriorsP.hlsl deleted file mode 100644 index c1f2c9065..000000000 --- a/Templates/Empty/game/shaders/common/debugInteriorsP.hlsl +++ /dev/null @@ -1,53 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Structures -//----------------------------------------------------------------------------- -struct ConnectData -{ - float2 texCoord : TEXCOORD0; -}; - - -struct Fragout -{ - float4 col : COLOR0; -}; - - -//----------------------------------------------------------------------------- -// Main -//----------------------------------------------------------------------------- -Fragout main( ConnectData IN, - uniform sampler2D diffuseMap : register(S0), - uniform float4 shadeColor : register(C0) - -) -{ - Fragout OUT; - - OUT.col = shadeColor; - OUT.col *= tex2D(diffuseMap, IN.texCoord); - - return OUT; -} diff --git a/Templates/Empty/game/shaders/common/debugInteriorsV.hlsl b/Templates/Empty/game/shaders/common/debugInteriorsV.hlsl deleted file mode 100644 index ae6066fc5..000000000 --- a/Templates/Empty/game/shaders/common/debugInteriorsV.hlsl +++ /dev/null @@ -1,49 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "hlslStructs.h" - -//----------------------------------------------------------------------------- -// Structures -//----------------------------------------------------------------------------- - -struct ConnectData -{ - float4 hpos : POSITION; - float2 outTexCoord : TEXCOORD0; -}; - - -//----------------------------------------------------------------------------- -// Main -//----------------------------------------------------------------------------- -ConnectData main( VertexIn_PNTTTB IN, - uniform float4x4 modelview : register(C0) -) -{ - ConnectData OUT; - - OUT.hpos = mul(modelview, IN.pos); - OUT.outTexCoord = IN.uv0; - - return OUT; -} diff --git a/Templates/Empty/game/shaders/common/gl/debugInteriorsP.glsl b/Templates/Empty/game/shaders/common/gl/debugInteriorsP.glsl deleted file mode 100644 index 36725d38a..000000000 --- a/Templates/Empty/game/shaders/common/gl/debugInteriorsP.glsl +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -uniform sampler2D diffuseMap; -uniform vec4 shadeColor; - -varying vec2 TEX0; - -void main() -{ - vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); - - gl_FragColor = diffuseColor; - gl_FragColor *= shadeColor; -} diff --git a/Templates/Empty/game/shaders/common/gl/debugInteriorsV.glsl b/Templates/Empty/game/shaders/common/gl/debugInteriorsV.glsl deleted file mode 100644 index 8bfab07eb..000000000 --- a/Templates/Empty/game/shaders/common/gl/debugInteriorsV.glsl +++ /dev/null @@ -1,33 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -uniform mat4 modelview; - -varying vec2 TEX0; - -void main() -{ - gl_Position = modelview * gl_Vertex; - TEX0 = gl_MultiTexCoord0.st; -} - - diff --git a/Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs b/Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs index f4465c281..b13b20b46 100644 --- a/Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs +++ b/Templates/Empty/game/tools/materialEditor/scripts/materialEditor.ed.cs @@ -300,7 +300,7 @@ function MaterialEditorGui::prepareActiveObject( %this, %override ) if( MaterialEditorGui.currentObject == %obj && !%override) return; - // TSStatics, ShapeBase, and Interiors should have getModelFile methods + // TSStatics and ShapeBase objects should have getModelFile methods if( %obj.isMethod( "getModelFile" ) ) { MaterialEditorGui.currentObject = %obj; @@ -310,30 +310,11 @@ function MaterialEditorGui::prepareActiveObject( %this, %override ) MaterialEditorGui.setMode(); - if( MaterialEditorGui.currentObject.isMethod( "getNumDetailLevels" ) ) // Interiors + for(%j = 0; %j < MaterialEditorGui.currentObject.getTargetCount(); %j++) { - for(%j = 0; %j < MaterialEditorGui.currentObject.getNumDetailLevels(); %j++) - { - %target = "Detail Level " @ %j; - %count = SubMaterialSelector.getCount(); - SubMaterialSelector.addCategory(%target); - - for(%k = 0; %k < MaterialEditorGui.currentObject.getTargetCount(%j); %k++) - { - %target = MaterialEditorGui.currentObject.getTargetName(%j, %k); - %count = SubMaterialSelector.getCount(); - SubMaterialSelector.add(%target); - } - } - } - else // TSStatic and ShapeBase - { - for(%j = 0; %j < MaterialEditorGui.currentObject.getTargetCount(); %j++) - { - %target = MaterialEditorGui.currentObject.getTargetName(%j); - %count = SubMaterialSelector.getCount(); - SubMaterialSelector.add(%target); - } + %target = MaterialEditorGui.currentObject.getTargetName(%j); + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.add(%target); } } else // Other classes that support materials if possible @@ -523,9 +504,7 @@ function MaterialEditorGui::setMaterialDirty(%this) { %obj = MaterialEditorGui.currentObject; - if( %obj.interiorFile !$= "" ) - %shapePath = %obj.interiorFile; - else if( %obj.shapeName !$= "" ) + if( %obj.shapeName !$= "" ) %shapePath = %obj.shapeName; else if( %obj.isMethod("getDatablock") ) { diff --git a/Templates/Empty/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui index a21fbb60b..9f8b496e0 100644 --- a/Templates/Empty/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui +++ b/Templates/Empty/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui @@ -373,7 +373,7 @@ AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "Interiors"; + text = "Objects"; maxLength = "1024"; maxPopupHeight = "200"; sbUsesNAColor = "0"; diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiInteriorExportGui.gui b/Templates/Empty/game/tools/worldEditor/gui/guiInteriorExportGui.gui deleted file mode 100644 index ed40ec47a..000000000 --- a/Templates/Empty/game/tools/worldEditor/gui/guiInteriorExportGui.gui +++ /dev/null @@ -1,240 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -%guiContent = new GuiControl(InteriorExportGui, EditorGuiGroup) { - canSaveDynamicFields = "0"; - Profile = "ToolsGuiOverlayProfile"; - Enabled = "1"; - isContainer = "1"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "0 0"; - Extent = "1024 768"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - - new GuiWindowCtrl(InteriorExportWindow) { - profile = "ToolsGuiWindowProfile"; - canSaveDynamicFields = "0"; - internalName = "InteriorExport"; - Enabled = "1"; - isContainer = "1"; - HorizSizing = "center"; - VertSizing = "center"; - Position = "248 248"; - Extent = "290 235"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "1"; - AnchorLeft = "1"; - AnchorRight = "1"; - resizeWidth = "0"; - resizeHeight = "0"; - canMove = "1"; - canClose = "1"; - canMinimize = "0"; - canMaximize = "0"; - minSize = "50 50"; - closeCommand = "InteriorExportGui.close();"; - EdgeSnap = "0"; - canCollapse = "0"; - text = "Export Interiors to COLLADA"; - - new GuiScrollCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "1"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "9 43"; - Extent = "272 112"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "dynamic"; - lockHorizScroll = "true"; - lockVertScroll = "false"; - constantThumbHeight = "0"; - childMargin = "0 0"; - - new GuiListBoxCtrl(InteriorSelectListBox) { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "2 2"; - Extent = "248 104"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - AllowMultipleSelections = "1"; - fitParentWidth = "1"; - }; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "9 25"; - Extent = "88 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Select Interior(s):"; - maxLength = "1024"; - }; - new GuiCheckBoxCtrl(InteriorSelectAllToggle) { - profile = "ToolsGuiCheckBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 158"; - extent = "248 23"; - minExtent = "8 8"; - visible = "1"; - text = " Select / deselect all"; - groupNum = "-1"; - buttonType = "ToggleButton"; - helpTag = "0"; - maxLength = "255"; - }; - new GuiCheckBoxCtrl(InteriorExportTransToggle) { - profile = "ToolsGuiCheckBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 176"; - extent = "248 23"; - minExtent = "8 8"; - visible = "1"; - text = " Export Interiors with transforms baked in"; - groupNum = "-1"; - buttonType = "ToggleButton"; - helpTag = "0"; - maxLength = "255"; - }; - new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "9 202"; - Extent = "107 24"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "InteriorExportGui.export();"; - hovertime = "1000"; - text = "Export"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "174 202"; - Extent = "107 24"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "InteriorExportGui.close();"; - hovertime = "1000"; - text = "Cancel"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - }; -}; -//--- OBJECT WRITE END --- - -function InteriorExportGui::findAllInteriors( %this ) -{ - InteriorSelectListBox.clearItems(); - - // Find all of the Interior files - initContainerTypeSearch( $TypeMasks::InteriorObjectType ); - - while ( (%interiorObject = containerSearchNext()) != 0 ) - { - %interiorName = %interiorObject.getName(); - if ( %interiorName $= "" ) - %interiorName = fileBase(%interiorObject.interiorFile); - - %text = %interiorName SPC "(" @ %interiorObject.getId() @ ")"; - InteriorSelectListBox.addItem( %text, %interiorObject ); - } -} - -function InteriorExportGui::export( %this ) -{ - %selected = InteriorSelectListBox.getSelectedItems(); - - %numSel = getWordCount(%selected); - - if ( %numSel == 0 ) - MessageBoxOk("Select Interior(s)", "You must select at least one Interior to export"); - - for (%i = 0; %i < %numSel; %i++) - { - %index = getWord(%selected, %i); - - %interiorObj = InteriorSelectListBox.getItemObject( %index ); - - if (!isObject(%interiorObj)) - continue; - - %interiorObj.exportToCollada(InteriorExportTransToggle.getValue()); - } - - %this.close(); -} - -function InteriorExportGui::onWake( %this ) -{ - %this.findAllInteriors(); - - InteriorSelectAllToggle.setValue(false); - InteriorExportTransToggle.setValue(true); -} - -function InteriorExportGui::close( %this ) -{ - Canvas.popDialog( %this ); -} - -function InteriorSelectAllToggle::onClick( %this ) -{ - if (InteriorSelectAllToggle.getValue()) - { - %numItems = InteriorSelectListBox.getItemCount(); - - for (%i = 0; %i < %numItems; %i++) - InteriorSelectListBox.setSelected(%i); - } - else - InteriorSelectListBox.clearSelection(); -} - diff --git a/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui b/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui index a2d8a95b3..03a3d6d8a 100644 --- a/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui +++ b/Templates/Empty/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui @@ -178,7 +178,7 @@ AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "Interiors"; + text = "Objects"; maxLength = "1024"; maxPopupHeight = "200"; sbUsesNAColor = "0"; diff --git a/Templates/Empty/game/tools/worldEditor/main.cs b/Templates/Empty/game/tools/worldEditor/main.cs index d028f8923..1b20201e0 100644 --- a/Templates/Empty/game/tools/worldEditor/main.cs +++ b/Templates/Empty/game/tools/worldEditor/main.cs @@ -32,7 +32,6 @@ function initializeWorldEditor() exec("./gui/genericPromptDialog.ed.gui" ); exec("./gui/guiTerrainImportGui.gui" ); exec("./gui/guiTerrainExportGui.gui" ); - exec("./gui/guiInteriorExportGui.gui" ); exec("./gui/EditorGui.ed.gui"); exec("./gui/objectBuilderGui.ed.gui"); exec("./gui/TerrainEditorVSettingsGui.ed.gui"); diff --git a/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs index b6e4319f5..a60d7794d 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -1862,12 +1862,6 @@ function EditorTree::GetTooltipParticleEmitterNode( %this, %obj ) return %text; } -// Tooltip for InteriorInstance -function EditorTree::GetTooltipInteriorInstance( %this, %obj ) -{ - return "File: " @ %obj.interiorFile; -} - // Tooltip for WorldEditorSelection function EditorTree::GetTooltipWorldEditorSelection( %this, %obj ) { diff --git a/Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs index cb16ce72d..18493ef4a 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -169,31 +169,6 @@ function EWCreatorWindow::setNewObjectGroup( %this, %group ) EditorTree.markItem( %itemId ); } -function EWCreatorWindow::createInterior( %this, %file ) -{ - if ( !$missionRunning ) - return; - - if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) - { - MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); - return; - } - - if( !isObject(%this.objectGroup) ) - %this.setNewObjectGroup( MissionGroup ); - - %objId = new InteriorInstance() - { - position = %this.getCreateObjectPosition(); - rotation = "0 0 0"; - interiorFile = %file; - parentGroup = %this.objectGroup; - }; - - %this.onObjectCreated( %objId ); -} - function EWCreatorWindow::createStatic( %this, %file ) { if ( !$missionRunning ) @@ -381,10 +356,7 @@ function EWCreatorWindow::navigate( %this, %address ) // Is this file in the current folder? if ( stricmp( %pathFolders, %address ) == 0 ) { - if ( fileExt( %fullPath ) $= ".dif" ) - %this.addInteriorIcon( %fullPath ); - else - %this.addStaticIcon( %fullPath ); + %this.addStaticIcon( %fullPath ); } // Then is this file in a subfolder we need to add // a folder icon for? @@ -752,30 +724,6 @@ function EWCreatorWindow::addStaticIcon( %this, %fullPath ) %this.contentCtrl.addGuiControl( %ctrl ); } -function EWCreatorWindow::addInteriorIcon( %this, %fullPath ) -{ - %ctrl = EWCreatorWindow.createIcon(); - - %file = fileBase( %fullPath ); - %fileLong = %file @ fileExt( %fullPath ); - - %tip = %fileLong NL - "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL - "Date Created: " @ fileCreatedTime( %fullPath ) NL - "Last Modified: " @ fileModifiedTime( %fullPath ); - - %ctrl.altCommand = "EWCreatorWindow.createInterior( \"" @ %fullPath @ "\" );"; - %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "InteriorInstance" ); - %ctrl.text = %file; - %ctrl.class = "CreatorInteriorIconBtn"; - %ctrl.tooltip = %tip; - - %ctrl.buttonType = "radioButton"; - %ctrl.groupNum = "-1"; - - %this.contentCtrl.addGuiControl( %ctrl ); -} - function EWCreatorWindow::addPrefabIcon( %this, %fullPath ) { %ctrl = %this.createIcon(); diff --git a/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs index 021d6bb6e..7ae583a98 100644 --- a/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/Empty/game/tools/worldEditor/scripts/menus.ed.cs @@ -135,7 +135,6 @@ function EditorGui::buildMenus(%this) { %fileMenu.appendItem("Export Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainExportGui );"); %fileMenu.appendItem("-"); - %fileMenu.appendItem("Export Interiors To COLLADA..." TAB "" TAB "Canvas.pushDialog( InteriorExportGui );"); %fileMenu.appendItem("Export To COLLADA..." TAB "" TAB "EditorExportToCollada();"); //item[5] = "Import Terraform Data..." TAB "" TAB "Heightfield::import();"; //item[6] = "Import Texture Data..." TAB "" TAB "Texture::import();"; diff --git a/Templates/Full/game/core/scripts/client/metrics.cs b/Templates/Full/game/core/scripts/client/metrics.cs index 75f8c8972..339dc5fad 100644 --- a/Templates/Full/game/core/scripts/client/metrics.cs +++ b/Templates/Full/game/core/scripts/client/metrics.cs @@ -142,8 +142,6 @@ function decalMetricsCallback() function renderMetricsCallback() { return " | Render |" @ - " Int: " @ $RenderMetrics::RIT_Interior @ - " IntDL: " @ $RenderMetrics::RIT_InteriorDynamicLighting @ " Mesh: " @ $RenderMetrics::RIT_Mesh @ " MeshDL: " @ $RenderMetrics::RIT_MeshDynamicLighting @ " Shadow: " @ $RenderMetrics::RIT_Shadow @ diff --git a/Templates/Full/game/core/scripts/client/renderManager.cs b/Templates/Full/game/core/scripts/client/renderManager.cs index 672451f2d..dcd1628fe 100644 --- a/Templates/Full/game/core/scripts/client/renderManager.cs +++ b/Templates/Full/game/core/scripts/client/renderManager.cs @@ -55,7 +55,6 @@ function initRenderManager() DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Begin"; renderOrder = 0.2; processAddOrder = 0.2; } ); // Normal mesh rendering. - DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Interior"; renderOrder = 0.3; processAddOrder = 0.3; } ); DiffuseRenderPassManager.addManager( new RenderTerrainMgr() { renderOrder = 0.4; processAddOrder = 0.4; } ); DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Mesh"; renderOrder = 0.5; processAddOrder = 0.5; } ); DiffuseRenderPassManager.addManager( new RenderImposterMgr() { renderOrder = 0.56; processAddOrder = 0.56; } ); diff --git a/Templates/Full/game/core/scripts/client/shaders.cs b/Templates/Full/game/core/scripts/client/shaders.cs index bf6744fa4..76b35884c 100644 --- a/Templates/Full/game/core/scripts/client/shaders.cs +++ b/Templates/Full/game/core/scripts/client/shaders.cs @@ -25,19 +25,6 @@ //----------------------------------------------------------------------------- -singleton ShaderData( _DebugInterior_ ) -{ - DXVertexShaderFile = "shaders/common/debugInteriorsV.hlsl"; - DXPixelShaderFile = "shaders/common/debugInteriorsP.hlsl"; - - OGLVertexShaderFile = "shaders/common/gl/debugInteriorsV.glsl"; - OGLPixelShaderFile = "shaders/common/gl/debugInteriorsP.glsl"; - - samplerNames[0] = "$diffuseMap"; - - pixVersion = 1.1; -}; - singleton ShaderData( ParticlesShaderData ) { DXVertexShaderFile = "shaders/common/particlesV.hlsl"; diff --git a/Templates/Full/game/scripts/client/default.bind.cs b/Templates/Full/game/scripts/client/default.bind.cs index 68de1a7d3..803124bc0 100644 --- a/Templates/Full/game/scripts/client/default.bind.cs +++ b/Templates/Full/game/scripts/client/default.bind.cs @@ -616,70 +616,6 @@ GlobalActionMap.bind(keyboard, "ctrl o", bringUpOptions); // Debugging Functions //------------------------------------------------------------------------------ -$MFDebugRenderMode = 0; -function cycleDebugRenderMode(%val) -{ - if (!%val) - return; - - $MFDebugRenderMode++; - - if ($MFDebugRenderMode > 16) - $MFDebugRenderMode = 0; - if ($MFDebugRenderMode == 15) - $MFDebugRenderMode = 16; - - setInteriorRenderMode($MFDebugRenderMode); - - if (isObject(ChatHud)) - { - %message = "Setting Interior debug render mode to "; - %debugMode = "Unknown"; - - switch($MFDebugRenderMode) - { - case 0: - %debugMode = "NormalRender"; - case 1: - %debugMode = "NormalRenderLines"; - case 2: - %debugMode = "ShowDetail"; - case 3: - %debugMode = "ShowAmbiguous"; - case 4: - %debugMode = "ShowOrphan"; - case 5: - %debugMode = "ShowLightmaps"; - case 6: - %debugMode = "ShowTexturesOnly"; - case 7: - %debugMode = "ShowPortalZones"; - case 8: - %debugMode = "ShowOutsideVisible"; - case 9: - %debugMode = "ShowCollisionFans"; - case 10: - %debugMode = "ShowStrips"; - case 11: - %debugMode = "ShowNullSurfaces"; - case 12: - %debugMode = "ShowLargeTextures"; - case 13: - %debugMode = "ShowHullSurfaces"; - case 14: - %debugMode = "ShowVehicleHullSurfaces"; - // Depreciated - //case 15: - // %debugMode = "ShowVertexColors"; - case 16: - %debugMode = "ShowDetailLevel"; - } - - ChatHud.addLine(%message @ %debugMode); - } -} - -GlobalActionMap.bind(keyboard, "F9", cycleDebugRenderMode); //------------------------------------------------------------------------------ // diff --git a/Templates/Full/game/shaders/common/debugInteriorsP.hlsl b/Templates/Full/game/shaders/common/debugInteriorsP.hlsl deleted file mode 100644 index c1f2c9065..000000000 --- a/Templates/Full/game/shaders/common/debugInteriorsP.hlsl +++ /dev/null @@ -1,53 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Structures -//----------------------------------------------------------------------------- -struct ConnectData -{ - float2 texCoord : TEXCOORD0; -}; - - -struct Fragout -{ - float4 col : COLOR0; -}; - - -//----------------------------------------------------------------------------- -// Main -//----------------------------------------------------------------------------- -Fragout main( ConnectData IN, - uniform sampler2D diffuseMap : register(S0), - uniform float4 shadeColor : register(C0) - -) -{ - Fragout OUT; - - OUT.col = shadeColor; - OUT.col *= tex2D(diffuseMap, IN.texCoord); - - return OUT; -} diff --git a/Templates/Full/game/shaders/common/debugInteriorsV.hlsl b/Templates/Full/game/shaders/common/debugInteriorsV.hlsl deleted file mode 100644 index ae6066fc5..000000000 --- a/Templates/Full/game/shaders/common/debugInteriorsV.hlsl +++ /dev/null @@ -1,49 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "hlslStructs.h" - -//----------------------------------------------------------------------------- -// Structures -//----------------------------------------------------------------------------- - -struct ConnectData -{ - float4 hpos : POSITION; - float2 outTexCoord : TEXCOORD0; -}; - - -//----------------------------------------------------------------------------- -// Main -//----------------------------------------------------------------------------- -ConnectData main( VertexIn_PNTTTB IN, - uniform float4x4 modelview : register(C0) -) -{ - ConnectData OUT; - - OUT.hpos = mul(modelview, IN.pos); - OUT.outTexCoord = IN.uv0; - - return OUT; -} diff --git a/Templates/Full/game/shaders/common/gl/debugInteriorsP.glsl b/Templates/Full/game/shaders/common/gl/debugInteriorsP.glsl deleted file mode 100644 index 36725d38a..000000000 --- a/Templates/Full/game/shaders/common/gl/debugInteriorsP.glsl +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -uniform sampler2D diffuseMap; -uniform vec4 shadeColor; - -varying vec2 TEX0; - -void main() -{ - vec4 diffuseColor = texture2D( diffuseMap, TEX0 ); - - gl_FragColor = diffuseColor; - gl_FragColor *= shadeColor; -} diff --git a/Templates/Full/game/shaders/common/gl/debugInteriorsV.glsl b/Templates/Full/game/shaders/common/gl/debugInteriorsV.glsl deleted file mode 100644 index 8bfab07eb..000000000 --- a/Templates/Full/game/shaders/common/gl/debugInteriorsV.glsl +++ /dev/null @@ -1,33 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -uniform mat4 modelview; - -varying vec2 TEX0; - -void main() -{ - gl_Position = modelview * gl_Vertex; - TEX0 = gl_MultiTexCoord0.st; -} - - diff --git a/Templates/Full/game/tools/materialEditor/scripts/materialEditor.ed.cs b/Templates/Full/game/tools/materialEditor/scripts/materialEditor.ed.cs index f4465c281..169fae5e4 100644 --- a/Templates/Full/game/tools/materialEditor/scripts/materialEditor.ed.cs +++ b/Templates/Full/game/tools/materialEditor/scripts/materialEditor.ed.cs @@ -300,7 +300,7 @@ function MaterialEditorGui::prepareActiveObject( %this, %override ) if( MaterialEditorGui.currentObject == %obj && !%override) return; - // TSStatics, ShapeBase, and Interiors should have getModelFile methods + // TSStatics and ShapeBase objects should have getModelFile methods if( %obj.isMethod( "getModelFile" ) ) { MaterialEditorGui.currentObject = %obj; @@ -310,30 +310,11 @@ function MaterialEditorGui::prepareActiveObject( %this, %override ) MaterialEditorGui.setMode(); - if( MaterialEditorGui.currentObject.isMethod( "getNumDetailLevels" ) ) // Interiors + for(%j = 0; %j < MaterialEditorGui.currentObject.getTargetCount(); %j++) { - for(%j = 0; %j < MaterialEditorGui.currentObject.getNumDetailLevels(); %j++) - { - %target = "Detail Level " @ %j; - %count = SubMaterialSelector.getCount(); - SubMaterialSelector.addCategory(%target); - - for(%k = 0; %k < MaterialEditorGui.currentObject.getTargetCount(%j); %k++) - { - %target = MaterialEditorGui.currentObject.getTargetName(%j, %k); - %count = SubMaterialSelector.getCount(); - SubMaterialSelector.add(%target); - } - } - } - else // TSStatic and ShapeBase - { - for(%j = 0; %j < MaterialEditorGui.currentObject.getTargetCount(); %j++) - { - %target = MaterialEditorGui.currentObject.getTargetName(%j); - %count = SubMaterialSelector.getCount(); - SubMaterialSelector.add(%target); - } + %target = MaterialEditorGui.currentObject.getTargetName(%j); + %count = SubMaterialSelector.getCount(); + SubMaterialSelector.add(%target); } } else // Other classes that support materials if possible @@ -523,9 +504,7 @@ function MaterialEditorGui::setMaterialDirty(%this) { %obj = MaterialEditorGui.currentObject; - if( %obj.interiorFile !$= "" ) - %shapePath = %obj.interiorFile; - else if( %obj.shapeName !$= "" ) + if( %obj.shapeName !$= "" ) %shapePath = %obj.shapeName; else if( %obj.isMethod("getDatablock") ) { @@ -2163,9 +2142,7 @@ function MaterialEditorGui::changeMaterial(%this, %fromMaterial, %toMaterial) MaterialEditorGui.currentObject.changeMaterial( %materialTarget, %fromMaterial.getName(), %toMaterial.getName() ); - if( MaterialEditorGui.currentObject.interiorFile !$= "" ) - %sourcePath = MaterialEditorGui.currentObject.interiorFile; - else if( MaterialEditorGui.currentObject.shapeName !$= "" ) + if( MaterialEditorGui.currentObject.shapeName !$= "" ) %sourcePath = MaterialEditorGui.currentObject.shapeName; else if( MaterialEditorGui.currentObject.isMethod("getDatablock") ) { diff --git a/Templates/Full/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui b/Templates/Full/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui index a21fbb60b..9f8b496e0 100644 --- a/Templates/Full/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui +++ b/Templates/Full/game/tools/worldEditor/gui/WorldEditorTreeWindow.ed.gui @@ -373,7 +373,7 @@ AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "Interiors"; + text = "Objects"; maxLength = "1024"; maxPopupHeight = "200"; sbUsesNAColor = "0"; diff --git a/Templates/Full/game/tools/worldEditor/gui/guiInteriorExportGui.gui b/Templates/Full/game/tools/worldEditor/gui/guiInteriorExportGui.gui deleted file mode 100644 index ed40ec47a..000000000 --- a/Templates/Full/game/tools/worldEditor/gui/guiInteriorExportGui.gui +++ /dev/null @@ -1,240 +0,0 @@ -//--- OBJECT WRITE BEGIN --- -%guiContent = new GuiControl(InteriorExportGui, EditorGuiGroup) { - canSaveDynamicFields = "0"; - Profile = "ToolsGuiOverlayProfile"; - Enabled = "1"; - isContainer = "1"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "0 0"; - Extent = "1024 768"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - - new GuiWindowCtrl(InteriorExportWindow) { - profile = "ToolsGuiWindowProfile"; - canSaveDynamicFields = "0"; - internalName = "InteriorExport"; - Enabled = "1"; - isContainer = "1"; - HorizSizing = "center"; - VertSizing = "center"; - Position = "248 248"; - Extent = "290 235"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "1"; - AnchorLeft = "1"; - AnchorRight = "1"; - resizeWidth = "0"; - resizeHeight = "0"; - canMove = "1"; - canClose = "1"; - canMinimize = "0"; - canMaximize = "0"; - minSize = "50 50"; - closeCommand = "InteriorExportGui.close();"; - EdgeSnap = "0"; - canCollapse = "0"; - text = "Export Interiors to COLLADA"; - - new GuiScrollCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "1"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "9 43"; - Extent = "272 112"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - willFirstRespond = "1"; - hScrollBar = "alwaysOff"; - vScrollBar = "dynamic"; - lockHorizScroll = "true"; - lockVertScroll = "false"; - constantThumbHeight = "0"; - childMargin = "0 0"; - - new GuiListBoxCtrl(InteriorSelectListBox) { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "2 2"; - Extent = "248 104"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - AllowMultipleSelections = "1"; - fitParentWidth = "1"; - }; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "9 25"; - Extent = "88 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Select Interior(s):"; - maxLength = "1024"; - }; - new GuiCheckBoxCtrl(InteriorSelectAllToggle) { - profile = "ToolsGuiCheckBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 158"; - extent = "248 23"; - minExtent = "8 8"; - visible = "1"; - text = " Select / deselect all"; - groupNum = "-1"; - buttonType = "ToggleButton"; - helpTag = "0"; - maxLength = "255"; - }; - new GuiCheckBoxCtrl(InteriorExportTransToggle) { - profile = "ToolsGuiCheckBoxProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 176"; - extent = "248 23"; - minExtent = "8 8"; - visible = "1"; - text = " Export Interiors with transforms baked in"; - groupNum = "-1"; - buttonType = "ToggleButton"; - helpTag = "0"; - maxLength = "255"; - }; - new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "9 202"; - Extent = "107 24"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "InteriorExportGui.export();"; - hovertime = "1000"; - text = "Export"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - Enabled = "1"; - isContainer = "0"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "174 202"; - Extent = "107 24"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "InteriorExportGui.close();"; - hovertime = "1000"; - text = "Cancel"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - }; -}; -//--- OBJECT WRITE END --- - -function InteriorExportGui::findAllInteriors( %this ) -{ - InteriorSelectListBox.clearItems(); - - // Find all of the Interior files - initContainerTypeSearch( $TypeMasks::InteriorObjectType ); - - while ( (%interiorObject = containerSearchNext()) != 0 ) - { - %interiorName = %interiorObject.getName(); - if ( %interiorName $= "" ) - %interiorName = fileBase(%interiorObject.interiorFile); - - %text = %interiorName SPC "(" @ %interiorObject.getId() @ ")"; - InteriorSelectListBox.addItem( %text, %interiorObject ); - } -} - -function InteriorExportGui::export( %this ) -{ - %selected = InteriorSelectListBox.getSelectedItems(); - - %numSel = getWordCount(%selected); - - if ( %numSel == 0 ) - MessageBoxOk("Select Interior(s)", "You must select at least one Interior to export"); - - for (%i = 0; %i < %numSel; %i++) - { - %index = getWord(%selected, %i); - - %interiorObj = InteriorSelectListBox.getItemObject( %index ); - - if (!isObject(%interiorObj)) - continue; - - %interiorObj.exportToCollada(InteriorExportTransToggle.getValue()); - } - - %this.close(); -} - -function InteriorExportGui::onWake( %this ) -{ - %this.findAllInteriors(); - - InteriorSelectAllToggle.setValue(false); - InteriorExportTransToggle.setValue(true); -} - -function InteriorExportGui::close( %this ) -{ - Canvas.popDialog( %this ); -} - -function InteriorSelectAllToggle::onClick( %this ) -{ - if (InteriorSelectAllToggle.getValue()) - { - %numItems = InteriorSelectListBox.getItemCount(); - - for (%i = 0; %i < %numItems; %i++) - InteriorSelectListBox.setSelected(%i); - } - else - InteriorSelectListBox.clearSelection(); -} - diff --git a/Templates/Full/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui b/Templates/Full/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui index a2d8a95b3..03a3d6d8a 100644 --- a/Templates/Full/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui +++ b/Templates/Full/game/tools/worldEditor/gui/guiWorldEditorCreatorWindow.ed.gui @@ -178,7 +178,7 @@ AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "Interiors"; + text = "Objects"; maxLength = "1024"; maxPopupHeight = "200"; sbUsesNAColor = "0"; diff --git a/Templates/Full/game/tools/worldEditor/main.cs b/Templates/Full/game/tools/worldEditor/main.cs index d028f8923..1b20201e0 100644 --- a/Templates/Full/game/tools/worldEditor/main.cs +++ b/Templates/Full/game/tools/worldEditor/main.cs @@ -32,7 +32,6 @@ function initializeWorldEditor() exec("./gui/genericPromptDialog.ed.gui" ); exec("./gui/guiTerrainImportGui.gui" ); exec("./gui/guiTerrainExportGui.gui" ); - exec("./gui/guiInteriorExportGui.gui" ); exec("./gui/EditorGui.ed.gui"); exec("./gui/objectBuilderGui.ed.gui"); exec("./gui/TerrainEditorVSettingsGui.ed.gui"); diff --git a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs index b6e4319f5..a60d7794d 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -1862,12 +1862,6 @@ function EditorTree::GetTooltipParticleEmitterNode( %this, %obj ) return %text; } -// Tooltip for InteriorInstance -function EditorTree::GetTooltipInteriorInstance( %this, %obj ) -{ - return "File: " @ %obj.interiorFile; -} - // Tooltip for WorldEditorSelection function EditorTree::GetTooltipWorldEditorSelection( %this, %obj ) { diff --git a/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs index cb16ce72d..18493ef4a 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -169,31 +169,6 @@ function EWCreatorWindow::setNewObjectGroup( %this, %group ) EditorTree.markItem( %itemId ); } -function EWCreatorWindow::createInterior( %this, %file ) -{ - if ( !$missionRunning ) - return; - - if(isFunction("getObjectLimit") && MissionGroup.getFullCount() >= getObjectLimit()) - { - MessageBoxOKBuy( "Object Limit Reached", "You have exceeded the object limit of " @ getObjectLimit() @ " for this demo. You can remove objects if you would like to add more.", "", "Canvas.showPurchaseScreen(\"objectlimit\");" ); - return; - } - - if( !isObject(%this.objectGroup) ) - %this.setNewObjectGroup( MissionGroup ); - - %objId = new InteriorInstance() - { - position = %this.getCreateObjectPosition(); - rotation = "0 0 0"; - interiorFile = %file; - parentGroup = %this.objectGroup; - }; - - %this.onObjectCreated( %objId ); -} - function EWCreatorWindow::createStatic( %this, %file ) { if ( !$missionRunning ) @@ -381,10 +356,7 @@ function EWCreatorWindow::navigate( %this, %address ) // Is this file in the current folder? if ( stricmp( %pathFolders, %address ) == 0 ) { - if ( fileExt( %fullPath ) $= ".dif" ) - %this.addInteriorIcon( %fullPath ); - else - %this.addStaticIcon( %fullPath ); + %this.addStaticIcon( %fullPath ); } // Then is this file in a subfolder we need to add // a folder icon for? @@ -752,30 +724,6 @@ function EWCreatorWindow::addStaticIcon( %this, %fullPath ) %this.contentCtrl.addGuiControl( %ctrl ); } -function EWCreatorWindow::addInteriorIcon( %this, %fullPath ) -{ - %ctrl = EWCreatorWindow.createIcon(); - - %file = fileBase( %fullPath ); - %fileLong = %file @ fileExt( %fullPath ); - - %tip = %fileLong NL - "Size: " @ fileSize( %fullPath ) / 1000.0 SPC "KB" NL - "Date Created: " @ fileCreatedTime( %fullPath ) NL - "Last Modified: " @ fileModifiedTime( %fullPath ); - - %ctrl.altCommand = "EWCreatorWindow.createInterior( \"" @ %fullPath @ "\" );"; - %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "InteriorInstance" ); - %ctrl.text = %file; - %ctrl.class = "CreatorInteriorIconBtn"; - %ctrl.tooltip = %tip; - - %ctrl.buttonType = "radioButton"; - %ctrl.groupNum = "-1"; - - %this.contentCtrl.addGuiControl( %ctrl ); -} - function EWCreatorWindow::addPrefabIcon( %this, %fullPath ) { %ctrl = %this.createIcon(); diff --git a/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs index 021d6bb6e..7ae583a98 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs @@ -135,7 +135,6 @@ function EditorGui::buildMenus(%this) { %fileMenu.appendItem("Export Terrain Heightmap" TAB "" TAB "Canvas.pushDialog( TerrainExportGui );"); %fileMenu.appendItem("-"); - %fileMenu.appendItem("Export Interiors To COLLADA..." TAB "" TAB "Canvas.pushDialog( InteriorExportGui );"); %fileMenu.appendItem("Export To COLLADA..." TAB "" TAB "EditorExportToCollada();"); //item[5] = "Import Terraform Data..." TAB "" TAB "Heightfield::import();"; //item[6] = "Import Texture Data..." TAB "" TAB "Texture::import();"; diff --git a/Tools/projectGenerator/modules/T3D.inc b/Tools/projectGenerator/modules/T3D.inc index 26bc8da1d..f72a12908 100644 --- a/Tools/projectGenerator/modules/T3D.inc +++ b/Tools/projectGenerator/modules/T3D.inc @@ -23,7 +23,6 @@ // 3D addEngineSrcDir('collision'); -addEngineSrcDir('interior'); addEngineSrcDir('materials'); addEngineSrcDir('lighting'); addEngineSrcDir('lighting/common');