simPath.cpp
Engine/source/scene/simPath.cpp
Namespaces:
namespace
Public Variables
Public Functions
ConsoleDocClass(Marker , "@brief A single joint, or knot, along a path. Should be stored inside a Path container object. A path markers can <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">be\n</a>" "one of three primary movement types:\"normal\" , \"Position Only\" , or \"Kink\". \n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> path()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " isLooping = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classmarker/">Marker</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " seqNum = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " type = \"Normal\";\n" " msToNext = \"1000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " smoothingType = \"Spline\";\n" " position = \"-0.054708 -35.0612 234.802\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Path\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n</a>" )
ConsoleDocClass(SimPath::Path , "@brief A spline along which various objects can move along. The spline object acts like a container <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/class/classmarker/">Marker</a> objects, which <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">make\n</a>" "up the joints, or knots, along the path. Paths can be assigned a speed, can be looping or non-looping. Each of a path 's markers can <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">be\n</a>" "one of three primary movement types:\"normal\" , \"Position Only\" , or \"Kink\". \n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> path()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " isLooping = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classmarker/">Marker</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " seqNum = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " type = \"Normal\";\n" " msToNext = \"1000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " smoothingType = \"Spline\";\n" " position = \"-0.054708 -35.0612 234.802\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Marker\n</a>" "@see NetConnection::transmitPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see NetConnection::clearPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Path\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n</a>" )
DefineEngineFunction(pathOnMissionLoadDone , void , () , "@brief Load all Path information from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mission.\n\n</a>" "This function is usually called from the loadMissionStage2() server-side function " "after the mission <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> has loaded. Internally it places all Paths into the server's " "PathManager. From this point the Paths are ready <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> transmission <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">clients.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Inform the engine <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> load all Path information from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mission.\n</a>" "pathOnMissionLoadDone();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@see NetConnection::transmitPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see NetConnection::clearPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Path\n</a>" "@ingroup Networking" )
ImplementEnumType(MarkerKnotType , "The type of knot that this marker will <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">be.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n\n</a>" )
ImplementEnumType(MarkerSmoothingType , "The type of smoothing this marker will have <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> pathed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n\n</a>" )
Detailed Description
Public Variables
EndImplementEnumType
bool gEditingMission
For frame signal.
Point3F wedgePoints [4]
Public Functions
cmpPathObject(const void * p1, const void * p2)
ConsoleDocClass(Marker , "@brief A single joint, or knot, along a path. Should be stored inside a Path container object. A path markers can <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">be\n</a>" "one of three primary movement types:\"normal\" , \"Position Only\" , or \"Kink\". \n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> path()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " isLooping = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classmarker/">Marker</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " seqNum = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " type = \"Normal\";\n" " msToNext = \"1000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " smoothingType = \"Spline\";\n" " position = \"-0.054708 -35.0612 234.802\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Path\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n</a>" )
ConsoleDocClass(SimPath::Path , "@brief A spline along which various objects can move along. The spline object acts like a container <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/class/classmarker/">Marker</a> objects, which <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">make\n</a>" "up the joints, or knots, along the path. Paths can be assigned a speed, can be looping or non-looping. Each of a path 's markers can <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">be\n</a>" "one of three primary movement types:\"normal\" , \"Position Only\" , or \"Kink\". \n" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> path()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " isLooping = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " <a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classmarker/">Marker</a>()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " seqNum = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " type = \"Normal\";\n" " msToNext = \"1000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " smoothingType = \"Spline\";\n" " position = \"-0.054708 -35.0612 234.802\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " rotation = \"1 0 0 0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" " };\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Marker\n</a>" "@see NetConnection::transmitPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see NetConnection::clearPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Path\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n</a>" )
DefineEngineFunction(pathOnMissionLoadDone , void , () , "@brief Load all Path information from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mission.\n\n</a>" "This function is usually called from the loadMissionStage2() server-side function " "after the mission <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a702945180aa732857b380a007a7e2a21">file</a> has loaded. Internally it places all Paths into the server's " "PathManager. From this point the Paths are ready <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> transmission <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">clients.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Inform the engine <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> load all Path information from the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">mission.\n</a>" "pathOnMissionLoadDone();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@see NetConnection::transmitPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see NetConnection::clearPaths()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@see <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Path\n</a>" "@ingroup Networking" )
IMPLEMENT_CO_NETOBJECT_V1(Marker )
ImplementEnumType(MarkerKnotType , "The type of knot that this marker will <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">be.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n\n</a>" )
ImplementEnumType(MarkerSmoothingType , "The type of smoothing this marker will have <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> pathed <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">objects.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n\n</a>" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "scene/simPath.h" 26 27#include "gfx/gfxDevice.h" 28#include "gfx/gfxVertexBuffer.h" 29#include "gfx/gfxPrimitiveBuffer.h" 30#include "gfx/gfxTransformSaver.h" 31#include "console/consoleTypes.h" 32#include "scene/pathManager.h" 33#include "scene/sceneRenderState.h" 34#include "math/mathIO.h" 35#include "core/stream/bitStream.h" 36#include "renderInstance/renderPassManager.h" 37#include "console/engineAPI.h" 38 39extern bool gEditingMission; 40 41//-------------------------------------------------------------------------- 42//-------------------------------------- Console functions and cmp funcs 43// 44DefineEngineFunction(pathOnMissionLoadDone, void, (),, 45 "@brief Load all Path information from the mission.\n\n" 46 47 "This function is usually called from the loadMissionStage2() server-side function " 48 "after the mission file has loaded. Internally it places all Paths into the server's " 49 "PathManager. From this point the Paths are ready for transmission to the clients.\n\n" 50 51 "@tsexample\n" 52 "// Inform the engine to load all Path information from the mission.\n" 53 "pathOnMissionLoadDone();\n\n" 54 "@endtsexample\n" 55 56 "@see NetConnection::transmitPaths()\n" 57 "@see NetConnection::clearPaths()\n" 58 "@see Path\n" 59 60 "@ingroup Networking") 61{ 62 // Need to load subobjects for all loaded interiors... 63 SimGroup* pMissionGroup = dynamic_cast<SimGroup*>(Sim::findObject("MissionGroup")); 64 AssertFatal(pMissionGroup != NULL, "Error, mission done loading and no mission group?"); 65 66 U32 currStart = 0; 67 U32 currEnd = 1; 68 Vector<SimGroup*> groups; 69 groups.push_back(pMissionGroup); 70 71 while (true) { 72 for (U32 i = currStart; i < currEnd; i++) { 73 for (SimGroup::iterator itr = groups[i]->begin(); itr != groups[i]->end(); itr++) { 74 if (dynamic_cast<SimGroup*>(*itr) != NULL) 75 groups.push_back(static_cast<SimGroup*>(*itr)); 76 } 77 } 78 79 if (groups.size() == currEnd) { 80 break; 81 } else { 82 currStart = currEnd; 83 currEnd = groups.size(); 84 } 85 } 86 87 for (U32 i = 0; i < groups.size(); i++) { 88 SimPath::Path* pPath = dynamic_cast<SimPath::Path*>(groups[i]); 89 if (pPath) 90 pPath->updatePath(); 91 } 92} 93 94S32 FN_CDECL cmpPathObject(const void* p1, const void* p2) 95{ 96 SimObject* o1 = *((SimObject**)p1); 97 SimObject* o2 = *((SimObject**)p2); 98 99 Marker* m1 = dynamic_cast<Marker*>(o1); 100 Marker* m2 = dynamic_cast<Marker*>(o2); 101 102 if (m1 == NULL && m2 == NULL) 103 return 0; 104 else if (m1 != NULL && m2 == NULL) 105 return 1; 106 else if (m1 == NULL && m2 != NULL) 107 return -1; 108 else { 109 // Both markers... 110 return S32(m1->mSeqNum) - S32(m2->mSeqNum); 111 } 112} 113 114ConsoleDocClass(SimPath::Path, 115 "@brief A spline along which various objects can move along. The spline object acts like a container for Marker objects, which make\n" 116 "up the joints, or knots, along the path. Paths can be assigned a speed, can be looping or non-looping. Each of a path's markers can be\n" 117 "one of three primary movement types: \"normal\", \"Position Only\", or \"Kink\". \n" 118 119 "@tsexample\n" 120 "new path()\n" 121 " {\n" 122 " isLooping = \"1\";\n" 123 "\n" 124 " new Marker()\n" 125 " {\n" 126 " seqNum = \"0\";\n" 127 " type = \"Normal\";\n" 128 " msToNext = \"1000\";\n" 129 " smoothingType = \"Spline\";\n" 130 " position = \"-0.054708 -35.0612 234.802\";\n" 131 " rotation = \"1 0 0 0\";\n" 132 " };\n" 133 "\n" 134 " };\n" 135 "@endtsexample\n" 136 137 "@see Marker\n" 138 "@see NetConnection::transmitPaths()\n" 139 "@see NetConnection::clearPaths()\n" 140 "@see Path\n" 141 142 "@ingroup enviroMisc\n" 143); 144 145namespace SimPath 146{ 147 148//-------------------------------------------------------------------------- 149//-------------------------------------- Implementation 150// 151IMPLEMENT_CONOBJECT(Path); 152 153Path::Path() 154{ 155 mPathIndex = NoPathIndex; 156 mIsLooping = true; 157} 158 159Path::~Path() 160{ 161 // 162} 163 164//-------------------------------------------------------------------------- 165void Path::initPersistFields() 166{ 167 addField("isLooping", TypeBool, Offset(mIsLooping, Path), "If this is true, the loop is closed, otherwise it is open.\n"); 168 169 Parent::initPersistFields(); 170 // 171} 172 173 174 175//-------------------------------------------------------------------------- 176bool Path::onAdd() 177{ 178 if(!Parent::onAdd()) 179 return false; 180 181 return true; 182} 183 184 185void Path::onRemove() 186{ 187 // 188 189 Parent::onRemove(); 190} 191 192 193 194//-------------------------------------------------------------------------- 195/// Sort the markers objects into sequence order 196void Path::sortMarkers() 197{ 198 dQsort(objectList.address(), objectList.size(), sizeof(SimObject*), cmpPathObject); 199} 200 201void Path::updatePath() 202{ 203 // If we need to, allocate a path index from the manager 204 if (mPathIndex == NoPathIndex) 205 mPathIndex = gServerPathManager->allocatePathId(); 206 207 sortMarkers(); 208 209 Vector<Point3F> positions; 210 Vector<QuatF> rotations; 211 Vector<U32> times; 212 Vector<U32> smoothingTypes; 213 214 for (iterator itr = begin(); itr != end(); itr++) 215 { 216 Marker* pMarker = dynamic_cast<Marker*>(*itr); 217 if (pMarker != NULL) 218 { 219 Point3F pos; 220 pMarker->getTransform().getColumn(3, &pos); 221 positions.push_back(pos); 222 223 QuatF rot; 224 rot.set(pMarker->getTransform()); 225 rotations.push_back(rot); 226 227 times.push_back(pMarker->mMSToNext); 228 smoothingTypes.push_back(pMarker->mSmoothingType); 229 } 230 } 231 232 // DMMTODO: Looping paths. 233 gServerPathManager->updatePath(mPathIndex, positions, rotations, times, smoothingTypes); 234} 235 236void Path::addObject(SimObject* obj) 237{ 238 Parent::addObject(obj); 239 240 if (mPathIndex != NoPathIndex) { 241 // If we're already finished, and this object is a marker, then we need to 242 // update our path information... 243 if (dynamic_cast<Marker*>(obj) != NULL) 244 updatePath(); 245 } 246} 247 248void Path::removeObject(SimObject* obj) 249{ 250 bool recalc = dynamic_cast<Marker*>(obj) != NULL; 251 252 Parent::removeObject(obj); 253 254 if (mPathIndex != NoPathIndex && recalc == true) 255 updatePath(); 256} 257 258DefineEngineMethod( Path, getPathId, S32, (),, 259 "@brief Returns the PathID (not the object ID) of this path.\n\n" 260 "@return PathID (not the object ID) of this path.\n" 261 "@tsexample\n" 262 "// Acquire the PathID of this path object.\n" 263 "%pathID = %thisPath.getPathId();\n\n" 264 "@endtsexample\n\n" 265 ) 266{ 267 Path *path = static_cast<Path *>(object); 268 return path->getPathIndex(); 269} 270 271} // Namespace 272 273//-------------------------------------------------------------------------- 274//-------------------------------------------------------------------------- 275 276GFXStateBlockRef Marker::smStateBlock; 277GFXVertexBufferHandle<GFXVertexPCT> Marker::smVertexBuffer; 278GFXPrimitiveBufferHandle Marker::smPrimitiveBuffer; 279 280static Point3F wedgePoints[4] = { 281 Point3F(-1, -1, 0), 282 Point3F( 0, 1, 0), 283 Point3F( 1, -1, 0), 284 Point3F( 0,-.75, .5), 285}; 286 287void Marker::initGFXResources() 288{ 289 if(smVertexBuffer != NULL) 290 return; 291 292 GFXStateBlockDesc d; 293 d.cullDefined = true; 294 d.cullMode = GFXCullNone; 295 296 smStateBlock = GFX->createStateBlock(d); 297 298 smVertexBuffer.set(GFX, 4, GFXBufferTypeStatic); 299 GFXVertexPCT* verts = smVertexBuffer.lock(); 300 verts[0].point = wedgePoints[0] * 1.25f; 301 verts[1].point = wedgePoints[1] * 1.25f; 302 verts[2].point = wedgePoints[2] * 1.25f; 303 verts[3].point = wedgePoints[3] * 1.25f; 304 verts[1].color = GFXVertexColor(ColorI(255, 0, 0, 255)); 305 verts[0].color = verts[2].color = verts[3].color = GFXVertexColor(ColorI(0, 0, 255, 255)); 306 smVertexBuffer.unlock(); 307 308 smPrimitiveBuffer.set(GFX, 24, 12, GFXBufferTypeStatic); 309 U16* prims; 310 smPrimitiveBuffer.lock(&prims); 311 prims[0] = 0; 312 prims[1] = 3; 313 prims[2] = 3; 314 prims[3] = 1; 315 prims[4] = 1; 316 prims[5] = 0; 317 318 prims[6] = 3; 319 prims[7] = 1; 320 prims[8] = 1; 321 prims[9] = 2; 322 prims[10] = 2; 323 prims[11] = 3; 324 325 prims[12] = 0; 326 prims[13] = 3; 327 prims[14] = 3; 328 prims[15] = 2; 329 prims[16] = 2; 330 prims[17] = 0; 331 332 prims[18] = 0; 333 prims[19] = 2; 334 prims[20] = 2; 335 prims[21] = 1; 336 prims[22] = 1; 337 prims[23] = 0; 338 smPrimitiveBuffer.unlock(); 339} 340 341IMPLEMENT_CO_NETOBJECT_V1(Marker); 342 343ConsoleDocClass( Marker, 344 "@brief A single joint, or knot, along a path. Should be stored inside a Path container object. A path markers can be\n" 345 "one of three primary movement types: \"normal\", \"Position Only\", or \"Kink\". \n" 346 347 "@tsexample\n" 348 "new path()\n" 349 " {\n" 350 " isLooping = \"1\";\n" 351 "\n" 352 " new Marker()\n" 353 " {\n" 354 " seqNum = \"0\";\n" 355 " type = \"Normal\";\n" 356 " msToNext = \"1000\";\n" 357 " smoothingType = \"Spline\";\n" 358 " position = \"-0.054708 -35.0612 234.802\";\n" 359 " rotation = \"1 0 0 0\";\n" 360 " };\n" 361 "\n" 362 " };\n" 363 "@endtsexample\n" 364 "@see Path\n" 365 "@ingroup enviroMisc\n" 366); 367 368Marker::Marker() 369{ 370 // Not ghostable unless we're editing... 371 mNetFlags.clear(Ghostable); 372 373 mTypeMask |= MarkerObjectType; 374 375 mSeqNum = 0; 376 mMSToNext = 1000; 377 mSmoothingType = SmoothingTypeSpline; 378 mKnotType = KnotTypeNormal; 379} 380 381Marker::~Marker() 382{ 383 // 384} 385 386//-------------------------------------------------------------------------- 387 388ImplementEnumType( MarkerSmoothingType, 389 "The type of smoothing this marker will have for pathed objects.\n" 390 "@ingroup enviroMisc\n\n") 391 { Marker::SmoothingTypeSpline , "Spline", "Marker will cause the movements of the pathed object to be smooth.\n" }, 392 { Marker::SmoothingTypeLinear , "Linear", "Marker will have no smoothing effect.\n" }, 393 //{ Marker::SmoothingTypeAccelerate , "Accelerate" }, 394EndImplementEnumType; 395 396ImplementEnumType( MarkerKnotType, 397 "The type of knot that this marker will be.\n" 398 "@ingroup enviroMisc\n\n") 399 { Marker::KnotTypeNormal , "Normal", "Knot will have a smooth camera translation/rotation effect.\n" }, 400 { Marker::KnotTypePositionOnly, "Position Only", "Will do the same for translations, leaving rotation un-touched.\n" }, 401 { Marker::KnotTypeKink, "Kink", "The rotation will take effect immediately for an abrupt rotation change.\n" }, 402EndImplementEnumType; 403 404void Marker::initPersistFields() 405{ 406 addGroup( "Misc" ); 407 addField("seqNum", TypeS32, Offset(mSeqNum, Marker), "Marker position in sequence of markers on this path.\n"); 408 addField("type", TYPEID< KnotType >(), Offset(mKnotType, Marker), "Type of this marker/knot. A \"normal\" knot will have a smooth camera translation/rotation effect.\n\"Position Only\" will do the same for translations, leaving rotation un-touched.\nLastly, a \"Kink\" means the rotation will take effect immediately for an abrupt rotation change.\n"); 409 addField("msToNext", TypeS32, Offset(mMSToNext, Marker), "Milliseconds to next marker in sequence.\n"); 410 addField("smoothingType", TYPEID< SmoothingType >(), Offset(mSmoothingType, Marker), "Path smoothing at this marker/knot. \"Linear\" means no smoothing, while \"Spline\" means to smooth.\n"); 411 endGroup("Misc"); 412 413 Parent::initPersistFields(); 414} 415 416//-------------------------------------------------------------------------- 417bool Marker::onAdd() 418{ 419 if(!Parent::onAdd()) 420 return false; 421 422 mObjBox = Box3F(Point3F(-1.25, -1.25, -1.25), Point3F(1.25, 1.25, 1.25)); 423 resetWorldBox(); 424 425 if(gEditingMission) 426 onEditorEnable(); 427 428 return true; 429} 430 431 432void Marker::onRemove() 433{ 434 if(gEditingMission) 435 onEditorDisable(); 436 437 Parent::onRemove(); 438 439 smVertexBuffer = NULL; 440 smPrimitiveBuffer = NULL; 441} 442 443void Marker::onGroupAdd() 444{ 445 mSeqNum = getGroup()->size() - 1; 446} 447 448 449/// Enable scoping so we can see this thing on the client. 450void Marker::onEditorEnable() 451{ 452 mNetFlags.set(Ghostable); 453 setScopeAlways(); 454 addToScene(); 455} 456 457/// Disable scoping so we can see this thing on the client 458void Marker::onEditorDisable() 459{ 460 removeFromScene(); 461 mNetFlags.clear(Ghostable); 462 clearScopeAlways(); 463} 464 465 466/// Tell our parent that this Path has been modified 467void Marker::inspectPostApply() 468{ 469 SimPath::Path *path = dynamic_cast<SimPath::Path*>(getGroup()); 470 if (path) 471 path->updatePath(); 472} 473 474 475//-------------------------------------------------------------------------- 476void Marker::prepRenderImage( SceneRenderState* state ) 477{ 478 // This should be sufficient for most objects that don't manage zones, and 479 // don't need to return a specialized RenderImage... 480 ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); 481 ri->renderDelegate.bind( this, &Marker::renderObject ); 482 ri->type = RenderPassManager::RIT_Editor; 483 state->getRenderPass()->addInst(ri); 484} 485 486 487void Marker::renderObject(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* overrideMat) 488{ 489 initGFXResources(); 490 491 for(U32 i = 0; i < GFX->getNumSamplers(); i++) 492 GFX->setTexture(i, NULL); 493 GFXTransformSaver saver; 494 MatrixF mat = getRenderTransform(); 495 mat.scale(mObjScale); 496 GFX->multWorld(mat); 497 498 GFX->setStateBlock(smStateBlock); 499 GFX->setVertexBuffer(smVertexBuffer); 500 GFX->setPrimitiveBuffer(smPrimitiveBuffer); 501 GFX->setupGenericShaders(); 502 GFX->drawIndexedPrimitive(GFXLineList, 0, 0, 4, 0, 12); 503} 504 505 506//-------------------------------------------------------------------------- 507U32 Marker::packUpdate(NetConnection* con, U32 mask, BitStream* stream) 508{ 509 U32 retMask = Parent::packUpdate(con, mask, stream); 510 511 // Note that we don't really care about efficiency here, since this is an 512 // edit-only ghost... 513 stream->writeAffineTransform(mObjToWorld); 514 515 return retMask; 516} 517 518void Marker::unpackUpdate(NetConnection* con, BitStream* stream) 519{ 520 Parent::unpackUpdate(con, stream); 521 522 // Transform 523 MatrixF otow; 524 stream->readAffineTransform(&otow); 525 526 setTransform(otow); 527} 528
