[Python-ogre-commit] SF.net SVN: python-ogre:[753] trunk/python-ogre
Brought to you by:
andy_miller,
roman_yakovenko
From: <and...@us...> - 2008-10-05 07:09:43
|
Revision: 753 http://python-ogre.svn.sourceforge.net/python-ogre/?rev=753&view=rev Author: andy_miller Date: 2008-10-05 07:08:22 +0000 (Sun, 05 Oct 2008) Log Message: ----------- Changed all code generation modules to use the common_code Auto_Functional_Transformation function Fix auto transform funtion to not wrap reference arguments that are const (bug) Fix auto transform funtion to handle extern free functions Removed 'asClassType' functions as they didn't actually do anything (and are not needed) Added PSSM camera functionality - it was missing from the sizeof.h file Added helper functions to OgreODE as constructors needed hand wrapping Fix to Py++ to handle bool/int references correctly (renderQueueListener functions) Simplified Ogre patch file requirements due to fix in Py++ for bool refs Fixed a couple of incorrect versions in environment.py Added opensteer source code and inital wrapper -- not done yet Modified Paths: -------------- trunk/python-ogre/ChangeLog.txt trunk/python-ogre/PythonOgreConfig_nt.py trunk/python-ogre/ThirdParty/Hydrax/Hydrax.h trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.cpp trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.h trunk/python-ogre/ThirdParty/caelum/SkyLight.cpp trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIManager.cpp trunk/python-ogre/ThirdParty/quickgui/QuickGUIManager.h trunk/python-ogre/code_generators/bullet/generate_code.py trunk/python-ogre/code_generators/cadunetree/generate_code.py trunk/python-ogre/code_generators/caelum/generate_code.py trunk/python-ogre/code_generators/common_utils/__init__.py trunk/python-ogre/code_generators/common_utils/ogre_properties.py trunk/python-ogre/code_generators/et/generate_code.py trunk/python-ogre/code_generators/hikari/generate_code.py trunk/python-ogre/code_generators/hydrax/generate_code.py trunk/python-ogre/code_generators/noise/generate_code.py trunk/python-ogre/code_generators/nxogre/generate_code.py trunk/python-ogre/code_generators/ode/generate_code.py trunk/python-ogre/code_generators/ofusion/generate_code.py trunk/python-ogre/code_generators/ogre/generate_code.py trunk/python-ogre/code_generators/ogre/hand_made_wrappers.py trunk/python-ogre/code_generators/ogre/python_ogre_aliases.h trunk/python-ogre/code_generators/ogre/python_ogre_sizeof.h trunk/python-ogre/code_generators/ogreal/generate_code.py trunk/python-ogre/code_generators/ogrebulletc/generate_code.py trunk/python-ogre/code_generators/ogrebulletd/generate_code.py trunk/python-ogre/code_generators/ogreforests/generate_code.py trunk/python-ogre/code_generators/ogreode/generate_code.py trunk/python-ogre/code_generators/ogreode/hand_made_wrappers.py trunk/python-ogre/code_generators/ogrepcz/generate_code.py trunk/python-ogre/code_generators/ois/generate_code.py trunk/python-ogre/code_generators/particleuniverse/generate_code.py trunk/python-ogre/code_generators/quickgui/generate_code.py trunk/python-ogre/code_generators/watermesh/generate_code.py trunk/python-ogre/demos/ogre/Demo_CameraTracking.py trunk/python-ogre/demos/ogre/Demo_Shadows.py trunk/python-ogre/demos/ogre/Demo_SkeletalAnimation.py trunk/python-ogre/demos/ogre/tests/Test_RenderQueue.py trunk/python-ogre/demos/ogre/tests/Test_TextureGetByName.py trunk/python-ogre/demos/ogrebullet/Demo_OgreCollision01.py trunk/python-ogre/environment.py Added Paths: ----------- trunk/python-ogre/ThirdParty/opensteer/Camera.cpp trunk/python-ogre/ThirdParty/opensteer/Clock.cpp trunk/python-ogre/ThirdParty/opensteer/Color.cpp trunk/python-ogre/ThirdParty/opensteer/Obstacle.cpp trunk/python-ogre/ThirdParty/opensteer/OldPathway.cpp trunk/python-ogre/ThirdParty/opensteer/OpenSteer/ trunk/python-ogre/ThirdParty/opensteer/OpenSteer/AbstractVehicle.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Annotation.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Camera.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Clock.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Color.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/LocalSpace.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Obstacle.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/OldPathway.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Path.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Pathway.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/PolylineSegmentedPath.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/PolylineSegmentedPathwaySegmentRadii.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/PolylineSegmentedPathwaySingleRadius.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Proximity.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/QueryPathAlike.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/QueryPathAlikeBaseDataExtractionPolicies.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/QueryPathAlikeMappings.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/QueryPathAlikeUtilities.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/SegmentedPath.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/SegmentedPathAlikeUtilities.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/SegmentedPathway.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/SharedPointer.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/SimpleVehicle.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/StandardTypes.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/SteerLibrary.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/UnusedParameter.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Utilities.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Vec3.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/Vec3Utilities.h trunk/python-ogre/ThirdParty/opensteer/OpenSteer/lq.h trunk/python-ogre/ThirdParty/opensteer/Path.cpp trunk/python-ogre/ThirdParty/opensteer/Pathway.cpp trunk/python-ogre/ThirdParty/opensteer/PolylineSegmentedPath.cpp trunk/python-ogre/ThirdParty/opensteer/PolylineSegmentedPathwaySegmentRadii.cpp trunk/python-ogre/ThirdParty/opensteer/PolylineSegmentedPathwaySingleRadius.cpp trunk/python-ogre/ThirdParty/opensteer/SegmentedPath.cpp trunk/python-ogre/ThirdParty/opensteer/SegmentedPathway.cpp trunk/python-ogre/ThirdParty/opensteer/SimpleVehicle.cpp trunk/python-ogre/ThirdParty/opensteer/Vec3.cpp trunk/python-ogre/ThirdParty/opensteer/Vec3Utilities.cpp trunk/python-ogre/ThirdParty/opensteer/lq.c trunk/python-ogre/code_generators/opensteer/ trunk/python-ogre/code_generators/opensteer/customization_data.py trunk/python-ogre/code_generators/opensteer/generate_code.py trunk/python-ogre/code_generators/opensteer/hand_made_wrappers.py trunk/python-ogre/code_generators/opensteer/python_opensteer.h trunk/python-ogre/code_generators/opensteer/python_opensteer_aliases.h trunk/python-ogre/code_generators/opensteer/python_opensteer_sizeof.h trunk/python-ogre/patch/ogre_1.6.0RC2.patch trunk/python-ogre/scripts/MakeOgrePatch.bat trunk/python-ogre/scripts/ogre.excludes Modified: trunk/python-ogre/ChangeLog.txt =================================================================== --- trunk/python-ogre/ChangeLog.txt 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/ChangeLog.txt 2008-10-05 07:08:22 UTC (rev 753) @@ -1,6 +1,15 @@ xxxx xx 2008 : Release 1.6.0 xxxx ================================== - +Changed all code generation modules to use the common_code Auto_Functional_Transformation function +Fix auto transform funtion to not wrap reference arguments that are const (bug) +Fix auto transform funtion to handle extern free functions +Removed 'asClassType' functions as they didn't actually do anything (and are not needed) +Added PSSM camera functionality - it was missing from the sizeof.h file +Added helper functions to OgreODE as constructors needed hand wrapping +Fix to Py++ to handle bool/int references correctly (renderQueueListener functions) +Simplified Ogre patch file requirements due to fix in Py++ for bool refs +Fixed a couple of incorrect versions in environment.py +Added opensteer source code and inital wrapper -- not done yet Updates to QuickGUI and Caelum C++ library source Implemented Hikari demo (implemented callbacks in the wrapper generation) Fixed code generation for QuickGui, bullet and noise to correctly generate PyDoc documentation strings Modified: trunk/python-ogre/PythonOgreConfig_nt.py =================================================================== --- trunk/python-ogre/PythonOgreConfig_nt.py 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/PythonOgreConfig_nt.py 2008-10-05 07:08:22 UTC (rev 753) @@ -30,7 +30,7 @@ # We need to know where to find gccxml...... gccxml_bin = os.path.join(BASE_DIR, 'gccxml/bin/release/gccxml.exe') # and the Py++ directory as sometimes we need access to the code repository there -pyplusplus_install_dir = os.path.join(BASE_DIR, 'pygccxml') +pyplusplus_install_dir = os.path.join(BASE_DIR, 'pyplusplus') ## Parent directories of the libraries PATH_THIRDPARTY = os.path.join(module_dir, 'ThirdParty' ) Modified: trunk/python-ogre/ThirdParty/Hydrax/Hydrax.h =================================================================== --- trunk/python-ogre/ThirdParty/Hydrax/Hydrax.h 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/ThirdParty/Hydrax/Hydrax.h 2008-10-05 07:08:22 UTC (rev 753) @@ -537,7 +537,7 @@ public: /** Called at the start of the queue */ - bool renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool skipThisInvocation) + void renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) { if ((queueGroupId == Ogre::RENDER_QUEUE_SKIES_EARLY || queueGroupId == Ogre::RENDER_QUEUE_SKIES_LATE) && mActive) @@ -545,12 +545,11 @@ mHydrax->getCamera()->disableCustomNearClipPlane(); Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mHydrax->getCamera()->getProjectionMatrixRS()); } - return skipThisInvocation; } /** Called on the end of the queue */ - bool renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool skipThisInvocation) + void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) { if ((queueGroupId == Ogre::RENDER_QUEUE_SKIES_EARLY || queueGroupId == Ogre::RENDER_QUEUE_SKIES_LATE) && mActive) @@ -558,7 +557,6 @@ mHydrax->getCamera()->enableCustomNearClipPlane(mHydrax->mReflectionPlane); Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mHydrax->getCamera()->getProjectionMatrixRS()); } - return skipThisInvocation; } /// Hydrax pointer Modified: trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h =================================================================== --- trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/ThirdParty/caelum/CaelumPrerequisites.h 2008-10-05 07:08:22 UTC (rev 753) @@ -31,21 +31,21 @@ #include <memory> // Define the dll export qualifier if compiling for Windows -#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 +// #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 // #ifdef CAELUM_LIB // #define CAELUM_EXPORT __declspec (dllexport) // #else // #ifdef __MINGW32__ - #define CAELUM_EXPORT +// #define CAELUM_EXPORT // #else // #define CAELUM_EXPORT __declspec (dllimport) // #endif // #endif -#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE - #define CAELUM_EXPORT __attribute__ ((visibility("default"))) -#else +// #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE +// #define CAELUM_EXPORT __attribute__ ((visibility("default"))) +// #else #define CAELUM_EXPORT -#endif +// #endif // Define the version code #define CAELUM_VERSION_MAIN 0 Modified: trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.cpp =================================================================== --- trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.cpp 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.cpp 2008-10-05 07:08:22 UTC (rev 753) @@ -180,13 +180,13 @@ void FlatCloudLayer::setCloudBlendPos (const Ogre::Real value) { mCloudBlendPos = value; - uint textureCount = mNoiseTextureNames.size(); + int textureCount = static_cast<int>(mNoiseTextureNames.size()); // Convert to int and bring to [0, textureCount) int currentTextureIndex = static_cast<int>(floor(mCloudBlendPos)); currentTextureIndex = ((currentTextureIndex % textureCount) + textureCount) % textureCount; assert(0 <= currentTextureIndex); - assert(currentTextureIndex < static_cast<int>(textureCount)); + assert(currentTextureIndex < textureCount); // Check if we have to change textures. if (currentTextureIndex != mCurrentTextureIndex) { Modified: trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.h =================================================================== --- trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.h 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/ThirdParty/caelum/FlatCloudLayer.h 2008-10-05 07:08:22 UTC (rev 753) @@ -107,7 +107,7 @@ /** Gets cloud movement speed. * @param cloudSpeed Cloud movement speed. */ - Ogre::Vector2 getCloudSpeed () const; + Ogre::Vector2 getCloudSpeed () const { return mCloudSpeed; } /** Sets cloud cover, between 0 (completely clear) and 1 (completely covered) * @param cloudCover Cloud cover between 0 and 1 Modified: trunk/python-ogre/ThirdParty/caelum/SkyLight.cpp =================================================================== --- trunk/python-ogre/ThirdParty/caelum/SkyLight.cpp 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/ThirdParty/caelum/SkyLight.cpp 2008-10-05 07:08:22 UTC (rev 753) @@ -42,8 +42,6 @@ mMainLight = sceneMgr->createLight (lightName); mMainLight->setType (Ogre::Light::LT_DIRECTIONAL); - // HDR power scale, REALLY bright: - mMainLight->setPowerScale (10); sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_SUN)->setShadowsEnabled(false); Modified: trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp =================================================================== --- trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp 2008-09-29 05:02:26 UTC (rev 752) +++ trunk/python-ogre/ThirdParty/forests/BatchedGeometry.cpp 2008-10-05 07:08:22 UTC (rev 753) @@ -119,7 +119,6 @@ uint16 *data = (uint16*)id->indexBuffer->lock(id->indexStart * sizeof(uint16), id->indexCount * sizeof(uint16), HardwareBuffer::HBL_READ_ONLY); - std::map<uint16, uint32> histogram; for (i = 0; i < id->indexCount; i++) { uint16 index = data[i]; if (ibmap.find(index) == ibmap.end()) ibmap[index] = ibmap.size(); @@ -134,7 +133,6 @@ uint32 *data = (uint32*)id->indexBuffer->lock(id->indexStart * sizeof(uint32), id->indexCount * sizeof(uint32), HardwareBuffer::HBL_READ_ONLY); - std::map<uint32, uint32> histogram; for (i = 0; i < id->indexCount; i++) { uint32 index = data[i]; if (ibmap.find(index) == ibmap.end()) ibmap[index] = ibmap.size(); Added: trunk/python-ogre/ThirdParty/opensteer/Camera.cpp =================================================================== --- trunk/python-ogre/ThirdParty/opensteer/Camera.cpp (rev 0) +++ trunk/python-ogre/ThirdParty/opensteer/Camera.cpp 2008-10-05 07:08:22 UTC (rev 753) @@ -0,0 +1,433 @@ +// ---------------------------------------------------------------------------- +// +// +// OpenSteer -- Steering Behaviors for Autonomous Characters +// +// Copyright (c) 2002-2005, Sony Computer Entertainment America +// Original author: Craig Reynolds <cra...@pl...> +// +// 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. +// +// +// ---------------------------------------------------------------------------- +// +// +// camera control for OpenSteerDemo +// +// a camera ("point of view") with various "aiming modes" to track a +// moving vehicle +// +// 10-04-04 bk: put everything into the OpenSteer namespace +// 06-26-02 cwr: created +// +// +// ---------------------------------------------------------------------------- + + +#include "OpenSteer/Camera.h" +#include "OpenSteer/Draw.h" + + +// ---------------------------------------------------------------------------- +// constructor + + +OpenSteer::Camera::Camera (void) +{ + reset (); +} + + +// ---------------------------------------------------------------------------- +// reset all camera state to default values + + +void +OpenSteer::Camera::reset (void) +{ + // reset camera's position and orientation + resetLocalSpace (); + + // "look at" point, center of view + target = Vec3::zero; + + // vehicle being tracked + vehicleToTrack = NULL; + + // aim at predicted position of vehicleToTrack, this far into thefuture + aimLeadTime = 1; + + // make first update abrupt + smoothNextMove = false; + + // relative rate at which camera transitions proceed + smoothMoveSpeed = 1.5f; + + // select camera aiming mode + mode = cmFixed; + + // "constant distance from vehicle" camera mode parameters + fixedDistDistance = 1; + fixedDistVOffset = 0; + + // "look straight down at vehicle" camera mode parameters + lookdownDistance = 30; + + // "static" camera mode parameters + fixedPosition.set (75, 75, 75); + fixedTarget = Vec3::zero; + fixedUp = Vec3::up; + + // "fixed local offset" camera mode parameters + fixedLocalOffset.set (5, 5, -5); + + // "offset POV" camera mode parameters + povOffset.set (0, 1, -3); +} + + +// ---------------------------------------------------------------------------- +// called once per frame to update camera state according to currently +// selected mode and per-mode parameters. Works in position/target/up +// ("look at") space. +// +// parameter names commented out to prevent compiler warning from "-W" + + +void +OpenSteer::Camera::update (const float /*currentTime*/, + const float elapsedTime, + const bool simulationPaused) +{ + // vehicle being tracked (just a reference with a more concise name) + const AbstractVehicle& v = *vehicleToTrack; + const bool noVehicle = vehicleToTrack == NULL; + + // new position/target/up, set in switch below, defaults to current + Vec3 newPosition = position(); + Vec3 newTarget = target; + Vec3 newUp = up(); + + + // prediction time to compensate for lag caused by smoothing moves + const float antiLagTime = simulationPaused ? 0 : 1 / smoothMoveSpeed; + + // aim at a predicted future position of the target vehicle + const float predictionTime = aimLeadTime + antiLagTime; + + // set new position/target/up according to camera aim mode + switch (mode) + { + case cmFixed: + newPosition = fixedPosition; + newTarget = fixedTarget; + newUp = fixedUp; + break; + + case cmFixedDistanceOffset: + if (noVehicle) break; + newUp = Vec3::up; // xxx maybe this should be v.up ? + newTarget = v.predictFuturePosition (predictionTime); + newPosition = constDistHelper (elapsedTime); + break; + + case cmStraightDown: + if (noVehicle) break; + newUp = v.forward(); + newTarget = v.predictFuturePosition (predictionTime); + newPosition = newTarget; + newPosition.y += lookdownDistance; + break; + + case cmFixedLocalOffset: + if (noVehicle) break; + newUp = v.up(); + newTarget = v.predictFuturePosition (predictionTime); + newPosition = v.globalizePosition (fixedLocalOffset); + break; + + case cmOffsetPOV: + { + if (noVehicle) break; + newUp = v.up(); + const Vec3 futurePosition = v.predictFuturePosition (antiLagTime); + const Vec3 globalOffset = v.globalizeDirection (povOffset); + newPosition = futurePosition + globalOffset; + // XXX hack to improve smoothing between modes (no effect on aim) + const float L = 10; + newTarget = newPosition + (v.forward() * L); + break; + } + default: + break; + } + + // blend from current position/target/up towards new values + smoothCameraMove (newPosition, newTarget, newUp, elapsedTime); + + // set camera in draw module + drawCameraLookAt (position(), target, up()); +} + + +// ---------------------------------------------------------------------------- +// Smoothly move camera: blend (at a rate controlled by smoothMoveSpeed) +// from current camera state toward newly determined camera state. +// +// The flag smoothNextMove can be set (with doNotSmoothNextMove()) to +// make next update (say at simulation initialization time). + + +void +OpenSteer::Camera::smoothCameraMove (const Vec3& newPosition, + const Vec3& newTarget, + const Vec3& newUp, + const float elapsedTime) +{ + if (smoothNextMove) + { + const float smoothRate = elapsedTime * smoothMoveSpeed; + + Vec3 tempPosition = position(); + Vec3 tempUp = up(); + blendIntoAccumulator (smoothRate, newPosition, tempPosition); + blendIntoAccumulator (smoothRate, newTarget, target); + blendIntoAccumulator (smoothRate, newUp, tempUp); + setPosition (tempPosition); + setUp (tempUp); + + // xxx not sure if these are needed, seems like a good idea + // xxx (also if either up or oldUP are zero, use the other?) + // xxx (even better: force up to be perp to target-position axis)) + if (up() == Vec3::zero) + setUp (Vec3::up); + else + setUp (up().normalize ()); + } + else + { + smoothNextMove = true; + + setPosition (newPosition); + target = newTarget; + setUp (newUp); + } +} + + +// ---------------------------------------------------------------------------- +// computes a new camera position which follows "target" at distant of +// "dragTargetDistance" +// +// parameter names commented out to prevent compiler warning from "-W" + + +OpenSteer::Vec3 +OpenSteer::Camera::constDistHelper (const float /*elapsedTime*/) +{ + // is the "global up"/"vertical" offset constraint enabled? (it forces + // the camera's global-up (Y) cordinate to be a above/below the target + // vehicle by a given offset.) + const bool constrainUp = (fixedDistVOffset != 0); + + // vector offset from target to current camera position + const Vec3 adjustedPosition (position().x, + (constrainUp) ? target.y : position().y, + position().z); + const Vec3 offset = adjustedPosition - target; + + // current distance between them + const float distance = offset.length(); + + // move camera only when geometry is well-defined (avoid degenerate case) + if (distance == 0) + { + return position(); + } + else + { + // unit vector along original offset + const Vec3 unitOffset = offset / distance; + + // new offset of length XXX + const float xxxDistance = sqrtXXX (square (fixedDistDistance) - + square (fixedDistVOffset)); + const Vec3 newOffset = unitOffset * xxxDistance; + + // return new camera position: adjust distance to target + return target + newOffset + Vec3 (0, fixedDistVOffset, 0); + } +} + + +// ---------------------------------------------------------------------------- +// select next camera mode, used by OpenSteerDemo + + +void +OpenSteer::Camera::selectNextMode (void) +{ + mode = successorMode (mode); + if (mode >= cmEndMode) mode = successorMode (cmStartMode); +} + + +// ---------------------------------------------------------------------------- +// cycles through the various camera modes + + +OpenSteer::Camera::cameraMode +OpenSteer::Camera::successorMode (const cameraMode cm) const +{ + return (cameraMode)(((int)cm) + 1); +} + + +// ---------------------------------------------------------------------------- +// string naming current camera mode, used by OpenSteerDemo + + +char* +OpenSteer::Camera::modeName (void) +{ + switch (mode) + { + case cmFixed: return "static"; break; + case cmFixedDistanceOffset: return "fixed distance offset"; break; + case cmFixedLocalOffset: return "fixed local offset"; break; + case cmOffsetPOV: return "offset POV"; break; + case cmStraightDown: return "straight down"; break; + default: return "?"; + } +} + + +// ---------------------------------------------------------------------------- +// adjust the offest vector of the current camera mode based on a +// "mouse adjustment vector" from OpenSteerDemo (xxx experiment 10-17-02) + + +void +OpenSteer::Camera::mouseAdjustOffset (const Vec3& adjustment) +{ + // vehicle being tracked (just a reference with a more concise name) + const AbstractVehicle& v = *vehicleToTrack; + + switch (mode) + { + case cmFixed: + { + const Vec3 offset = fixedPosition - fixedTarget; + const Vec3 adjusted = mouseAdjustPolar (adjustment, offset); + fixedPosition = fixedTarget + adjusted; + break; + } + case cmFixedDistanceOffset: + { + // XXX this is the oddball case, adjusting "position" instead + // XXX of mode parameters, hence no smoothing during adjustment + // XXX Plus the fixedDistVOffset feature complicates things + const Vec3 offset = position() - target; + const Vec3 adjusted = mouseAdjustPolar (adjustment, offset); + // XXX -------------------------------------------------- +// position = target + adjusted; +// fixedDistDistance = adjusted.length(); +// fixedDistVOffset = position.y - target.y; + // XXX -------------------------------------------------- +// const float s = smoothMoveSpeed * (1.0f/40f); +// const Vec3 newPosition = target + adjusted; +// position = interpolate (s, position, newPosition); +// fixedDistDistance = interpolate (s, fixedDistDistance, adjusted.length()); +// fixedDistVOffset = interpolate (s, fixedDistVOffset, position.y - target.y); + // XXX -------------------------------------------------- +// position = target + adjusted; + setPosition (target + adjusted); + fixedDistDistance = adjusted.length(); +// fixedDistVOffset = position.y - target.y; + fixedDistVOffset = position().y - target.y; + // XXX -------------------------------------------------- + break; + } + case cmStraightDown: + { + const Vec3 offset (0, 0, lookdownDistance); + const Vec3 adjusted = mouseAdjustPolar (adjustment, offset); + lookdownDistance = adjusted.z; + break; + } + case cmFixedLocalOffset: + { + const Vec3 offset = v.globalizeDirection (fixedLocalOffset); + const Vec3 adjusted = mouseAdjustPolar (adjustment, offset); + fixedLocalOffset = v.localizeDirection (adjusted); + break; + } + case cmOffsetPOV: + { + // XXX this might work better as a translation control, it is + // XXX non-obvious using a polar adjustment when the view + // XXX center is not at the camera aim target + const Vec3 offset = v.globalizeDirection (povOffset); + const Vec3 adjusted = mouseAdjustOrtho (adjustment, offset); + povOffset = v.localizeDirection (adjusted); + break; + } + default: + break; + } +} + + +// ---------------------------------------------------------------------------- + + +OpenSteer::Vec3 +OpenSteer::Camera::mouseAdjust2 (const bool polar, + const Vec3& adjustment, + const Vec3& offsetToAdjust) +{ + // value to be returned + Vec3 result = offsetToAdjust; + + // using the camera's side/up axes (essentially: screen space) move the + // offset vector sideways according to adjustment.x and vertically + // according to adjustment.y, constrain the offset vector's length to + // stay the same, hence the offset's "tip" stays on the surface of a + // sphere. + const float oldLength = result.length (); + const float rate = polar ? oldLength : 1; + result += xxxls().side() * (adjustment.x * rate); + result += xxxls().up() * (adjustment.y * rate); + if (polar) + { + const float newLength = result.length (); + result *= oldLength / newLength; + } + + // change the length of the offset vector according to adjustment.z + if (polar) + result *= (1 + adjustment.z); + else + result += xxxls().forward() * adjustment.z; + + return result; +} + + +// ---------------------------------------------------------------------------- Added: trunk/python-ogre/ThirdParty/opensteer/Clock.cpp =================================================================== --- trunk/python-ogre/ThirdParty/opensteer/Clock.cpp (rev 0) +++ trunk/python-ogre/ThirdParty/opensteer/Clock.cpp 2008-10-05 07:08:22 UTC (rev 753) @@ -0,0 +1,310 @@ +// ---------------------------------------------------------------------------- +// +// +// OpenSteer -- Steering Behaviors for Autonomous Characters +// +// Copyright (c) 2002-2005, Sony Computer Entertainment America +// Original author: Craig Reynolds <cra...@pl...> +// +// 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. +// +// +// ---------------------------------------------------------------------------- +// +// +// discrete time simulation clock for OpenSteerDemo +// +// Keeps track of real clock time and simulation time. Encapsulates OS's +// time API. Can be put in either "as fast as possible" variable time step +// mode (where simulation time steps are based on real time elapsed between +// updates), or in fixed "target FPS" mode where the simulation steps are +// constrained to start on 1/FPS boundaries (e.g. on a 60 hertz video game +// console). Also handles the notion of "pausing" simulation time. +// +// Usage: allocate a clock, set its "paused" or "targetFPS" parameters, +// then call updateGlobalSimulationClock before each simulation step. +// +// 10-04-04 bk: put everything into the OpenSteer namespace +// 09-24-02 cwr: major overhaul +// 06-26-02 cwr: created +// +// +// ---------------------------------------------------------------------------- + + +#include "OpenSteer/Clock.h" + + +// ---------------------------------------------------------------------------- +// XXX This is a bit ad hoc. Need to revisit conditionalization on operating +// XXX system. As of 5-5-03, this module knows about Win32 (code thanks to +// XXX Leaf Garland and Bruce Mitchener) and Linux/Unix (Craig's original +// XXX version). It tests for Xbox and Win32 and assumes Linux/Unix +// XXX otherwise. + + +#if defined (_XBOX) + #include <xtl.h> +#elif defined (_WIN32) + #include <windows.h> +#else + #include <sys/time.h> +#endif + + +// ---------------------------------------------------------------------------- +// Constructor + + +OpenSteer::Clock::Clock (void) +{ + // default is "real time, variable frame rate" and not paused + setFixedFrameRate (0); + setPausedState (false); + setAnimationMode (false); + setVariableFrameRateMode (true); + + // real "wall clock" time since launch + totalRealTime = 0; + + // time simulation has run + totalSimulationTime = 0; + + // time spent paused + totalPausedTime = 0; + + // sum of (non-realtime driven) advances to simulation time + totalAdvanceTime = 0; + + // interval since last simulation time + elapsedSimulationTime = 0; + + // interval since last clock update time + elapsedRealTime = 0; + + // interval since last clock update, + // exclusive of time spent waiting for frame boundary when targetFPS>0 + elapsedNonWaitRealTime = 0; + + // "manually" advance clock by this amount on next update + newAdvanceTime = 0; + + // "Calendar time" when this clock was first updated +#ifdef _WIN32 + basePerformanceCounter = 0; // from QueryPerformanceCounter on Windows +#else + baseRealTimeSec = 0; // from gettimeofday on Linux and Mac OS X + baseRealTimeUsec = 0; +#endif + + // clock keeps track of "smoothed" running average of recent frame rates. + // When a fixed frame rate is used, a running average of "CPU load" is + // kept (aka "non-wait time", the percentage of each frame time (time + // step) that the CPU is busy). + smoothedFPS = 0; + smoothedUsage = 0; +} + + +// ---------------------------------------------------------------------------- +// update this clock, called once per simulation step ("frame") to: +// +// track passage of real time +// manage passage of simulation time (modified by Paused state) +// measure time elapsed between time updates ("frame rate") +// optionally: "wait" for next realtime frame boundary + + +void +OpenSteer::Clock::update (void) +{ + // keep track of average frame rate and average usage percentage + updateSmoothedRegisters (); + + // wait for next frame time (when targetFPS>0) + // XXX should this be at the end of the update function? + frameRateSync (); + + // save previous real time to measure elapsed time + const float previousRealTime = totalRealTime; + + // real "wall clock" time since this application was launched + totalRealTime = realTimeSinceFirstClockUpdate (); + + // time since last clock update + elapsedRealTime = totalRealTime - previousRealTime; + + // accumulate paused time + if (paused) totalPausedTime += elapsedRealTime; + + // save previous simulation time to measure elapsed time + const float previousSimulationTime = totalSimulationTime; + + // update total simulation time + if (getAnimationMode ()) + { + // for "animation mode" use fixed frame time, ignore real time + const float frameDuration = 1.0f / getFixedFrameRate (); + totalSimulationTime += paused ? newAdvanceTime : frameDuration; + if (!paused) newAdvanceTime += frameDuration - elapsedRealTime; + } + else + { + // new simulation time is total run time minus time spent paused + totalSimulationTime = (totalRealTime + + totalAdvanceTime + - totalPausedTime); + } + + + // update total "manual advance" time + totalAdvanceTime += newAdvanceTime; + + // how much time has elapsed since the last simulation step? + elapsedSimulationTime = (paused ? + newAdvanceTime : + (totalSimulationTime - previousSimulationTime)); + + // reset advance amount + newAdvanceTime = 0; +} + + +// ---------------------------------------------------------------------------- +// "wait" until next frame time (actually spin around this tight loop) +// +// +// (xxx there are probably a smarter ways to do this (using events or +// thread waits (eg usleep)) but they are likely to be unportable. xxx) + + +void +OpenSteer::Clock::frameRateSync (void) +{ + // when in real time fixed frame rate mode + // (not animation mode and not variable frame rate mode) + if ((! getAnimationMode ()) && (! getVariableFrameRateMode ())) + { + // find next (real time) frame start time + const float targetStepSize = 1.0f / getFixedFrameRate (); + const float now = realTimeSinceFirstClockUpdate (); + const int lastFrameCount = (int) (now / targetStepSize); + const float nextFrameTime = (lastFrameCount + 1) * targetStepSize; + + // record usage ("busy time", "non-wait time") for OpenSteerDemo app + elapsedNonWaitRealTime = now - totalRealTime; + + // wait until next frame time + do {} while (realTimeSinceFirstClockUpdate () < nextFrameTime); + } +} + + +// ---------------------------------------------------------------------------- +// force simulation time ahead, ignoring passage of real time. +// Used for OpenSteerDemo's "single step forward" and animation mode + + +float +OpenSteer::Clock::advanceSimulationTimeOneFrame (void) +{ + // decide on what frame time is (use fixed rate, average for variable rate) + const float fps = (getVariableFrameRateMode () ? + getSmoothedFPS () : + getFixedFrameRate ()); + const float frameTime = 1 / fps; + + // bump advance time + advanceSimulationTime (frameTime); + + // return the time value used (for OpenSteerDemo) + return frameTime; +} + + +void +OpenSteer::Clock::advanceSimulationTime (const float seconds) +{ + if (seconds < 0) { + /// @todo - throw? how to handle error conditions? Not by crashing an app! + std::cerr << "negative arg to advanceSimulationTime - results will not be valid"; + } + else + newAdvanceTime += seconds; +} + + +namespace { + +// ---------------------------------------------------------------------------- +// Returns the number of seconds of real time (represented as a float) since +// the clock was first updated. +// +// XXX Need to revisit conditionalization on operating system. + + + + float + clockErrorExit (void) + { + /// @todo - throw? how to handle error conditions? Not by crashing an app! + std::cerr << "Problem reading system clock - results will not be valid"; + return 0.0f; + } + +} // anonymous namespace + +float +OpenSteer::Clock::realTimeSinceFirstClockUpdate (void) +#ifdef _WIN32 +{ + // get time from Windows + LONGLONG counter, frequency; + bool clockOK = (QueryPerformanceCounter ((LARGE_INTEGER *)&counter) && + QueryPerformanceFrequency ((LARGE_INTEGER *)&frequency)); + if (!clockOK) return clockErrorExit (); + + // ensure the base counter is recorded once after launch + if (basePerformanceCounter == 0) basePerformanceCounter = counter; + + // real "wall clock" time since launch + const LONGLONG counterDifference = counter - basePerformanceCounter; + return ((float) counterDifference) / ((float)frequency); +} +#else +{ + // get time from Linux (Unix, Mac OS X, ...) + timeval t; + if (gettimeofday (&t, 0) != 0) return clockErrorExit (); + + // ensure the base time is recorded once after launch + if (baseRealTimeSec == 0) + { + baseRealTimeSec = t.tv_sec; + baseRealTimeUsec = t.tv_usec; + } + + // real "wall clock" time since launch + return (( t.tv_sec - baseRealTimeSec) + + ((t.tv_usec - baseRealTimeUsec) / 1000000.0f)); +} +#endif + + +// ---------------------------------------------------------------------------- Added: trunk/python-ogre/ThirdParty/opensteer/Color.cpp =================================================================== --- trunk/python-ogre/ThirdParty/opensteer/Color.cpp (rev 0) +++ trunk/python-ogre/ThirdParty/opensteer/Color.cpp 2008-10-05 07:08:22 UTC (rev 753) @@ -0,0 +1,262 @@ +// ---------------------------------------------------------------------------- +// +// +// OpenSteer -- Steering Behaviors for Autonomous Characters +// +// Copyright (c) 2002-2005, Sony Computer Entertainment America +// Original author: Craig Reynolds <cra...@pl...> +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// +// ---------------------------------------------------------------------------- + +#include "OpenSteer/Color.h" + +// Include OpenSteer::Vec3 +#include "OpenSteer/Vec3.h" + +// Include assert +#include <cassert> + + +OpenSteer::Color::Color() + : r_(1.0f), g_(1.0f), b_(1.0f), a_ (1.0f) +{ + +} + + +OpenSteer::Color::Color( float greyValue ) + : r_( greyValue ), g_( greyValue ), b_( greyValue ), a_ (1.0f) +{ + +} + + +OpenSteer::Color::Color( float rValue, float gValue, float bValue, float aValue ) + : r_( rValue ), g_( gValue ), b_( bValue ), a_( aValue ) +{ + +} + + +OpenSteer::Color::Color( Vec3 const& vector ) + : r_( vector.x ), g_( vector.y ), b_( vector.z ), a_ (1.0f) +{ + +} + + + +float +OpenSteer::Color::r() const +{ + return r_; +} + + +float +OpenSteer::Color::g() const +{ + return g_; +} + + +float +OpenSteer::Color::b() const +{ + return b_; +} + + +float +OpenSteer::Color::a() const +{ + return a_; +} + + + +void +OpenSteer::Color::setR( float value ) +{ + r_ = value; +} + + +void +OpenSteer::Color::setG( float value ) +{ + g_ = value; +} + + +void +OpenSteer::Color::setB( float value ) +{ + b_ = value; +} + +void +OpenSteer::Color::setA( float value ) +{ + a_ = value; +} + +void +OpenSteer::Color::set( float rValue, float gValue, float bValue, float aValue ) +{ + r_ = rValue; + g_ = gValue; + b_ = bValue; + a_ = aValue; +} + + +OpenSteer::Vec3 +OpenSteer::Color::convertToVec3() const +{ + return Vec3( r_, g_, b_ ); +} + + +OpenSteer::Color& +OpenSteer::Color::operator+=( Color const& other ) +{ + r_ += other.r_; + g_ += other.g_; + b_ += other.b_; + return *this; +} + + +OpenSteer::Color& +OpenSteer::Color::operator-=( Color const& other ) +{ + r_ -= other.r_; + g_ -= other.g_; + b_ -= other.b_; + return *this; +} + + +OpenSteer::Color& +OpenSteer::Color::operator*=( float factor ) +{ + r_ *= factor; + g_ *= factor; + b_ *= factor; + return *this; +} + + +OpenSteer::Color& +OpenSteer::Color::operator/=( float factor ) +{ + assert( 0.0f != factor && "Division by zero." ); + return operator*=( 1.0f / factor ); +} + + + + + + +OpenSteer::Color +OpenSteer::grayColor( float value ) +{ + return Color( value ); +} + + + +OpenSteer::Color +OpenSteer::operator+( Color const& lhs, Color const& rhs ) +{ + Color result( lhs ); + return result += rhs; +} + + +OpenSteer::Color +OpenSteer::operator-( Color const& lhs, Color const& rhs ) +{ + Color result( lhs ); + return result -= rhs; +} + + +OpenSteer::Color +OpenSteer::operator*( Color const& lhs, float rhs ) +{ + Color result( lhs ); + return result *= rhs; +} + + +OpenSteer::Color +OpenSteer::operator*( float lhs, Color const& rhs ) +{ + return operator*( rhs, lhs ); +} + + +OpenSteer::Color +OpenSteer::operator/( Color const& lhs, float rhs ) +{ + Color result( lhs ); + return result /= rhs; +} + + + + + + + +OpenSteer::Color const OpenSteer::gBlack(0.0f, 0.0f, 0.0f); +OpenSteer::Color const OpenSteer::gWhite(1.0f, 1.0f, 1.0f); + +OpenSteer::Color const OpenSteer::gRed(1.0f, 0.0f, 0.0f); +OpenSteer::Color const OpenSteer::gGreen(0.0f, 1.0f, 0.0f); +OpenSteer::Color const OpenSteer::gBlue(0.0f, 0.0f, 1.0f); +OpenSteer::Color const OpenSteer::gYellow(1.0f, 1.0f, 0.0f); +OpenSteer::Color const OpenSteer::gCyan(0.0f, 1.0f, 1.0f); +OpenSteer::Color const OpenSteer::gMagenta(1.0f, 0.0f, 1.0f); +OpenSteer::Color const OpenSteer::gOrange(1.0f, 0.5f, 0.0f); + +OpenSteer::Color const OpenSteer::gDarkRed(0.5f, 0.0f, 0.0f); +OpenSteer::Color const OpenSteer::gDarkGreen(0.0f, 0.5f, 0.0f); +OpenSteer::Color const OpenSteer::gDarkBlue(0.0f, 0.0f, 0.5f); +OpenSteer::Color const OpenSteer::gDarkYellow(0.5f, 0.5f, 0.0f); +OpenSteer::Color const OpenSteer::gDarkCyan(0.0f, 0.5f, 0.5f); +OpenSteer::Color const OpenSteer::gDarkMagenta(0.5f, 0.0f, 0.5f); +OpenSteer::Color const OpenSteer::gDarkOrange(0.5f, 0.25f, 0.0f); + +OpenSteer::Color const OpenSteer::gGray10(0.1f); +OpenSteer::Color const OpenSteer::gGray20(0.2f); +OpenSteer::Color const OpenSteer::gGray30(0.3f); +OpenSteer::Color const OpenSteer::gGray40(0.4f); +OpenSteer::Color const OpenSteer::gGray50(0.5f); +OpenSteer::Color const OpenSteer::gGray60(0.6f); +OpenSteer::Color const OpenSteer::gGray70(0.7f); +OpenSteer::Color const OpenSteer::gGray80(0.8f); +OpenSteer::Color const OpenSteer::gGray90(0.9f); + Added: trunk/python-ogre/ThirdParty/opensteer/Obstacle.cpp =================================================================== --- trunk/python-ogre/ThirdParty/opensteer/Obstacle.cpp (rev 0) +++ trunk/python-ogre/ThirdParty/opensteer/Obstacle.cpp 2008-10-05 07:08:22 UTC (rev 753) @@ -0,0 +1,355 @@ +// ---------------------------------------------------------------------------- +// +// +// OpenSteer -- Steering Behaviors for Autonomous Characters +// +// Copyright (c) 2002-2004, Sony Computer Entertainment America +// Original author: Craig Reynolds <cra...@pl...> +// +// 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. +// +// +// ---------------------------------------------------------------------------- +// +// +// OpenSteer Obstacle classes +// +// 10-28-04 cwr: split off from Obstacle.h +// +// +// ---------------------------------------------------------------------------- + + +#include "OpenSteer/Obstacle.h" + + +// ---------------------------------------------------------------------------- +// Obstacle +// compute steering for a vehicle to avoid this obstacle, if needed + + +OpenSteer::Vec3 +OpenSteer::Obstacle::steerToAvoid (const AbstractVehicle& vehicle, + const float minTimeToCollision) const +{ + // find nearest intersection with this obstacle along vehicle's path + PathIntersection pi; + findIntersectionWithVehiclePath (vehicle, pi); + + // return steering for vehicle to avoid intersection, or zero if non found + return pi.steerToAvoidIfNeeded (vehicle, minTimeToCollision); +} + + +// ---------------------------------------------------------------------------- +// Obstacle +// static method to apply steerToAvoid to nearest obstacle in an ObstacleGroup + + +OpenSteer::Vec3 +OpenSteer::Obstacle:: +steerToAvoidObstacles (const AbstractVehicle& vehicle, + const float minTimeToCollision, + const ObstacleGroup& obstacles) +{ + PathIntersection nearest, next; + + // test all obstacles in group for an intersection with the vehicle's + // future path, select the one whose point of intersection is nearest + firstPathIntersectionWithObstacleGroup (vehicle, obstacles, nearest, next); + + // if nearby intersection found, steer away from it, otherwise no steering + return nearest.steerToAvoidIfNeeded (vehicle, minTimeToCollision); +} + + +// ---------------------------------------------------------------------------- +// Obstacle +// static method to find first vehicle path intersection in an ObstacleGroup +// +// returns its results in the PathIntersection argument "nearest", +// "next" is used to store internal state. + + +void +OpenSteer::Obstacle:: +firstPathIntersectionWithObstacleGroup (const AbstractVehicle& vehicle, + const ObstacleGroup& obstacles, + PathIntersection& nearest, + PathIntersection& next) +{ + // test all obstacles in group for an intersection with the vehicle's + // future path, select the one whose point of intersection is nearest + next.intersect = false; + nearest.intersect = false; + for (ObstacleIterator o = obstacles.begin(); o != obstacles.end(); o++) + { + // find nearest point (if any) where vehicle path intersects obstacle + // o, storing the results in PathIntersection object "next" + (**o).findIntersectionWithVehiclePath (vehicle, next); + + // if this is the first intersection found, or it is the nearest found + // so far, store it in PathIntersection object "nearest" + const bool firstFound = !nearest.intersect; + const bool nearestFound = (next.intersect && + (next.distance < nearest.distance)); + if (firstFound || nearestFound) nearest = next; + } +} + + +// ---------------------------------------------------------------------------- +// PathIntersection +// determine steering once path intersections have been found + + +OpenSteer::Vec3 +OpenSteer::Obstacle::PathIntersection:: +steerToAvoidIfNeeded (const AbstractVehicle& vehicle, + const float minTimeToCollision) const +{ + // if nearby intersection found, steer away from it, otherwise no steering + const float minDistanceToCollision = minTimeToCollision * vehicle.speed(); + if (intersect && (distance < minDistanceToCollision)) + { + // compute avoidance steering force: take the component of + // steerHint which is lateral (perpendicular to vehicle's + // forward direction), set its length to vehicle's maxForce + Vec3 lateral = steerHint.perpendicularComponent (vehicle.forward ()); + return lateral.normalize () * vehicle.maxForce (); + } + else + { + return Vec3::zero; + } +} + + +// ---------------------------------------------------------------------------- +// SphereObstacle +// find first intersection of a vehicle's path with this obstacle + + +void +OpenSteer:: +SphereObstacle:: +findIntersectionWithVehiclePath (const AbstractVehicle& vehicle, + PathIntersection& pi) const +{ + // This routine is based on the Paul Bourke's derivation in: + // Intersection of a Line and a Sphere (or circle) + // http://www.swin.edu.au/astronomy/pbourke/geometry/sphereline/ + // But the computation is done in the vehicle's local space, so + // the line in question is the Z (Forward) axis of the space which + // simplifies some of the calculations. + + float b, c, d, p, q, s; + Vec3 lc; + + // initialize pathIntersection object to "no intersection found" + pi.intersect = false; + + // find sphere's "local center" (lc) in the vehicle's coordinate space + lc = vehicle.localizePosition (center); + pi.vehicleOutside = lc.length () > radius; + + // if obstacle is seen from inside, but vehicle is outside, must avoid + // (noticed once a vehicle got outside it ignored the obstacle 2008-5-20) + if (pi.vehicleOutside && (seenFrom () == inside)) + { + pi.intersect = true; + pi.distance = 0.0f; + pi.steerHint = (center - vehicle.position()).normalize(); + return; + } + + // compute line-sphere intersection parameters + const float r = radius + vehicle.radius(); + b = -2 * lc.z; + c = square (lc.x) + square (lc.y) + square (lc.z) - square (r); + d = (b * b) - (4 * c); + + // when the path does not intersect the sphere + if (d < 0) return; + + // otherwise, the path intersects the sphere in two points with + // parametric coordinates of "p" and "q". (If "d" is zero the two + // points are coincident, the path is tangent) + s = sqrtXXX (d); + p = (-b + s) / 2; + q = (-b - s) / 2; + + // both intersections are behind us, so no potential collisions + if ((p < 0) && (q < 0)) return; + + // at least one intersection is in front, so intersects our forward + // path + pi.intersect = true; + pi.obstacle = this; + pi.distance = + ((p > 0) && (q > 0)) ? + // both intersections are in front of us, find nearest one + ((p < q) ? p : q) : + // otherwise one is ahead and one is behind: we are INSIDE obstacle + (seenFrom () == outside ? + // inside a solid obstacle, so distance to obstacle is zero + 0.0f : + // hollow obstacle (or "both"), pick point that is in front + ((p > 0) ? p : q)); + pi.surfacePoint = + vehicle.position() + (vehicle.forward() * pi.distance); + pi.surfaceNormal = (pi.surfacePoint-center).normalize(); + switch (seenFrom ()) + { + case outside: + pi.steerHint = pi.surfaceNormal; + break; + case inside: + pi.steerHint = -pi.surfaceNormal; + break; + case both: + pi.steerHint = pi.surfaceNormal * (pi.vehicleOutside ? 1.0f : -1.0f); + break; + } +} + + +// ---------------------------------------------------------------------------- +// BoxObstacle +// find first intersection of a vehicle's path with this obstacle + + +void +OpenSteer:: +BoxObstacle:: +findIntersectionWithVehiclePath (const AbstractVehicle& vehicle, + PathIntersection& pi) const +{ + // abbreviations + const float w = width; // dimensions + const float h = height; + const float d = depth; + const Vec3 s = side (); // local space + const Vec3 u = up (); + const Vec3 f = forward (); + const Vec3 p = position (); + const Vec3 hw = s * (0.5f * width); // offsets for face centers + const Vec3 hh = u * (0.5f * height); + const Vec3 hd = f * (0.5f * depth); + const seenFromState sf = seenFrom (); + + // the box's six rectangular faces + RectangleObstacle r1 (w, h, s, u, f, p + hd, sf); // front + RectangleObstacle r2 (w, h, -s, u, -f, p - hd, sf); // back + RectangleObstacle r3 (d, h, -f, u, s, p + hw, sf); // side + RectangleObstacle r4 (d, h, f, u, -s, p - hw, sf); // other side + RectangleObstacle r5 (w, d, s, -f, u, p + hh, sf); // top + RectangleObstacle r6 (w, d, -s, -f, -u, p - hh, sf); // bottom + + // group the six RectangleObstacle faces together + ObstacleGroup faces; + faces.push_back (&r1); + faces.push_back (&r2); + faces.push_back (&r3); + faces.push_back (&r4); + faces.push_back (&r5); + faces.push_back (&r6); + + // find first intersection of vehicle path with group of six faces + PathIntersection next; + firstPathIntersectionWithObstacleGroup (vehicle, faces, pi, next); + + // when intersection found, adjust PathIntersection for the box case + if (pi.intersect) + { + pi.obstacle = this; + pi.steerHint = ((pi.surfacePoint - position ()).normalize () * + (pi.vehicleOutside ? 1.0f : -1.0f)); + } +} + + +// ---------------------------------------------------------------------------- +// PlaneObstacle +// find first intersection of a vehicle's path with this obstacle + + +void +OpenSteer:: +PlaneObstacle:: +findIntersectionWithVehiclePath (const AbstractVehicle& vehicle, + PathIntersection& pi) const +{ + // initialize pathIntersection object to "no intersection found" + pi.intersect = false; + + const Vec3 lp = localizePosition (vehicle.position ()); + const Vec3 ld = localizeDirection (vehicle.forward ()); + + // no obstacle intersection if path is parallel to XY (side/up) plane + if (ld.dot (Vec3::forward) == 0.0f) return; + + // no obstacle intersection if vehicle is heading away from the XY plane + if ((lp.z > 0.0f) && (ld.z > 0.0f)) return; + if ((lp.z < 0.0f) && (ld.z < 0.0f)) return; + + // no obstacle intersection if obstacle "not seen" from vehicle's side + if ((seenFrom () == outside) && (lp.z < 0.0f)) return; + if ((seenFrom () == inside) && (lp.z > 0.0f)) return; + + // find intersection of path with rectangle's plane (XY plane) + const float ix = lp.x - (ld.x * lp.z / ld.z); + const float iy = lp.y - (ld.y * lp.z / ld.z); + const Vec3 planeIntersection (ix, iy, 0.0f); + + // no obstacle intersection if plane intersection is outside 2d shape + if (!xyPointInsideShape (planeIntersection, vehicle.radius ())) return; + + // otherwise, the vehicle path DOES intersect this rectangle + const Vec3 localXYradial = planeIntersection.normalize ()... [truncated message content] |