//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //----------------------------------------------------------------------------- #ifndef _COLLISION_H_ #define _COLLISION_H_ #ifndef _DATACHUNKER_H_ #include "core/dataChunker.h" #endif #ifndef _MPLANE_H_ #include "math/mPlane.h" #endif #ifndef _MPOINT2_H_ #include "math/mPoint2.h" #endif class SceneObject; class BaseMatInstance; //---------------------------------------------------------------------------- struct Collision { SceneObject* object; Point3F point; VectorF normal; BaseMatInstance* material; // generate UV coordinate across (TSStatic) mesh based on // matching normals, this isn't done by default and is // primarily of interest in matching a collision point to // either a GUI control coordinate or finding a hit pixel in texture space bool generateTexCoord; // If generateTexCoord is set this will either be invalid (-1, -1) // or a value in texture space (assuming 0..1 UV mapping) Point2F texCoord; // Face and Face dot are currently only set by the extrudedPolyList // clipper. Values are otherwise undefined. U32 face; // Which face was hit F32 faceDot; // -Dot of face with poly normal F32 distance; Collision() : object( NULL ), material( NULL ), generateTexCoord(false), texCoord(-1.0f, -1.0f), face(0), faceDot(0.0f), distance(0) { } }; class CollisionList { public: enum { MaxCollisions = 64 }; protected: dsize_t mCount; Collision mCollision[MaxCollisions]; F32 mT; // MaxHeight is currently only set by the extrudedPolyList // clipper. It represents the maximum vertex z value of // the returned collision surfaces. F32 mMaxHeight; public: // Constructor CollisionList( /* const dsize_t reserveSize = MaxCollisions */ ) : mCount( 0 ), mT( 0.0f ), mMaxHeight( 0.0f ) { } // Accessors S32 getCount() const { return mCount; } F32 getTime() const { return mT; } F32 getMaxHeight() const { return mMaxHeight; } const Collision &operator[] ( const dsize_t idx ) const { AssertFatal( idx < mCount, "Out of bounds index." ); return mCollision[idx]; } Collision &operator[] ( const dsize_t idx ) { AssertFatal( idx < mCount, "Out of bounds index." ); return mCollision[idx]; } // Increment does NOT reset the collision which it returns. It is the job of // the caller to make sure that the entry has data properly assigned to it. Collision &increment() { return mCollision[mCount++]; } void clear() { mCount = 0; } void setTime( const F32 t ) { mT = t; } void setMaxHeight( const F32 height ) { mMaxHeight = height; } }; //---------------------------------------------------------------------------- // BSP Collision tree // Solid nodes are represented by structures with NULL frontNode and // backNode pointers. The material field is only valid on a solid node. // There is no structure for empty nodes, frontNode or backNode // should be set to NULL to represent empty half-spaces. struct BSPNode { U32 material; PlaneF plane; BSPNode *frontNode, *backNode; }; typedef Chunker BSPTree; /// Extension of the collision structure to allow use with raycasting. /// @see Collision struct RayInfo : public Collision { RayInfo() : t(0), userData( NULL ) {} // The collision struct has object, point, normal & material. /// Distance along ray to contact point. F32 t; /// Set the point of intersection according to t and the given ray. /// /// Several pieces of code will not use ray information but rather rely /// on contact points directly, so it is a good thing to always set /// this in castRay functions. void setContactPoint( const Point3F& start, const Point3F& end ) { Point3F startToEnd = end - start; startToEnd *= t; point = startToEnd + start; } /// A generic data void pointer. /// Passing a void* around to random objects of unknown class types that may /// interpret it differently would be very dangerous. Only use userData when /// you call castRay/etc on an individual object of a known type. void *userData; }; #endif // _COLLISION_H_