Added sharedCollision library

This commit is contained in:
Anonymous
2014-01-14 10:50:02 -07:00
parent 8342abaeec
commit ddde05869d
185 changed files with 38126 additions and 0 deletions
+1
View File
@@ -1,4 +1,5 @@
add_subdirectory(sharedCollision)
add_subdirectory(sharedCompression)
add_subdirectory(sharedDebug)
add_subdirectory(sharedFile)
@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 2.8)
project(sharedCollision)
if(WIN32)
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public)
add_subdirectory(src)
@@ -0,0 +1 @@
#include "../../src/shared/core/BarrierObject.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/BaseClass.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/BaseExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/BoxExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/BoxTree.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Bresenham.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollideParameters.h"
@@ -0,0 +1,2 @@
#error obsolete
@@ -0,0 +1 @@
#include "../../src/shared/core/Collision2d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionBuckets.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/CollisionDetect.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionEnums.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionInfo.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionMesh.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionNotification.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionProperty.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionResolve.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionSurface.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionUtils.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionVolume.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CollisionWorld.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/ComponentExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/CompositeExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/ConfigSharedCollision.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Contact3d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/ContactPoint.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/core/Containment1d.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/core/Containment2d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Containment3d.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/CylinderExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/DetailExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Distance2d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Distance3d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/DoorHelper.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/core/DoorInfo.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/DoorObject.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/Extent.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/ExtentList.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FirstSharedCollision.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Floor.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FloorContactShape.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FloorLocator.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FloorManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FloorMesh.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FloorTri.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Footprint.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FootprintForceReattachManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Intersect1d.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/core/Intersect2d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Intersect3d.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/MeshExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/MultiList.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/NeighborObject.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/OrientedCylinderExtent.h"
@@ -0,0 +1,2 @@
#include "../../src/shared/core/Overlap2d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Overlap3d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/Resolve3d.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SetupSharedCollision.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SimpleCollisionMesh.h"
@@ -0,0 +1 @@
#include "../../src/shared/extent/SimpleExtent.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SpaceAvoidanceManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SpatialDatabase.h"
@@ -0,0 +1 @@
#error obsolete
@@ -0,0 +1,156 @@
set(SHARED_SOURCES
shared/core/BarrierObject.cpp
shared/core/BarrierObject.h
shared/core/BaseClass.h
shared/core/BoxTree.cpp
shared/core/BoxTree.h
shared/core/Bresenham.cpp
shared/core/Bresenham.h
shared/core/CollideParameters.cpp
shared/core/CollideParameters.h
shared/core/Collision2d.cpp
shared/core/Collision2d.h
shared/core/CollisionBuckets.cpp
shared/core/CollisionBuckets.h
shared/core/CollisionEnums.cpp
shared/core/CollisionEnums.h
shared/core/CollisionInfo.h
shared/core/CollisionMesh.cpp
shared/core/CollisionMesh.h
shared/core/CollisionNotification.cpp
shared/core/CollisionNotification.h
shared/core/CollisionProperty.cpp
shared/core/CollisionProperty.h
shared/core/CollisionResolve.cpp
shared/core/CollisionResolve.h
shared/core/CollisionSurface.cpp
shared/core/CollisionSurface.h
shared/core/CollisionUtils.cpp
shared/core/CollisionUtils.h
shared/core/CollisionVolume.cpp
shared/core/CollisionVolume.h
shared/core/CollisionWorld.cpp
shared/core/CollisionWorld.h
shared/core/ConfigSharedCollision.cpp
shared/core/ConfigSharedCollision.h
shared/core/Contact3d.cpp
shared/core/Contact3d.h
shared/core/ContactPoint.cpp
shared/core/ContactPoint.h
shared/core/Containment1d.cpp
shared/core/Containment1d.h
shared/core/Containment2d.cpp
shared/core/Containment2d.h
shared/core/Containment3d.cpp
shared/core/Containment3d.h
shared/core/Distance2d.cpp
shared/core/Distance2d.h
shared/core/Distance3d.cpp
shared/core/Distance3d.h
shared/core/DoorHelper.cpp
shared/core/DoorHelper.h
shared/core/DoorInfo.h
shared/core/DoorObject.cpp
shared/core/DoorObject.h
shared/core/FirstSharedCollision.h
shared/core/FloorContactShape.cpp
shared/core/FloorContactShape.h
shared/core/Floor.cpp
shared/core/Floor.h
shared/core/FloorLocator.cpp
shared/core/FloorLocator.h
shared/core/FloorManager.cpp
shared/core/FloorManager.h
shared/core/FloorMesh.cpp
shared/core/FloorMesh.h
shared/core/FloorTri.cpp
shared/core/FloorTri.h
shared/core/Footprint.cpp
shared/core/Footprint.h
shared/core/FootprintForceReattachManager.cpp
shared/core/FootprintForceReattachManager.h
shared/core/Intersect1d.cpp
shared/core/Intersect1d.h
shared/core/Intersect2d.cpp
shared/core/Intersect2d.h
shared/core/Intersect3d.cpp
shared/core/Intersect3d.h
shared/core/MultiList.cpp
shared/core/MultiList.h
shared/core/NeighborObject.cpp
shared/core/NeighborObject.h
shared/core/Overlap2d.cpp
shared/core/Overlap2d.h
shared/core/Overlap3d.cpp
shared/core/Overlap3d.h
shared/core/Resolve3d.cpp
shared/core/Resolve3d.h
shared/core/SetupSharedCollision.cpp
shared/core/SetupSharedCollision.h
shared/core/SimpleCollisionMesh.cpp
shared/core/SimpleCollisionMesh.h
shared/core/SpaceAvoidanceManager.cpp
shared/core/SpaceAvoidanceManager.h
shared/core/SpatialDatabase.cpp
shared/core/SpatialDatabase.h
shared/extent/BaseExtent.cpp
shared/extent/BaseExtent.h
shared/extent/BoxExtent.cpp
shared/extent/BoxExtent.h
shared/extent/CollisionDetect.cpp
shared/extent/CollisionDetect.h
shared/extent/ComponentExtent.cpp
shared/extent/ComponentExtent.h
shared/extent/CompositeExtent.cpp
shared/extent/CompositeExtent.h
shared/extent/CylinderExtent.cpp
shared/extent/CylinderExtent.h
shared/extent/DetailExtent.cpp
shared/extent/DetailExtent.h
shared/extent/Extent.cpp
shared/extent/Extent.h
shared/extent/ExtentList.cpp
shared/extent/ExtentList.h
shared/extent/MeshExtent.cpp
shared/extent/MeshExtent.h
shared/extent/OrientedCylinderExtent.cpp
shared/extent/OrientedCylinderExtent.h
shared/extent/SimpleExtent.cpp
shared/extent/SimpleExtent.h
)
if(WIN32)
set(PLATFORM_SOURCES
win32/FirstSharedCollision.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
else()
set(PLATFORM_SOURCES "")
endif()
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/shared
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedGame/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
)
add_library(sharedCollision STATIC
${SHARED_SOURCES}
${PLATFORM_SOURCES}
)
@@ -0,0 +1,220 @@
// ======================================================================
//
// BarrierObject.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/BarrierObject.h"
#include "sharedCollision/CollisionProperty.h"
#include "sharedCollision/DoorObject.h"
#include "sharedCollision/SimpleExtent.h"
#include "sharedCollision/Extent.h"
#include "sharedCollision/Containment3d.h"
#include "sharedCollision/Distance3d.h"
#include "sharedCollision/CollisionUtils.h"
#include "sharedMath/AxialBox.h"
#include "sharedMath/VectorArgb.h"
#include "sharedObject/Appearance.h"
#include "sharedObject/Portal.h"
#include "sharedObject/CellProperty.h"
static VectorArgb gs_barrierColor(0.85f,0.3f,0.02f,0.01f);
// ----------------------------------------------------------------------
class BarrierCollisionProperty : public CollisionProperty
{
public:
explicit BarrierCollisionProperty( Object & owner )
: CollisionProperty(owner)
{
}
virtual bool canCollideWith ( CollisionProperty const * otherCollision ) const
{
if(otherCollision == NULL)
{
return false;
}
BarrierObject const * barrier = safe_cast<BarrierObject const *>(&getOwner());
if(barrier == NULL)
{
return false;
}
if(barrier->getParentCell() != otherCollision->getLastCell())
{
return false;
}
if(otherCollision->isPlayer())
{
return barrier->isActive();
}
else
{
return false;
}
}
virtual bool blocksInteraction ( InteractionType interaction ) const
{
BarrierObject const * barrier = safe_cast<BarrierObject const *>(&getOwner());
bool barrierActive = barrier && barrier->isActive();
bool doorClosed = barrier && barrier->getDoor() && barrier->getDoor()->isClosed();
if(barrierActive)
{
// The barrier is active. All interactions are blocked except IT_See, which
// is blocked if the door is closed.
if(interaction == IT_See)
{
return doorClosed;
}
else
{
return true;
}
}
else
{
// The barrier is inactive.
return doorClosed;
}
}
virtual bool blocksMovement () const
{
BarrierObject const * barrier = safe_cast<BarrierObject const *>(&getOwner());
bool barrierActive = barrier && barrier->isActive();
if(barrierActive)
{
return CollisionProperty::blocksMovement();
}
else
{
return false;
}
}
protected:
private:
BarrierCollisionProperty();
BarrierCollisionProperty(const BarrierCollisionProperty&);
BarrierCollisionProperty& operator= (const BarrierCollisionProperty&);
};
// ----------------------------------------------------------------------
BarrierObject::BarrierObject(DoorObject const * door, bool needsAppearance)
: NeighborObject(),
m_door(door)
{
setDebugName("Barrier object");
BarrierCollisionProperty * collision = new BarrierCollisionProperty(*this); //lint !e1524 new in constructor for class which has no explicit destructor
addProperty(*collision);
createCollisionExtent();
if(needsAppearance)
{
createAppearance();
}
}//lint !e429 custodial pointer collision has not been freed or returned // actually, addProperty takes custody of collision
// ----------------------------------------------------------------------
void BarrierObject::createCollisionExtent ( void )
{
CollisionProperty * collision = getCollisionProperty();
if(collision)
{
AxialBox box = m_door->getPortal()->getLocalBox();
float r = 0.05f;
box.setMax( box.getMax() + Vector(r,r,r) );
box.setMin( box.getMin() - Vector(r,r,r) );
SimpleExtent * extent = new SimpleExtent( MultiShape(box) );
collision->attachSourceExtent(extent);
}
}
// ----------------------------------------------------------------------
void BarrierObject::createAppearance ( void )
{
// Create the portal polygon and translate it
// to the origin so that it matches the door
// hardpoint
VertexList verts;
m_door->getPortal()->getLocalVerts(verts);
Collision3d::MovePolyOnto(verts,Vector::zero);
// Create our barrier appearance
Appearance * appearance = CellProperty::createPortalBarrier(verts,gs_barrierColor);
if(appearance != NULL)
{
setAppearance( appearance );
// Create an extent for the barrier appearance - without it the barrier won't be rendered
Extent * appearanceExtent = new Extent( Containment3d::EncloseSphere(verts) );
IGNORE_RETURN(appearanceExtent->incrementReference()); // Extent::incrementReference() returns the ref count, not an error condition that needs to be checked
appearance->setExtent( appearanceExtent );
}//lint !e429 custodial pointer 'appearanceExtent' has not been freed or returned // setExtent takes custody
}
// ----------------------------------------------------------------------
// ----------
// Barriers are active if their doors don't allow passage
bool BarrierObject::isActive ( void ) const
{
return m_door && (!m_door->isPassageAllowed());
}
// Barriers should be rendered if their doors disallow passage in either
// direction
bool BarrierObject::shouldRender ( void ) const
{
return m_door && m_door->isOpen() && (!m_door->isPassageAllowed());
}
DoorObject const * BarrierObject::getDoor ( void ) const
{
return m_door;
}
// ----------------------------------------------------------------------
@@ -0,0 +1,44 @@
// ======================================================================
//
// BarrierObject.h
// Copyright 2002 Sony Online Entertainment
// All Rights Reserved.
//
// ======================================================================
#ifndef INCLUDED_BarrierObject_H
#define INCLUDED_BarrierObject_H
#include "sharedCollision/NeighborObject.h"
class DoorObject;
// ----------------------------------------------------------------------
class BarrierObject : public NeighborObject
{
public:
BarrierObject(DoorObject const * door, bool needsAppearance);
virtual bool isActive ( void ) const;
virtual bool shouldRender ( void ) const;
DoorObject const * getDoor ( void ) const;
protected:
void createCollisionExtent ( void );
void createAppearance ( void );
DoorObject const * m_door;
private:
BarrierObject( BarrierObject const & copy );
BarrierObject & operator = ( BarrierObject const & copy );
};
// ======================================================================
#endif
@@ -0,0 +1,20 @@
// ======================================================================
//
// BaseClass.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_BaseClass_H
#define INCLUDED_BaseClass_H
class BaseClass
{
public:
BaseClass() {}
virtual ~BaseClass() {}
};
#endif
@@ -0,0 +1,730 @@
// ======================================================================
//
// BoxTree.cpp
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/BoxTree.h"
#include "sharedCollision/BaseClass.h"
#include "sharedCollision/Overlap3d.h"
#include "sharedCollision/Containment3d.h"
#include "sharedCollision/Distance3d.h"
#include "sharedFile/Iff.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedMath/VectorArgb.h"
#include "sharedMath/DebugShapeRenderer.h"
#include "sharedMath/Line3d.h"
#include "sharedFoundation/MemoryBlockManagerMacros.h"
#include "sharedFoundation/MemoryBlockManager.h"
#include <vector>
const Tag TAG_BTRE = TAG(B,T,R,E);
const Tag TAG_NODS = TAG(N,O,D,S);
// ======================================================================
class BoxTreeNode
{
MEMORY_BLOCK_MANAGER_INTERFACE_WITH_INSTALL;
public:
BoxTreeNode();
~BoxTreeNode();
BoxTreeNode ( AxialBox const & box, int userId );
BoxTreeNode ( BoxTreeNode * childA, BoxTreeNode * childB );
// ----------
void drawDebugShapes ( DebugShapeRenderer * renderer, VectorArgb color, int level ) const;
int getNodeCount ( void ) const;
float calcWeight ( void ) const;
float calcBalance ( void ) const;
void assignIndices ( void );
void recursePackInto ( BoxTreeNode * & nodeCursor, BoxTreeNode * base ) const;
void packInto ( BoxTreeNode * flatNode, BoxTreeNode * base ) const;
void assignIndices ( int & counter );
void deleteChildren ( void );
void read ( Iff & iff, BoxTreeNode * base );
void write ( Iff & iff, BoxTreeNode * base );
bool findClosest ( Vector const & V, float maxDistance, float & outDistance, int & outId ) const;
float distanceTo ( Vector const & V ) const;
float childDistanceTo ( Vector const & V ) const;
// ----------
// This is stripped down to be 40 bytes, I can't really get it much smaller
// without majorly changing how the code works.
AxialBox m_box; // The box. Can't live without this, though it could be made lower-precision.
int m_index; // Used during packing to keep track of where in the packed array the node goes.
// Not absolutely necessary, but without it packing would be a pain.
int m_userId; // A user-supplied integer
BoxTreeNode * m_childA;
BoxTreeNode * m_childB;
};
MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITH_INSTALL(BoxTreeNode, true, 0, 0, 0);
// ======================================================================
typedef std::vector<BoxTreeNode*> BoxTreeNodePVec;
typedef std::pair<int,int> IntPair;
IntPair findClosestPair( BoxTreeNodePVec const & nodes )
{
int nodeCount = nodes.size();
float minValue = REAL_MAX;
int minA = -1;
int minB = -1;
for(int i = 0; i < nodeCount - 1; i++)
{
for(int j = i+1; j < nodeCount; j++)
{
AxialBox tempBox( nodes[i]->m_box, nodes[j]->m_box );
float tempValue = tempBox.getVolume();
if(tempValue < minValue)
{
minValue = tempValue;
minA = i;
minB = j;
}
}
}
return IntPair(minA,minB);
}
// ----------
// Erase one or two elements from a vector in constant time,
// but this changes the order of the elements.
inline void erase( BoxTreeNodePVec & nodes, int whichNode )
{
nodes[whichNode] = nodes.back();
nodes.resize(nodes.size()-1);
}
// When erasing more than one element, we have to erase them in order
// from back to front.
inline void erase( BoxTreeNodePVec & nodes, int nodeA, int nodeB )
{
if(nodeA == nodeB)
{
erase(nodes,nodeA);
}
else if(nodeA > nodeB)
{
erase(nodes,nodeA);
erase(nodes,nodeB);
}
else
{
erase(nodes,nodeB);
erase(nodes,nodeA);
}
}
// ----------------------------------------------------------------------
BoxTreeNode::BoxTreeNode()
: m_box(),
m_index(-1),
m_userId(-1),
m_childA(NULL),
m_childB(NULL)
{
}
BoxTreeNode::BoxTreeNode ( AxialBox const & box, int userId )
: m_box(box),
m_index(-1),
m_userId(userId),
m_childA(NULL),
m_childB(NULL)
{
}
BoxTreeNode::BoxTreeNode ( BoxTreeNode * childA, BoxTreeNode * childB )
: m_box(),
m_index(-1),
m_userId(-1),
m_childA(childA),
m_childB(childB)
{
if(m_childA) m_box.add(m_childA->m_box);
if(m_childB) m_box.add(m_childB->m_box);
}
BoxTreeNode::~BoxTreeNode()
{
}
// ----------------------------------------------------------------------
void BoxTreeNode::drawDebugShapes ( DebugShapeRenderer * renderer, VectorArgb color, int level ) const
{
UNREF(renderer);
UNREF(color);
UNREF(level);
#ifdef _DEBUG
if(m_childA == NULL) return;
if(m_childB == NULL) return;
if(renderer == NULL) return;
VectorArgb newColor( color.a, color.r * 0.9f, color.g * 0.9f, color.b * 0.9f );
if(m_childA) m_childA->drawDebugShapes(renderer,newColor,level+1);
if(m_childB) m_childB->drawDebugShapes(renderer,newColor,level+1);
renderer->setColor(color);
renderer->drawBox(m_box);
#endif
}
// ----------------------------------------------------------------------
int BoxTreeNode::getNodeCount ( void ) const
{
int accum = 1;
if(m_childA) accum += m_childA->getNodeCount();
if(m_childB) accum += m_childB->getNodeCount();
return accum;
}
// ----------
float BoxTreeNode::calcWeight ( void ) const
{
if((m_childA == NULL) && (m_childB == NULL)) return 1.0f;
float accum = 0.0f;
if(m_childA) accum += m_childA->calcWeight();
if(m_childB) accum += m_childB->calcWeight();
return accum;
}
// ----------
float BoxTreeNode::calcBalance ( void ) const
{
if((m_childA == NULL) && (m_childB == NULL)) return 1.0f;
if((m_childA != NULL) && (m_childB != NULL))
{
return m_childA->calcWeight() / m_childB->calcWeight();
}
else
{
return 0.0f;
}
}
// ----------------------------------------------------------------------
void BoxTreeNode::assignIndices ( void )
{
int counter = 0;
assignIndices(counter);
}
void BoxTreeNode::assignIndices ( int & counter )
{
m_index = counter;
counter++;
if(m_childA) m_childA->assignIndices(counter);
if(m_childB) m_childB->assignIndices(counter);
}
// ----------------------------------------------------------------------
void BoxTreeNode::recursePackInto ( BoxTreeNode * & nodeCursor, BoxTreeNode * base ) const
{
packInto(nodeCursor,base);
nodeCursor++;
if(m_childA) m_childA->recursePackInto(nodeCursor,base);
if(m_childB) m_childB->recursePackInto(nodeCursor,base);
}
void BoxTreeNode::packInto ( BoxTreeNode * node, BoxTreeNode * base ) const
{
node->m_box = m_box;
node->m_index = m_index;
node->m_childA = m_childA ? (base + m_childA->m_index) : NULL;
node->m_childB = m_childB ? (base + m_childB->m_index) : NULL;
node->m_userId = m_userId;
}
// ----------------------------------------------------------------------
void BoxTreeNode::deleteChildren ( void )
{
if(m_childA) m_childA->deleteChildren();
if(m_childB) m_childB->deleteChildren();
delete m_childA;
m_childA = NULL;
delete m_childB;
m_childB = NULL;
}
// ----------------------------------------------------------------------
void BoxTreeNode::write ( Iff & iff, BoxTreeNode * base )
{
iff.insertChunkFloatVector( m_box.getMax() );
iff.insertChunkFloatVector( m_box.getMin() );
iff.insertChunkData(m_index);
iff.insertChunkData(m_userId);
int indexA = ( m_childA ? m_childA - base : -1 );
int indexB = ( m_childB ? m_childB - base : -1 );
iff.insertChunkData(indexA);
iff.insertChunkData(indexB);
}
// ----------
void BoxTreeNode::read ( Iff & iff, BoxTreeNode * base )
{
Vector max = iff.read_floatVector();
Vector min = iff.read_floatVector();
m_box = AxialBox(min,max);
m_index = iff.read_int32();
m_userId = iff.read_int32();
int indexA = iff.read_int32();
int indexB = iff.read_int32();
m_childA = ( indexA != -1 ? base + indexA : NULL );
m_childB = ( indexB != -1 ? base + indexB : NULL );
}
// ----------------------------------------------------------------------
bool BoxTreeNode::findClosest ( Vector const & V, float maxDistance, float & outDistance, int & outIndex ) const
{
float dist = Distance3d::Distance2PointABox(V,m_box);
if(dist >= maxDistance)
{
// This node is too far away - don't recurse
return false;
}
// ----------
// Leaf node case - this leaf node is closer
if((m_childA == NULL) && (m_childB == NULL))
{
outDistance = dist;
outIndex = m_userId;
return true;
}
// ----------
// Branch node case - recurse through both children and return the closer (if there is one)
float distanceA = REAL_MAX;
float distanceB = REAL_MAX;
int indexA = -1;
int indexB = -1;
bool closerA = m_childA->findClosest(V,maxDistance,distanceA,indexA);
// reduce maxDistance for the child B search so we don't waste time searching through descendants of B that are farther than the closest descendant found in A
if(closerA) maxDistance = distanceA;
bool closerB = m_childB->findClosest(V,maxDistance,distanceB,indexB);
if(closerA || closerB)
{
if(distanceA < distanceB)
{
outDistance = distanceA;
outIndex = indexA;
}
else
{
outDistance = distanceB;
outIndex = indexB;
}
return true;
}
else
{
return false;
}
}
// ======================================================================
void BoxTree::install()
{
BoxTreeNode::install();
}
// ----------------------------------------------------------------------
BoxTree::BoxTree()
: m_flatNodes(NULL),
m_root(NULL),
m_testCounter(0)
{
}
BoxTree::~BoxTree()
{
clear();
}
// ----------------------------------------------------------------------
inline BoxTreeNode const * BoxTree::getRoot ( void ) const
{
return m_root;
}
// ----------------------------------------------------------------------
void BoxTree::build ( BoxVec const & boxes )
{
if(boxes.empty()) return;
// ----------
BoxTreeNodePVec nodes(boxes.size(),NULL);
int boxcount = boxes.size();
for(int i = 0; i < boxcount; i++)
{
nodes[i] = new BoxTreeNode(boxes[i],i);
}
// ----------
// Build the tree, brute-force bottom-up (slooooow)
while(nodes.size() > 1)
{
IntPair closestPair = findClosestPair(nodes);
int A = closestPair.first;
int B = closestPair.second;
BoxTreeNode * newNode = new BoxTreeNode( nodes[A], nodes[B] );
erase(nodes,A,B);
nodes.push_back(newNode);
}
// ----------
m_root = nodes[0];
pack();
m_root->deleteChildren();
delete m_root;
m_root = &m_flatNodes->front();
}
// ----------------------------------------------------------------------
void BoxTree::drawDebugShapes ( DebugShapeRenderer * renderer ) const
{
UNREF(renderer);
#ifdef _DEBUG
if(renderer == NULL) return;
if(m_root) m_root->drawDebugShapes( renderer, VectorArgb::solidWhite, 0 );
#endif
}
// ----------------------------------------------------------------------
int BoxTree::getNodeCount ( void ) const
{
if(m_flatNodes) return m_flatNodes->size();
else if(m_root) return m_root->getNodeCount();
else return 0;
}
// ----------
float BoxTree::calcWeight ( void ) const
{
if(m_root)
return m_root->calcWeight();
else
return 0.0f;
}
// ----------
float BoxTree::calcBalance ( void ) const
{
if(m_root)
return m_root->calcBalance();
else
return 1.0f;
}
// ----------------------------------------------------------------------
template< class TestShape >
static inline void templateTestOverlapRecurse( BoxTreeNode const * node, TestShape const & testShape, IdVec & outIds )
{
if(Overlap3d::Test(testShape,node->m_box))
{
if(node->m_userId != -1)
{
outIds.push_back(node->m_userId);
}
if(node->m_childA) templateTestOverlapRecurse(node->m_childA,testShape,outIds);
if(node->m_childB) templateTestOverlapRecurse(node->m_childB,testShape,outIds);
}
}
template< class TestShape >
static inline bool templateTestOverlap( BoxTree const & tree, TestShape const & testShape, IdVec & outIds )
{
if(tree.getRoot() == NULL) return false;
int oldSize = outIds.size();
templateTestOverlapRecurse( tree.getRoot(), testShape, outIds );
return oldSize != static_cast<int>(outIds.size());
}
// ----------
// Slightly different recursion - test the bounding box of the shape on nodes,
// only test against the actual shape on leaf nodes
template< class TestShape >
static inline void templateTestOverlapRecurse2( BoxTreeNode const * node, TestShape const & testShape, AxialBox const & shapeBounds, IdVec & outIds )
{
if(Overlap3d::Test(shapeBounds,node->m_box))
{
if(node->m_userId != -1)
{
if(Overlap3d::Test(testShape,node->m_box))
{
outIds.push_back(node->m_userId);
}
}
if(node->m_childA) templateTestOverlapRecurse(node->m_childA,testShape,outIds);
if(node->m_childB) templateTestOverlapRecurse(node->m_childB,testShape,outIds);
}
}
template< class TestShape >
static inline bool templateTestOverlap2( BoxTree const & tree, TestShape const & testShape, IdVec & outIds )
{
if(tree.getRoot() == NULL) return false;
int oldSize = outIds.size();
AxialBox shapeBounds = Containment3d::EncloseABox(testShape);
templateTestOverlapRecurse( tree.getRoot(), testShape, shapeBounds, outIds );
return oldSize != outIds.size();
}
// ----------
bool BoxTree::testOverlap ( AxialBox const & box, IdVec & outIds ) const { return templateTestOverlap(*this,box,outIds); }
bool BoxTree::testOverlap ( Line3d const & line, IdVec & outIds ) const { return templateTestOverlap(*this,line,outIds); }
bool BoxTree::testOverlap ( Ray3d const & ray, IdVec & outIds ) const { return templateTestOverlap(*this,ray,outIds); }
bool BoxTree::testOverlap ( Segment3d const & segment, IdVec & outIds ) const { return templateTestOverlap(*this,segment,outIds); }
// ----------------------------------------------------------------------
bool BoxTree::findClosest ( Vector const & V, float maxDistance, float & outDistance, int & outId ) const
{
return getRoot()->findClosest(V,maxDistance,outDistance,outId);
}
// ----------------------------------------------------------------------
void BoxTree::write ( Iff & iff )
{
iff.insertForm(TAG_BTRE);
iff.insertForm(TAG_0000);
// ----------
iff.insertChunk(TAG_NODS);
{
int nodeCount = m_flatNodes->size();
iff.insertChunkData(nodeCount);
BoxTreeNode * base = &m_flatNodes->front();
for( int i = 0; i < nodeCount; i++ )
{
m_flatNodes->at(i).write(iff,base);
}
}
iff.exitChunk(TAG_NODS);
// ----------
iff.exitForm(TAG_0000);
iff.exitForm(TAG_BTRE);
}
// ----------------------------------------------------------------------
void BoxTree::read ( Iff & iff )
{
iff.enterForm(TAG_BTRE);
switch (iff.getCurrentName())
{
case TAG_0000:
read_0000(iff);
break;
default:
FATAL(true,("FloorMesh::Invalid version"));
break;
}
iff.exitForm(TAG_BTRE);
if(m_flatNodes)
{
m_root = &m_flatNodes->front();
}
}
// ----------------------------------------------------------------------
void BoxTree::read_0000 ( Iff & iff )
{
clear();
iff.enterForm(TAG_0000);
// ----------
iff.enterChunk(TAG_NODS);
{
int nodeCount = iff.read_int32();
m_flatNodes = new BoxTreeNodeVec(nodeCount);
BoxTreeNode * base = &m_flatNodes->front();
for(int i = 0; i < nodeCount; i++)
{
m_flatNodes->at(i).read(iff,base);
}
}
iff.exitChunk(TAG_NODS);
// ----------
iff.exitForm(TAG_0000);
}
// ----------------------------------------------------------------------
void BoxTree::clear ( void )
{
if(m_root && !isFlat())
{
m_root->deleteChildren();
delete m_root;
m_root = NULL;
}
delete m_flatNodes;
m_flatNodes = NULL;
}
// ----------------------------------------------------------------------
void BoxTree::pack ( void )
{
if(!m_root) return;
if(m_flatNodes) return;
int nodeCount = getNodeCount();
m_flatNodes = new BoxTreeNodeVec();
m_flatNodes->resize(nodeCount);
BoxTreeNode * nodeCursor = &m_flatNodes->front();
m_root->assignIndices();
m_root->recursePackInto(nodeCursor,nodeCursor);
}
// ----------------------------------------------------------------------
@@ -0,0 +1,116 @@
// ======================================================================
//
// BoxTree.h
// copyright (c) 2001 Sony Online Entertainment
//
// This is a very simple, limited bounding box hierarchy used for speeding
// up collision queries
//
// ======================================================================
#ifndef INCLUDED_BoxTree_H
#define INCLUDED_BoxTree_H
#include "sharedMath/AxialBox.h"
#include "sharedFoundation/Tag.h"
class BoxTreeNode;
class DebugShapeRenderer;
class Line3d;
class Ray3d;
class Segment3d;
class VectorArgb;
class BoxTreeNode;
class Iff;
typedef stdvector<BoxTreeNode>::fwd BoxTreeNodeVec;
typedef stdvector<AxialBox>::fwd BoxVec;
typedef stdvector<int>::fwd IdVec;
// ----------------------------------------------------------------------
class BoxTree
{
public:
static void install();
public:
BoxTree();
~BoxTree();
// ----------
BoxTreeNode const * getRoot ( void ) const;
// ----------
void build ( BoxVec const & boxes );
void drawDebugShapes ( DebugShapeRenderer * renderer ) const;
int getNodeCount ( void ) const;
float calcWeight ( void ) const;
float calcBalance ( void ) const;
bool testOverlap ( AxialBox const & box, IdVec & outIds ) const;
bool testOverlap ( Line3d const & line, IdVec & outIds ) const;
bool testOverlap ( Ray3d const & ray, IdVec & outIds ) const;
bool testOverlap ( Segment3d const & segment, IdVec & outIds ) const;
bool findClosest ( Vector const & V, float maxDistance, float & outDistance, int & outId ) const;
void clearTestCounter( void );
int getTestCounter ( void ) const;
void write ( Iff & iff );
void read ( Iff & iff );
protected:
void clear ( void );
void read_0000 ( Iff & iff );
void pack ( void );
bool isFlat ( void ) const;
// ----------
BoxTreeNodeVec * m_flatNodes;
BoxTreeNode * m_root;
int m_testCounter;
private:
BoxTree( BoxTree const & copy );
BoxTree & operator = ( BoxTree const & copy );
};
// ----------------------------------------------------------------------
inline void BoxTree::clearTestCounter ( void )
{
m_testCounter = 0;
}
inline int BoxTree::getTestCounter ( void ) const
{
return m_testCounter;
}
// ----------
inline bool BoxTree::isFlat ( void ) const
{
return m_flatNodes != NULL;
}
// ======================================================================
#endif // #ifndef INCLUDED_BoxTree_H
@@ -0,0 +1,177 @@
// ======================================================================
//
// Bresenham.cpp
// copyright (c) 2004 Sony Online Entertainment
// tford
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/Bresenham.h"
#include <vector>
#include <algorithm>
// ======================================================================
Bresenham::Point3D::Point3D(int const xx, int const yy, int const zz)
: x(xx)
, y(yy)
, z(zz)
{
}
// ======================================================================
Bresenham::PointSetter3d::PointSetter3d()
{
}
// ----------------------------------------------------------------------
Bresenham::PointSetter3d::~PointSetter3d()
{
}
// ----------------------------------------------------------------------
void Bresenham::PointSetter3d::set(Point3D const & point)
{
realSet(point);
}
// ======================================================================
void Bresenham::FindPointsAlong(Point3D const & begin, Point3D const & end, bool const sloppyStep, PointSetter3d & howTo)
{
int const deltaX = end.x - begin.x;
int const deltaY = end.y - begin.y;
int const deltaZ = end.z - begin.z;
int const lengthX = abs(deltaX);
int const lengthY = abs(deltaY);
int const lengthZ = abs(deltaZ);
int const lengthX2 = lengthX * 2;
int const lengthY2 = lengthY * 2;
int const lengthZ2 = lengthZ * 2;
int const incrementX = (deltaX < 0) ? -1 : 1;
int const incrementY = (deltaY < 0) ? -1 : 1;
int const incrementZ = (deltaZ < 0) ? -1 : 1;
int x = begin.x;
int y = begin.y;
int z = begin.z;
// check x is dominant
if (lengthX2 >= std::max(lengthY2, lengthZ2))
{
int errorY = lengthY2 - lengthX;
int errorZ = lengthZ2 - lengthX;
while (x != (end.x + incrementX))
{
howTo.set(Point3D(x, y, z));
if (errorY >= 0)
{
if (sloppyStep)
{
howTo.set(Point3D(x + incrementX, y, z));
howTo.set(Point3D(x, y + incrementY, z));
}
y += incrementY;
errorY -= lengthX2;
}
if (errorZ >= 0)
{
if (sloppyStep)
{
howTo.set(Point3D(x + incrementX, y, z));
howTo.set(Point3D(x, y, z + incrementZ));
}
z += incrementZ;
errorZ -= lengthX2;
}
x += incrementX;
errorY += lengthY2;
errorZ += lengthZ2;
}
}
// check y is dominant
else if (lengthY2 >= std::max(lengthX2, lengthZ2))
{
int errorX = lengthX2 - lengthY;
int errorZ = lengthZ2 - lengthY;
while (y != (end.y + incrementY))
{
howTo.set(Point3D(x, y, z));
if (errorX >= 0)
{
if (sloppyStep)
{
howTo.set(Point3D(x, y + incrementY, z));
howTo.set(Point3D(x + incrementX, y, z));
}
x += incrementX;
errorX -= lengthY2;
}
if (errorZ >= 0)
{
if (sloppyStep)
{
howTo.set(Point3D(x, y + incrementY, z));
howTo.set(Point3D(x, y, z + incrementZ));
}
z += incrementZ;
errorZ -= lengthY2;
}
y += incrementY;
errorX += lengthX2;
errorZ += lengthZ2;
}
}
// check z is dominant
else if (lengthZ2 >= std::max(lengthX2, lengthY2))
{
int errorX = lengthZ2 - lengthZ;
int errorY = lengthZ2 - lengthZ;
while (z != (end.z + incrementZ))
{
howTo.set(Point3D(x, y, z));
if (errorX >= 0)
{
if (sloppyStep)
{
howTo.set(Point3D(x, y, z + incrementZ));
howTo.set(Point3D(x + incrementX, y, z));
}
x += incrementX;
errorX -= lengthY2;
}
if (errorY >= 0)
{
if (sloppyStep)
{
howTo.set(Point3D(x, y, z + incrementZ));
howTo.set(Point3D(x, y + incrementY, z));
}
y += incrementY;
errorY -= lengthX2;
}
z += incrementZ;
errorX += lengthX2;
errorY += lengthY2;
}
}
}
@@ -0,0 +1,69 @@
// ======================================================================
//
// Bresenham.h
// copyright (c) 2004 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_Bresenham_H
#define INCLUDED_Bresenham_H
// ======================================================================
class Bresenham
{
public:
//integer point class for use as parameters, etc.
struct Point3D
{
Point3D(int const xx, int const yy, int const zz);
int x;
int y;
int z;
};
// functor interface class for allowing FindPointsAlong to convey
// information back to the caller
class PointSetter3d
{
public:
PointSetter3d();
virtual ~PointSetter3d();
void set(Point3D const & point);
private:
PointSetter3d(PointSetter3d const & copy);
PointSetter3d & operator=(PointSetter3d const & copy);
virtual void realSet(Point3D const & point) = 0;
};
// FindPointsAlong will march from begin to end using a 3D Bresenham
// line. for each 'pixel' that the line passes over,
// HowToSetPoint::set will be called with that pixels placement.
// sloppyStep allows additional redundency whenever 'shifts' occur
// while creating the line. example lines based of the value of
// sloppyStep are below
//
// sloppyStep == false sloppyStep == true
// .x.... .x....
// .x.... .xx...
// ..x... .xx...
// ..x... ..x...
// ..x... ..xx..
// ...x.. ..xx..
// ...x.. ...x..
static void FindPointsAlong(Point3D const & begin, Point3D const & end, bool const sloppyStep, PointSetter3d & howTo);
private:
Bresenham();
Bresenham(Bresenham const & copy);
Bresenham & operator=(Bresenham const & copy);
};
// ======================================================================
#endif
@@ -0,0 +1,97 @@
// ======================================================================
//
// CollideParameters.cpp
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/CollideParameters.h"
// ======================================================================
CollideParameters const CollideParameters::cms_default;
CollideParameters const CollideParameters::cms_toolPickDefault(CollideParameters::Q_high, CollideParameters::T_collidable, true);
// ======================================================================
CollideParameters::CollideParameters() :
m_quality(Q_high),
m_type(T_collidable),
m_isToolPickTest(false)
{
}
// ----------------------------------------------------------------------
CollideParameters::CollideParameters(CollideParameters::Quality q, CollideParameters::Type t, bool isToolPickTest) :
m_quality(q),
m_type(t),
m_isToolPickTest(isToolPickTest)
{
}
// ----------------------------------------------------------------------
CollideParameters::~CollideParameters()
{
}
// ----------------------------------------------------------------------
CollideParameters::Quality CollideParameters::getQuality() const
{
return m_quality;
}
// ----------------------------------------------------------------------
void CollideParameters::setQuality(Quality const quality)
{
m_quality = quality;
}
// ----------------------------------------------------------------------
CollideParameters::Type CollideParameters::getType() const
{
return m_type;
}
// ----------------------------------------------------------------------
void CollideParameters::setType(Type const type)
{
m_type = type;
}
// ----------------------------------------------------------------------
bool CollideParameters::getToolPickTest() const
{
return m_isToolPickTest;
}
// ----------------------------------------------------------------------
void CollideParameters::setToolPickTest(bool isToolPickTest)
{
m_isToolPickTest = isToolPickTest;
}
// ----------------------------------------------------------------------
bool CollideParameters::typeShouldCollide(bool const collidable, bool const opaqueSolid) const
{
if (m_type == T_collidable && collidable)
return true;
if (m_type == T_opaqueSolid && opaqueSolid)
return true;
return false;
}
// ======================================================================
@@ -0,0 +1,65 @@
// ====================================================================== //
//
// CollideParameters.h
// asommers
//
// copyright 2004, sony online entertainment
//
// ======================================================================
#ifndef INCLUDED_CollideParameters_H
#define INCLUDED_CollideParameters_H
// ======================================================================
class CollideParameters
{
public:
static CollideParameters const cms_default;
static CollideParameters const cms_toolPickDefault;
public:
enum Quality
{
Q_high,
Q_medium,
Q_low
};
enum Type
{
T_collidable,
T_opaqueSolid
};
public:
//-- Default constructed CollideParameters will choose the first enum
CollideParameters();
CollideParameters(Quality q, Type t, bool isToolPickTest);
~CollideParameters();
Quality getQuality() const;
void setQuality(Quality quality);
Type getType() const;
void setType(Type type);
bool getToolPickTest() const;
void setToolPickTest(bool isToolPickTest);
bool typeShouldCollide(bool collidable, bool opaqueSolid) const;
private:
Quality m_quality;
Type m_type;
bool m_isToolPickTest;
};
// ======================================================================
#endif
@@ -0,0 +1,11 @@
// ======================================================================
//
// Collision2d.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/Collision2d.h"
const real gkInvertEpsilon = 1.0e-6f;
@@ -0,0 +1,111 @@
// ======================================================================
//
// Collision2d.h
// copyright (c) 2001 Sony Online Entertainment
//
// ----------------------------------------------------------------------
#ifndef INCLUDED_Collision2d_H
#define INCLUDED_Collision2d_H
#include "sharedMath/Vector.h"
#include "sharedMath/Vector2d.h"
class Triangle2d;
// ----------------------------------------------------------------------
//@todo - Move this to its own class!
extern const real gkInvertEpsilon;
struct Matrix2
{
real m00,m01,m10,m11;
Matrix2()
{
}
Matrix2( real a, real b, real c, real d )
: m00(a), m01(b), m10(c), m11(d)
{
}
// ----------
static bool Invert ( Matrix2 const & mat, Matrix2 & out )
{
real det = mat.m00 * mat.m11 - mat.m01 * mat.m10;
if(fabs(det) < gkInvertEpsilon)
{
return false;
}
real invDet = 1.0f / det;
out.m00 = mat.m11 * invDet;
out.m01 = -mat.m01 * invDet;
out.m10 = -mat.m10 * invDet;
out.m11 = mat.m00 * invDet;
return true;
}
static Matrix2 fromColumns( Vector2d const & A, Vector2d const & B )
{
return Matrix2(A.x,B.x,A.y,B.y);
}
Matrix2 inverted ( void )
{
// compiler complains if this isn't initialized
Matrix2 temp(0,0,0,0);
Invert(*this,temp);
return temp;
}
bool solveFor ( Vector2d const & V, Vector2d & result )
{
Matrix2 inv(0,0,0,0);
if(Invert(*this,inv))
{
result = inv * V;
return true;
}
else
{
return false;
}
}
Vector2d operator * ( Vector2d const & V )
{
Vector2d temp;
temp.x = m00 * V.x + m01 * V.y;
temp.y = m10 * V.x + m11 * V.y;
return temp;
}
};
// ----------------------------------------------------------------------
// 2d operations - work in the X-Y plane
namespace Collision2d
{
inline Vector flatten ( Vector const & V ) { return Vector(V.x,0.0f,V.z); }
inline Vector2d flatten2d ( Vector const & V ) { return Vector2d(V.x,V.z); }
inline Vector expand ( Vector2d const & V ) { return Vector(V.x, 0.0f, V.y); }
}; // namespace Collision2d
// ----------------------------------------------------------------------
#endif
@@ -0,0 +1,500 @@
// ======================================================================
//
// CollisionBuckets.cpp
// copyright (c) 2001 Sony Online Entertainment
// tford
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/CollisionBuckets.h"
#include "sharedCollision/Bresenham.h"
#include "sharedCollision/FloorTri.h" // for IndexedTri
#include "sharedCollision/Intersect2d.h"
#include "sharedCollision/Intersect3d.h"
#include "sharedMath/DebugShapeRenderer.h"
#include "sharedMath/IndexedTriangleList.h"
#include "sharedMath/Ray3d.h"
namespace CollisionBucketsNamespace
{
float const cs_maximumNodeSpan = 100.0f;
float const cs_minimumNodeSpan = 10.0f;
unsigned int const cs_framesToRenderEachBucket = 50;
bool s_renderTravelingNode = true;
bool s_renderNodesAroundPath = true;
// ----------------------------------------------------------------------
class NodeChooser : public Bresenham::PointSetter3d
{
public:
typedef std::vector<Bresenham::Point3D> PointVector;
explicit NodeChooser(Bresenham::Point3D const & maximumDimension);
PointVector const & getResultPointVector() const;
private:
NodeChooser();
NodeChooser(NodeChooser const & copy);
NodeChooser & operator=(NodeChooser const & copy);
virtual void realSet(Bresenham::Point3D const & point);
private:
Bresenham::Point3D const m_maximumDimension;
PointVector m_results;
};
}
// ======================================================================
CollisionBucketsNamespace::NodeChooser::NodeChooser(Bresenham::Point3D const & maximumDimension)
: PointSetter3d()
, m_maximumDimension(maximumDimension)
, m_results()
{ }
// ----------------------------------------------------------------------
CollisionBucketsNamespace::NodeChooser::PointVector const & CollisionBucketsNamespace::NodeChooser::getResultPointVector() const
{
return m_results;
}
// ----------------------------------------------------------------------
void CollisionBucketsNamespace::NodeChooser::realSet(Bresenham::Point3D const & point)
{
if (point.x >= m_maximumDimension.x) return;
if (point.y >= m_maximumDimension.y) return;
if (point.z >= m_maximumDimension.z) return;
if (point.x < 0) return;
if (point.y < 0) return;
if (point.z < 0) return;
m_results.push_back(point);
}
// ======================================================================
using namespace CollisionBucketsNamespace;
// ======================================================================
CollisionBuckets::Node::Node(AxialBox const & bounds)
: m_indices()
, m_bounds(bounds)
{
}
// ======================================================================
CollisionBuckets::CollisionBuckets(IndexedTriangleList * const indexedTriangleList)
: m_indexedTriangleList(indexedTriangleList)
, m_bounds()
, m_spanOfBounds()
, m_sizeOfNode()
, m_bucketsAlongX(0)
, m_bucketsAlongY(0)
, m_bucketsAlongZ(0)
, m_nodeMatrix(0)
#ifdef _DEBUG
, m_renderXX(0)
, m_renderYY(0)
, m_renderZZ(0)
, m_timesRendered(0)
, m_lastTestedNodes()
, m_hitTriangle()
#endif
{
}
// ----------------------------------------------------------------------
CollisionBuckets::~CollisionBuckets()
{
destroy();
// destroy will delete m_nodeMatrix
m_nodeMatrix = 0;
}
// ----------------------------------------------------------------------
void CollisionBuckets::build(Vector const & minimumBounds, Vector const & maximumBounds)
{
if (m_nodeMatrix != 0)
{
return;
}
typedef std::vector<Vector> Vertices;
typedef std::vector<int> Indices;
Vertices const & vertices = m_indexedTriangleList->getVertices();
Indices const & indices = m_indexedTriangleList->getIndices();
m_bounds.setMin(minimumBounds);
m_bounds.setMax(maximumBounds);
m_spanOfBounds = m_bounds.getMax() - m_bounds.getMin();
m_bucketsAlongX = ((m_spanOfBounds.x > cs_maximumNodeSpan)
? static_cast<unsigned int>(m_spanOfBounds.x / cs_maximumNodeSpan)
: static_cast<unsigned int>(m_spanOfBounds.x / cs_minimumNodeSpan)) + 1;
m_bucketsAlongY = ((m_spanOfBounds.y > cs_maximumNodeSpan)
? static_cast<unsigned int>(m_spanOfBounds.y / cs_maximumNodeSpan)
: static_cast<unsigned int>(m_spanOfBounds.y / cs_minimumNodeSpan)) + 1;
m_bucketsAlongZ = ((m_spanOfBounds.z > cs_maximumNodeSpan)
? static_cast<unsigned int>(m_spanOfBounds.z / cs_maximumNodeSpan)
: static_cast<unsigned int>(m_spanOfBounds.z / cs_minimumNodeSpan)) + 1;
m_sizeOfNode.x = m_spanOfBounds.x / static_cast<float>(m_bucketsAlongX);
m_sizeOfNode.y = m_spanOfBounds.y / static_cast<float>(m_bucketsAlongY);
m_sizeOfNode.z = m_spanOfBounds.z / static_cast<float>(m_bucketsAlongZ);
{ // size the matrix
m_nodeMatrix = new NodeMatrix;
(*m_nodeMatrix).resize(m_bucketsAlongX);
for (unsigned int xx = 0; xx < m_bucketsAlongX; ++xx)
{
(*m_nodeMatrix)[xx].resize(m_bucketsAlongY);
for (unsigned int yy = 0; yy < m_bucketsAlongY; ++yy)
{
// note that nodes are initialized to NULL
(*m_nodeMatrix)[xx][yy].resize(m_bucketsAlongZ, 0);
}
}
}
unsigned int numberOfFaces = indices.size() / 3;
for (unsigned int i = 0, index = 0; i < numberOfFaces; ++i)
{
int const index1 = indices[index++];
int const index2 = indices[index++];
int const index3 = indices[index++];
Vector const & point1 = vertices[static_cast<unsigned int>(index1)];
Vector const & point2 = vertices[static_cast<unsigned int>(index2)];
Vector const & point3 = vertices[static_cast<unsigned int>(index3)];
for (unsigned int xx = 0; xx < m_bucketsAlongX; ++xx)
{
for (unsigned int yy = 0; yy < m_bucketsAlongY; ++yy)
{
for (unsigned int zz = 0; zz < m_bucketsAlongZ; ++zz)
{
Vector const minimumNodeOffset(m_sizeOfNode.x * xx, m_sizeOfNode.y * yy, m_sizeOfNode.z * zz);
Vector const minimumNodeBounds(minimumNodeOffset + minimumBounds);
Vector const maximumNodeBounds(minimumNodeBounds + m_sizeOfNode);
AxialBox const bounds(minimumNodeBounds, maximumNodeBounds);
if (Intersect3d::intersectTriangleBox(bounds, point1, point2, point3))
{
if ((*m_nodeMatrix)[xx][yy][zz] == 0)
{
(*m_nodeMatrix)[xx][yy][zz] = new Node(bounds);
}
Node * const node = (*m_nodeMatrix)[xx][yy][zz];
node->m_indices.push_back(index1);
node->m_indices.push_back(index2);
node->m_indices.push_back(index3);
}
}
}
}
}
}
// ----------------------------------------------------------------------
void CollisionBuckets::destroy()
{
if (m_nodeMatrix != 0)
{
unsigned int const bucketsPerDimensionX = (*m_nodeMatrix).size();
for (unsigned int xx = 0; xx < bucketsPerDimensionX; ++xx)
{
unsigned int const bucketsPerDimensionY = (*m_nodeMatrix)[xx].size();
for (unsigned int yy = 0; yy < bucketsPerDimensionY; ++yy)
{
unsigned int const bucketsPerDimensionZ = (*m_nodeMatrix)[xx][yy].size();
for (unsigned int zz = 0; zz < bucketsPerDimensionZ; ++zz)
{
delete (*m_nodeMatrix)[xx][yy][zz];
}
}
}
delete m_nodeMatrix;
m_nodeMatrix = 0;
}
}
// ----------------------------------------------------------------------
bool CollisionBuckets::intersect(Vector const & begin, Vector const & end, Vector * surfaceNormal, float * time) const
{
Vector direction(end - begin);
float const magnitude = direction.magnitude();
bool hit = false;
if (direction.normalize())
{
Ray3d const ray(begin, direction);
Intersect3d::ResultData data;
if ((m_bounds.contains(begin)) || (Intersect3d::intersectRayABoxWithData(ray, m_bounds, &data)))
{
float const lengthToFront = data.m_length;
data.m_length = 0.0f;
// the comment below explains the reason for doing the reverse test
if ((m_bounds.contains(end)) || (Intersect3d::intersectRayABoxWithData(Ray3d(end, -direction), m_bounds, &data)))
{
float const lengthToBack = data.m_length;
BucketNodeList nodesToTest;
{
// closeBegin and closeEnd need to be calculated for
// extreme distances (~1000 units) to help keep the
// Bresenham traversal from losing precision
Vector const closeBegin(ray.atParam(lengthToFront));
Vector const closeEnd(ray.atParam(magnitude - lengthToBack));
findCandidateBucketsToTestClosestToFarthest(closeBegin, closeEnd, nodesToTest);
}
#ifdef _DEBUG
m_lastTestedNodes = nodesToTest;
m_hitTriangle = Triangle3d();
#endif
if (!nodesToTest.empty())
{
float bestTime = magnitude;
Triangle3d bestTriangle;;
typedef std::vector<Vector> Vertices;
Vertices const & vertices = m_indexedTriangleList->getVertices();
BucketNodeList::const_iterator ii = nodesToTest.begin();
BucketNodeList::const_iterator iiEnd = nodesToTest.end();
for (bool done = false; ((ii != iiEnd) && (!done)); ++ii)
{
Node const * const node = *ii;
// pretest each bucket for early rejection
if ((node != 0) && (Intersect3d::intersectRayABoxWithData(ray, node->m_bounds, &data)))
{
// no point testing beyond best time if the remaining
// boxes are past this also
done = (data.m_length > bestTime);
if (!done)
{
Node::Indices const & indices = node->m_indices;
unsigned int const numberOfFaces = indices.size() / 3;
for (unsigned int i = 0, index = 0; i < numberOfFaces; ++i)
{
int const index1 = indices[index++];
int const index2 = indices[index++];
int const index3 = indices[index++];
Vector const & point1 = vertices[static_cast<unsigned int>(index1)];
Vector const & point2 = vertices[static_cast<unsigned int>(index2)];
Vector const & point3 = vertices[static_cast<unsigned int>(index3)];
Triangle3d const triangle(point1, point2, point3);
Vector hitPoint;
real t;
if (Intersect3d::IntersectRayTriSided(ray, triangle, hitPoint, t))
{
if (t < bestTime)
{
bestTriangle = triangle;
#ifdef _DEBUG
m_hitTriangle = bestTriangle;
#endif
bestTime = t;
hit = true;
}
}
}
}
}
}
if (hit)
{
if (surfaceNormal != 0)
{
*surfaceNormal = bestTriangle.getNormal();
}
if (time != 0)
{
*time = bestTime / magnitude;
}
}
}
}
}
}
return hit;
}
// ----------------------------------------------------------------------
void CollisionBuckets::findCandidateBucketsToTestClosestToFarthest(Vector const & begin, Vector const & end, BucketNodeList & bucketNodeList) const
{
if (m_nodeMatrix != 0)
{
int const beginIndexX = static_cast<int>((begin.x - m_bounds.getMin().x) / m_sizeOfNode.x);
int const beginIndexY = static_cast<int>((begin.y - m_bounds.getMin().y) / m_sizeOfNode.y);
int const beginIndexZ = static_cast<int>((begin.z - m_bounds.getMin().z) / m_sizeOfNode.z);
int const endIndexX = static_cast<int>((end.x - m_bounds.getMin().x) / m_sizeOfNode.x);
int const endIndexY = static_cast<int>((end.y - m_bounds.getMin().y) / m_sizeOfNode.y);
int const endIndexZ = static_cast<int>((end.z - m_bounds.getMin().z) / m_sizeOfNode.z);
Bresenham::Point3D const beginIndex(beginIndexX, beginIndexY, beginIndexZ);
Bresenham::Point3D const endIndex(endIndexX, endIndexY, endIndexZ);
NodeChooser howToPick(Bresenham::Point3D(static_cast<int>(m_bucketsAlongX), static_cast<int>(m_bucketsAlongY), static_cast<int>(m_bucketsAlongZ)));
Bresenham::FindPointsAlong(beginIndex, endIndex, true, howToPick);
bucketNodeList.reserve(howToPick.getResultPointVector().size());
NodeChooser::PointVector::const_iterator ii = howToPick.getResultPointVector().begin();
NodeChooser::PointVector::const_iterator iiEnd = howToPick.getResultPointVector().end();
for (; ii != iiEnd; ++ii)
{
Bresenham::Point3D const & point = *ii;
unsigned int const xx = static_cast<unsigned int>(point.x);
unsigned int const yy = static_cast<unsigned int>(point.y);
unsigned int const zz = static_cast<unsigned int>(point.z);
Node * node = (*m_nodeMatrix)[xx][yy][zz];
if (node != 0)
{
bucketNodeList.push_back(node);
}
}
}
}
// ----------------------------------------------------------------------
void CollisionBuckets::drawDebugShapes(DebugShapeRenderer * const renderer) const
{
UNREF(renderer);
#ifdef _DEBUG
if (renderer != 0)
{
typedef std::vector<Vector> Vertices;
if (s_renderNodesAroundPath)
{
renderer->setColor(VectorArgb::solidYellow);
BucketNodeList::const_iterator ii = m_lastTestedNodes.begin();
BucketNodeList::const_iterator iiEnd = m_lastTestedNodes.end();
for (; ii != iiEnd; ++ii)
{
Node const * const node = *ii;
if (node != 0)
{
renderer->drawBox(node->m_bounds);
}
}
if (!m_lastTestedNodes.empty())
{
Vertices lineList;
lineList.push_back(m_hitTriangle.getCornerA());
lineList.push_back(m_hitTriangle.getCornerB());
lineList.push_back(m_hitTriangle.getCornerB());
lineList.push_back(m_hitTriangle.getCornerC());
lineList.push_back(m_hitTriangle.getCornerC());
lineList.push_back(m_hitTriangle.getCornerA());
renderer->setColor(VectorArgb::solidRed);
renderer->drawLineList(lineList);
}
}
if ((s_renderTravelingNode) && (m_nodeMatrix != 0))
{
// draw the current selected box
renderer->setColor(VectorArgb::solidBlack);
Node const * const node = (*m_nodeMatrix)[m_renderXX][m_renderYY][m_renderZZ];
if (node != 0)
{
renderer->drawBox(node->m_bounds);
// draw the triangles in the selected box
renderer->setColor(VectorArgb::solidRed);
Node::Indices const & indices = node->m_indices;
Vertices const & vertices = m_indexedTriangleList->getVertices();
Vertices lineList;
unsigned int const numberOfFaces = indices.size() / 3;
for (unsigned int i = 0, index = 0; i < numberOfFaces; ++i)
{
int const index1 = indices[index++];
int const index2 = indices[index++];
int const index3 = indices[index++];
Vector const & point1 = vertices[static_cast<unsigned int>(index1)];
Vector const & point2 = vertices[static_cast<unsigned int>(index2)];
Vector const & point3 = vertices[static_cast<unsigned int>(index3)];
lineList.push_back(point1);
lineList.push_back(point2);
lineList.push_back(point2);
lineList.push_back(point3);
lineList.push_back(point3);
lineList.push_back(point1);
}
renderer->drawLineList(lineList);
}
else
{
m_timesRendered = cs_framesToRenderEachBucket;
}
// select the next box to show
++m_timesRendered;
if (m_timesRendered > cs_framesToRenderEachBucket)
{
m_timesRendered = 0;
++m_renderZZ;
if (m_renderZZ >= m_bucketsAlongZ)
{
m_renderZZ = 0;
++m_renderYY;
if (m_renderYY >= m_bucketsAlongY)
{
m_renderYY = 0;
++m_renderXX;
if (m_renderXX >= m_bucketsAlongX)
{
m_renderXX = 0;
}
}
}
}
}
}
#endif
}
@@ -0,0 +1,86 @@
// ======================================================================
//
// CollisionBuckets.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CollisionBuckets_H
#define INCLUDED_CollisionBuckets_H
// ======================================================================
#include "sharedCollision/CollisionSurface.h"
#include "sharedMath/AxialBox.h"
#include "sharedMath/Triangle3d.h"
#include <vector>
class DebugShapeRenderer;
class IndexedTriangleList;
// ======================================================================
class CollisionBuckets
{
public:
explicit CollisionBuckets(IndexedTriangleList * const indexedTriangleList);
~CollisionBuckets();
void build(Vector const & minimumBounds, Vector const & maximumBounds);
void destroy();
void drawDebugShapes(DebugShapeRenderer * const renderer) const;
bool intersect(Vector const & begin, Vector const & end, Vector * surfaceNormal, float * time) const;
private:
CollisionBuckets();
CollisionBuckets(const CollisionBuckets & source);
CollisionBuckets & operator=(const CollisionBuckets & source);
struct Node;
typedef std::vector<Node *> BucketNodeList;
void findCandidateBucketsToTestClosestToFarthest(Vector const & begin, Vector const & end, BucketNodeList & bucketNodeList) const;
private:
IndexedTriangleList const * const m_indexedTriangleList;
AxialBox m_bounds;
Vector m_spanOfBounds;
Vector m_sizeOfNode;
unsigned int m_bucketsAlongX;
unsigned int m_bucketsAlongY;
unsigned int m_bucketsAlongZ;
struct Node
{
Node(AxialBox const & bounds);
typedef std::vector<int> Indices;
Indices m_indices;
AxialBox m_bounds;
};
typedef std::vector<Node *> NodeRow;
typedef std::vector<NodeRow> NodeColumn;
typedef std::vector<NodeColumn> NodeMatrix;
NodeMatrix * m_nodeMatrix;
#ifdef _DEBUG
mutable unsigned int m_renderXX;
mutable unsigned int m_renderYY;
mutable unsigned int m_renderZZ;
mutable unsigned int m_timesRendered;
mutable BucketNodeList m_lastTestedNodes;
mutable Triangle3d m_hitTriangle;
#endif
};
// ======================================================================
#endif
@@ -0,0 +1,66 @@
// ======================================================================
//
// CollisionEnums.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/CollisionEnums.h"
namespace Containment
{
// Used to turn containment results for two orthogonal axes into a single containment result
ContainmentResult ComposeAxisTests ( ContainmentResult A, ContainmentResult B )
{
if(A == B)
{
return A;
}
else if((A == CR_Outside) || (B == CR_Outside))
{
return CR_Outside;
}
else if ((A == CR_TouchingOutside) || (B == CR_TouchingOutside))
{
return CR_TouchingOutside;
}
else if ((A == CR_Overlap) || (B == CR_Overlap))
{
if((A == CR_Boundary) || (B == CR_Boundary))
{
// One exception to this pattern - if the test volume overlaps the boundary
// along one axis and is in the boundary along the other axis, then the test
// volume touches the outside of the boundary
return CR_TouchingOutside;
}
else
{
return CR_Boundary;
}
}
else if((A == CR_Boundary) || (B == CR_Boundary))
{
return CR_Boundary;
}
else if((A == CR_TouchingInside) || (B == CR_TouchingInside))
{
return CR_TouchingInside;
}
else
{
return CR_Inside;
}
}
ContainmentResult ComposeAxisTests ( ContainmentResult A, ContainmentResult B, ContainmentResult C )
{
return Containment::ComposeAxisTests(ComposeAxisTests(A,B),C);
}
// ----------------------------------------------------------------------
} // namespace Containment
@@ -0,0 +1,266 @@
// ======================================================================
//
// CollisionEnums.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CollisionEnums_H
#define INCLUDED_CollisionEnums_H
// ======================================================================
enum CanMoveResult
{
CMR_MoveOK,
CMR_HitFloorEdge,
CMR_HitObstacle,
CMR_MissedGoal,
CMR_Error,
CMR_Invalid
};
enum EdgeIntersectResult
{
EIR_MissedEdge,
EIR_HitEdge,
EIR_PassesEdge,
EIR_GrazesEdge,
EIR_Invalid
};
enum ContainmentResult
{
CR_Outside, // Test point/shape is totally outside the boundary
CR_Inside, // Test point/shape is totally contained by the boundary
CR_Boundary, // Test point/shape is entirely within epsilon of the boundary of the containing shape,
CR_Overlap, // Test shape is on both sides of the boundary
CR_TouchingInside, // Test shape has points inside the boundary and within epsilon of the boundary
CR_TouchingOutside, // Test shape has points outside the boundary and within epsilon of the boundary
CR_Invalid,
};
namespace Containment
{
// True if the object has no points outside of the boundary
inline bool isContainment( ContainmentResult C )
{
return (C == CR_Inside) || (C == CR_TouchingInside) || (C == CR_Boundary);
}
// True if the object has no points inside the boundary
inline bool isNonContainment( ContainmentResult C )
{
return (C == CR_Outside) || (C == CR_TouchingOutside) || (C == CR_Boundary);
}
// True if the object has points on the boundary
inline bool isContact( ContainmentResult C )
{
return (C == CR_Boundary) || (C == CR_Overlap) || (C == CR_TouchingInside) || (C == CR_TouchingOutside);
}
ContainmentResult ComposeAxisTests ( ContainmentResult A, ContainmentResult B );
ContainmentResult ComposeAxisTests ( ContainmentResult A, ContainmentResult B, ContainmentResult C );
}
// ----------
enum ResolutionResult
{
RR_NoCollision, // The objects don't collide
RR_DontKnowHow, // We don't know how to resolve collisions between those types of objects
RR_Past, // The collision happened in the past, we can't resolve it.
RR_Future, // The collision happens too far in the future, we can't resolve it
RR_Resolved, // The objects collided, and the collision has been resolved
RR_Failed, // The objects collided, but we were unable to resolve the collision
RR_Invalid
};
// ----------
enum FloorEdgeType
{
FET_Uncrossable = 0,
FET_Crossable = 1,
FET_WallBase = 2,
FET_WallTop = 3,
FET_Invalid,
};
// ----------
enum HitResult
{
HR_Miss, // Primitive does not hit the test shape
HR_Hit, // Primitive hits the test shape
HR_HitFront, // Primitive hits the front side of the test shape
HR_HitBack, // Primtiive hits the back side of the test shape
HR_TouchFront, // Segment's begin point is in front of the shape and its end point is on the shape
HR_TouchBack, // Segment's begin point is in front of the shape and its end point is on the shape
HR_LeaveFront, // Segment/ray begins on the shape and goes in front of the shape
HR_LeaveBack, // Segment/ray begins on the shape and goes behind the shape
HR_Coplanar, // Primitive is coplanar with the test shape
HR_Invalid,
};
// ----------
enum CollinearResult
{
CLR_LeftSide, // (2D) Point lies on the left (counterclockwise) side of AB
CLR_RightSide, // (2D) Point lies on the right (clockwise) side of AB
CLR_CoincidentA, // Point is coincident with A
CLR_CoincidentB, // Point is coincident with B
CLR_OverlapLeft, // Point is collinear with AB, forms line V-A-B
CLR_OverlapCenter, // Point is collinear with AB, forms line A-V-B
CLR_OverlapRight, // Point is collinear with AB, forms line A-B-V
// ----------
CLR_Disjoint, // (3D) Point does not lie on the line
CLR_Overlap, // OverlapLeft || OverlapRight || OverlapCenter || CoincidentA || CoincidentB
};
// ----------
/*
enum OverlapResult
{
OR_Identical,
OR_AContainsB,
OR_BContainsA,
OR_Overlap,
OR_Disjoint,
OR_Invalid
};
*/
// ----------
// The values for these two enums are taken from SharedObjectTemplate.h
// If they change, this file needs to change too
// Why did I duplicate them? Well, since their definition is nested inside
// SharedObjectTemplate, there's no way to get to them without #including
// SharedObjectTemplate.h, and including that file creates a bunch of dependencies
// that tend to break builds since there are two different files named
// SharedObjectTemplate.h, one in sharedTemplate and one in sharedGame.
enum InteractionType
{
IT_See = 0x0001,
IT_Target = 0x0002,
IT_CombatRanged = 0x0004,
IT_CombatMelee = 0x0008,
IT_Manipulate = 0x0010,
IT_Talk = 0x0020, // // Sound doesn't travel in straight lines, but...
IT_RadialDamage = 0x0040, // // Explosions cause radial damage
IT_Camera = 0x0080, // // This is a bit different from the other actions - if an object blocks CAT_Camera it means the object blocks the camera's view of the target.
IT_All = IT_See | IT_Target | IT_CombatRanged | IT_CombatMelee | IT_Manipulate | IT_Talk | IT_RadialDamage | IT_Camera,
IT_Any = 0xFFFFFFFF,
};
enum MaterialType
{
MT_Solid = 0x0001, // // Generic solid 'stuff'
MT_Meat = 0x0002, // // Living things are made of meat
MT_Metal = 0x0004, // // Droids and machines are made of metal
MT_Energy = 0x0008, // // Ghosts are made of energy
MT_Brush = 0x0010, // // Bushes are made of brush
MT_Door = 0x0020, // // Doors are made of door
MT_Monster = 0x0040, // // Monsters are made of monster
MT_Player = 0x0080, // // Players are made of player
MT_NPC = 0x0100, // // NPCs are made of NPC
MT_Any = 0xFFFFFFFF,
};
// ----------
// Update the database name table in CollisionWorld if this changes
enum SpatialDatabaseType
{
SDT_Floors,
SDT_Statics,
SDT_Flora,
SDT_Invalid,
};
// ----------
enum ExtentType
{
ET_Sphere,
ET_Cylinder,
ET_Box,
ET_Detail,
ET_Component,
ET_Mesh,
ET_Terrain,
ET_OrientedBox,
ET_OrientedCylinder,
ET_Simple,
ET_Null, // Dummy extent - doesn't collide with anything
ET_Floor,
ET_ExtentTypeCount,
};
// ----------
enum PathWalkResult
{
PWR_MissedStartTri, // The walk failed because the path didn't enter the mesh at the starting triangle
PWR_CantEnter, // The walk failed because the path couldn't enter the starting triangle
PWR_DoesntEnter, // The walk didn't enter the floor
PWR_HitBeforeEnter, // The footprint circle hit an edge of the floor before the center entered the floor
PWR_WalkOk, // The walk succeeded
PWR_WalkFailed, // The walk failed (probably an error)
PWR_HitEdge, // The walk hit an edge of the mesh
PWR_HitPortalEdge, // The walk hit a portal-adjacent edge of the mesh
PWR_HitPast, // The walk hit an edge some time in the past
PWR_InContact, // The walk was unable to move because the point/circle was already in contact with something
PWR_ExitedMesh, // The walk exited the mesh
PWR_CenterHitEdge, // The center of the circle hit an edge
PWR_CenterInContact, // The center of the circle is in contact with an edge
PWR_StartLocInvalid, // bad starting point for the walk (embedded in a wall or something)
PWR_Invalid,
};
// ----------
enum QueryInteractionResult
{
QIR_None,
QIR_HitTerrain,
QIR_HitObjectExtent,
QIR_HitObjectFloor,
QIR_HitCellExtent,
QIR_HitCellFloor,
QIR_MissedTarget,
QIR_Invalid,
};
// ======================================================================
#endif //#ifndef INCLUDED_CollisionEnums_H
@@ -0,0 +1,121 @@
//===================================================================
//
// CollisionInfo.h
// asommers 2-10-99
//
// copyright 1999, bootprint entertainment
// copyright 2002, sony online entertainment
//
//===================================================================
#ifndef INCLUDED_CollisionInfo_H
#define INCLUDED_CollisionInfo_H
//===================================================================
#include "sharedMath/Vector.h"
class Object;
//===================================================================
class CollisionInfo
{
public:
CollisionInfo ();
~CollisionInfo ();
const Object* getObject () const;
void setObject (const Object* object);
const Vector& getPoint () const;
void setPoint (const Vector& point);
const Vector& getNormal () const;
void setNormal (const Vector& normal);
float getTime () const;
void setTime (float time);
private:
const Object* m_object;
Vector m_point;
Vector m_normal;
float m_time;
};
//===================================================================
inline CollisionInfo::CollisionInfo () :
m_object (0),
m_point (),
m_normal (),
m_time (0.f)
{
}
//-------------------------------------------------------------------
inline CollisionInfo::~CollisionInfo ()
{
m_object = 0;
}
//-------------------------------------------------------------------
inline const Object* CollisionInfo::getObject () const
{
return m_object;
}
//-------------------------------------------------------------------
inline void CollisionInfo::setObject (const Object* const object)
{
m_object = object;
}
//-------------------------------------------------------------------
inline const Vector& CollisionInfo::getPoint () const
{
return m_point;
}
//-------------------------------------------------------------------
inline void CollisionInfo::setPoint (const Vector& point)
{
m_point = point;
}
//-------------------------------------------------------------------
inline const Vector& CollisionInfo::getNormal () const
{
return m_normal;
}
//-------------------------------------------------------------------
inline void CollisionInfo::setNormal (const Vector& normal)
{
m_normal = normal;
}
//-------------------------------------------------------------------
inline float CollisionInfo::getTime () const
{
return m_time;
}
//-------------------------------------------------------------------
inline void CollisionInfo::setTime (const float time)
{
m_time = time;
}
// ======================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,231 @@
// ======================================================================
//
// CollisionMesh.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CollisionMesh_H
#define INCLUDED_CollisionMesh_H
// ======================================================================
#include "sharedCollision/CollisionSurface.h"
class Iff;
class IndexedTri;
class ConnectedTri;
class Triangle3d;
class IndexedTriangleList;
class AxialBox;
class SimpleExtent;
class Sphere;
class Vector;
class Line3d;
class Ray3d;
class Segment3d;
class Range;
class BoxTree;
class FloorLocator;
typedef stdvector<Vector>::fwd VectorVector;
typedef stdvector<int>::fwd IntVector;
// ======================================================================
class CollisionMesh : public CollisionSurface
{
public:
explicit CollisionMesh();
virtual ~CollisionMesh();
// ----------
// Interface inherited from CollisionSurface
virtual Transform const & getTransform_o2p ( void ) const;
virtual Transform const & getTransform_o2w ( void ) const;
virtual float getScale ( void ) const;
virtual BaseExtent const * getExtent_l ( void ) const;
virtual BaseExtent const * getExtent_p ( void ) const;
// ----------
virtual void clear ( void );
virtual void merge ( void );
virtual int scrub ( void );
virtual void calcBounds ( void ) const;
virtual bool getBoundsDirty ( void ) const;
virtual void setBoundsDirty ( bool dirty ) const;
virtual AxialBox getBoundingABox ( void ) const;
virtual Sphere getBoundingSphere ( void ) const;
// ----------
// Basic interface - accessors
virtual int getVertexCount ( void ) const = 0;
virtual Vector const & getVertex ( int whichVertex ) const = 0;
virtual void setVertex ( int whichVertex, Vector const & newPoint ) = 0;
virtual int getTriCount ( void ) const = 0;
virtual IndexedTri const & getIndexedTri ( int whichTri ) const = 0;
virtual void setIndexedTri ( int whichTri, IndexedTri const & newTri ) = 0;
virtual Triangle3d getTriangle ( int whichTri ) const = 0;
virtual void deleteVertex ( int whichVertex ) = 0;
virtual void deleteVertices ( IntVector const & vertIndices ) = 0;
virtual void deleteTri ( int whichTri ) = 0;
virtual void deleteTris ( IntVector const & triIndices ) = 0;
// ----------
// Single-triangle intersection methods
virtual bool intersect(Vector const & begin, Vector const & end, Vector * surfaceNormal, float * time ) const;
virtual bool testIntersect ( Line3d const & L, int triId ) const;
virtual bool testIntersect ( Ray3d const & R, int triId ) const;
virtual bool testIntersect ( Segment3d const & S, int triId ) const;
virtual bool testIntersectUnsided ( Line3d const & L, int triId ) const;
virtual bool testIntersectUnsided ( Ray3d const & R, int triId ) const;
virtual bool testIntersectUnsided ( Segment3d const & S, int triId ) const;
virtual bool testIntersect ( Line3d const & L, int triId, ContactPoint & outLoc ) const;
virtual bool testIntersect ( Ray3d const & R, int triId, ContactPoint & outLoc ) const;
virtual bool testIntersect ( Segment3d const & S, int triId, ContactPoint & outLoc ) const;
virtual bool testIntersectUnsided ( Line3d const & L, int triId, ContactPoint & outLoc ) const;
virtual bool testIntersectUnsided ( Ray3d const & R, int triId, ContactPoint & outLoc ) const;
virtual bool testIntersectUnsided ( Segment3d const & S, int triId, ContactPoint & outLoc ) const;
virtual bool testIntersect ( Line3d const & L, int triId, LineIntersectResult & result ) const;
virtual bool testIntersect ( Ray3d const & R, int triId, LineIntersectResult & result ) const;
virtual bool testIntersect ( Segment3d const & S, int triId, LineIntersectResult & result ) const;
// ----------
// Whole-mesh intersection methods
// Search for any intersection with the mesh, return true if there is one
virtual bool testIntersect ( Line3d const & line ) const;
virtual bool testIntersect ( Ray3d const & ray ) const;
virtual bool testIntersect ( Segment3d const & seg ) const;
// Search for any point of intersection with the linear primitive
virtual bool intersectAny ( Line3d const & line, ContactPoint & outLoc ) const;
virtual bool intersectAny ( Ray3d const & ray, ContactPoint & outLoc ) const;
virtual bool intersectAny ( Segment3d const & seg, ContactPoint & outLoc ) const;
// Search for the point of intersection with the linear primitive that has the minimum
// parametric intersection time.
virtual bool intersectClosest( Line3d const & line, ContactPoint & outLoc ) const;
virtual bool intersectClosest( Ray3d const & ray, ContactPoint & outLoc ) const;
virtual bool intersectClosest( Segment3d const & seg, ContactPoint & outLoc) const;
// Find all intersection points with the linear primitive. Return value is the number of hits
virtual int intersectAll ( Line3d const & line, LineIntersectResultVec & results ) const;
virtual int intersectAll ( Ray3d const & ray, LineIntersectResultVec & results ) const;
virtual int intersectAll ( Segment3d const & seg, LineIntersectResultVec & results ) const;
// Return the parametric intersection time range with the linear primitive
virtual Range intersectRange ( Line3d const & line ) const;
virtual Range intersectRange ( Ray3d const & ray ) const;
virtual Range intersectRange ( Segment3d const & seg ) const;
// ----------
virtual bool findClosestPair ( Line3d const & line,
int ignoreId,
FloorLocator & outClosestFront,
FloorLocator & outClosestBack ) const;
virtual bool findClosestPair ( FloorLocator const & testLoc,
Vector const & down,
FloorLocator & outClosestAbove,
FloorLocator & outClosestBelow ) const;
// ----------
virtual bool testBounds ( Line3d const & line ) const;
virtual bool testBounds ( Ray3d const & ray ) const;
virtual bool testBounds ( Segment3d const & seg ) const;
// ----------
virtual void transform ( CollisionMesh const * sourceMesh, Transform const & tform, float scale );
virtual bool hasBoxTree ( void ) const;
virtual void buildBoxTree ( void );
virtual BoxTree const * getBoxTree ( void ) const;
IntVector & getTempResultVector ( void ) const;
void getVertices ( VectorVector & outVerts ) const;
void getIndices ( IntVector & outIndices ) const;
// ----------
// Utility functions
//@todo - These could be moved elsewhere
static int FindEdgeDirected ( IndexedTri const & T, int index1, int index2 );
static int FindEdgeUndirected ( IndexedTri const & T, int index1, int index2 );
static void LinkTris ( ConnectedTri & A, ConnectedTri & B );
void makeResult ( bool hit, int id, Vector const & pos, float param, ContactPoint & result ) const;
void makeResult ( bool hit, int id, Vector const & pos, float param, LineIntersectResult & result ) const;
void makeResult ( bool hit, int id, Vector const & pos, float param, bool & result ) const;
protected:
// Disable copying
CollisionMesh(const CollisionMesh &source);
CollisionMesh & operator =(const CollisionMesh &source);
private:
virtual void finalizeData();
protected:
int m_id;
int m_version;
BoxTree * m_boxTree;
mutable SimpleExtent * m_extent;
private:
mutable bool m_boundsDirty;
};
// ----------------------------------------------------------------------
inline bool CollisionMesh::getBoundsDirty ( void ) const
{
return m_boundsDirty;
}
// ----------
inline BoxTree const * CollisionMesh::getBoxTree ( void ) const
{
return m_boxTree;
}
// ======================================================================
#endif
@@ -0,0 +1,177 @@
// ======================================================================
//
// CollisionWorld.cpp
// copyright (c) 2002 Sony Online Entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/CollisionNotification.h"
#include "sharedCollision/CollisionProperty.h"
#include "sharedCollision/CollisionWorld.h"
#include "sharedObject/Object.h"
#include "sharedFoundation/Watcher.h"
#include <vector>
// ----------
struct AddRemoveQueueEntry
{
bool m_added;
Watcher<Object> m_object;
};
// ----------
namespace CollisionNotificationNamespace
{
CollisionNotification g_collisionNotification;
std::vector<AddRemoveQueueEntry> g_addRemoveQueue;
};
using namespace CollisionNotificationNamespace;
// ----------------------------------------------------------------------
CollisionNotification::CollisionNotification()
: ObjectNotification()
{
}
CollisionNotification::~CollisionNotification()
{
}
// ----------
CollisionNotification & CollisionNotification::getInstance ( void )
{
return g_collisionNotification;
}
// ----------
int CollisionNotification::getPriority() const
{
return 4;
}
// ----------------------------------------------------------------------
void CollisionNotification::purgeQueue ( void )
{
int count = g_addRemoveQueue.size();
for(int i = 0; i < count; i++)
{
AddRemoveQueueEntry & entry = g_addRemoveQueue[i];
Object * object = entry.m_object;
if(object == NULL) continue;
if(entry.m_added)
{
CollisionWorld::addObject(object);
}
else
{
CollisionWorld::removeObject(object);
}
}
g_addRemoveQueue.clear();
}
// ----------------------------------------------------------------------
void CollisionNotification::visibilityDataChanged ( Object & object ) const
{
CollisionWorld::appearanceChanged(&object);
}
// ----------
void CollisionNotification::extentChanged ( Object & object ) const
{
CollisionWorld::appearanceChanged(&object);
}
// ----------
void CollisionNotification::addToWorld ( Object & object ) const
{
if(CollisionWorld::isUpdating())
{
AddRemoveQueueEntry entry;
entry.m_added = true;
entry.m_object = &object;
g_addRemoveQueue.push_back(entry);
}
else
{
CollisionWorld::addObject(&object);
}
}
// ----------
void CollisionNotification::removeFromWorld( Object & object ) const
{
if(CollisionWorld::isUpdating())
{
AddRemoveQueueEntry entry;
entry.m_added = false;
entry.m_object = &object;
g_addRemoveQueue.push_back(entry);
}
else
{
CollisionWorld::removeObject(&object);
}
}
// ----------
bool CollisionNotification::positionChanged( Object & object, bool, Vector const & ) const
{
CollisionWorld::moveObject(&object);
return true;
}
// ----------
void CollisionNotification::rotationChanged( Object & object, bool ) const
{
CollisionWorld::moveObject(&object);
}
// ----------
bool CollisionNotification::positionAndRotationChanged ( Object & object, bool, Vector const & ) const
{
CollisionWorld::moveObject(&object);
return true;
}
// ----------
void CollisionNotification::cellChanged( Object & object, bool ) const
{
CollisionWorld::cellChanged(&object);
}
// ----------------------------------------------------------------------
@@ -0,0 +1,50 @@
// ======================================================================
//
// CollisionNotification.h
// copyright (c) 2001 Sony Online Entertainment
//
// ----------------------------------------------------------------------
#ifndef INCLUDED_CollisionNotification_H
#define INCLUDED_CollisionNotification_H
#include "sharedObject/ObjectNotification.h"
#include "sharedMath/Vector.h"
// ======================================================================
class CollisionNotification : public ObjectNotification
{
public:
CollisionNotification();
virtual ~CollisionNotification();
static CollisionNotification & getInstance ( void );
static void purgeQueue ( void );
virtual int getPriority ( void ) const;
virtual void visibilityDataChanged ( Object & object ) const;
virtual void extentChanged ( Object & object ) const;
virtual void addToWorld ( Object & object ) const;
virtual void removeFromWorld ( Object & object ) const;
virtual bool positionChanged ( Object & object, bool dueToParentChange, Vector const & oldPosition) const;
virtual void rotationChanged ( Object & object, bool dueToParentChange ) const;
virtual bool positionAndRotationChanged ( Object & object, bool dueToParentChange, Vector const & oldPosition ) const;
virtual void cellChanged ( Object & object, bool dueToParentChange ) const;
protected:
private:
CollisionNotification(const CollisionNotification &);
CollisionNotification &operator =(const CollisionNotification &);
};
// ======================================================================
#endif // #ifndef INCLUDED_CollisionNotification_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,459 @@
// ======================================================================
//
// CollisionProperty.h
//
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CollisionProperty_H
#define INCLUDED_CollisionProperty_H
#include "sharedCollision/SpatialDatabase.h"
#include "sharedObject/Property.h"
#include "sharedMath/Transform.h"
#include "sharedMath/Vector.h"
#include "sharedMath/Sphere.h"
#include "sharedMath/Capsule.h"
#include "sharedFoundation/Watcher.h"
class BaseExtent;
class CellProperty;
class CollisionProperty;
class DebugShapeRenderer;
class Floor;
class Footprint;
class SharedObjectTemplate;
class SpatialDatabase;
class SpatialSubdivisionHandle;
class Transform;
typedef stdvector<CollisionProperty*>::fwd ColliderList;
// ======================================================================
class CollisionProperty : public Property
{
public:
static PropertyId getClassPropertyId ( void );
enum Flags
{
F_mobile = 0x0001,
F_flora = 0x0002,
F_player = 0x0004,
F_mount = 0x0008,
F_ship = 0x0010,
F_playerControlled = 0x0020,
F_collidable = 0x0040,
F_serverSide = 0x0080,
F_inCombat = 0x0100,
F_inCollisionWorld = 0x0200,
F_idle = 0x0400,
F_disableCollisionWorldAddRemove = 0x0800
};
public:
CollisionProperty( Object & owner );
CollisionProperty( Object & owner, SharedObjectTemplate const * objTemplate );
virtual ~CollisionProperty();
void initFloor ( void );
void initFromTemplate ( SharedObjectTemplate const * objTemplate );
// ----------
void addToCollisionWorld ( void );
void removeFromCollisionWorld ( void );
bool isInCollisionWorld ( void ) const;
// ----------
void setDisableCollisionWorldAddRemove (bool disable);
bool getDisableCollisionWorldAddRemove () const;
// ----------
// Accessors
Transform const & getTransform_o2p ( void ) const;
Transform const & getTransform_o2w ( void ) const;
Transform getTransform_o2c ( void ) const;
// ----------
CellProperty * getCell ( void );
CellProperty const * getCell ( void ) const;
Vector getLastPos_p ( void ) const;
Vector getLastPos_w ( void ) const;
Transform const & getLastTransform_p ( void ) const;
Transform const & getLastTransform_w ( void ) const;
CellProperty * getLastCell ( void );
CellProperty const * getLastCell ( void ) const;
void setLastPos ( CellProperty * cell, Transform const & transform_p );
// ----------
Floor * getFloor ( void );
Floor const * getFloor ( void ) const;
Footprint * getFootprint ( void );
Footprint const * getFootprint ( void ) const;
// ----------
// Extents
bool getExtentsDirty ( void ) const;
void setExtentsDirty ( bool dirty ) const;
BaseExtent const * getExtent_l ( void ) const;
BaseExtent const * getExtent_p ( void ) const;
Sphere const & getBoundingSphere_l ( void ) const;
Sphere const & getBoundingSphere_w ( void ) const;
Capsule getQueryCapsule_w ( void ) const;
float getCollisionRadius ( void ) const;
float getCollisionHeight ( void ) const;
void attachSourceExtent ( BaseExtent * newSourceExtent ) const;
// ----------
float getScale ( void ) const;
// ----------
// Flags
void setMobile ( bool mobile );
void setFlora ( bool flora );
void setPlayer ( bool player );
void setMount ( bool mount );
void setShip ( bool ship );
void setPlayerControlled ( bool playerControlled );
void setCollidable ( bool collidable );
void setServerSide ( bool serverSide );
void setInCombat ( bool inCombat );
bool isMobile ( void ) const;
bool isFlora ( void ) const;
bool isPlayer ( void ) const;
bool isMount ( void ) const;
bool isShip ( void ) const;
bool isPlayerControlled ( void ) const;
bool isCollidable ( void ) const;
bool isServerSide ( void ) const;
bool isInCombat ( void ) const;
// ----------
bool isIdle ( void ) const;
void updateIdle ( void );
void setIdle ( bool active );
void attachList ( CollisionProperty * & head );
void detachList ( void );
CollisionProperty * getPrev ( void );
CollisionProperty * getNext ( void );
static CollisionProperty * getActiveHead ( void );
// ----------
virtual bool canCollideWith ( CollisionProperty const * otherCollision ) const;
virtual bool blocksInteraction (InteractionType interaction) const;
virtual bool blocksMovement () const;
virtual void objectWarped ( void );
void storePosition ( void );
// ----------
SpatialSubdivisionHandle * getSpatialSubdivisionHandle ( void );
void setSpatialSubdivisionHandle ( SpatialSubdivisionHandle * newHandle );
// ----------
// Misc
void drawDebugShapes ( DebugShapeRenderer * renderer ) const;
void cellChanged ( void );
void updateExtents ( void ) const;
int elevatorMove ( int nFloors, Transform & outTransform );
virtual void hit ( CollisionProperty * staticCollider );
virtual void hitBy ( CollisionProperty * dynamicCollider );
Object const * getStandingOn ( void ) const;
bool getDistance ( Vector const & point_w, float maxDistance, float & outDistance ) const;
int getFlags() const;
void setFlags(int flags);
bool hasFlags(int flags) const;
void modifyFlags(int flags, bool onOff);
// ----------
SpatialDatabase::Query getSpatialDatabaseStorageType() const;
protected:
typedef Watcher<Object> CellWatcher;
Transform m_lastTransform_w;
Transform m_lastTransform_p;
CellWatcher m_lastCellObject;
// ----------
// Since I can't get to the shared object template from shared code when running on the server,
// I have to cache these four variables from the template here.
float m_stepHeight;
float m_defaultRadius;
float m_offsetX;
float m_offsetZ;
// ----------
mutable bool m_extentsDirty;
mutable BaseExtent * m_extent_l;
mutable BaseExtent * m_extent_p;
mutable Sphere m_sphere_l;
mutable Sphere m_sphere_w;
mutable float m_scale;
// ----------
SpatialSubdivisionHandle * m_spatialSubdivisionHandle;
Floor * m_floor;
Footprint * m_footprint;
int m_idleCounter;
CollisionProperty * m_next;
CollisionProperty * m_prev;
bool m_disableCollisionWorldAddRemove;
uint16 m_flags;
private:
CollisionProperty();
CollisionProperty(const CollisionProperty&);
CollisionProperty& operator= (const CollisionProperty&);
private:
SpatialDatabase::Query m_spatialDatabaseStorageType; // SpatialDatabase::Query values
};
// ----------------------------------------------------------------------
inline Floor * CollisionProperty::getFloor ( void )
{
return m_floor;
}
inline Floor const * CollisionProperty::getFloor ( void ) const
{
return m_floor;
}
// ----------
inline Footprint * CollisionProperty::getFootprint ( void )
{
return m_footprint;
}
inline Footprint const * CollisionProperty::getFootprint ( void ) const
{
return m_footprint;
}
// ----------
// Extents
inline bool CollisionProperty::getExtentsDirty ( void ) const
{
return m_extentsDirty;
}
inline void CollisionProperty::setExtentsDirty ( bool dirty ) const
{
m_extentsDirty = dirty;
}
inline BaseExtent const * CollisionProperty::getExtent_l ( void ) const
{
if(getExtentsDirty()) updateExtents();
return m_extent_l;
}
inline BaseExtent const * CollisionProperty::getExtent_p ( void ) const
{
if(getExtentsDirty()) updateExtents();
return m_extent_p;
}
// ----------
inline float CollisionProperty::getScale ( void ) const
{
return m_scale;
}
// ----------
// Flags
inline void CollisionProperty::setMobile ( bool mobile )
{
modifyFlags(F_mobile, mobile);
}
inline void CollisionProperty::setFlora ( bool flora )
{
modifyFlags(F_flora, flora);
}
inline void CollisionProperty::setPlayer ( bool player )
{
modifyFlags(F_player, player);
}
inline void CollisionProperty::setPlayerControlled ( bool playerControlled )
{
modifyFlags(F_playerControlled, playerControlled);
}
inline void CollisionProperty::setCollidable ( bool collidable )
{
modifyFlags(F_collidable, collidable);
}
inline void CollisionProperty::setInCombat ( bool inCombat )
{
modifyFlags(F_inCombat, inCombat);
}
// ----------
inline bool CollisionProperty::isMobile ( void ) const
{
return hasFlags(F_mobile);
}
inline bool CollisionProperty::isFlora ( void ) const
{
return hasFlags(F_flora);
}
inline bool CollisionProperty::isPlayer ( void ) const
{
return hasFlags(F_player);
}
inline bool CollisionProperty::isMount ( void ) const
{
return hasFlags(F_mount);
}
inline bool CollisionProperty::isShip ( void ) const
{
return hasFlags(F_ship);
}
inline bool CollisionProperty::isPlayerControlled ( void ) const
{
return hasFlags(F_playerControlled);
}
inline bool CollisionProperty::isCollidable ( void ) const
{
return hasFlags(F_collidable);
}
inline bool CollisionProperty::isInCombat ( void ) const
{
return hasFlags(F_inCombat);
}
// ----------
inline bool CollisionProperty::isIdle ( void ) const
{
return hasFlags(F_idle);
}
// ----------
inline CollisionProperty * CollisionProperty::getPrev ( void )
{
return m_prev;
}
inline CollisionProperty * CollisionProperty::getNext ( void )
{
return m_next;
}
// ----------
inline SpatialDatabase::Query CollisionProperty::getSpatialDatabaseStorageType() const
{
return m_spatialDatabaseStorageType;
}
//----------------------------------------------------------------------
inline int CollisionProperty::getFlags() const
{
return m_flags;
}
//----------------------------------------------------------------------
inline void CollisionProperty::setFlags(int flags)
{
m_flags = static_cast<uint16>(flags);
}
//----------------------------------------------------------------------
inline bool CollisionProperty::hasFlags(int flags) const
{
return (m_flags & flags) == flags;
}
//----------------------------------------------------------------------
inline void CollisionProperty::modifyFlags(int flags, bool onOff)
{
if (onOff)
m_flags |= flags;
else
m_flags &= ~flags;
}
// ======================================================================
#endif // #ifndef INCLUDED_CollisionProperty_H
@@ -0,0 +1,834 @@
// ======================================================================
//
// CollisionResolve.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/CollisionResolve.h"
#include "sharedCollision/CollisionProperty.h"
#include "sharedCollision/ConfigSharedCollision.h"
#include "sharedCollision/Resolve3d.h"
#include "sharedCollision/Contact3d.h"
#include "sharedCollision/SimpleExtent.h"
#include "sharedCollision/ComponentExtent.h"
#include "sharedCollision/DetailExtent.h"
#include "sharedCollision/CollisionUtils.h"
#include "sharedCollision/Footprint.h"
#include "sharedCollision/FloorContactShape.h"
#include "sharedCollision/Floor.h"
#include "sharedCollision/FloorMesh.h"
#include "sharedMath/Cylinder.h"
#include "sharedMath/ShapeUtils.h"
#include "sharedObject/Object.h"
#include "sharedObject/CellProperty.h"
#include <vector>
typedef std::vector<FloorContactShape *> FloorContactList;
typedef MultiListDataIterator<FloorContactShape> ContactIterator;
// ======================================================================
Vector MoveSegment::getBegin ( CellProperty const * relativeCell ) const
{
return CollisionUtils::transformToCell(m_cellA,m_pointA,relativeCell);
}
Vector MoveSegment::getEnd ( CellProperty const * relativeCell ) const
{
return CollisionUtils::transformToCell(m_cellB,m_pointB,relativeCell);
}
Vector MoveSegment::getDelta ( CellProperty const * relativeCell ) const
{
return getEnd(relativeCell) - getBegin(relativeCell);
}
Vector MoveSegment::getDelta_b ( void ) const
{
return m_pointB - getBegin(m_cellB);
}
Vector MoveSegment::getDelta_a ( void ) const
{
return getEnd(m_cellA) - m_pointA;
}
Vector MoveSegment::atParam ( CellProperty const * relativeCell, float time ) const
{
Vector begin = getBegin(relativeCell);
Vector end = getEnd(relativeCell);
return begin + (end-begin)*time;
}
float MoveSegment::lengthSquared ( void ) const
{
return getDelta_a().magnitudeSquared();
}
// ======================================================================
namespace CollisionResolveNamespace
{
int ms_colliderCount = 0;
int ms_obstacleCount = 0;
int ms_collisionCount = 0;
int ms_bounceCount = 0;
ObstacleList ms_obstacleList;
ContactList ms_contactList;
FloorContactList ms_floorContactList;
Floor const * ms_ignoreFloor = NULL;
int ms_ignoreTriId = -1;
int ms_ignoreEdge = -1;
Vector ms_ignoreNormal = Vector::zero;
float ms_ignoreTime = REAL_MAX;
bool ms_debugBackupContacts = false;
bool ms_debugTestClear = false;
bool ms_debugRedoResolve = false;
};
using namespace CollisionResolveNamespace;
// ----------------------------------------------------------------------
void CollisionResolve::install ( void )
{
}
void CollisionResolve::remove ( void )
{
}
// ----------------------------------------------------------------------
// Resolve all collisions in the collision world
int CollisionResolve::getColliderCount ( void )
{
return ms_colliderCount;
}
int CollisionResolve::getObstacleCount ( void )
{
return ms_obstacleCount;
}
int CollisionResolve::getCollisionCount ( void )
{
return ms_collisionCount;
}
int CollisionResolve::getBounceCount ( void )
{
return ms_bounceCount;
}
void CollisionResolve::resetCounters ( void )
{
ms_colliderCount = 0;
ms_obstacleCount = 0;
ms_collisionCount = 0;
ms_bounceCount = 0;
}
// ----------------------------------------------------------------------
// @todo - handle extents in cells
void translateExtent ( CellProperty const * cell, BaseExtent * extent, Vector const & delta )
{
UNREF(cell);
Transform tform = Transform::identity;
tform.move_p(delta);
extent->transform(extent,tform,1.0f);
}
void translateExtent ( CellProperty const * cell, BaseExtent * extent, MoveSegment const & moveSeg, float moveParam )
{
Transform tform = Transform::identity;
Vector delta = moveSeg.getDelta(cell);
delta *= moveParam;
tform.move_p(delta);
extent->transform(extent,tform,1.0f);
}
void translateFloorContacts ( FloorContactList & floorContacts, MoveSegment const & moveSeg, float moveParam, int ignoreTriId, int ignoreEdge )
{
int floorContactCount = ms_floorContactList.size();
for(int i = 0; i < floorContactCount; i++)
{
FloorContactShape * shape = floorContacts[i];
FloorLocator & loc = shape->m_contact;
Floor const * floor = loc.getFloor();
CellProperty const * floorCell = loc.getCell();
Vector begin = loc.getPosition_p();
Vector end = moveSeg.getEnd(floorCell);
Vector delta = end - begin;
Vector goal = begin + delta * moveParam;
if(floor)
{
FloorLocator tempLoc;
IGNORE_RETURN( floor->moveLocator( loc, goal, ignoreTriId, ignoreEdge, tempLoc ) );
loc = tempLoc;
}
else
{
Vector end = moveSeg.getEnd(loc.getCell());
loc.setPosition_p(end);
}
}
}
// ----------------------------------------------------------------------
void moveObjectAlong ( Object * object, CellPositionList const & positions )
{
int count = positions.size();
for(int i = 0; i < count; i++)
{
CellProperty * const objectCell = object->getParentCell();
CellProperty const * newCell = positions[i].m_cell;
Vector const & newEnd = positions[i].m_position;
Vector localEnd = CollisionUtils::transformToCell(newCell,newEnd,objectCell);
object->setPosition_p( localEnd );
}
}
// ----------
void CollisionResolve::translateEverything ( CellProperty const * cell, SimpleExtent * extent, FloorContactList & floorContacts, MoveSegment const & moveSeg, float moveParam, int ignoreTriId, int ignoreEdge )
{
translateExtent(cell,extent,moveSeg,moveParam);
translateFloorContacts(floorContacts,moveSeg,moveParam,ignoreTriId,ignoreEdge);
}
// ----------------------------------------------------------------------
// Explode the collidee list into a list of simple extents, move the
// collider back to the beginning of the timestep, resolve all collisions
// during the timestep, and then move the collider's object to the
// resolved position.
ResolutionResult CollisionResolve::resolveCollisions(CollisionProperty * colliderA, ColliderList const & colliderList)
{
NOT_NULL(colliderA);
if (colliderList.empty())
{
Footprint * foot = colliderA->getFootprint();
NOT_NULL(foot);
if(!foot->hasContacts())
{
return RR_NoCollision;
}
}
Object * objectA = &(colliderA->getOwner());
NOT_NULL(objectA);
MoveSegment moveSeg;
moveSeg.m_cellA = colliderA->getLastCell();
moveSeg.m_pointA = colliderA->getLastPos_p();
moveSeg.m_cellB = objectA->getParentCell();
moveSeg.m_pointB = objectA->getPosition_p();
if(moveSeg.lengthSquared() == 0.0f)
{
return RR_NoCollision;
}
ResolutionResult result = resolveCollisions(colliderA, moveSeg, colliderList);
return result;
}
// ----------------------------------------------------------------------
ResolutionResult CollisionResolve::resolveCollisions(CollisionProperty * colliderA, MoveSegment const & moveSeg, ColliderList const & colliderList)
{
Object * objectA = &(colliderA->getOwner());
BaseExtent const * baseExtentA = colliderA->getExtent_p();
if (!baseExtentA)
return RR_NoCollision;
CellProperty const * objectCell = objectA->getParentCell();
SimpleExtent const * objectExtent = safe_cast<SimpleExtent const *>(baseExtentA);
NOT_NULL(objectExtent);
if (!objectExtent)
return RR_NoCollision;
explodeCollider(colliderA, colliderList);
// ----------
SimpleExtent * tempExtent = safe_cast<SimpleExtent*>(objectExtent->clone());
translateExtent(objectCell,tempExtent,-moveSeg.getDelta(objectCell));
static CellPositionList positions;
positions.clear();
ResolutionResult result = resolveCollisions(objectCell,tempExtent,ms_floorContactList,moveSeg,&ms_obstacleList,positions, colliderA->getFootprint());
delete tempExtent;
if(result == RR_Resolved)
{
colliderA->hitBy(NULL);
colliderA->setExtentsDirty(true);
Vector resetPos = moveSeg.getBegin(moveSeg.m_cellB);
objectA->setPosition_p(resetPos);
moveObjectAlong(objectA,positions);
}
return result;
}
// ----------------------------------------------------------------------
ResolutionResult CollisionResolve::resolveCollisions ( CellProperty const * cellA, SimpleExtent * extentA, FloorContactList & floorContactsA,
MoveSegment const & startMoveSeg,
ObstacleList * obstacleList,
CellPositionList & outList, Footprint * footprint )
{
CellProperty const * startCell = startMoveSeg.m_cellA;
Vector startDelta = startMoveSeg.getDelta(startCell);
MoveSegment moveSeg = startMoveSeg;
const int iterationCount = 8;
ms_ignoreFloor = NULL;
ms_ignoreTriId = -1;
ms_ignoreEdge = -1;
ms_ignoreTime = REAL_MAX;
ms_ignoreNormal = Vector::zero;
for(int i = 0; i < iterationCount; i++)
{
int minIndex = -1;
Contact contact;
bool foundContact = findFirstContact(cellA,extentA,moveSeg,obstacleList,minIndex,contact, footprint);
if(!foundContact)
{
outList.push_back( CellPosition(moveSeg.m_cellB,moveSeg.m_pointB) );
translateEverything(cellA,extentA,floorContactsA,moveSeg,1.0f,ms_ignoreTriId,ms_ignoreEdge);
if(i == 0)
{
return RR_NoCollision;
}
else
{
return RR_Resolved;
}
}
if(!contact.m_resolvable)
{
return RR_DontKnowHow;
}
if(!contact.m_exists)
{
return RR_Resolved;
}
// ----------
ms_bounceCount++;
CellProperty const * contactCell = contact.m_cell;
Vector contactPoint = moveSeg.atParam(contactCell,contact.m_time);
outList.push_back( CellPosition(contactCell,contactPoint) );
MoveSegment secondSeg;
secondSeg.m_cellA = contactCell;
secondSeg.m_pointA = contactPoint;
secondSeg.m_cellB = moveSeg.m_cellB;
secondSeg.m_pointB = moveSeg.m_pointB;
if(contact.m_time != 0.0f)
{
translateEverything(cellA,extentA,floorContactsA,moveSeg,contact.m_time,ms_ignoreTriId,ms_ignoreEdge);
}
// ----------
int contactCount = ms_contactList.size() + 1;
if(contactCount == 1)
{
Vector delta = secondSeg.getDelta(contactCell);
Vector slidDelta = Collision3d::SingleSlide(delta,contact.m_normal);
// Stop resolution if the velocity starts to move backwards
Vector localStartDelta = CollisionUtils::rotateToCell(startCell,startDelta,contactCell);
if(slidDelta.dot(localStartDelta) <= 0.0f)
{
return RR_Resolved;
}
ms_contactList.push_back(contact);
moveSeg.m_cellA = contactCell;
moveSeg.m_pointA = contactPoint;
moveSeg.m_cellB = contactCell;
moveSeg.m_pointB = contactPoint + slidDelta;
}
else if (contactCount == 2)
{
Vector delta = secondSeg.getDelta(contactCell);
Contact contactA = contact;
Contact contactB = ms_contactList.front();
Vector normalA = contactA.m_normal;
Vector normalB = CollisionUtils::rotateToCell(contactB.m_cell,contactB.m_normal,contactA.m_cell);
Vector slidDelta = Collision3d::DoubleSlide(delta,normalA,normalB);
// Stop resolution if the velocity starts to move backwards
Vector localStartDelta = CollisionUtils::rotateToCell(startCell,startDelta,contactCell);
if(slidDelta.dot(localStartDelta) <= 0.0f)
{
return RR_Resolved;
}
// ----------
// Keep only the contacts that the new velocity is not moving away
// from
ms_contactList.clear();
if(slidDelta.dot(normalA) < 0.0001f)
{
ms_contactList.push_back(contactA);
}
if(slidDelta.dot(normalB) < 0.0001f)
{
ms_contactList.push_back(contactB);
}
// ----------
moveSeg.m_cellA = contactCell;
moveSeg.m_pointA = contactPoint;
moveSeg.m_cellB = contactCell;
moveSeg.m_pointB = contactPoint + slidDelta;
}
else
{
// triple-contact - stop movement because this is too much of a pain
// to resolve correctly.
return RR_Resolved;
}
// ----------
// Remove the hit obstacle from the extent list
if(obstacleList->at(minIndex).m_extent != NULL)
{
obstacleList->at(minIndex) = obstacleList->back();
obstacleList->resize(obstacleList->size()-1);
ms_ignoreFloor = NULL;
ms_ignoreTriId = -1;
ms_ignoreEdge = -1;
ms_ignoreTime = REAL_MAX;
ms_ignoreNormal = Vector::zero;
}
else
{
ms_ignoreFloor = obstacleList->at(minIndex).m_floorContact->m_contact.getFloor();
ms_ignoreTriId = contact.m_surfaceId1;
ms_ignoreEdge = contact.m_surfaceId2;
ms_ignoreTime = contact.m_time;
ms_ignoreNormal = contact.m_normal;
}
}
// For all practical purposes the code should never get here.
DEBUG_WARNING(true,("CollisionResolve::resolveCollisions - Resolution went through 8 iterations without success"));
outList.push_back( CellPosition(moveSeg.m_cellA,moveSeg.m_pointA) );
return RR_Resolved;
}
// ----------------------------------------------------------------------
void CollisionResolve::explodeExtent ( CellProperty const * cell, SimpleExtent const * extent, ObstacleList & list )
{
list.push_back( ObstacleInfo(cell,extent) );
}
// ----------
void CollisionResolve::explodeExtent ( CellProperty const * cell, ComponentExtent const * extent, ObstacleList & list )
{
int extentCount = extent->getExtentCount();
for(int i = 0; i < extentCount; i++)
{
explodeExtent(cell,extent->getExtent(i),list);
}
}
// ----------
void CollisionResolve::explodeExtent ( CellProperty const * cell, DetailExtent const * extent, ObstacleList & list )
{
int extentCount = extent->getExtentCount();
explodeExtent(cell,extent->getExtent(extentCount-1),list);
}
// ----------
void CollisionResolve::explodeExtent ( CellProperty const * cell, BaseExtent const * extent, ObstacleList & list )
{
NOT_NULL(extent);
ExtentType type = extent->getType();
// ----------
if (type == ET_Simple) explodeExtent(cell,safe_cast<SimpleExtent const *>(extent),list);
else if(type == ET_Component) explodeExtent(cell,safe_cast<ComponentExtent const *>(extent),list);
else if(type == ET_Detail) explodeExtent(cell,safe_cast<DetailExtent const *>(extent),list);
}
// ----------
void CollisionResolve::explodeFootprint ( Footprint * foot, ObstacleList & obstacleList, FloorContactList & floorContacts )
{
if(foot == NULL) return;
for(ContactIterator it(foot->getFloorList()); it; ++it)
{
FloorContactShape * contact = (*it);
if(contact == NULL)
continue;
obstacleList.push_back( ObstacleInfo(contact->m_contact.getCell(),contact) );
floorContacts.push_back(contact);
}
}
// ----------
// Explode the extents of all colliders into SimpleExtents, accumuluate
// the extents into ms_obstacleList
void CollisionResolve::explodeCollider(CollisionProperty * colliderA, ColliderList const & colliderList)
{
NOT_NULL(colliderA);
ms_obstacleList.clear();
ms_contactList.clear();
ms_floorContactList.clear();
ColliderList::const_iterator ii = colliderList.begin();
ColliderList::const_iterator iiEnd = colliderList.end();
for(; ii != iiEnd; ++ii)
{
CollisionProperty const * const colliderB = *ii;
if(colliderB == NULL) continue;
BaseExtent const * const extentB = colliderB->getExtent_p();
explodeExtent(colliderB->getOwner().getParentCell(), extentB, ms_obstacleList);
}
if(!(colliderA->isServerSide() && colliderA->isPlayerControlled()) && ConfigSharedCollision::getEnableFloorCollision())
{
explodeFootprint(colliderA->getFootprint(),ms_obstacleList,ms_floorContactList);
}
else
{
Footprint * const foot = colliderA->getFootprint();
for(ContactIterator it(foot->getFloorList()); it; ++it)
{
FloorContactShape * const contact = (*it);
if(contact == NULL) continue;
ms_floorContactList.push_back(contact);
}
}
ms_obstacleCount += ms_obstacleList.size();
}
// ----------------------------------------------------------------------
bool CollisionResolve::findFirstContact ( CellProperty const * cellA, SimpleExtent const * extentA, MoveSegment const & moveSeg, ObstacleList * obstacleList, int & outMinIndex, Contact & outContact, Footprint * footprint )
{
int extentCount = obstacleList->size();
outContact = Contact::noContact;
outMinIndex = -1;
for(int i = 0; i < extentCount; i++)
{
ObstacleInfo & obstacle = obstacleList->at(i);
Contact contact = findContactWithObstacle(cellA,extentA,moveSeg,obstacle, footprint);
if(!contact.m_resolvable)
{
continue;
}
else if(contact.m_exists && (contact.m_time < outContact.m_time))
{
if(contact.m_time < 0.0f)
{
Vector delta = moveSeg.getDelta(contact.m_cell);
float stepDistance = delta.magnitude();
float contactDistance = stepDistance * -contact.m_time;
if(contactDistance > 0.05f) continue;
}
outContact = contact;
outMinIndex = i;
}
}
return outContact.m_exists;
}
// ----------------------------------------------------------------------
Contact CollisionResolve::findContactWithExtent ( CellProperty const * cellA, SimpleExtent const * extentA, MoveSegment const & moveSeg, CellProperty const * cellB, SimpleExtent const * extentB )
{
NOT_NULL(extentA);
NOT_NULL(extentB);
MultiShape const & shapeA = extentA->getShape();
MultiShape const & shapeB = extentB->getShape();
MultiShape tempShapeA = shapeA;
if(cellA != cellB)
{
tempShapeA = CollisionUtils::transformToCell(cellA,shapeA,cellB);
}
Vector delta = moveSeg.getDelta(cellA);
Contact temp = Contact3d::FindContact(tempShapeA,delta,shapeB);
temp.m_cell = cellB;
temp.m_extent = extentB;
Vector normV = delta;
IGNORE_RETURN(normV.normalize());
float dot = normV.dot(temp.m_normal);
if(dot < 0.0f)
{
return temp;
}
else
{
return Contact::noContact;
}
}
// ----------------------------------------------------------------------
Contact CollisionResolve::findContactWithFloor ( FloorContactShape * floorContact, MoveSegment const & moveSeg, Footprint * footprint )
{
NOT_NULL(floorContact);
FloorLocator & loc = floorContact->m_contact;
FloorLocator & result = floorContact->m_result;
Floor const * floor = loc.getFloor();
if(floor == NULL) return Contact::noContact;
CellProperty const * floorCell = loc.getCell();
Vector begin = loc.getPosition_p();
Vector end = moveSeg.getEnd(floorCell);
Vector delta = end - begin;
// The Y component must be zeroed out or floor contacts far above/below the avatar can
// produce erroneous results
delta.y = 0.0f;
PathWalkResult walkResult;
if(delta.magnitudeSquared() == 0.0f)
{
return Contact::noContact;
}
if (footprint)
{
if (!footprint->isFloorWithinThreshold(*floorContact))
return Contact::noContact;
}
if((ms_ignoreFloor == NULL) || (floor != ms_ignoreFloor))
{
walkResult = floor->canMove(loc,delta,-1,-1,result);
}
else
{
walkResult = floor->canMove(loc,delta,ms_ignoreTriId,ms_ignoreEdge,result);
}
Contact tempContact = Contact::noContact;
if(walkResult != PWR_WalkOk)
{
if((walkResult == PWR_HitEdge) || (walkResult == PWR_InContact) || (walkResult == PWR_HitBeforeEnter) || (walkResult == PWR_HitPast) || (walkResult == PWR_CenterHitEdge) || (walkResult == PWR_CenterInContact))
{
Vector normV = delta;
IGNORE_RETURN(normV.normalize());
float dot = normV.dot(result.getContactNormal());
if(dot < 0.0f)
{
if((result.getContactNormal() != ms_ignoreNormal) || (result.getTime() != ms_ignoreTime))
{
tempContact.m_exists = true;
tempContact.m_resolvable = true;
tempContact.m_time = result.getTime();
tempContact.m_point = Vector::zero; //result.clipPoint;
tempContact.m_normal = result.getContactNormal();
tempContact.m_surfaceId1 = result.getHitTriId();
tempContact.m_surfaceId2 = result.getHitEdgeId();
tempContact.m_cell = floorCell;
tempContact.m_extent = NULL;
tempContact.m_surface = result.getFloor();
}
}
}
}
return tempContact;
}
// ----------------------------------------------------------------------
Contact CollisionResolve::findContactWithObstacle ( CellProperty const * cellA, SimpleExtent const * extentA, MoveSegment const & seg, ObstacleInfo const & obstacle, Footprint * footprint )
{
NOT_NULL(extentA);
if(obstacle.m_extent)
{
return findContactWithExtent(cellA,extentA,seg,obstacle.m_cell,obstacle.m_extent);
}
else if(obstacle.m_floorContact)
{
return findContactWithFloor(obstacle.m_floorContact,seg, footprint);
}
else
{
return Contact::noContact;
}
}
// ----------------------------------------------------------------------
/*
ResolutionResult CollisionResolve::resolveCollisionAsCylinders( SimpleExtent const * extentA,
Vector const & delta,
SimpleExtent const * extentB,
Vector & outDelta )
{
NOT_NULL(extentA);
NOT_NULL(extentB);
MultiShape shapeA = extentA->getShape();
MultiShape shapeB = extentB->getShape();
// Stretch the cylinders vertically so that players can't squeeze under creatures
shapeA.setExtentY( shapeA.getExtentY() * 5.0f );
shapeB.setExtentY( shapeB.getExtentY() * 5.0f );
return Resolve3d::Resolve(shapeA.getCylinder(),delta,shapeB.getCylinder(),outDelta);
}
*/
// ----------------------------------------------------------------------
@@ -0,0 +1,154 @@
// ======================================================================
//
// CollisionResolve.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CollisionResolve_H
#define INCLUDED_CollisionResolve_H
#include "sharedCollision/CollisionEnums.h"
#include "sharedMath/Vector.h"
class CollisionProperty;
class CellProperty;
class BaseExtent;
class Vector;
class Contact;
class BaseExtent;
class SimpleExtent;
class ComponentExtent;
class DetailExtent;
class Footprint;
class FloorContactShape;
class Floor;
struct ObstacleInfo
{
ObstacleInfo()
: m_cell(NULL),
m_extent(NULL),
m_floorContact(NULL)
{
}
ObstacleInfo ( CellProperty const * cell, SimpleExtent const * extent )
: m_cell(cell),
m_extent(extent),
m_floorContact(NULL)
{
}
ObstacleInfo ( CellProperty const * cell, FloorContactShape * contact )
: m_cell(cell),
m_extent(NULL),
m_floorContact(contact)
{
}
CellProperty const * m_cell;
SimpleExtent const * m_extent;
FloorContactShape * m_floorContact;
};
struct CellPosition
{
CellPosition( CellProperty const * cell, Vector const & position )
{
m_cell = cell;
m_position = position;
}
CellProperty const * m_cell;
Vector m_position;
};
typedef stdvector<CollisionProperty*>::fwd ColliderList;
typedef stdvector<ObstacleInfo>::fwd ObstacleList;
typedef stdvector<Contact>::fwd ContactList;
typedef stdvector<FloorContactShape*>::fwd FloorContactList;
typedef stdvector<CellPosition>::fwd CellPositionList;
struct MoveSegment
{
CellProperty const * m_cellA;
Vector m_pointA;
CellProperty const * m_cellB;
Vector m_pointB;
Vector getBegin ( CellProperty const * relativeCell ) const;
Vector getEnd ( CellProperty const * relativeCell ) const;
Vector getDelta ( CellProperty const * relativeCell ) const;
Vector getDelta_a ( void ) const;
Vector getDelta_b ( void ) const;
Vector atParam ( CellProperty const * relativeCell, float time ) const;
float lengthSquared ( void ) const;
};
// ======================================================================
class CollisionResolve
{
public:
static void install ( void );
static void remove ( void );
static void resolveAllCollisions ( void );
static int getColliderCount ( void );
static int getObstacleCount ( void );
static int getCollisionCount ( void );
static int getBounceCount ( void );
static void resetCounters ( void );
static ResolutionResult resolveCollisions(CollisionProperty * colliderA, ColliderList const & colliderList);
protected:
static Contact findContactWithObstacle ( CellProperty const * cellA, SimpleExtent const * extentA, MoveSegment const & moveSeg, ObstacleInfo const & obstacle, Footprint * footprint);
static Contact findContactWithExtent ( CellProperty const * cellA, SimpleExtent const * extentA, MoveSegment const & moveSeg, CellProperty const * cellB, SimpleExtent const * extentB );
static Contact findContactWithFloor ( FloorContactShape * floorContact, MoveSegment const & moveSeg, Footprint * footprint);
// ----------
static ResolutionResult resolveCollisions(CollisionProperty * colliderA, MoveSegment const & moveSeg, ColliderList const & colliderList);
static ResolutionResult resolveCollisions ( CellProperty const * cellA, SimpleExtent * extentA, FloorContactList & floorContactsA,
MoveSegment const & moveSeg,
ObstacleList * extentList,
CellPositionList & outList, Footprint * footprint );
static bool findFirstContact ( CellProperty const * cellA, SimpleExtent const * extentA,
MoveSegment const & moveSeg,
ObstacleList * ObstacleList,
int & outMinIndex, Contact & outContact, Footprint * footprint);
// ----------
static void explodeExtent ( CellProperty const * cell, SimpleExtent const * extent, ObstacleList & list );
static void explodeExtent ( CellProperty const * cell, ComponentExtent const * extent, ObstacleList & list );
static void explodeExtent ( CellProperty const * cell, DetailExtent const * extent, ObstacleList & list );
static void explodeExtent ( CellProperty const * cell, BaseExtent const * extent, ObstacleList & list );
static void explodeFootprint ( Footprint * foot, ObstacleList & obstacleList, FloorContactList & floorContacts );
static void explodeCollider(CollisionProperty * colliderA, ColliderList const & colliderList);
static void translateEverything ( CellProperty const * cell, SimpleExtent * extent, FloorContactList & floorContacts, MoveSegment const & moveSeg, float moveParam, int ignoreTriId, int ignoreEdge );
};
// ======================================================================
#endif // #ifndef INCLUDED_CollisionResolve_H
@@ -0,0 +1,21 @@
// ======================================================================
//
// CollisionSurface.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/CollisionSurface.h"
CollisionSurface::CollisionSurface()
{
}
// ----------
CollisionSurface::~CollisionSurface()
{
}
@@ -0,0 +1,88 @@
// ======================================================================
//
// CollisionSurface.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CollisionSurface_H
#define INCLUDED_CollisionSurface_H
#include "sharedCollision/ContactPoint.h"
// ----------
class Transform;
class BaseExtent;
class Vector;
class Line3d;
class Segment3d;
// ----------
struct LineIntersectResult
{
LineIntersectResult ()
: m_hit(false),
m_hitTime(0.0f),
m_hitLoc()
{
}
LineIntersectResult ( bool hit, float hitTime, ContactPoint const & contact )
: m_hit(hit),
m_hitTime(hitTime),
m_hitLoc(contact)
{
}
// ----------
static LineIntersectResult null;
// ----------
bool operator < ( LineIntersectResult const & result ) const
{
return m_hitTime < result.m_hitTime;
}
bool m_hit;
float m_hitTime;
ContactPoint m_hitLoc;
};
typedef stdvector<LineIntersectResult>::fwd LineIntersectResultVec;
// ======================================================================
class CollisionSurface
{
public:
CollisionSurface();
virtual ~CollisionSurface();
// ----------
virtual Transform const & getTransform_o2p ( void ) const = 0;
virtual Transform const & getTransform_o2w ( void ) const = 0;
virtual float getScale ( void ) const = 0;
virtual BaseExtent const * getExtent_l ( void ) const = 0;
virtual BaseExtent const * getExtent_p ( void ) const = 0;
// ----------
// Intersection methods
protected:
// Disable copying
CollisionSurface(const CollisionSurface &source);
CollisionSurface & operator =(const CollisionSurface &source);
};
// ----------------------------------------------------------------------
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,221 @@
// ======================================================================
//
// CollisionUtils.h
// copyright (c) 2001 Sony Online Entertainment
//
// ----------------------------------------------------------------------
#ifndef INCLUDED_CollisionUtils_H
#define INCLUDED_CollisionUtils_H
#include "sharedMath/Vector.h"
#include "sharedMath/Transform.h"
class Vector;
class ABox;
class Vector;
class Triangle3d;
class Line3d;
class Segment3d;
class Ribbon3d;
class Circle;
class Sphere;
class Capsule;
class Transform;
class CellProperty;
class Object;
class CollisionProperty;
class MultiShape;
class BaseExtent;
typedef stdvector<Vector>::fwd VectorVector;
typedef stdvector<Vector>::fwd VertexList;
typedef stdvector<BaseExtent const *>::fwd ExtentVec;
// ----------------------------------------------------------------------
#ifdef _MSC_VER
inline bool isNan ( float const & x )
{
if(_isnan(x)) return true;
if(!_finite(x)) return true;
return false;
}
inline bool isNan ( Vector const & v )
{
if(isNan(v.x)) return true;
if(isNan(v.y)) return true;
if(isNan(v.z)) return true;
return false;
}
inline bool isNan ( Transform const & t )
{
return t.isNaN();
}
#define NAN_CHECK(x) DEBUG_FATAL(isNan(x),("Floating-point value is not a number"))
#else
#define NAN_CHECK(x)
#endif
// ----------------------------------------------------------------------
struct Matrix3
{
static Matrix3 fromRows( Vector const & row0, Vector const & row1, Vector const & row2);
static Matrix3 fromColumns ( Vector const & col0, Vector const & col1, Vector const & col2 );
// ----------
Vector row0 ( void ) const;
Vector row1 ( void ) const;
Vector row2 ( void ) const;
Vector col0 ( void ) const;
Vector col1 ( void ) const;
Vector col2 ( void ) const;
bool invert ( Matrix3 & out ) const;
Matrix3 multiply ( Matrix3 const & A ) const;
Vector operator * ( Vector const & V ) const;
// ----------
float m00, m01, m02;
float m10, m11, m12;
float m20, m21, m22;
};
// ----------------------------------------------------------------------
namespace Collision
{
extern const real gs_equalityEpsilon;
extern const real gs_planarEpsilon;
extern const real gs_spatialEpsilon;
extern const real gs_twistEpsilon;
};
// ----------------------------------------------------------------------
// 2d operations
namespace Collision2d
{
float ComponentAlong ( Vector const & V, Vector const & N );
}; // namespace Collision2d
// ----------------------------------------------------------------------
// 3d operations
namespace Collision3d
{
// ----------------------------------------------------------------------
// Side/twist tests
int TestLineLineTwist ( Line3d const & A, Line3d const & B );
int TestLineSegTwist ( Line3d const & A, Segment3d const & B );
int TestSegLineTwist ( Segment3d const & A, Line3d const & B );
int TestSegSegTwist ( Segment3d const & A, Segment3d const & B);
// ----------------------------------------------------------------------
// Miscellaneous
// The idea of an exit test for a segment exiting a triangle in 3d is a
// little wonky. This does effectively the same thing as projecting the
// segment down onto the triangle and figuring out which edge the projected
// segment exits.
int TestExitTri ( Ribbon3d const & R, Triangle3d const & tri );
int TestEntranceTri ( Ribbon3d const & R, Triangle3d const & tri );
Vector ClipPath ( Vector const & begin,
Vector const & delta,
Triangle3d const & tri,
int whichEdge,
Vector const & up );
float ComponentAlong ( Vector const & V, Vector const & N );
Vector SlideAlong ( Vector const & V, Vector const & N, float t );
Vector SingleSlide ( Vector V, Vector A );
Vector DoubleSlide ( Vector V, Vector A, Vector B );
bool IsEdgeConcave ( Triangle3d const & triA, int edgeA,
Triangle3d const & triB );
Vector MoveIntoTriangle ( Vector const & point,
Triangle3d const & tri,
real desiredDist );
void MovePolyOnto ( VertexList & verts, Vector V );
bool FindTangentPoint ( Vector A, Circle C, bool right, Vector & outTangent );
bool FindAvoidancePoint ( Vector A, Vector B, Circle C, Vector & outPoint );
bool FindAvoidanceThetas ( Vector A, MultiShape const & shape, float & outThetaA, float & outDistA, float & outThetaB, float & outDistB );
bool CalcAvoidancePoint ( Object const * mob, Vector const & delta, Object const * obstacle, Vector & out );
bool CalcAvoidancePoints3d ( Sphere const & mob, Vector const & delta, Sphere const & obstacle, Vector & avoidA, Vector & avoidB );
// ----------------------------------------------------------------------
}; // namespace Collision3d
// ----------------------------------------------------------------------
namespace CollisionUtils
{
Vector transformToWorld ( CellProperty const * cellA, Vector const & point_A );
Sphere transformToWorld ( CellProperty const * cellA, Sphere const & sphere_A );
Capsule transformToWorld ( CellProperty const * cellA, Capsule const & capsule_A );
Transform transformToWorld ( CellProperty const * cellA, Transform const & transform_A );
Vector transformFromWorld ( Vector const & point_w, CellProperty const * cellB );
Sphere transformFromWorld ( Sphere const & sphere_w, CellProperty const * cellB );
Capsule transformFromWorld ( Capsule const & capsule_w, CellProperty const * cellB );
Transform transformFromWorld ( Transform const & transform_w, CellProperty const * cellB );
// ----------
Vector transformToCell ( CellProperty const * cellA, Vector const & point, CellProperty const * cellB );
Transform transformToCell ( CellProperty const * cellA, Transform const & transform, CellProperty const * cellB );
Sphere transformToCell ( CellProperty const * cellA, Sphere const & sphere, CellProperty const * cellB );
Capsule transformToCell ( CellProperty const * cellA, Capsule const & capsule, CellProperty const * cellB );
MultiShape transformToCell ( CellProperty const * cellA, MultiShape const & shape, CellProperty const * cellB );
Vector rotateToCell ( CellProperty const * cellA, Vector const & dir, CellProperty const * cellB );
// ----------
bool testPortalVis ( CellProperty const * cellA, Vector const & pointA, CellProperty const * cellB, Vector const & pointB );
// ----------
bool epsilonEqual ( Sphere const & A, Sphere const & B, float epsilon );
};
// ----------------------------------------------------------------------
#endif
@@ -0,0 +1,8 @@
// ======================================================================
//
// CollisionVolume.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedCollision/FirstSharedCollision.h"
@@ -0,0 +1,39 @@
// ======================================================================
//
// CollisionVolume.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CollisionVolume_H
#define INCLUDED_CollisionVolume_H
// ======================================================================
class Vector;
// ======================================================================
class CollisionVolume
{
public:
CollisionVolume();
virtual ~CollisionVolume();
// ----------
// Generic interface
bool contains ( Vector const & V );
protected:
// Disable copying
CollisionVolume(const CollisionVolume &source);
CollisionVolume & operator =(const CollisionVolume &source);
};
// ----------------------------------------------------------------------
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,176 @@
// ======================================================================
//
// CollisionWorld.h
// copyright (c) 2001 Sony Online Entertainment
//
// ----------------------------------------------------------------------
#ifndef INCLUDED_CollisionWorld_H
#define INCLUDED_CollisionWorld_H
#include "sharedCollision/CollisionEnums.h"
#include "sharedCollision/CollisionNotification.h"
#include "sharedCollision/FloorContactShape.h"
#include "sharedCollision/MultiList.h"
#include "sharedMath/Vector.h"
class Camera;
class CellProperty;
class Circle;
class CollisionProperty;
class Floor;
class FloorLocator;
class Footprint;
class Line3d;
class Object;
class Segment3d;
class SpatialDatabase;
class Sphere;
class MultiShape;
typedef stdvector<Object*>::fwd ObjectVec;
typedef stdvector<CollisionProperty*>::fwd ColliderList;
typedef stdvector<Footprint*>::fwd FootprintList;
// ======================================================================
class CollisionWorld
{
public:
typedef void (*WarpWarningCallback)(Object const &object, Vector const &oldPosition_w, Vector const &newPosition_w, int segmentCount);
// collision callbacks that are used by non-Footprint objects that are in a 3D environment.
// these are mostly used by space objects such as ShipObject
typedef bool (*CanTestCollisionDetectionOnObjectThisFrameFunction)(Object * const object);
typedef void (*NoCollisionDetectionThisFrameFunction)(Object * const object);
typedef bool (*CollisionDetectionOnHitFunction)(Object * const object, Object * const wasHitByThisObject);
typedef bool (*DoCollisionWithTerrainFunction)(Object * const object);
static void registerCanTestCollisionDetectionOnObjectThisFrame(CanTestCollisionDetectionOnObjectThisFrameFunction);
static void registerNoCollisionDetectionThisFrame(NoCollisionDetectionThisFrameFunction);
static void registerDoCollisionDetectionOnHit(CollisionDetectionOnHitFunction);
static void registerDoCollisionWithTerrain(DoCollisionWithTerrainFunction);
public:
// ----------
static void install ( bool serverSide );
static void remove ( void );
static void update ( float time );
static bool isUpdating ( void );
static void reportCallback ( void );
static void setNearWarpWarningCallback(WarpWarningCallback callback);
static void setFarWarpWarningCallback(WarpWarningCallback callback);
// ----------
static void addObject ( Object * object );
static void removeObject ( Object * object );
static void moveObject ( Object * object );
static void cellChanged ( Object * object );
static void appearanceChanged ( Object * object );
// ----------
static void objectWarped ( Object * object );
static SpatialDatabase * getDatabase ( void );
// ----------
// Queries
static bool query ( Line3d const & line, ObjectVec * outList );
static bool query ( Sphere const & sphere, ObjectVec * outList );
static QueryInteractionResult queryInteraction ( CellProperty const * cellA, Vector const & pointA,
CellProperty const * cellB, Vector const & pointB,
Object const * ignoreObject,
bool useTerrainLos,
bool generateTerrainLos,
float terrainLosMinDistance,
float terrainLosMaxDistance,
float & outHitTime, Object const * & outHitObject );
// ----------
// CanMove
// checkY - if true, the canMove succeeds only if the object would end up at the correct X,Y, and Z coords. if false, only checks X and Z
static CanMoveResult canMove ( Object const * object, Vector const & goal, float moveRadius, bool checkY, bool checkFlora, bool checkFauna );
static CanMoveResult canMove ( CellProperty const * startCell, Vector const & startPos, Vector const & goal, float moveRadius, bool checkY, bool checkFlora, bool checkFauna );
static bool findFirstObstacle ( Object const * object, float radius, Vector const & testPos, Vector const & goalPos, bool testStatics, bool testCreatures, Object const * & outObject );
static bool findFirstObstacle ( Sphere const & sphere, Vector const & goalPos, bool testStatics, bool testCreatures, Object const * & outObject );
static bool calcBubble ( CellProperty const * cell, Vector const & point_p, float maxDistance, float & outRadius );
static bool calcBubble ( CellProperty const * cell, Vector const & point_p, Object const * ignoreObject, float maxDistance, float & outRadius );
static bool testClear ( CellProperty const * cell, Sphere const & sphere_p );
static bool canMoveInSpace ( Object const * object, Sphere const & sphere, Vector const & goal );
// ----------
static bool findLocators ( CellProperty const * cell, Vector const & point, stdvector<FloorLocator>::fwd & outLocs );
static bool makeLocator ( CellProperty const * cell, Vector const & point, FloorLocator & outLoc);
static void environmentChanged ( MultiShape const & shape );
static void shoveAway(CollisionProperty * const collisionProperty, ColliderList const & colliderList, float time);
static bool isServerSide ( void );
static void setServerSide ( bool serverSide );
static void handleSceneChange(std::string const & sceneId);
static Floor const * getFloorStandingOn(Object const & object);
protected:
// collision callbacks that are used by non-Footprint objects such as ShipObject
static bool canTestCollisionDetectionOnObjectThisFrame(Object * object);
static void noCollisionDetectionThisFrame(Object * object);
static bool doCollisionDetectionOnHit(Object * object, Object * wasHitByThisObject);
static bool doCollisionWithTerrain(Object * object);
static void update ( CollisionProperty * collision, float time );
static void updateSegment ( CollisionProperty * collision, float time );
static ResolutionResult updateStep ( CollisionProperty * collision, float time );
static bool spatialSweepAndResolve(CollisionProperty * collider);
// ----------
static CanMoveResult canMove ( Object const * object, CellProperty const * startCell, FloorLocator const & startLoc, CellProperty const * goalCell, FloorLocator const & goalLoc, bool checkY, bool checkFlora, bool checkFauna );
static CanMoveResult canMove ( Object const * object, CellProperty const * startCell, FloorLocator const & startLoc, Vector const & goalPos, bool checkY, bool checkFlora, bool checkFauna, FloorLocator & endLoc );
static CanMoveResult canMoveOnFloor ( Object const * object, Vector const & startPos, float moveRadius, Floor const * floor, FloorLocator const & goalLoc, bool checkY, bool checkFlora, bool checkFauna, FloorLocator & outLoc, int & outHitPortalId );
static CanMoveResult canMoveOnFloor ( Object const * object, FloorLocator const & startLoc, Floor const * floor, FloorLocator const & goalLoc, bool checkY, bool checkFlora, bool checkFauna, FloorLocator & outLoc, int & outHitPortalId );
static CanMoveResult canMoveInCell ( Object const * object, CellProperty const * startCell, FloorLocator const & startLoc, Vector const & goalPos, bool checkY, bool checkFlora, bool checkFauna, FloorLocator & outLoc, int & outHitPortalId );
static CanMoveResult canMoveInCell ( Object const * object, CellProperty const * startCell, FloorLocator const & startLoc, FloorLocator const & goalLoc, bool checkY, bool checkFlora, bool checkFauna, FloorLocator & outLoc, int & outHitPortalId );
// ----------
static void updateReportString ( void );
private:
CollisionWorld();
CollisionWorld( CollisionWorld const & copy );
CollisionWorld & operator = ( CollisionWorld const & copy );
};
// ======================================================================
#endif // #ifndef INCLUDED_CollisionWorld_H
@@ -0,0 +1,222 @@
//===================================================================
//
// ConfigSharedCollision.cpp
// copyright 2000, verant interactive
//
//===================================================================
#include "sharedCollision/FirstSharedCollision.h"
#include "sharedCollision/ConfigSharedCollision.h"
#include "sharedCollision/CollisionWorld.h"
#include "sharedCollision/SpatialDatabase.h"
#include "sharedFoundation/ConfigFile.h"
#include "sharedFoundation/Production.h"
#include "sharedDebug/DebugFlags.h"
//===================================================================
namespace ConfigSharedCollisionNamespace
{
bool ms_drawFloors = false;
bool ms_drawExtents = false;
bool ms_drawCollisionNormals = false;
bool ms_drawSphereTrees = false;
bool ms_drawPathNodes = false;
bool ms_drawBoxTrees = false;
bool ms_drawCMeshes = false;
bool ms_drawFootprints = false;
bool ms_drawCreatureLengths = false;
bool ms_enableStaticCollision = true;
bool ms_enableFloraCollision = true;
bool ms_enableFloorCollision = true;
bool ms_enableCollisionResolve = true;
bool ms_enableCollisionFlags = false;
bool ms_enableCollisionValidate = false;
bool ms_enableRemoteCollision = false;
bool ms_enableTestCode = false;
bool ms_enableCreatureCollision = true;
bool ms_enableIntraFrameTests = true;
bool ms_enableMountRadii = false;
bool ms_buildBoxTrees = false;
bool ms_buildDebugData = false;
bool ms_updateStatus = true;
bool ms_reportStatus = false;
bool ms_reportChanges = false;
bool ms_reportMessages = false;
#if PRODUCTION == 0
bool ms_reportWarnings = true;
#else
bool ms_reportWarnings = false;
#endif
bool ms_reportEvents = false;
bool ms_reportFloating = false;
bool ms_logLongFrames = false;
bool ms_ignoreTerrainLos = true;
bool ms_generateTerrainLos = false;
bool ms_shoveEnabled = true;
float ms_wallEpsilon = 0.01f; // the distance that we keep the footprints away from the walls
float ms_areaEpsilon = 0.000001f; // One square millimeter
float ms_hopHeight = 0.30f; // how high a floor can be off the terrain and still allow us to hop up onto it
float ms_terrainLOSMinDistance = 4.0f;
float ms_terrainLOSMaxDistance = 64.0f;
float ms_losUprightScale = 1.5f;
float ms_losProneScale = 1.0f;
PlayEffectHook ms_playEffectHook = NULL;
IsPlayerHouseHook ms_isPlayerHouseHook = NULL;
int ms_spatialSweepAndResolveDefaultMask = static_cast<int>(SpatialDatabase::Q_Static);
bool ms_spaceAiLoggingEnabled = false;
bool ms_useOriginalAvoidanceAlgorithm = false;
}
using namespace ConfigSharedCollisionNamespace;
// ----------------------------------------------------------------------
void ConfigSharedCollision::install ( void )
{
#if PRODUCTION == 0
DebugFlags::registerFlag( ms_drawFloors, "SharedCollision", "drawFloors");
DebugFlags::registerFlag( ms_drawExtents, "SharedCollision", "drawExtents");
DebugFlags::registerFlag( ms_drawCollisionNormals, "SharedCollision", "drawCollisionNormals");
DebugFlags::registerFlag( ms_drawSphereTrees, "SharedCollision", "drawSphereTrees");
DebugFlags::registerFlag( ms_drawPathNodes, "SharedCollision", "drawPathNodes");
DebugFlags::registerFlag( ms_drawBoxTrees, "SharedCollision", "drawBoxTrees");
DebugFlags::registerFlag( ms_drawCMeshes, "SharedCollision", "drawCMeshes");
DebugFlags::registerFlag( ms_drawFootprints, "SharedCollision", "drawFootprints");
DebugFlags::registerFlag( ms_drawCreatureLengths, "SharedCollision", "drawCreatureLengths");
DebugFlags::registerFlag( ms_enableStaticCollision, "SharedCollision", "enableStaticCollision");
DebugFlags::registerFlag( ms_enableFloraCollision, "SharedCollision", "enableFloraCollision");
DebugFlags::registerFlag( ms_enableFloorCollision, "SharedCollision", "enableFloorCollision");
DebugFlags::registerFlag( ms_enableCollisionResolve, "SharedCollision", "enableCollisionResolve");
DebugFlags::registerFlag( ms_enableCollisionFlags, "SharedCollision", "enableCollisionFlags");
DebugFlags::registerFlag( ms_enableCollisionValidate, "SharedCollision", "enableCollisionValidate");
DebugFlags::registerFlag( ms_enableTestCode, "SharedCollision", "enableTestCode");
DebugFlags::registerFlag( ms_enableCreatureCollision, "SharedCollision", "enableCreatureCollision");
DebugFlags::registerFlag( ms_enableIntraFrameTests, "SharedCollision", "enableIntraFrameTests");
DebugFlags::registerFlag( ms_enableMountRadii, "SharedCollision", "enableMountRadii");
DebugFlags::registerFlag( ms_buildBoxTrees, "SharedCollision", "buildBoxTrees");
DebugFlags::registerFlag( ms_buildDebugData, "SharedCollision", "buildDebugData");
DebugFlags::registerFlag( ms_updateStatus, "SharedCollision", "updateStatus", CollisionWorld::reportCallback);
DebugFlags::registerFlag( ms_reportStatus, "SharedCollision", "reportStatus");
DebugFlags::registerFlag( ms_reportChanges, "SharedCollision", "reportChanges");
DebugFlags::registerFlag( ms_reportMessages, "SharedCollision", "reportMessages");
DebugFlags::registerFlag( ms_reportWarnings, "SharedCollision", "reportWarnings");
DebugFlags::registerFlag( ms_reportEvents, "SharedCollision", "reportEvents");
DebugFlags::registerFlag( ms_reportFloating, "SharedCollision", "reportFloating");
DebugFlags::registerFlag( ms_logLongFrames, "SharedCollision", "logLongFrames");
DebugFlags::registerFlag( ms_shoveEnabled, "SharedCollision", "0x4F474F67"); // hash of shoveEnabled
DebugFlags::registerFlag( ms_spaceAiLoggingEnabled, "SharedCollision", "spaceAiLoggingEnabled");
DebugFlags::registerFlag( ms_useOriginalAvoidanceAlgorithm, "SharedCollision", "useOriginalAvoidanceAlgorithm");
// ----------
#endif
// the following options should be read regardless of production mode
DebugFlags::registerFlag( ms_ignoreTerrainLos, "SharedCollision", "ignoreTerrainLos");
DebugFlags::registerFlag( ms_generateTerrainLos, "SharedCollision", "generateTerrainLos");
ms_wallEpsilon = ConfigFile::getKeyFloat("SharedCollision", "wallEpsilon", ms_wallEpsilon);
ms_areaEpsilon = ConfigFile::getKeyFloat("SharedCollision", "areaEpsilon", ms_areaEpsilon);
ms_hopHeight = ConfigFile::getKeyFloat("SharedCollision", "hopHeight", ms_hopHeight);
ms_terrainLOSMinDistance = ConfigFile::getKeyFloat("SharedCollision", "terrainLOSMinDistance", ms_terrainLOSMinDistance);
ms_terrainLOSMaxDistance = ConfigFile::getKeyFloat("SharedCollision", "terrainLOSMaxDistance", ms_terrainLOSMaxDistance);
}
// ----------------------------------------------------------------------
bool ConfigSharedCollision::getDrawFloors ( void ) { return ms_drawFloors; }
bool ConfigSharedCollision::getDrawExtents ( void ) { return ms_drawExtents; }
bool ConfigSharedCollision::getDrawCollisionNormals ( void ) { return ms_drawCollisionNormals; }
bool ConfigSharedCollision::getDrawSphereTrees ( void ) { return ms_drawSphereTrees; }
bool ConfigSharedCollision::getDrawPathNodes ( void ) { return ms_drawPathNodes; }
bool ConfigSharedCollision::getDrawBoxTrees ( void ) { return ms_drawBoxTrees; }
bool ConfigSharedCollision::getDrawCMeshes ( void ) { return ms_drawCMeshes; }
bool ConfigSharedCollision::getDrawFootprints ( void ) { return ms_drawFootprints; }
bool ConfigSharedCollision::getDrawCreatureLengths ( void ) { return ms_drawCreatureLengths; }
void ConfigSharedCollision::setDrawFloors ( bool draw ) { ms_drawFloors = draw; }
void ConfigSharedCollision::setDrawExtents ( bool draw ) { ms_drawExtents = draw; }
void ConfigSharedCollision::setDrawCollisionNormals ( bool draw ) { ms_drawCollisionNormals = draw; }
void ConfigSharedCollision::setDrawSphereTrees ( bool draw ) { ms_drawSphereTrees = draw; }
void ConfigSharedCollision::setDrawPathNodes ( bool draw ) { ms_drawPathNodes = draw; }
void ConfigSharedCollision::setDrawBoxTrees ( bool draw ) { ms_drawBoxTrees = draw; }
void ConfigSharedCollision::setDrawCMeshes ( bool draw ) { ms_drawCMeshes = draw; }
void ConfigSharedCollision::setDrawFootprints ( bool draw ) { ms_drawFootprints = draw; }
void ConfigSharedCollision::setDrawCreatureLengths ( bool draw ) { ms_drawCreatureLengths = draw; }
bool ConfigSharedCollision::getEnableStaticCollision ( void ) { return ms_enableStaticCollision; }
bool ConfigSharedCollision::getEnableFloraCollision ( void ) { return ms_enableFloraCollision; }
bool ConfigSharedCollision::getEnableFloorCollision ( void ) { return ms_enableFloorCollision; }
bool ConfigSharedCollision::getEnableCollisionResolve ( void ) { return ms_enableCollisionResolve; }
bool ConfigSharedCollision::getEnableCollisionFlags ( void ) { return ms_enableCollisionFlags; }
bool ConfigSharedCollision::getEnableCollisionValidate ( void ) { return ms_enableCollisionValidate; }
bool ConfigSharedCollision::getEnableRemoteCollision ( void ) { return ms_enableRemoteCollision; }
bool ConfigSharedCollision::getEnableTestCode ( void ) { return ms_enableTestCode; }
bool ConfigSharedCollision::getEnableCreatureCollision ( void ) { return ms_enableCreatureCollision; }
bool ConfigSharedCollision::getEnableIntraFrameTests ( void ) { return ms_enableIntraFrameTests; }
bool ConfigSharedCollision::getEnableMountRadii ( void ) { return ms_enableMountRadii; }
bool ConfigSharedCollision::getBuildBoxTrees ( void ) { return ms_buildBoxTrees; }
bool ConfigSharedCollision::getBuildDebugData ( void ) { return ms_buildDebugData; }
void ConfigSharedCollision::setBuildDebugData (bool val)
{
ms_buildDebugData = val;
}
bool ConfigSharedCollision::getReportStatus ( void ) { return ms_reportStatus; }
bool ConfigSharedCollision::getReportChanges ( void ) { return ms_reportChanges; }
bool ConfigSharedCollision::getReportMessages ( void ) { return ms_reportMessages; }
bool ConfigSharedCollision::getReportWarnings ( void ) { return ms_reportWarnings; }
bool ConfigSharedCollision::getReportEvents ( void ) { return ms_reportEvents; }
bool ConfigSharedCollision::getReportFloating ( void ) { return ms_reportFloating; }
bool ConfigSharedCollision::getLogLongFrames ( void ) { return ms_logLongFrames; }
bool ConfigSharedCollision::getIgnoreTerrainLos ( void ) { return ms_ignoreTerrainLos; }
bool ConfigSharedCollision::getGenerateTerrainLos ( void ) { return ms_generateTerrainLos; }
bool ConfigSharedCollision::getShoveEnabled ( void ) { return ms_shoveEnabled; }
float ConfigSharedCollision::getWallEpsilon ( void ) { return ms_wallEpsilon; }
float ConfigSharedCollision::getAreaEpsilon ( void ) { return ms_areaEpsilon; }
float ConfigSharedCollision::getHopHeight ( void ) { return ms_hopHeight; }
float ConfigSharedCollision::getTerrainLOSMinDistance ( void ) { return ms_terrainLOSMinDistance; }
float ConfigSharedCollision::getTerrainLOSMaxDistance ( void ) { return ms_terrainLOSMaxDistance; }
float ConfigSharedCollision::getLosUprightScale ( void ) { return ms_losUprightScale; }
float ConfigSharedCollision::getLosProneScale ( void ) { return ms_losProneScale; }
bool ConfigSharedCollision::isSpaceAiLoggingEnabled() { return ms_spaceAiLoggingEnabled; }
bool ConfigSharedCollision::useOriginalAvoidanceAlgorithm() { return ms_useOriginalAvoidanceAlgorithm; }
// ----------
void ConfigSharedCollision::setPlayEffectHook ( PlayEffectHook hook ) { ms_playEffectHook = hook; }
PlayEffectHook ConfigSharedCollision::getPlayEffectHook ( void ) { return ms_playEffectHook; }
void ConfigSharedCollision::setIsPlayerHouseHook ( IsPlayerHouseHook hook ) { ms_isPlayerHouseHook = hook; }
IsPlayerHouseHook ConfigSharedCollision::getIsPlayerHouseHook ( void) { return ms_isPlayerHouseHook; }
int ConfigSharedCollision::getSpatialSweepAndResolveDefaultMask()
{
return ms_spatialSweepAndResolveDefaultMask;
}
void ConfigSharedCollision::setSpatialSweepAndResolveDefaultMask(int queryMask)
{
ms_spatialSweepAndResolveDefaultMask = queryMask;
}
@@ -0,0 +1,108 @@
//===================================================================
//
// ConfigSharedCollision.h
// copyright 2000, verant interactive
//
//===================================================================
#ifndef INCLUDED_ConfigSharedCollision_H
#define INCLUDED_ConfigSharedCollision_H
class CrcLowerString;
class Object;
typedef bool (*PlayEffectHook)(CrcLowerString const & effectName, Object * object, CrcLowerString const & hardpoint );
typedef bool (*IsPlayerHouseHook)(Object const * object);
//===================================================================
class ConfigSharedCollision
{
public:
static void install ();
static bool getDrawFloors ( void );
static bool getDrawExtents ( void );
static bool getDrawCollisionNormals ( void );
static bool getDrawSphereTrees ( void );
static bool getDrawPathNodes ( void );
static bool getDrawBoxTrees ( void );
static bool getDrawCMeshes ( void );
static bool getDrawFootprints ( void );
static bool getDrawCreatureLengths ( void );
static void setDrawFloors ( bool draw );
static void setDrawExtents ( bool draw );
static void setDrawCollisionNormals ( bool draw );
static void setDrawSphereTrees ( bool draw );
static void setDrawPathNodes ( bool draw );
static void setDrawBoxTrees ( bool draw );
static void setDrawCMeshes ( bool draw );
static void setDrawFootprints ( bool draw );
static void setDrawCreatureLengths ( bool draw );
static bool getEnableStaticCollision ( void );
static bool getEnableFloraCollision ( void );
static bool getEnableFloorCollision ( void );
static bool getEnableCollisionResolve ( void );
static bool getEnableCollisionFlags ( void );
static bool getEnableCollisionValidate ( void );
static bool getEnableRemoteCollision ( void );
static bool getEnableTestCode ( void );
static bool getEnableCreatureCollision ( void ); // If enabled, the player will collide with mobs
static bool getEnableIntraFrameTests ( void );
static bool getEnableMountRadii ( void );
static bool getBuildBoxTrees ( void );
static bool getBuildDebugData ( void );
static void setBuildDebugData ( bool val );
static void setEnableCreatureCollision ( bool enable );
static bool getReportStatus ( void ); // Spam that goes to the debug window - # of objects in collision world, profiling
static bool getReportChanges ( void ); // Objects entering/leaving the collision world
static bool getReportMessages ( void ); // Debugging message spam
static bool getReportWarnings ( void ); // Possible errors in the collision system
static bool getReportEvents ( void ); // Game-relevant events - objects colliding
static bool getReportFloating ( void ); // whether objects are floating, when they start/stop floating
static bool getLogLongFrames ( void );
static bool getIgnoreTerrainLos ( void );
static bool getGenerateTerrainLos ( void );
static bool getShoveEnabled ( void );
static float getWallEpsilon ( void );
static float getAreaEpsilon ( void );
static float getHopHeight ( void );
static float getTerrainLOSMinDistance ( void );
static float getTerrainLOSMaxDistance ( void );
static float getLosUprightScale ( void );
static float getLosProneScale ( void );
// ----------
static void setPlayEffectHook ( PlayEffectHook hook );
static PlayEffectHook getPlayEffectHook ( void );
static void setIsPlayerHouseHook ( IsPlayerHouseHook hook );
static IsPlayerHouseHook getIsPlayerHouseHook ( void );
// SpatialSweepAndResolveDefaultMask deals with SpatialDatabase::Query masks
// the default is SpatialDatabase::Q_Static
static int getSpatialSweepAndResolveDefaultMask();
static void setSpatialSweepAndResolveDefaultMask(int queryMask);
static bool isSpaceAiLoggingEnabled();
static bool useOriginalAvoidanceAlgorithm();
private:
ConfigSharedCollision ();
ConfigSharedCollision (const ConfigSharedCollision&);
ConfigSharedCollision& operator= (const ConfigSharedCollision&);
};
//===================================================================
#endif

Some files were not shown because too many files have changed in this diff Show More