Remove Interior Object format (DIF)

This commit is contained in:
thecelloman 2013-04-05 12:39:26 -04:00
parent a868b649ad
commit b4ea1123dc
99 changed files with 76 additions and 17318 deletions

View file

@ -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 )

View file

@ -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" );

View file

@ -1363,7 +1363,6 @@ void Camera::_validateEyePoint(F32 pos, MatrixF *mat)
disableCollision();
RayInfo collision;
U32 mask = TerrainObjectType |
InteriorObjectType |
WaterObjectType |
StaticShapeObjectType |
PlayerObjectType |

View file

@ -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 )

View file

@ -41,8 +41,7 @@
#include "lighting/lightQuery.h"
const U32 csmStaticCollisionMask = TerrainObjectType |
InteriorObjectType;
const U32 csmStaticCollisionMask = TerrainObjectType;
const U32 csmDynamicCollisionMask = StaticShapeObjectType;

View file

@ -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;

View file

@ -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,

View file

@ -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.

View file

@ -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;

View file

@ -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.

View file

@ -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;

View file

@ -45,7 +45,6 @@
static const U32 dropHitMask =
TerrainObjectType |
InteriorObjectType |
WaterObjectType |
StaticShapeObjectType;

View file

@ -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);

View file

@ -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);

View file

@ -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 )
};

View file

@ -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)
{

View file

@ -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;

View file

@ -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;

View file

@ -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.

View file

@ -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.

View file

@ -37,7 +37,6 @@ static U32 sScanTypeMask = PlayerObjectType |
VehicleObjectType;
static U32 sAimTypeMask = TerrainObjectType |
InteriorObjectType |
WaterObjectType |
PlayerObjectType |
StaticShapeObjectType |

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -83,7 +83,6 @@ enum ConvexType {
TSConvexType,
BoxConvexType,
TerrainConvexType,
InteriorConvexType,
ShapeBaseConvexType,
TSStaticConvexType,
AtlasChunkConvexType, ///< @deprecated

View file

@ -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 |

View file

@ -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<InteriorInstance*> 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)

View file

@ -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<Point3F> uniqueNormals(mPlanes.size());
Vector<U16> 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<Point3F> 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<U16>& 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<U16> planes;
buildPolyList_r(0, planes, list, sphere);
AssertFatal(planes.size() == 0, "Error, unbalanced plane stack!");
return !list->isEmpty();
}

View file

@ -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<StringTableEntry> mTriggers;
Box3F mBoundingBox;
SphereF mBoundingSphere;
Vector<PlaneF> mPlanes;
Vector<Point3F> mPoints;
Vector<IBSPNode> mBSPNodes;
Vector<IBSPLeafSolid> mBSPSolidLeaves;
Vector<U32> mSolidLeafSurfaces;
bool mPreppedForRender;
Vector<U32> mWindings;
Vector<Surface> mSurfaces;
protected:
bool castRay_r(const U16, const Point3F&, const Point3F&, RayInfo*);
void buildPolyList_r(const U16, Vector<U16>&, 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_

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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<ItrPaddedPoint>& points,
Vector<U32>& 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<ItrPaddedPoint>& points,
Vector<U32>& 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; j<mZones[i].surfaceCount; j++ )
{
U32 surfaceIndex = mZoneSurfaces[mZones[i].surfaceStart + j];
Surface& rSurface = mSurfaces[ surfaceIndex ];
PrimBuild::color3f(0.0f, 0.0f, 0.0f);
lineLoopFromStrip(mPoints, mWindings, rSurface.windingStart, rSurface.windingCount);
}
}
}
void Interior::debugShowSurfaceFlag(const ZoneVisDeterminer& zoneVis, const U32 flag, const ColorF& c)
{
preDebugRender();
for (U32 i = 0; i < mZones.size(); i++)
{
if (zoneVis.isZoneVisible(i) == false)
continue;
for( U32 j=0; j<mZones[i].surfaceCount; j++ )
{
U32 surfaceIndex = mZoneSurfaces[mZones[i].surfaceStart + j];
Surface& rSurface = mSurfaces[ surfaceIndex ];
ColorF col(0.0f, 0.0f, 0.0f);
if (rSurface.surfaceFlags & flag)
col = c;
else
{
if (smFocusedDebug == true)
continue;
else
col.set(1.0f, 1.0f, 1.0f);
}
mDebugShaderConsts->setSafe(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<mZones[i].surfaceCount; j++ )
{
U32 surfaceIndex = mZoneSurfaces[mZones[i].surfaceStart + j];
Surface& rSurface = mSurfaces[ surfaceIndex ];
U32 numIndices;
U32 fanIndices[32];
collisionFanFromSurface(rSurface, fanIndices, &numIndices);
// Filled brush
PrimBuild::color3f(1.0f, 1.0f, 1.0f);
PrimBuild::begin(GFXTriangleFan, numIndices);
for (U32 i = 0; i < numIndices; i++)
PrimBuild::vertex3fv(mPoints[fanIndices[i]].point);
PrimBuild::end();
// Outline
PrimBuild::color3f(0.0f, 0.0f, 0.0f);
PrimBuild::begin(GFXLineStrip, numIndices+1);
for (U32 i = 0; i < numIndices; i++)
PrimBuild::vertex3fv(mPoints[fanIndices[i]].point);
if (numIndices > 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; j<mZoneRNList[i].renderNodeList.size(); j++ )
{
RenderNode &node = mZoneRNList[i].renderNodeList[j];
U32 index = (i+j) % 14;
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);
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; j<mZoneRNList[i].renderNodeList.size(); j++ )
{
RenderNode &node = mZoneRNList[i].renderNodeList[j];
GFX->drawPrimitive(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; i<getNumZones(); i++ )
{
if (zoneVis.isZoneVisible(i) == false)
continue;
for( U32 j=0; j<mZoneRNList[i].renderNodeList.size(); j++ )
{
RenderNode &node = mZoneRNList[i].renderNodeList[j];
static U16 curBaseTexIndex = 0;
// setup base map
if( node.baseTexIndex != U16_MAX )
curBaseTexIndex = node.baseTexIndex;
// setup lightmap
if( node.lightMapIndex != U8(-1) )
sgData.lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), 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; i<getNumZones(); i++ )
{
if (zoneVis.isZoneVisible(i) == false)
continue;
for( U32 j=0; j<mZoneRNList[i].renderNodeList.size(); j++ )
{
RenderNode &node = mZoneRNList[i].renderNodeList[j];
static U16 curBaseTexIndex = 0;
// setup base map
if ( node.baseTexIndex != U16_MAX )
curBaseTexIndex = node.baseTexIndex;
GFX->setTexture( 0, mMaterialList->getDiffuseTexture( curBaseTexIndex ));
GFX->drawPrimitive( node.primInfoIndex );
}
}
}
void Interior::debugShowLargeTextures(const ZoneVisDeterminer& zoneVis, SceneData &sgData,
InteriorInstance *intInst)
{
preDebugRender();
for( U32 i=0; i<getNumZones(); i++ )
{
if (zoneVis.isZoneVisible(i) == false)
continue;
for( U32 j=0; j<mZoneRNList[i].renderNodeList.size(); j++ )
{
RenderNode &node = mZoneRNList[i].renderNodeList[j];
static U16 curBaseTexIndex = 0;
// setup base map
if( node.baseTexIndex != U16_MAX )
curBaseTexIndex = node.baseTexIndex;
GFXTexHandle t = mMaterialList->getDiffuseTexture( 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; i<getNumZones(); i++ )
{
if (zoneVis.isZoneVisible(i) == false)
continue;
for( U32 j=0; j<mZoneRNList[i].renderNodeList.size(); j++ )
{
RenderNode &node = mZoneRNList[i].renderNodeList[j];
// setup lightmap
if( node.lightMapIndex != U8(-1) )
sgData.lightmap = gInteriorLMManager.getHandle(mLMHandle, intInst->getLMHandle(), node.lightMapIndex );
GFX->setTexture(1, sgData.lightmap);
GFX->drawPrimitive( node.primInfoIndex );
}
}
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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<InteriorResource> 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<InteriorResource> & 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_

View file

@ -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<GFXTexHandle>& 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<GFXTexHandle>& baseHandles = getHandles(interiorHandle, 0);
Vector<GFXTexHandle>& 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<InteriorResource> & 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<GFXTexHandle> & 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];
}

View file

@ -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<GFXTexHandle> mLightmapHandles;
};
struct InteriorLMInfo {
Interior * mInterior;
LM_HANDLE * mHandlePtr;
U32 mNumLightmaps;
LM_HANDLE mBaseInstanceHandle;
Vector<InstanceLMInfo*> mInstances;
};
Vector<InteriorLMInfo*> 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<GFXTexHandle> & 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

View file

@ -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<MeshRenderInst>();
*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<MeshRenderInst>();
*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<MeshRenderInst>();
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<ObjectRenderInst>();
ri->renderDelegate.bind(intInst, &InteriorInstance::_renderObject);
ri->type = RenderPassManager::RIT_Object;
state->getRenderPass()->addInst( ri );
return;
}
#endif
// render zones
for( U32 i=0; i<mZones.size(); i++ )
{
// No need to try to render zones without any surfaces
if (mZones[i].surfaceCount == 0)
continue;
if( zoneVis.isZoneVisible(i) == false && !state->isReflectPass() )
continue;
for( U32 j=0; j<mZoneRNList[i].renderNodeList.size(); j++ )
{
RenderNode &node = mZoneRNList[i].renderNodeList[j];
renderZoneNode( state, node, intInst, sgData, coreRi );
}
}
// render static meshes...
for(U32 i=0; i<mStaticMeshes.size(); i++)
mStaticMeshes[i]->render( state, *coreRi, getLMHandle(),
intInst->getLMHandle(), intInst );
// render reflective surfaces
if ( !state->isReflectPass() )
{
renderLights(state, intInst, sgData, coreRi, zoneVis);
for( U32 i=0; i<mZones.size(); i++ )
{
if( zoneVis.isZoneVisible(i) == false ) continue;
for( U32 j=0; j<mZoneReflectRNList[i].reflectList.size(); j++ )
{
ReflectRenderNode &node = mZoneReflectRNList[i].reflectList[j];
renderReflectNode( state, node, intInst, sgData, coreRi );
}
}
}
}
void Interior::renderLights( SceneRenderState* state,
InteriorInstance *intInst,
SceneData &sgData,
MeshRenderInst *coreRi,
const ZoneVisDeterminer &zonevis )
{
// TODO!
/*
if (!smLightPlugin)
return;
if (!smLightPlugin->interiorInstInit(intInst))
return;
// build the render instances...
for(U32 z=0; z<mZones.size(); z++)
{
if(!zonevis.isZoneVisible(z))
continue;
Zone &zone = mZones[z];
S32 zoneid = zone.zoneId - 1;
if(zoneid > -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<MeshRenderInst*> sRenderList;
sRenderList.clear();
for(U32 j=0; j<mZoneRNList[z].renderNodeList.size(); j++)
{
RenderNode &node = mZoneRNList[z].renderNodeList[j];
if (!node.matInst)
continue;
MeshRenderInst *ri = state->getRenderPass()->allocInst<MeshRenderInst>();
*ri = *coreRi;
ri->type = RenderPassManager::RIT_InteriorDynamicLighting;
ri->matInst = node.matInst;
ri->primBuffIndex = node.primInfoIndex;
sRenderList.push_back(ri);
}
smLightPlugin->processRI(state, sRenderList);
}
*/
}

View file

@ -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<Interior*>(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<InteriorResource>::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<InteriorResource>::signature()
{
return MakeFourCC('t','d','i','f');
}

View file

@ -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<Interior*> mDetailLevels;
Vector<Interior*> mSubObjects;
Vector<InteriorResTrigger*> mTriggers;
Vector<InteriorPathFollower*> mInteriorPathFollowers;
Vector<ForceField*> mForceFields;
Vector<AISpecialNode*> mAISpecialNodes;
Vector<ItrGameEntity*> 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_

View file

@ -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);
}

View file

@ -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<InteriorDictEntry>
{
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<U32> mTriggerIds;
Vector<WayPoint> 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_

View file

@ -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<MeshRenderInst *> *InteriorSimpleMesh::renderInstList = new Vector<MeshRenderInst *>();
// 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; p<primitives.size(); p++)
// {
// primitive &prim = primitives[p];
// for(U32 t=2; t<prim.count; t++)
// {
// Point3F &v1 = verts[prim.start+t-2];
// Point3F &v2 = verts[prim.start+t-1];
// Point3F &v3 = verts[prim.start+t];
//
// F32 cur_t = 0;
// Point2F b;
//
// if(castRayTriangle(start, dir, v1, v2, v3, cur_t, b))
// {
// if(cur_t < best_t)
// {
// best_t = cur_t;
// best_normal = norms[prim.start+t];
// found = true;
// }
// }
// }
// }
//
// if(found && info)
// {
// info->t = 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; p<primitives.size(); p++)
{
primitive &prim = primitives[p];
for(U32 t=2; t<prim.count; t++)
{
Point3F v[3];
v[0] = verts[prim.start+t-2];
v[1] = verts[prim.start+t-1];
v[2] = verts[prim.start+t];
if(_whichSide(left, v) == PlaneF::Front)
continue;
if(_whichSide(right, v) == PlaneF::Front)
continue;
if(_whichSide(top, v) == PlaneF::Front)
continue;
if(_whichSide(bottom, v) == PlaneF::Front)
continue;
return true;
}
}
return false;
}
void InteriorSimpleMesh::render( SceneRenderState* state,
const MeshRenderInst &copyinst,
U32 interiorlmhandle,
U32 instancelmhandle,
InteriorInstance* intInst )
{
/*
AssertFatal((primBuff->mPrimitiveCount == packedPrimitives.size()), "Primitive mismatch");
renderInstList->clear();
for(S32 i=0; i<packedPrimitives.size(); i++)
{
primitive &draw = packedPrimitives[i];
MeshRenderInst *inst = state->getRenderPass()->allocInst<MeshRenderInst>();
*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<MeshRenderInst *> &list = *renderInstList;
// clone the origial instances to avoid damaging the originals' data
for(int i=0; i<renderInstList->size(); i++)
{
MeshRenderInst *inst = state->getRenderPass()->allocInst<MeshRenderInst>();
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<bool> addedprim;
addedprim.setSize(primitives.size());
dMemset(addedprim.address(), 0, (addedprim.size() * sizeof(bool)));
Vector<Point3F> tang;
Vector<Point3F> 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<primitives.size(); p++)
{
if(addedprim[p])
continue;
addedprim[p] = true;
const primitive &primold = primitives[p];
packedPrimitives.increment();
primitive &primnew = packedPrimitives.last();
primnew.start = packedIndices.size();
primnew.count = 0;
primnew.alpha = primold.alpha;
primnew.diffuseIndex = primold.diffuseIndex;
primnew.lightMapIndex = primold.lightMapIndex;
packPrimitive(primnew, primold, packedIndices, flipped, tang, binorm);
for(U32 gp=(p+1); gp<primitives.size(); gp++)
{
if(addedprim[gp])
continue;
const primitive &primgrouped = primitives[gp];
if((primnew.alpha != primgrouped.alpha) || (primnew.diffuseIndex != primgrouped.diffuseIndex) ||
(primnew.lightMapIndex != primgrouped.lightMapIndex))
continue;
addedprim[gp] = true;
packPrimitive(primnew, primgrouped, packedIndices, flipped, tang, binorm);
}
}
// normalize
for(U32 i=0; i<tang.size(); i++)
{
tang[i].normalize();
binorm[i].normalize();
}
// verify...
F32 oldcount = 0;
F32 newcount = 0;
for(U32 i=0; i<primitives.size(); i++)
oldcount += F32(primitives[i].count) - 2.0f;
for(U32 i=0; i<packedPrimitives.size(); i++)
newcount += F32(packedPrimitives[i].count) / 3.0f;
AssertFatal((oldcount == newcount), "Invalid primitive pack.");
// build the GFX buffers...
Vector<GFXPrimitive> packedprims;
packedprims.setSize(packedPrimitives.size());
for(U32 i=0; i<packedprims.size(); i++)
{
GFXPrimitive &p = packedprims[i];
primitive &prim = packedPrimitives[i];
p.type = GFXTriangleList;
p.numPrimitives = prim.count / 3;
p.startIndex = prim.start;
p.minIndex = U32_MAX;
U32 maxindex = 0;
for(U32 ii=0; ii<prim.count; ii++)
{
if(p.minIndex > 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<GFXVertexPNTTB> packedverts;
packedverts.setSize(verts.size());
// fill it
for(U32 i=0; i<packedverts.size(); i++)
{
GFXVertexPNTTB &v = packedverts[i];
trans.mulP(verts[i], &v.point);
trans.mulV(norms[i], &v.normal);
trans.mulV(tang[i], &v.T);
trans.mulV(binorm[i], &v.B);
v.texCoord = diffuseUVs[i];
v.texCoord2 = lightmapUVs[i];
v.T = v.T - v.normal * mDot(v.normal, v.T);
v.T.normalize();
Point3F b;
mCross(v.normal, v.T, &b);
b *= (mDot(b, v.B) < 0.0F) ? -1.0F : 1.0F;
v.B = b;
}
// set up the vb and fill all at once
vertBuff.set(GFX, packedverts.size(), GFXBufferTypeStatic);
GFXVertexPNTTB *rawvb = vertBuff.lock();
dMemcpy(rawvb, packedverts.address(), packedverts.size() * sizeof(GFXVertexPNTTB));
vertBuff.unlock();
// set up the pb and fill all at once
U16 *rawi;
GFXPrimitive *rawp;
primBuff.set(GFX, packedIndices.size(), packedprims.size(), GFXBufferTypeStatic);
primBuff.lock(&rawi, &rawp);
dMemcpy(rawi, packedIndices.address(), packedIndices.size() * sizeof(U16));
dMemcpy(rawp, packedprims.address(), packedprims.size() * sizeof(GFXPrimitive));
primBuff.unlock();
}
void InteriorSimpleMesh::buildTangent(U32 i0, U32 i1, U32 i2, Vector<Point3F> &tang, Vector<Point3F> &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<U16> &indicesnew,
bool flipped, Vector<Point3F> &tang, Vector<Point3F> &binorm)
{
// convert from strip to list and add to primnew
for(U32 p=2; p<primold.count; p++)
{
bool direction = (p & 0x1);
U32 i0, i1, i2;
if(flipped)
direction = !direction;
if(direction)
{
i0 = indices[p + primold.start - 1];
i1 = indices[p + primold.start - 2];
i2 = indices[p + primold.start];
}
else
{
i0 = indices[p + primold.start - 2];
i1 = indices[p + primold.start - 1];
i2 = indices[p + primold.start];
}
indicesnew.push_back(i0);
indicesnew.push_back(i1);
indicesnew.push_back(i2);
buildTangent(i0, i1, i2, tang, binorm);
primnew.count += 3;
}
}
bool InteriorSimpleMesh::prepForRendering(const char* path)
{
//materialList->load(InteriorTexture, path, false);
materialList->mapMaterials();
// GFX2_RENDER_MERGE
materialList->initMatInstances( MATMGR->getDefaultFeatures(), getGFXVertexFormat<GFXVertexPNTTB>() );
return true;
}

View file

@ -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 &copyinst,
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<verts.size(); i++)
{
bounds.maxExtents.setMax(verts[i]);
bounds.minExtents.setMin(verts[i]);
}
}
Vector<U16> packedIndices;
Vector<primitive> packedPrimitives;/// tri-list instead of strips
GFXVertexBufferHandle<GFXVertexPNTTB> vertBuff;
GFXPrimitiveBufferHandle primBuff;
void buildBuffers();
void buildTangent(U32 i0, U32 i1, U32 i2, Vector<Point3F> &tang, Vector<Point3F> &binorm);
void packPrimitive(primitive &primnew, const primitive &primold, Vector<U16> &indicesnew,
bool flipped, Vector<Point3F> &tang, Vector<Point3F> &binorm);
bool prepForRendering(const char *path);
bool hasSolid;
bool hasTranslucency;
Box3F bounds;
MatrixF transform;
Point3F scale;
Vector<primitive> primitives;
// same index relationship...
Vector<U16> indices;
Vector<Point3F> verts;
Vector<Point3F> norms;
Vector<Point2F> diffuseUVs;
Vector<Point2F> lightmapUVs;
TSMaterialList *materialList;
bool containsPrimitiveType(bool translucent)
{
for(U32 i=0; i<primitives.size(); i++)
{
if(primitives[i].alpha == translucent)
return true;
}
return false;
}
void copyTo(InteriorSimpleMesh &dest)
{
dest.clear();
dest.hasSolid = hasSolid;
dest.hasTranslucency = hasTranslucency;
dest.bounds = bounds;
dest.transform = transform;
dest.scale = scale;
dest.primitives = primitives;
dest.indices = indices;
dest.verts = verts;
dest.norms = norms;
dest.diffuseUVs = diffuseUVs;
dest.lightmapUVs = lightmapUVs;
if(materialList)
dest.materialList = new TSMaterialList(materialList);
}
//bool castRay(const Point3F &start, const Point3F &end, RayInfo* info);
bool castPlanes(PlaneF left, PlaneF right, PlaneF top, PlaneF bottom);
bool read(Stream& stream);
bool write(Stream& stream) const;
private:
static Vector<MeshRenderInst *> *renderInstList;
};
#endif //_INTERIORSIMPLEMESH_H_

View file

@ -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()
{
//
}

View file

@ -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_

View file

@ -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<SGWinding> 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;
}

View file

@ -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

View file

@ -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<PathedInteriorData*>(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<SimPath::Path*>(*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;
}

View file

@ -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<StringTableEntry> mTriggers;
Point3F mOffset;
Box3F mExtrudedBox;
bool mStopped;
// Loaded resources and fields
protected:
static PathedInterior *mClientPathedInteriors;
SFXSource* mSustainSound;
StringTableEntry mInteriorResName;
S32 mInteriorResIndex;
Resource<InteriorResource> mInteriorRes;
Interior* mInterior;
Vector<ColorI> mVertexColorsNormal;
Vector<ColorI> 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

View file

@ -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

View file

@ -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:

File diff suppressed because it is too large Load diff

View file

@ -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_

View file

@ -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;

View file

@ -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<InteriorInstance *>(mLitObjects[object]->getObject());
if(interiorinst)
{
Interior *detail = interiorinst->getDetailLevel(0);
for(U32 i=0; i<detail->mNormalLMapIndices.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; i<mLights.size(); i++)

View file

@ -70,7 +70,6 @@ ShadowMapPass::ShadowMapPass(LightManager* lightManager, ShadowMapManager* shado
// Setup our render pass manager
mShadowRPM->addManager( 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<MeshRenderInst*>( inst );
if ( !meshRI->matInst )

View file

@ -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<MeshRenderInst*>(inst)->matInst;

View file

@ -86,7 +86,6 @@ RenderGlowMgr::RenderGlowMgr()
GFXFormatR8G8B8A8,
Point2I( 512, 512 ) )
{
notifyType( RenderPassManager::RIT_Interior );
notifyType( RenderPassManager::RIT_Decal );
notifyType( RenderPassManager::RIT_Translucent );

View file

@ -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");

View file

@ -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;

View file

@ -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;

View file

@ -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"

View file

@ -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");

View file

@ -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 @

View file

@ -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; } );

View file

@ -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";

View file

@ -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);
//------------------------------------------------------------------------------
//

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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") )
{

View file

@ -373,7 +373,7 @@
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Interiors";
text = "Objects";
maxLength = "1024";
maxPopupHeight = "200";
sbUsesNAColor = "0";

View file

@ -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();
}

View file

@ -178,7 +178,7 @@
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Interiors";
text = "Objects";
maxLength = "1024";
maxPopupHeight = "200";
sbUsesNAColor = "0";

View file

@ -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");

View file

@ -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 )
{

View file

@ -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();

View file

@ -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();";

View file

@ -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 @

View file

@ -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; } );

View file

@ -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";

View file

@ -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);
//------------------------------------------------------------------------------
//

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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") )
{

View file

@ -373,7 +373,7 @@
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Interiors";
text = "Objects";
maxLength = "1024";
maxPopupHeight = "200";
sbUsesNAColor = "0";

View file

@ -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();
}

View file

@ -178,7 +178,7 @@
AnchorBottom = "0";
AnchorLeft = "1";
AnchorRight = "0";
text = "Interiors";
text = "Objects";
maxLength = "1024";
maxPopupHeight = "200";
sbUsesNAColor = "0";

View file

@ -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");

View file

@ -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 )
{

View file

@ -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();

View file

@ -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();";

View file

@ -23,7 +23,6 @@
// 3D
addEngineSrcDir('collision');
addEngineSrcDir('interior');
addEngineSrcDir('materials');
addEngineSrcDir('lighting');
addEngineSrcDir('lighting/common');