mirror of
https://github.com/SWG-Source/src.git
synced 2026-07-29 23:15:56 -04:00
Added sharedCollision library
This commit is contained in:
@@ -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"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/CollideParameters.h"
|
||||
@@ -0,0 +1,2 @@
|
||||
#error obsolete
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/Collision2d.h"
|
||||
+1
@@ -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"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/CollisionNotification.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/CollisionProperty.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/CollisionResolve.h"
|
||||
+1
@@ -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"
|
||||
+1
@@ -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"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/FirstSharedCollision.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/Floor.h"
|
||||
+1
@@ -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"
|
||||
+1
@@ -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"
|
||||
+1
@@ -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"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/SetupSharedCollision.h"
|
||||
+1
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/core/SimpleCollisionMesh.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../src/shared/extent/SimpleExtent.h"
|
||||
+1
@@ -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
Reference in New Issue
Block a user