Path.cc 5.9 KB

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