Path.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #include "graphics/dgl.h"
  2. #include "2d/sceneobject/Path.h"
  3. #include "2d/sceneobject/Path_ScriptBinding.h"
  4. IMPLEMENT_CONOBJECT(Path);
  5. PathObject::PathObject():
  6. mObj(NULL),
  7. mPath(NULL)
  8. {
  9. mCurrNode = 0;
  10. mPrevNode = 0;
  11. mLoop = true;
  12. mOrient = false;
  13. mSnapToNode = false;
  14. mLoopCount = 0;
  15. mMaxLoop = -1;
  16. mMaxSpeed = 1.0f;
  17. mAngOff = 0.0f;
  18. }
  19. void PathObject::setCurrNode(S32 node)
  20. {
  21. }
  22. void PathObject::setNextNode(S32 node)
  23. {
  24. }
  25. void PathObject::setPrevNode(S32 node)
  26. {
  27. }
  28. Path::Path()
  29. {
  30. // Use a static body by default.
  31. mBodyDefinition.type = b2_staticBody;
  32. VECTOR_SET_ASSOCIATION(mObjs);
  33. VECTOR_SET_ASSOCIATION(mNodes);
  34. }
  35. Path::~Path()
  36. {
  37. }
  38. void Path::initPersistFields()
  39. {
  40. Parent::initPersistFields();
  41. }
  42. void Path::preIntegrate(const F32 totalTime, const F32 elapsedTime, DebugStats * pDebugStats)
  43. {
  44. Parent::preIntegrate(totalTime, elapsedTime, pDebugStats);
  45. Vector<PathObject*>::iterator i;
  46. for (i = mObjs.begin(); i != mObjs.end(); i++)
  47. {
  48. bool stop = false;
  49. PathObject &pObj = *(*i);
  50. Vector2 cPos = pObj.mObj->getPosition();
  51. Node &cNode = mNodes[pObj.mCurrNode];
  52. Vector2 cDst = mNodes[pObj.mCurrNode].position;
  53. F32 distance = (cDst - cPos).Length();
  54. if (distance < (pObj.mMaxSpeed * elapsedTime) || distance < cNode.distance )
  55. {
  56. S32 nCount = mNodes.size();
  57. S32 end = nCount - 1;
  58. if (pObj.mCurrNode == end)
  59. {
  60. if (pObj.mLoop)
  61. {
  62. pObj.mLoopCount++;
  63. if ((pObj.mMaxLoop > 0) && (pObj.mLoopCount >= pObj.mMaxLoop))
  64. {
  65. stop = true;
  66. }
  67. else
  68. {
  69. pObj.mPrevNode = pObj.mCurrNode;
  70. pObj.mCurrNode = 0;
  71. pObj.mNextNode = pObj.mCurrNode;
  72. }
  73. }
  74. else
  75. {
  76. stop = true;
  77. }
  78. }
  79. else
  80. {
  81. pObj.mPrevNode = pObj.mCurrNode;
  82. pObj.mCurrNode = pObj.mCurrNode + 1;
  83. pObj.mNextNode = pObj.mCurrNode;
  84. }
  85. if (pObj.mCurrNode >= nCount)
  86. {
  87. pObj.mCurrNode = 0;
  88. pObj.mNextNode = pObj.mCurrNode;
  89. }
  90. else if (pObj.mCurrNode < 0)
  91. {
  92. pObj.mCurrNode = 0;
  93. pObj.mNextNode = pObj.mCurrNode;
  94. }
  95. }
  96. if (!stop)
  97. {
  98. moveObject(pObj);
  99. }
  100. else
  101. {
  102. pObj.mObj->setLinearVelocity(Vector2(0.0f, 0.0f));
  103. }
  104. }
  105. }
  106. void Path::integrateObject(const F32 totalTime, const F32 elapsedTime, DebugStats * pDebugStats)
  107. {
  108. Parent::integrateObject(totalTime, elapsedTime, pDebugStats);
  109. }
  110. S32 Path::addNode(Vector2 pos, F32 distance, F32 weight)
  111. {
  112. S32 nodeCount = mNodes.size();
  113. mNodes.push_back(Node(pos, distance, weight));
  114. return nodeCount;
  115. }
  116. void Path::attachObject(SceneObject * object, F32 speed, bool orientToPath, F32 angleOff, bool snapToNode, S32 startNode, bool loop, S32 maxLoop)
  117. {
  118. if (snapToNode)
  119. {
  120. if ((startNode >= 0) && (startNode < mNodes.size()))
  121. object->setPosition(mNodes[startNode].position);
  122. }
  123. object->setLinearVelocity(Vector2::getZero());
  124. deleteNotify(object);
  125. PathObject *pObj = new PathObject();
  126. pObj->mPath = this;
  127. pObj->mObj = object;
  128. pObj->mObjId = object->getId();
  129. pObj->mOrient = orientToPath;
  130. pObj->mAngOff = angleOff;
  131. pObj->mLoop = loop;
  132. pObj->mMaxLoop = maxLoop;
  133. pObj->mMaxSpeed = speed;
  134. pObj->mCurrNode = startNode;
  135. pObj->mNextNode = startNode;
  136. mObjs.push_back(pObj);
  137. }
  138. void Path::detachObject(SceneObject * object)
  139. {
  140. if (!object)
  141. return;
  142. Vector<PathObject*>::iterator i;
  143. for (i = mObjs.begin(); i != mObjs.end(); i++)
  144. {
  145. PathObject *pObj = (*i);
  146. if(object == pObj->mObj)
  147. {
  148. if (!pObj->mObj.isNull())
  149. {
  150. pObj->mObj->setLinearVelocity(Vector2(0, 0));
  151. clearNotify(pObj->mObj);
  152. }
  153. delete pObj;
  154. mObjs.erase_fast(i);
  155. break;
  156. }
  157. }
  158. }
  159. void Path::moveObject(PathObject& obj)
  160. {
  161. Vector2 cDest = mNodes[obj.mNextNode].position;
  162. F32 slowRad = mNodes[obj.mNextNode].distance;
  163. Vector2 oPos = obj.mObj->getPosition();
  164. Vector2 dir = cDest - oPos;
  165. Vector2 currVel = obj.mObj->getLinearVelocity();
  166. dir.Normalize();
  167. F32 maxSpeed = obj.mMaxSpeed;
  168. F32 maxForce = 1.2f;
  169. Vector2 steer = seek(cDest, oPos, maxSpeed, currVel, slowRad);
  170. steer = truncate(steer, maxForce);
  171. steer = steer.scale(0.5);
  172. currVel = currVel.add(steer);
  173. currVel = truncate(currVel.add(steer), maxSpeed);
  174. Vector2 pos = oPos.add(currVel);
  175. //Steering Behavior
  176. obj.mObj->applyForce(pos, obj.mObj->getWorldCenter());
  177. //Simple direct move.
  178. //obj.mObj->setLinearVelocity(dir * obj.mMaxSpeed);
  179. if (obj.mOrient)
  180. {
  181. F32 rot = mRadToDeg(mAtan(dir.x, dir.y));
  182. rot = rot - obj.mAngOff;
  183. F32 ang = mDegToRad(rot);
  184. F32 speed = obj.mMaxSpeed;
  185. obj.mObj->rotateTo(ang, speed);
  186. }
  187. }
  188. Vector2 Path::truncate(Vector2 vec, F32 max)
  189. {
  190. F32 i = max;
  191. i = i < 1.0f ? 1.0f : i;
  192. vec = vec.scale(max);
  193. return vec;
  194. }
  195. Vector2 Path::seek(Vector2 target, Vector2 objPos, F32 max, Vector2 curr, F32 slowRad)
  196. {
  197. Vector2 des = target.sub(objPos);
  198. F32 dist = des.Length();
  199. des.Normalize();
  200. if (dist < slowRad)
  201. {
  202. des = des.scale(max * dist / slowRad);
  203. }
  204. else
  205. {
  206. des = des.scale(max);
  207. }
  208. Vector2 force = des.sub(curr);
  209. return force;
  210. }
  211. void Path::onDeleteNotify(SimObject* object)
  212. {
  213. Vector<PathObject*>::iterator i;
  214. SimObjectId objId = object->getId();
  215. for (i = mObjs.begin(); i != mObjs.end(); i++)
  216. {
  217. if ((*i)->mObjId == objId)
  218. {
  219. delete (*i);
  220. mObjs.erase_fast(i);
  221. break;
  222. }
  223. }
  224. }