entity.cpp 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "T3D/entity.h"
  24. #include "core/stream/bitStream.h"
  25. #include "console/consoleTypes.h"
  26. #include "console/consoleObject.h"
  27. #include "sim/netConnection.h"
  28. #include "scene/sceneRenderState.h"
  29. #include "scene/sceneManager.h"
  30. #include "T3D/gameBase/gameProcess.h"
  31. #include "console/engineAPI.h"
  32. #include "T3D/gameBase/gameConnection.h"
  33. #include "math/mathIO.h"
  34. #include "math/mTransform.h"
  35. #include "T3D/components/coreInterfaces.h"
  36. #include "T3D/components/render/renderComponentInterface.h"
  37. #include "T3D/components/collision/collisionInterfaces.h"
  38. #include "gui/controls/guiTreeViewCtrl.h"
  39. #include "assets/assetManager.h"
  40. #include "assets/assetQuery.h"
  41. #include "T3D/assets/ComponentAsset.h"
  42. #include "console/consoleInternal.h"
  43. #include "T3D/gameBase/std/stdMoveList.h"
  44. #include "T3D/prefab.h"
  45. //
  46. #include "gfx/sim/debugDraw.h"
  47. //
  48. extern bool gEditingMission;
  49. // Client prediction
  50. static F32 sMinWarpTicks = 0.5f; // Fraction of tick at which instant warp occurs
  51. static S32 sMaxWarpTicks = 3; // Max warp duration in ticks
  52. static S32 sMaxPredictionTicks = 30; // Number of ticks to predict
  53. IMPLEMENT_CO_NETOBJECT_V1(Entity);
  54. ConsoleDocClass(Entity,
  55. "@brief Base Entity class.\n\n"
  56. "Entity is typically made up of a shape and up to two particle emitters. In most cases Entity objects are "
  57. "not created directly. They are usually produced automatically by other means, such as through the Explosion "
  58. "class. When an explosion goes off, its ExplosionData datablock determines what Entity to emit.\n"
  59. "@tsexample\n"
  60. "datablock ExplosionData(GrenadeLauncherExplosion)\n"
  61. "{\n"
  62. " // Assiging Entity data\n"
  63. " Entity = GrenadeEntity;\n\n"
  64. " // Adjust how Entity is ejected\n"
  65. " EntityThetaMin = 10;\n"
  66. " EntityThetaMax = 60;\n"
  67. " EntityNum = 4;\n"
  68. " EntityNumVariance = 2;\n"
  69. " EntityVelocity = 25;\n"
  70. " EntityVelocityVariance = 5;\n\n"
  71. " // Note: other ExplosionData properties are not listed for this example\n"
  72. "};\n"
  73. "@endtsexample\n\n"
  74. "@note Entity are client side only objects.\n"
  75. "@see EntityData\n"
  76. "@see ExplosionData\n"
  77. "@see Explosion\n"
  78. "@ingroup FX\n"
  79. );
  80. Entity::Entity()
  81. {
  82. //mTypeMask |= DynamicShapeObjectType | StaticObjectType | ;
  83. mTypeMask |= EntityObjectType;
  84. mNetFlags.set(Ghostable | ScopeAlways);
  85. mPos = Point3F(0, 0, 0);
  86. mRot = Point3F(0, 0, 0);
  87. mDelta.pos = mDelta.posVec = Point3F::Zero;
  88. mDelta.rot[0].identity();
  89. mDelta.rot[1].identity();
  90. mDelta.warpOffset.set(0.0f, 0.0f, 0.0f);
  91. mDelta.warpTicks = mDelta.warpCount = 0;
  92. mDelta.dt = 1.0f;
  93. mDelta.move = NullMove;
  94. mComponents.clear();
  95. mStartComponentUpdate = false;
  96. mInitialized = false;
  97. }
  98. Entity::~Entity()
  99. {
  100. }
  101. void Entity::initPersistFields()
  102. {
  103. Parent::initPersistFields();
  104. removeField("DataBlock");
  105. addGroup("Transform");
  106. removeField("Position");
  107. addProtectedField("Position", TypePoint3F, Offset(mPos, Entity), &_setPosition, &_getPosition, "Object world orientation.");
  108. removeField("Rotation");
  109. addProtectedField("Rotation", TypeRotationF, Offset(mRot, Entity), &_setRotation, &_getRotation, "Object world orientation.");
  110. //These are basically renamed mountPos/Rot. pretty much there for conveinence
  111. addField("LocalPosition", TypeMatrixPosition, Offset(mMount.xfm, Entity), "Position we are mounted at ( object space of our mount object ).");
  112. addField("LocalRotation", TypeMatrixRotation, Offset(mMount.xfm, Entity), "Rotation we are mounted at ( object space of our mount object ).");
  113. endGroup("Transform");
  114. }
  115. //
  116. bool Entity::_setPosition(void *object, const char *index, const char *data)
  117. {
  118. Entity* so = static_cast<Entity*>(object);
  119. if (so)
  120. {
  121. Point3F pos;
  122. if (!dStrcmp(data, ""))
  123. pos = Point3F(0, 0, 0);
  124. else
  125. Con::setData(TypePoint3F, &pos, 0, 1, &data);
  126. so->setTransform(pos, so->mRot);
  127. }
  128. return false;
  129. }
  130. const char * Entity::_getPosition(void* obj, const char* data)
  131. {
  132. Entity* so = static_cast<Entity*>(obj);
  133. if (so)
  134. {
  135. Point3F pos = so->getPosition();
  136. static const U32 bufSize = 256;
  137. char* returnBuffer = Con::getReturnBuffer(bufSize);
  138. dSprintf(returnBuffer, bufSize, "%g %g %g", pos.x, pos.y, pos.z);
  139. return returnBuffer;
  140. }
  141. return "0 0 0";
  142. }
  143. bool Entity::_setRotation(void *object, const char *index, const char *data)
  144. {
  145. Entity* so = static_cast<Entity*>(object);
  146. if (so)
  147. {
  148. RotationF rot;
  149. Con::setData(TypeRotationF, &rot, 0, 1, &data);
  150. //so->mRot = rot;
  151. //MatrixF mat = rot.asMatrixF();
  152. //mat.setPosition(so->getPosition());
  153. //so->setTransform(mat);
  154. so->setTransform(so->getPosition(), rot);
  155. }
  156. return false;
  157. }
  158. const char * Entity::_getRotation(void* obj, const char* data)
  159. {
  160. Entity* so = static_cast<Entity*>(obj);
  161. if (so)
  162. {
  163. EulerF eulRot = so->mRot.asEulerF();
  164. static const U32 bufSize = 256;
  165. char* returnBuffer = Con::getReturnBuffer(bufSize);
  166. dSprintf(returnBuffer, bufSize, "%g %g %g", mRadToDeg(eulRot.x), mRadToDeg(eulRot.y), mRadToDeg(eulRot.z));
  167. return returnBuffer;
  168. }
  169. return "0 0 0";
  170. }
  171. bool Entity::onAdd()
  172. {
  173. if (!Parent::onAdd())
  174. return false;
  175. mObjBox = Box3F(Point3F(-1, -1, -1), Point3F(1, 1, 1));
  176. resetWorldBox();
  177. setObjectBox(mObjBox);
  178. addToScene();
  179. //Make sure we get positioned
  180. setMaskBits(TransformMask);
  181. return true;
  182. }
  183. void Entity::onRemove()
  184. {
  185. clearComponents(true);
  186. removeFromScene();
  187. onDataSet.removeAll();
  188. Parent::onRemove();
  189. }
  190. void Entity::onPostAdd()
  191. {
  192. mInitialized = true;
  193. //everything's done and added. go ahead and initialize the components
  194. for (U32 i = 0; i < mComponents.size(); i++)
  195. {
  196. mComponents[i]->onComponentAdd();
  197. }
  198. if (isMethod("onAdd"))
  199. Con::executef(this, "onAdd");
  200. }
  201. void Entity::setDataField(StringTableEntry slotName, const char *array, const char *value)
  202. {
  203. Parent::setDataField(slotName, array, value);
  204. onDataSet.trigger(this, slotName, value);
  205. }
  206. void Entity::onStaticModified(const char* slotName, const char* newValue)
  207. {
  208. Parent::onStaticModified(slotName, newValue);
  209. onDataSet.trigger(this, slotName, newValue);
  210. }
  211. //Updating
  212. void Entity::processTick(const Move* move)
  213. {
  214. if (!isHidden())
  215. {
  216. if (mDelta.warpCount < mDelta.warpTicks)
  217. {
  218. mDelta.warpCount++;
  219. // Set new pos.
  220. mObjToWorld.getColumn(3, &mDelta.pos);
  221. mDelta.pos += mDelta.warpOffset;
  222. mDelta.rot[0] = mDelta.rot[1];
  223. mDelta.rot[1].interpolate(mDelta.warpRot[0], mDelta.warpRot[1], F32(mDelta.warpCount) / mDelta.warpTicks);
  224. setTransform(mDelta.pos, mDelta.rot[1]);
  225. // Pos backstepping
  226. mDelta.posVec.x = -mDelta.warpOffset.x;
  227. mDelta.posVec.y = -mDelta.warpOffset.y;
  228. mDelta.posVec.z = -mDelta.warpOffset.z;
  229. }
  230. else
  231. {
  232. if (isMounted())
  233. {
  234. MatrixF mat;
  235. mMount.object->getMountTransform(mMount.node, mMount.xfm, &mat);
  236. Parent::setTransform(mat);
  237. Parent::setRenderTransform(mat);
  238. }
  239. else
  240. {
  241. if (!move)
  242. {
  243. if (isGhost())
  244. {
  245. // If we haven't run out of prediction time,
  246. // predict using the last known move.
  247. if (mPredictionCount-- <= 0)
  248. return;
  249. move = &mDelta.move;
  250. }
  251. else
  252. {
  253. move = &NullMove;
  254. }
  255. }
  256. }
  257. }
  258. Move prevMove = lastMove;
  259. if (move != NULL)
  260. lastMove = *move;
  261. else
  262. lastMove = NullMove;
  263. if (move && isServerObject())
  264. {
  265. if ((move->y != 0 || prevMove.y != 0)
  266. || (move->x != 0 || prevMove.x != 0)
  267. || (move->z != 0 || prevMove.x != 0))
  268. {
  269. if (isMethod("moveVectorEvent"))
  270. Con::executef(this, "moveVectorEvent", move->x, move->y, move->z);
  271. }
  272. if (move->yaw != 0)
  273. {
  274. if (isMethod("moveYawEvent"))
  275. Con::executef(this, "moveYawEvent", move->yaw);
  276. }
  277. if (move->pitch != 0)
  278. {
  279. if (isMethod("movePitchEvent"))
  280. Con::executef(this, "movePitchEvent", move->pitch);
  281. }
  282. if (move->roll != 0)
  283. {
  284. if (isMethod("moveRollEvent"))
  285. Con::executef(this, "moveRollEvent", move->roll);
  286. }
  287. for (U32 i = 0; i < MaxTriggerKeys; i++)
  288. {
  289. if (move->trigger[i] != prevMove.trigger[i])
  290. {
  291. if (isMethod("moveTriggerEvent"))
  292. Con::executef(this, "moveTriggerEvent", i, move->trigger[i]);
  293. }
  294. }
  295. }
  296. if (isMethod("processTick"))
  297. Con::executef(this, "processTick");
  298. }
  299. }
  300. void Entity::advanceTime(F32 dt)
  301. {
  302. }
  303. void Entity::interpolateTick(F32 dt)
  304. {
  305. if (dt == 0.0f)
  306. {
  307. setRenderTransform(mDelta.pos, mDelta.rot[1]);
  308. }
  309. else
  310. {
  311. QuatF rot;
  312. rot.interpolate(mDelta.rot[1], mDelta.rot[0], dt);
  313. Point3F pos = mDelta.pos + mDelta.posVec * dt;
  314. setRenderTransform(pos, rot);
  315. }
  316. mDelta.dt = dt;
  317. }
  318. //Render
  319. void Entity::prepRenderImage(SceneRenderState *state)
  320. {
  321. }
  322. //Networking
  323. U32 Entity::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
  324. {
  325. U32 retMask = Parent::packUpdate(con, mask, stream);
  326. if (stream->writeFlag(mask & TransformMask))
  327. {
  328. //mathWrite( *stream, getScale() );
  329. //stream->writeAffineTransform(mObjToWorld);
  330. //mathWrite(*stream, getPosition());
  331. //mathWrite(*stream, mPos);
  332. stream->writeCompressedPoint(mPos);
  333. mathWrite(*stream, getRotation());
  334. mDelta.move.pack(stream);
  335. stream->writeFlag(!(mask & NoWarpMask));
  336. }
  337. /*if (stream->writeFlag(mask & MountedMask))
  338. {
  339. mathWrite(*stream, mMount.xfm.getPosition());
  340. mathWrite(*stream, mMount.xfm.toEuler());
  341. }*/
  342. if (stream->writeFlag(mask & BoundsMask))
  343. {
  344. mathWrite(*stream, mObjBox);
  345. }
  346. //pass our behaviors around
  347. if (mask & ComponentsMask || mask & InitialUpdateMask)
  348. {
  349. stream->writeFlag(true);
  350. //now, we run through a list of our to-be-sent behaviors and begin sending them
  351. //if any fail, we keep our list and re-queue the mask
  352. S32 componentCount = mToLoadComponents.size();
  353. //build our 'ready' list
  354. //This requires both the instance and the instances' template to be prepped(if the template hasn't been ghosted,
  355. //then we know we shouldn't be passing the instance's ghosts around yet)
  356. U32 ghostedCompCnt = 0;
  357. for (U32 i = 0; i < componentCount; i++)
  358. {
  359. if (con->getGhostIndex(mToLoadComponents[i]) != -1)
  360. ghostedCompCnt++;
  361. }
  362. if (ghostedCompCnt != 0)
  363. {
  364. stream->writeFlag(true);
  365. stream->writeFlag(mStartComponentUpdate);
  366. //if not all the behaviors have been ghosted, we'll need another pass
  367. if (ghostedCompCnt != componentCount)
  368. retMask |= ComponentsMask;
  369. //write the currently ghosted behavior count
  370. stream->writeInt(ghostedCompCnt, 16);
  371. for (U32 i = 0; i < mToLoadComponents.size(); i++)
  372. {
  373. //now fetch them and pass the ghost
  374. S32 ghostIndex = con->getGhostIndex(mToLoadComponents[i]);
  375. if (ghostIndex != -1)
  376. {
  377. stream->writeInt(ghostIndex, NetConnection::GhostIdBitSize);
  378. mToLoadComponents.erase(i);
  379. i--;
  380. mStartComponentUpdate = false;
  381. }
  382. }
  383. }
  384. else if (componentCount)
  385. {
  386. //on the odd chance we have behaviors to ghost, but NONE of them have been yet, just set the flag now
  387. stream->writeFlag(false);
  388. retMask |= ComponentsMask;
  389. }
  390. else
  391. stream->writeFlag(false);
  392. }
  393. else
  394. stream->writeFlag(false);
  395. return retMask;
  396. }
  397. void Entity::unpackUpdate(NetConnection *con, BitStream *stream)
  398. {
  399. Parent::unpackUpdate(con, stream);
  400. if (stream->readFlag())
  401. {
  402. /*Point3F scale;
  403. mathRead( *stream, &scale );
  404. setScale( scale);*/
  405. //MatrixF objToWorld;
  406. //stream->readAffineTransform(&objToWorld);
  407. Point3F pos;
  408. stream->readCompressedPoint(&pos);
  409. //mathRead(*stream, &pos);
  410. RotationF rot;
  411. mathRead(*stream, &rot);
  412. mDelta.move.unpack(stream);
  413. if (stream->readFlag() && isProperlyAdded())
  414. {
  415. // Determine number of ticks to warp based on the average
  416. // of the client and server velocities.
  417. /*mDelta.warpOffset = pos - mDelta.pos;
  418. F32 dt = mDelta.warpOffset.len() / (0.5f * TickSec);
  419. mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f);
  420. //F32 as = (speed + mVelocity.len()) * 0.5f * TickSec;
  421. //F32 dt = (as > 0.00001f) ? mDelta.warpOffset.len() / as : sMaxWarpTicks;
  422. //mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f);
  423. //mDelta.warpTicks = (S32)((dt > sMinWarpTicks) ? getMax(mFloor(dt + 0.5f), 1.0f) : 0.0f);
  424. //mDelta.warpTicks = sMaxWarpTicks;
  425. mDelta.warpTicks = 0;
  426. if (mDelta.warpTicks)
  427. {
  428. // Setup the warp to start on the next tick.
  429. if (mDelta.warpTicks > sMaxWarpTicks)
  430. mDelta.warpTicks = sMaxWarpTicks;
  431. mDelta.warpOffset /= (F32)mDelta.warpTicks;
  432. mDelta.rot[0] = rot.asQuatF();
  433. mDelta.rot[1] = rot.asQuatF();
  434. mDelta.rotOffset = rot.asEulerF() - mDelta.rot.asEulerF();
  435. // Ignore small rotation differences
  436. if (mFabs(mDelta.rotOffset.x) < 0.001f)
  437. mDelta.rotOffset.x = 0;
  438. if (mFabs(mDelta.rotOffset.y) < 0.001f)
  439. mDelta.rotOffset.y = 0;
  440. if (mFabs(mDelta.rotOffset.z) < 0.001f)
  441. mDelta.rotOffset.z = 0;
  442. mDelta.rotOffset /= (F32)mDelta.warpTicks;
  443. }
  444. else
  445. {
  446. // Going to skip the warp, server and client are real close.
  447. // Adjust the frame interpolation to move smoothly to the
  448. // new position within the current tick.
  449. Point3F cp = mDelta.pos + mDelta.posVec * mDelta.dt;
  450. if (mDelta.dt == 0)
  451. {
  452. mDelta.posVec.set(0.0f, 0.0f, 0.0f);
  453. mDelta.rotVec.set(0.0f, 0.0f, 0.0f);
  454. }
  455. else
  456. {
  457. F32 dti = 1.0f / mDelta.dt;
  458. mDelta.posVec = (cp - pos) * dti;
  459. mDelta.rotVec.z = mRot.z - rot.z;
  460. mDelta.rotVec.z *= dti;
  461. }
  462. mDelta.pos = pos;
  463. mDelta.rot = rot;
  464. setTransform(pos, rot);
  465. }*/
  466. Point3F cp = mDelta.pos + mDelta.posVec * mDelta.dt;
  467. mDelta.warpOffset = pos - cp;
  468. // Calc the distance covered in one tick as the average of
  469. // the old speed and the new speed from the server.
  470. VectorF vel = pos - mDelta.pos;
  471. F32 dt, as = vel.len() * 0.5 * TickSec;
  472. // Cal how many ticks it will take to cover the warp offset.
  473. // If it's less than what's left in the current tick, we'll just
  474. // warp in the remaining time.
  475. if (!as || (dt = mDelta.warpOffset.len() / as) > sMaxWarpTicks)
  476. dt = mDelta.dt + sMaxWarpTicks;
  477. else
  478. dt = (dt <= mDelta.dt) ? mDelta.dt : mCeil(dt - mDelta.dt) + mDelta.dt;
  479. // Adjust current frame interpolation
  480. if (mDelta.dt)
  481. {
  482. mDelta.pos = cp + (mDelta.warpOffset * (mDelta.dt / dt));
  483. mDelta.posVec = (cp - mDelta.pos) / mDelta.dt;
  484. QuatF cr;
  485. cr.interpolate(mDelta.rot[1], mDelta.rot[0], mDelta.dt);
  486. mDelta.rot[1].interpolate(cr, rot.asQuatF(), mDelta.dt / dt);
  487. mDelta.rot[0].extrapolate(mDelta.rot[1], cr, mDelta.dt);
  488. }
  489. // Calculated multi-tick warp
  490. mDelta.warpCount = 0;
  491. mDelta.warpTicks = (S32)(mFloor(dt));
  492. if (mDelta.warpTicks)
  493. {
  494. mDelta.warpOffset = pos - mDelta.pos;
  495. mDelta.warpOffset /= mDelta.warpTicks;
  496. mDelta.warpRot[0] = mDelta.rot[1];
  497. mDelta.warpRot[1] = rot.asQuatF();
  498. }
  499. }
  500. else
  501. {
  502. // Set the entity to the server position
  503. mDelta.dt = 0;
  504. mDelta.pos = pos;
  505. mDelta.posVec.set(0, 0, 0);
  506. mDelta.rot[1] = mDelta.rot[0] = rot.asQuatF();
  507. mDelta.warpCount = mDelta.warpTicks = 0;
  508. setTransform(pos, rot);
  509. }
  510. }
  511. /*if (stream->readFlag())
  512. {
  513. Point3F mountOffset;
  514. EulerF mountRot;
  515. mathRead(*stream, &mountOffset);
  516. mathRead(*stream, &mountRot);
  517. RotationF rot = RotationF(mountRot);
  518. mountRot = rot.asEulerF(RotationF::Degrees);
  519. setMountOffset(mountOffset);
  520. setMountRotation(mountRot);
  521. }*/
  522. if (stream->readFlag())
  523. {
  524. mathRead(*stream, &mObjBox);
  525. resetWorldBox();
  526. }
  527. if (stream->readFlag())
  528. {
  529. //are we passing any behaviors currently?
  530. if (stream->readFlag())
  531. {
  532. //if we've just started the update, clear our behaviors
  533. if (stream->readFlag())
  534. clearComponents(false);
  535. S32 componentCount = stream->readInt(16);
  536. for (U32 i = 0; i < componentCount; i++)
  537. {
  538. S32 gIndex = stream->readInt(NetConnection::GhostIdBitSize);
  539. addComponent(dynamic_cast<Component*>(con->resolveGhost(gIndex)));
  540. }
  541. }
  542. }
  543. }
  544. //Manipulation
  545. void Entity::setTransform(const MatrixF &mat)
  546. {
  547. //setMaskBits(TransformMask);
  548. setMaskBits(TransformMask | NoWarpMask);
  549. if (isMounted())
  550. {
  551. // Use transform from mounted object
  552. Point3F newPos = mat.getPosition();
  553. Point3F parentPos = mMount.object->getTransform().getPosition();
  554. Point3F newOffset = newPos - parentPos;
  555. if (!newOffset.isZero())
  556. {
  557. //setMountOffset(newOffset);
  558. mPos = newOffset;
  559. }
  560. Point3F matEul = mat.toEuler();
  561. //mRot = Point3F(mRadToDeg(matEul.x), mRadToDeg(matEul.y), mRadToDeg(matEul.z));
  562. if (matEul != Point3F(0, 0, 0))
  563. {
  564. Point3F mountEul = mMount.object->getTransform().toEuler();
  565. Point3F diff = matEul - mountEul;
  566. //setMountRotation(Point3F(mRadToDeg(diff.x), mRadToDeg(diff.y), mRadToDeg(diff.z)));
  567. mRot = diff;
  568. }
  569. else
  570. {
  571. //setMountRotation(Point3F(0, 0, 0));
  572. mRot = Point3F(0, 0, 0);
  573. }
  574. RotationF addRot = mRot + RotationF(mMount.object->getTransform());
  575. MatrixF transf = addRot.asMatrixF();
  576. transf.setPosition(mPos + mMount.object->getPosition());
  577. Parent::setTransform(transf);
  578. }
  579. else
  580. {
  581. //Are we part of a prefab?
  582. /*Prefab* p = Prefab::getPrefabByChild(this);
  583. if (p)
  584. {
  585. //just let our prefab know we moved
  586. p->childTransformUpdated(this, mat);
  587. }*/
  588. //else
  589. {
  590. //mRot.set(mat);
  591. //Parent::setTransform(mat);
  592. RotationF rot = RotationF(mat);
  593. EulerF tempRot = rot.asEulerF(RotationF::Degrees);
  594. Point3F pos;
  595. mat.getColumn(3,&pos);
  596. setTransform(pos, rot);
  597. }
  598. }
  599. }
  600. void Entity::setTransform(Point3F position, RotationF rotation)
  601. {
  602. if (isMounted())
  603. {
  604. mPos = position;
  605. mRot = rotation;
  606. RotationF addRot = mRot + RotationF(mMount.object->getTransform());
  607. MatrixF transf = addRot.asMatrixF();
  608. transf.setPosition(mPos + mMount.object->getPosition());
  609. Parent::setTransform(transf);
  610. setMaskBits(TransformMask);
  611. }
  612. else
  613. {
  614. /*MatrixF newMat, imat, xmat, ymat, zmat;
  615. Point3F radRot = Point3F(mDegToRad(rotation.x), mDegToRad(rotation.y), mDegToRad(rotation.z));
  616. xmat.set(EulerF(radRot.x, 0, 0));
  617. ymat.set(EulerF(0.0f, radRot.y, 0.0f));
  618. zmat.set(EulerF(0, 0, radRot.z));
  619. imat.mul(zmat, xmat);
  620. newMat.mul(imat, ymat);*/
  621. MatrixF newMat = rotation.asMatrixF();
  622. newMat.setColumn(3, position);
  623. mPos = position;
  624. mRot = rotation;
  625. setMaskBits(TransformMask);
  626. //if (isServerObject())
  627. // setMaskBits(TransformMask);
  628. //setTransform(temp);
  629. // This test is a bit expensive so turn it off in release.
  630. #ifdef TORQUE_DEBUG
  631. //AssertFatal( mat.isAffine(), "SceneObject::setTransform() - Bad transform (non affine)!" );
  632. #endif
  633. //PROFILE_SCOPE(Entity_setTransform);
  634. // Update the transforms.
  635. Parent::setTransform(newMat);
  636. onTransformSet.trigger(&newMat);
  637. /*mObjToWorld = mWorldToObj = newMat;
  638. mWorldToObj.affineInverse();
  639. // Update the world-space AABB.
  640. resetWorldBox();
  641. // If we're in a SceneManager, sync our scene state.
  642. if (mSceneManager != NULL)
  643. mSceneManager->notifyObjectDirty(this);
  644. setRenderTransform(newMat);*/
  645. }
  646. }
  647. void Entity::setRenderTransform(const MatrixF &mat)
  648. {
  649. Parent::setRenderTransform(mat);
  650. }
  651. void Entity::setRenderTransform(Point3F position, RotationF rotation)
  652. {
  653. if (isMounted())
  654. {
  655. mPos = position;
  656. mRot = rotation;
  657. RotationF addRot = mRot + RotationF(mMount.object->getTransform());
  658. MatrixF transf = addRot.asMatrixF();
  659. transf.setPosition(mPos + mMount.object->getPosition());
  660. Parent::setRenderTransform(transf);
  661. }
  662. else
  663. {
  664. MatrixF newMat = rotation.asMatrixF();
  665. newMat.setColumn(3, position);
  666. mPos = position;
  667. mRot = rotation;
  668. Parent::setRenderTransform(newMat);
  669. onTransformSet.trigger(&newMat);
  670. }
  671. }
  672. MatrixF Entity::getTransform()
  673. {
  674. if (isMounted())
  675. {
  676. MatrixF mat;
  677. //Use transform from mount
  678. mMount.object->getMountTransform(mMount.node, mMount.xfm, &mat);
  679. Point3F transPos = mat.getPosition() + mPos;
  680. mat.mul(mRot.asMatrixF());
  681. mat.setPosition(transPos);
  682. return mat;
  683. }
  684. else
  685. {
  686. return Parent::getTransform();
  687. }
  688. }
  689. void Entity::setMountOffset(Point3F posOffset)
  690. {
  691. if (isMounted())
  692. {
  693. mMount.xfm.setColumn(3, posOffset);
  694. //mPos = posOffset;
  695. setMaskBits(MountedMask);
  696. }
  697. }
  698. void Entity::setMountRotation(EulerF rotOffset)
  699. {
  700. if (isMounted())
  701. {
  702. MatrixF temp, imat, xmat, ymat, zmat;
  703. Point3F radRot = Point3F(mDegToRad(rotOffset.x), mDegToRad(rotOffset.y), mDegToRad(rotOffset.z));
  704. xmat.set(EulerF(radRot.x, 0, 0));
  705. ymat.set(EulerF(0.0f, radRot.y, 0.0f));
  706. zmat.set(EulerF(0, 0, radRot.z));
  707. imat.mul(zmat, xmat);
  708. temp.mul(imat, ymat);
  709. temp.setColumn(3, mMount.xfm.getPosition());
  710. mMount.xfm = temp;
  711. //mRot = RotationF(temp);
  712. setMaskBits(MountedMask);
  713. }
  714. }
  715. //
  716. void Entity::getCameraTransform(F32* pos, MatrixF* mat)
  717. {
  718. Vector<CameraInterface*> updaters = getComponents<CameraInterface>();
  719. for (Vector<CameraInterface*>::iterator it = updaters.begin(); it != updaters.end(); it++)
  720. {
  721. if ((*it)->getCameraTransform(pos, mat))
  722. {
  723. return;
  724. }
  725. }
  726. }
  727. void Entity::getMountTransform(S32 index, const MatrixF &xfm, MatrixF *outMat)
  728. {
  729. RenderComponentInterface* renderInterface = getComponent<RenderComponentInterface>();
  730. if (renderInterface)
  731. {
  732. renderInterface->getShapeInstance()->animate();
  733. S32 nodeCount = renderInterface->getShapeInstance()->getShape()->nodes.size();
  734. if (index >= 0 && index < nodeCount)
  735. {
  736. MatrixF mountTransform = renderInterface->getShapeInstance()->mNodeTransforms[index];
  737. mountTransform.mul(xfm);
  738. const Point3F& scale = getScale();
  739. // The position of the mount point needs to be scaled.
  740. Point3F position = mountTransform.getPosition();
  741. position.convolve(scale);
  742. mountTransform.setPosition(position);
  743. // Also we would like the object to be scaled to the model.
  744. outMat->mul(mObjToWorld, mountTransform);
  745. return;
  746. }
  747. }
  748. // Then let SceneObject handle it.
  749. Parent::getMountTransform(index, xfm, outMat);
  750. }
  751. void Entity::getRenderMountTransform(F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat)
  752. {
  753. RenderComponentInterface* renderInterface = getComponent<RenderComponentInterface>();
  754. if (renderInterface && renderInterface->getShapeInstance())
  755. {
  756. renderInterface->getShapeInstance()->animate();
  757. S32 nodeCount = renderInterface->getShapeInstance()->getShape()->nodes.size();
  758. if (index >= 0 && index < nodeCount)
  759. {
  760. MatrixF mountTransform = renderInterface->getShapeInstance()->mNodeTransforms[index];
  761. mountTransform.mul(xfm);
  762. const Point3F& scale = getScale();
  763. // The position of the mount point needs to be scaled.
  764. Point3F position = mountTransform.getPosition();
  765. position.convolve(scale);
  766. mountTransform.setPosition(position);
  767. // Also we would like the object to be scaled to the model.
  768. outMat->mul(getRenderTransform(), mountTransform);
  769. return;
  770. }
  771. }
  772. // Then let SceneObject handle it.
  773. Parent::getMountTransform(index, xfm, outMat);
  774. }
  775. void Entity::setForwardVector(VectorF newForward, VectorF upVector)
  776. {
  777. MatrixF mat = getTransform();
  778. VectorF up(0.0f, 0.0f, 1.0f);
  779. VectorF axisX;
  780. VectorF axisY = newForward;
  781. VectorF axisZ;
  782. if (upVector != VectorF::Zero)
  783. up = upVector;
  784. // Validate and normalize input:
  785. F32 lenSq;
  786. lenSq = axisY.lenSquared();
  787. if (lenSq < 0.000001f)
  788. {
  789. axisY.set(0.0f, 1.0f, 0.0f);
  790. Con::errorf("Entity::setForwardVector() - degenerate forward vector");
  791. }
  792. else
  793. {
  794. axisY /= mSqrt(lenSq);
  795. }
  796. lenSq = up.lenSquared();
  797. if (lenSq < 0.000001f)
  798. {
  799. up.set(0.0f, 0.0f, 1.0f);
  800. Con::errorf("SceneObject::setForwardVector() - degenerate up vector - too small");
  801. }
  802. else
  803. {
  804. up /= mSqrt(lenSq);
  805. }
  806. if (fabsf(mDot(up, axisY)) > 0.9999f)
  807. {
  808. Con::errorf("SceneObject::setForwardVector() - degenerate up vector - same as forward");
  809. // i haven't really tested this, but i think it generates something which should be not parallel to the previous vector:
  810. F32 tmp = up.x;
  811. up.x = -up.y;
  812. up.y = up.z;
  813. up.z = tmp;
  814. }
  815. // construct the remaining axes:
  816. mCross(axisY, up, &axisX);
  817. mCross(axisX, axisY, &axisZ);
  818. mat.setColumn(0, axisX);
  819. mat.setColumn(1, axisY);
  820. mat.setColumn(2, axisZ);
  821. setTransform(mat);
  822. }
  823. //
  824. //These basically just redirect to any collision behaviors we have
  825. bool Entity::castRay(const Point3F &start, const Point3F &end, RayInfo* info)
  826. {
  827. Vector<CastRayInterface*> updaters = getComponents<CastRayInterface>();
  828. for (Vector<CastRayInterface*>::iterator it = updaters.begin(); it != updaters.end(); it++)
  829. {
  830. if ((*it)->castRay(start, end, info))
  831. {
  832. return true;
  833. }
  834. }
  835. return false;
  836. }
  837. bool Entity::castRayRendered(const Point3F &start, const Point3F &end, RayInfo *info)
  838. {
  839. Vector<CastRayRenderedInterface*> updaters = getComponents<CastRayRenderedInterface>();
  840. for (Vector<CastRayRenderedInterface*>::iterator it = updaters.begin(); it != updaters.end(); it++)
  841. {
  842. if ((*it)->castRayRendered(start, end, info))
  843. {
  844. return true;
  845. }
  846. }
  847. return false;
  848. }
  849. bool Entity::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere)
  850. {
  851. Vector<BuildPolyListInterface*> updaters = getComponents<BuildPolyListInterface>();
  852. for (Vector<BuildPolyListInterface*>::iterator it = updaters.begin(); it != updaters.end(); it++)
  853. {
  854. return (*it)->buildPolyList(context, polyList, box, sphere);
  855. }
  856. return false;
  857. }
  858. void Entity::buildConvex(const Box3F& box, Convex* convex)
  859. {
  860. Vector<BuildConvexInterface*> updaters = getComponents<BuildConvexInterface>();
  861. for (Vector<BuildConvexInterface*>::iterator it = updaters.begin(); it != updaters.end(); it++)
  862. {
  863. (*it)->buildConvex(box, convex);
  864. }
  865. }
  866. //
  867. // Mounting and heirarchy manipulation
  868. void Entity::mountObject(SceneObject* objB, MatrixF txfm)
  869. {
  870. Parent::mountObject(objB, -1, txfm);
  871. Parent::addObject(objB);
  872. }
  873. void Entity::mountObject(SceneObject *obj, S32 node, const MatrixF &xfm)
  874. {
  875. Parent::mountObject(obj, node, xfm);
  876. }
  877. void Entity::onMount(SceneObject *obj, S32 node)
  878. {
  879. deleteNotify(obj);
  880. // Are we mounting to a GameBase object?
  881. Entity *entityObj = dynamic_cast<Entity*>(obj);
  882. if (entityObj && entityObj->getControlObject() != this)
  883. processAfter(entityObj);
  884. if (!isGhost()) {
  885. setMaskBits(MountedMask);
  886. //TODO implement this callback
  887. //onMount_callback( this, obj, node );
  888. }
  889. }
  890. void Entity::onUnmount(SceneObject *obj, S32 node)
  891. {
  892. clearNotify(obj);
  893. Entity *entityObj = dynamic_cast<Entity*>(obj);
  894. if (entityObj && entityObj->getControlObject() != this)
  895. clearProcessAfter();
  896. if (!isGhost()) {
  897. setMaskBits(MountedMask);
  898. //TODO implement this callback
  899. //onUnmount_callback( this, obj, node );
  900. }
  901. }
  902. //Heirarchy stuff
  903. void Entity::addObject(SimObject* object)
  904. {
  905. Component* component = dynamic_cast<Component*>(object);
  906. if (component)
  907. {
  908. addComponent(component);
  909. return;
  910. }
  911. Entity* e = dynamic_cast<Entity*>(object);
  912. if (e)
  913. {
  914. MatrixF offset;
  915. //offset.mul(getWorldTransform(), e->getWorldTransform());
  916. //check if we're mounting to a node on a shape we have
  917. String node = e->getDataField("mountNode", NULL);
  918. if (!node.isEmpty())
  919. {
  920. RenderComponentInterface *renderInterface = getComponent<RenderComponentInterface>();
  921. if (renderInterface)
  922. {
  923. TSShape* shape = renderInterface->getShape();
  924. S32 nodeIdx = shape->findNode(node);
  925. mountObject(e, nodeIdx, MatrixF::Identity);
  926. }
  927. else
  928. {
  929. mountObject(e, MatrixF::Identity);
  930. }
  931. }
  932. else
  933. {
  934. /*Point3F posOffset = mPos - e->getPosition();
  935. mPos = posOffset;
  936. RotationF rotOffset = mRot - e->getRotation();
  937. mRot = rotOffset;
  938. setMaskBits(TransformMask);
  939. mountObject(e, MatrixF::Identity);*/
  940. mountObject(e, MatrixF::Identity);
  941. }
  942. //e->setMountOffset(e->getPosition() - getPosition());
  943. //Point3F diff = getWorldTransform().toEuler() - e->getWorldTransform().toEuler();
  944. //e->setMountRotation(Point3F(mRadToDeg(diff.x),mRadToDeg(diff.y),mRadToDeg(diff.z)));
  945. //mountObject(e, offset);
  946. }
  947. else
  948. {
  949. SceneObject* so = dynamic_cast<SceneObject*>(object);
  950. if (so)
  951. {
  952. //get the difference and build it as our offset!
  953. Point3F posOffset = so->getPosition() - mPos;
  954. RotationF rotOffset = RotationF(so->getTransform()) - mRot;
  955. MatrixF offset = rotOffset.asMatrixF();
  956. offset.setPosition(posOffset);
  957. mountObject(so, offset);
  958. return;
  959. }
  960. }
  961. Parent::addObject(object);
  962. }
  963. void Entity::removeObject(SimObject* object)
  964. {
  965. Entity* e = dynamic_cast<Entity*>(object);
  966. if (e)
  967. {
  968. mPos = mPos + e->getPosition();
  969. mRot = mRot + e->getRotation();
  970. unmountObject(e);
  971. setMaskBits(TransformMask);
  972. }
  973. else
  974. {
  975. SceneObject* so = dynamic_cast<SceneObject*>(object);
  976. if (so)
  977. unmountObject(so);
  978. }
  979. Parent::removeObject(object);
  980. }
  981. bool Entity::addComponent(Component *comp)
  982. {
  983. if (comp == NULL)
  984. return false;
  985. //double-check were not re-adding anything
  986. mComponents.push_back(comp);
  987. // Register the component with this owner.
  988. comp->setOwner(this);
  989. //if we've already been added and this is being added after the fact(at runtime),
  990. //then just go ahead and call it's onComponentAdd so it can get to work
  991. if (mInitialized)
  992. comp->onComponentAdd();
  993. onComponentAdded.trigger(comp);
  994. return true;
  995. }
  996. SimObject* Entity::findObjectByInternalName(StringTableEntry internalName, bool searchChildren)
  997. {
  998. for (U32 i = 0; i < mComponents.size(); i++)
  999. {
  1000. if (mComponents[i]->getInternalName() == internalName)
  1001. {
  1002. return mComponents[i];
  1003. }
  1004. }
  1005. return Parent::findObjectByInternalName(internalName, searchChildren);
  1006. }
  1007. //////////////////////////////////////////////////////////////////////////
  1008. bool Entity::removeComponent(Component *comp, bool deleteComponent)
  1009. {
  1010. if (comp == NULL)
  1011. return false;
  1012. if(mComponents.remove(comp))
  1013. {
  1014. AssertFatal(comp->isProperlyAdded(), "Don't know how but a component is not registered w/ the sim");
  1015. //setComponentsDirty();
  1016. onComponentRemoved.trigger(comp);
  1017. comp->setOwner(NULL);
  1018. comp->onComponentRemove(); //in case the behavior needs to do cleanup on the owner
  1019. if (deleteComponent)
  1020. comp->safeDeleteObject();
  1021. return true;
  1022. }
  1023. return false;
  1024. }
  1025. //////////////////////////////////////////////////////////////////////////
  1026. //NOTE:
  1027. //The actor class calls this and flags the deletion of the behaviors to false so that behaviors that should no longer be attached during
  1028. //a network update will indeed be removed from the object. The reason it doesn't delete them is because when clearing the local behavior
  1029. //list, it would delete them, purging the ghost, and causing a crash when the unpack update tried to fetch any existing behaviors' ghosts
  1030. //to re-add them. Need to implement a clean clear function that will clear the local list, and only delete unused behaviors during an update.
  1031. void Entity::clearComponents(bool deleteComponents)
  1032. {
  1033. bool srv = isServerObject();
  1034. if (!deleteComponents)
  1035. {
  1036. while (mComponents.size() > 0)
  1037. {
  1038. removeComponent(mComponents.first(), deleteComponents);
  1039. }
  1040. }
  1041. else
  1042. {
  1043. while (mComponents.size() > 0)
  1044. {
  1045. Component* comp = mComponents.first();
  1046. if (comp)
  1047. {
  1048. comp->onComponentRemove(); //in case the behavior needs to do cleanup on the owner
  1049. bool removed = mComponents.remove(comp);
  1050. //we only need to delete them on the server side. they'll be cleaned up on the client side
  1051. //via the ghosting system for us
  1052. if (isServerObject())
  1053. comp->deleteObject();
  1054. }
  1055. }
  1056. }
  1057. }
  1058. //////////////////////////////////////////////////////////////////////////
  1059. Component *Entity::getComponent(const U32 index) const
  1060. {
  1061. if (index < mComponents.size())
  1062. return mComponents[index];
  1063. return NULL;
  1064. }
  1065. Component *Entity::getComponent(String componentType)
  1066. {
  1067. for (U32 i = 0; i < mComponents.size(); i++)
  1068. {
  1069. Component* comp = mComponents[i];
  1070. /*String namespaceName = comp->getNamespace()->mName;
  1071. //check our namespace first
  1072. if (namespaceName == componentType)
  1073. {
  1074. return comp;
  1075. }
  1076. else
  1077. {*/
  1078. //lets scan up, just to be sure
  1079. Namespace *NS = comp->getNamespace();
  1080. //we shouldn't ever go past Component into net object, as we're no longer dealing with component classes
  1081. while (dStrcmp(NS->getName(), "NetObject"))
  1082. {
  1083. String namespaceName = NS->getName();
  1084. if (namespaceName == componentType)
  1085. {
  1086. return comp;
  1087. }
  1088. else
  1089. {
  1090. NS = NS->getParent();
  1091. }
  1092. }
  1093. //}
  1094. }
  1095. return NULL;
  1096. }
  1097. void Entity::onInspect()
  1098. {
  1099. Vector<EditorInspectInterface*> updaters = getComponents<EditorInspectInterface>();
  1100. for (Vector<EditorInspectInterface*>::iterator it = updaters.begin(); it != updaters.end(); it++)
  1101. {
  1102. (*it)->onInspect();
  1103. }
  1104. GuiTreeViewCtrl *editorTree = dynamic_cast<GuiTreeViewCtrl*>(Sim::findObject("EditorTree"));
  1105. if (!editorTree)
  1106. return;
  1107. GuiTreeViewCtrl::Item *newItem, *parentItem;
  1108. parentItem = editorTree->getItem(editorTree->findItemByObjectId(getId()));
  1109. S32 componentID = editorTree->insertItem(parentItem->getID(), "Components");
  1110. newItem = editorTree->getItem(componentID);
  1111. newItem->mState.set(GuiTreeViewCtrl::Item::VirtualParent);
  1112. newItem->mState.set(GuiTreeViewCtrl::Item::DenyDrag);
  1113. //newItem->mState.set(GuiTreeViewCtrl::Item::InspectorData);
  1114. newItem->mState.set(GuiTreeViewCtrl::Item::ForceItemName);
  1115. //newItem->mInspectorInfo.mObject = this;
  1116. AssetManager *assetDB = dynamic_cast<AssetManager*>(Sim::findObject("AssetDatabase"));
  1117. if (!assetDB)
  1118. return;
  1119. //This is used in the event of script-created assets, which likely only have
  1120. //the name and other 'friendly' properties stored in a ComponentAsset.
  1121. //So we'll do a query for those assets and find the asset based on the component's
  1122. //class name
  1123. AssetQuery* qry = new AssetQuery();
  1124. qry->registerObject();
  1125. assetDB->findAssetType(qry, "ComponentAsset");
  1126. for (U32 i = 0; i < mComponents.size(); ++i)
  1127. {
  1128. String compName = mComponents[i]->getFriendlyName();
  1129. if (compName == String(""))
  1130. {
  1131. String componentClass = mComponents[i]->getClassNamespace();
  1132. //Means that it's a script-derived component and we should consult the asset to try
  1133. //to get the info for it
  1134. S32 compAssetCount = qry->mAssetList.size();
  1135. for (U32 c = 0; c < compAssetCount; ++c)
  1136. {
  1137. StringTableEntry assetID = qry->mAssetList[c];
  1138. ComponentAsset* compAsset = assetDB->acquireAsset<ComponentAsset>(assetID);
  1139. String compAssetClass = compAsset->getComponentName();
  1140. if (componentClass == compAssetClass)
  1141. {
  1142. compName = compAsset->getFriendlyName();
  1143. break;
  1144. }
  1145. }
  1146. }
  1147. S32 compID = editorTree->insertItem(componentID, compName);
  1148. newItem = editorTree->getItem(compID);
  1149. newItem->mInspectorInfo.mObject = mComponents[i];
  1150. newItem->mState.set(GuiTreeViewCtrl::Item::ForceItemName);
  1151. newItem->mState.set(GuiTreeViewCtrl::Item::DenyDrag);
  1152. newItem->mState.set(GuiTreeViewCtrl::Item::InspectorData);
  1153. }
  1154. editorTree->buildVisibleTree(true);
  1155. }
  1156. void Entity::onEndInspect()
  1157. {
  1158. Vector<EditorInspectInterface*> updaters = getComponents<EditorInspectInterface>();
  1159. for (Vector<EditorInspectInterface*>::iterator it = updaters.begin(); it != updaters.end(); it++) {
  1160. (*it)->onEndInspect();
  1161. }
  1162. GuiTreeViewCtrl *editorTree = dynamic_cast<GuiTreeViewCtrl*>(Sim::findObject("EditorTree"));
  1163. if (!editorTree)
  1164. return;
  1165. S32 componentItemIdx = editorTree->findItemByName("Components");
  1166. editorTree->removeItem(componentItemIdx, false);
  1167. }
  1168. static void writeTabs(Stream &stream, U32 count)
  1169. {
  1170. char tab[] = " ";
  1171. while (count--)
  1172. stream.write(3, (void*)tab);
  1173. }
  1174. void Entity::write(Stream &stream, U32 tabStop, U32 flags)
  1175. {
  1176. // Do *not* call parent on this
  1177. /*VectorPtr<ComponentObject *> &componentList = lockComponentList();
  1178. // export selected only?
  1179. if( ( flags & SelectedOnly ) && !isSelected() )
  1180. {
  1181. for( BehaviorObjectIterator i = componentList.begin(); i != componentList.end(); i++ )
  1182. (*i)->write(stream, tabStop, flags);
  1183. goto write_end;
  1184. }*/
  1185. //catch if we have any written behavior fields already in the file, and clear them. We don't need to double-up
  1186. //the entries for no reason.
  1187. /*if(getFieldDictionary())
  1188. {
  1189. //get our dynamic field count, then parse through them to see if they're a behavior or not
  1190. //reset it
  1191. SimFieldDictionary* fieldDictionary = getFieldDictionary();
  1192. SimFieldDictionaryIterator itr(fieldDictionary);
  1193. for (S32 i = 0; i < fieldDictionary->getNumFields(); i++)
  1194. {
  1195. if (!(*itr))
  1196. break;
  1197. SimFieldDictionary::Entry* entry = *itr;
  1198. if(strstr(entry->slotName, "_behavior"))
  1199. {
  1200. entry->slotName = "";
  1201. entry->value = "";
  1202. }
  1203. ++itr;
  1204. }
  1205. }*/
  1206. //all existing written behavior fields should be cleared. now write the object block
  1207. writeTabs(stream, tabStop);
  1208. char buffer[1024];
  1209. dSprintf(buffer, sizeof(buffer), "new %s(%s) {\r\n", getClassName(), getName() ? getName() : "");
  1210. stream.write(dStrlen(buffer), buffer);
  1211. writeFields(stream, tabStop + 1);
  1212. stream.write(1, "\n");
  1213. ////first, write out our behavior objects
  1214. // NOW we write the behavior fields proper
  1215. if (mComponents.size() > 0)
  1216. {
  1217. // Pack out the behaviors into fields
  1218. U32 i = 0;
  1219. for (U32 i = 0; i < mComponents.size(); i++)
  1220. {
  1221. writeTabs(stream, tabStop + 1);
  1222. char buffer[1024];
  1223. dSprintf(buffer, sizeof(buffer), "new %s() {\r\n", mComponents[i]->getClassName());
  1224. stream.write(dStrlen(buffer), buffer);
  1225. //bi->writeFields( stream, tabStop + 2 );
  1226. mComponents[i]->packToStream(stream, tabStop + 2, i - 1, flags);
  1227. writeTabs(stream, tabStop + 1);
  1228. stream.write(4, "};\r\n");
  1229. }
  1230. }
  1231. //
  1232. //if (size() > 0)
  1233. // stream.write(2, "\r\n");
  1234. for (U32 i = 0; i < size(); i++)
  1235. {
  1236. SimObject* child = (*this)[i];
  1237. if (child->getCanSave())
  1238. child->write(stream, tabStop + 1, flags);
  1239. }
  1240. //stream.write(2, "\r\n");
  1241. writeTabs(stream, tabStop);
  1242. stream.write(4, "};\r\n");
  1243. //write_end:
  1244. //unlockComponentList();
  1245. }
  1246. SimObject* Entity::getTamlChild(const U32 childIndex) const
  1247. {
  1248. // Sanity!
  1249. AssertFatal(childIndex < getTamlChildCount(), "SimSet::getTamlChild() - Child index is out of range.");
  1250. // For when the assert is not used.
  1251. if (childIndex >= getTamlChildCount())
  1252. return NULL;
  1253. //we always order components first, child objects second
  1254. if (childIndex >= getComponentCount())
  1255. return at(childIndex - getComponentCount());
  1256. else
  1257. return getComponent(childIndex);
  1258. }
  1259. //
  1260. void Entity::onCameraScopeQuery(NetConnection* connection, CameraScopeQuery* query)
  1261. {
  1262. // Object itself is in scope.
  1263. Parent::onCameraScopeQuery(connection, query);
  1264. if (CameraInterface* cI = getComponent<CameraInterface>())
  1265. {
  1266. cI->onCameraScopeQuery(connection, query);
  1267. }
  1268. }
  1269. //
  1270. void Entity::setObjectBox(Box3F objBox)
  1271. {
  1272. mObjBox = objBox;
  1273. resetWorldBox();
  1274. if (isServerObject())
  1275. setMaskBits(BoundsMask);
  1276. }
  1277. void Entity::updateContainer()
  1278. {
  1279. PROFILE_SCOPE(Entity_updateContainer);
  1280. // Update container drag and buoyancy properties
  1281. containerInfo.box = getWorldBox();
  1282. //containerInfo.mass = mMass;
  1283. getContainer()->findObjects(containerInfo.box, WaterObjectType | PhysicalZoneObjectType, findRouter, &containerInfo);
  1284. //mWaterCoverage = info.waterCoverage;
  1285. //mLiquidType = info.liquidType;
  1286. //mLiquidHeight = info.waterHeight;
  1287. //setCurrentWaterObject( info.waterObject );
  1288. // This value might be useful as a datablock value,
  1289. // This is what allows the player to stand in shallow water (below this coverage)
  1290. // without jiggling from buoyancy
  1291. /*if (info.waterCoverage >= 0.25f)
  1292. {
  1293. // water viscosity is used as drag for in water.
  1294. // ShapeBaseData drag is used for drag outside of water.
  1295. // Combine these two components to calculate this ShapeBase object's
  1296. // current drag.
  1297. mDrag = (info.waterCoverage * info.waterViscosity) +
  1298. (1.0f - info.waterCoverage) * mDrag;
  1299. //mBuoyancy = (info.waterDensity / mDataBlock->density) * info.waterCoverage;
  1300. }
  1301. //mAppliedForce = info.appliedForce;
  1302. mGravityMod = info.gravityScale;*/
  1303. }
  1304. //
  1305. void Entity::setComponentsDirty()
  1306. {
  1307. if (mToLoadComponents.empty())
  1308. mStartComponentUpdate = true;
  1309. //we need to build a list of behaviors that need to be pushed across the network
  1310. for (U32 i = 0; i < mComponents.size(); i++)
  1311. {
  1312. // We can do this because both are in the string table
  1313. Component *comp = mComponents[i];
  1314. if (comp->isNetworked())
  1315. {
  1316. bool unique = true;
  1317. for (U32 i = 0; i < mToLoadComponents.size(); i++)
  1318. {
  1319. if (mToLoadComponents[i]->getId() == comp->getId())
  1320. {
  1321. unique = false;
  1322. break;
  1323. }
  1324. }
  1325. if (unique)
  1326. mToLoadComponents.push_back(comp);
  1327. }
  1328. }
  1329. setMaskBits(ComponentsMask);
  1330. }
  1331. void Entity::setComponentDirty(Component *comp, bool forceUpdate)
  1332. {
  1333. bool found = false;
  1334. for (U32 i = 0; i < mComponents.size(); i++)
  1335. {
  1336. if (mComponents[i]->getId() == comp->getId())
  1337. {
  1338. mComponents[i]->setOwner(this);
  1339. return;
  1340. }
  1341. }
  1342. if (!found)
  1343. return;
  1344. //if(mToLoadComponents.empty())
  1345. // mStartComponentUpdate = true;
  1346. /*if (comp->isNetworked() || forceUpdate)
  1347. {
  1348. bool unique = true;
  1349. for (U32 i = 0; i < mToLoadComponents.size(); i++)
  1350. {
  1351. if (mToLoadComponents[i]->getId() == comp->getId())
  1352. {
  1353. unique = false;
  1354. break;
  1355. }
  1356. }
  1357. if (unique)
  1358. mToLoadComponents.push_back(comp);
  1359. }
  1360. setMaskBits(ComponentsMask);*/
  1361. }
  1362. DefineEngineMethod(Entity, mountObject, bool,
  1363. (SceneObject* objB, TransformF txfm), (MatrixF::Identity),
  1364. "@brief Mount objB to this object at the desired slot with optional transform.\n\n"
  1365. "@param objB Object to mount onto us\n"
  1366. "@param slot Mount slot ID\n"
  1367. "@param txfm (optional) mount offset transform\n"
  1368. "@return true if successful, false if failed (objB is not valid)")
  1369. {
  1370. if (objB)
  1371. {
  1372. //BUG: Unsure how it broke, but atm the default transform passed in here is rotated 180 degrees. This doesn't happen
  1373. //for the SceneObject mountobject method. Hackish, but for now, just default to a clean MatrixF::Identity
  1374. object->mountObject(objB, /*MatrixF::Identity*/txfm.getMatrix());
  1375. return true;
  1376. }
  1377. return false;
  1378. }
  1379. DefineEngineMethod(Entity, setMountOffset, void,
  1380. (Point3F posOffset), (Point3F(0, 0, 0)),
  1381. "@brief Mount objB to this object at the desired slot with optional transform.\n\n"
  1382. "@param objB Object to mount onto us\n"
  1383. "@param slot Mount slot ID\n"
  1384. "@param txfm (optional) mount offset transform\n"
  1385. "@return true if successful, false if failed (objB is not valid)")
  1386. {
  1387. object->setMountOffset(posOffset);
  1388. }
  1389. DefineEngineMethod(Entity, setMountRotation, void,
  1390. (EulerF rotOffset), (EulerF(0, 0, 0)),
  1391. "@brief Mount objB to this object at the desired slot with optional transform.\n\n"
  1392. "@param objB Object to mount onto us\n"
  1393. "@param slot Mount slot ID\n"
  1394. "@param txfm (optional) mount offset transform\n"
  1395. "@return true if successful, false if failed (objB is not valid)")
  1396. {
  1397. object->setMountRotation(rotOffset);
  1398. }
  1399. DefineEngineMethod(Entity, getMountTransform, TransformF, (), ,
  1400. "@brief Mount objB to this object at the desired slot with optional transform.\n\n"
  1401. "@param objB Object to mount onto us\n"
  1402. "@param slot Mount slot ID\n"
  1403. "@param txfm (optional) mount offset transform\n"
  1404. "@return true if successful, false if failed (objB is not valid)")
  1405. {
  1406. MatrixF mat;
  1407. object->getMountTransform(0, MatrixF::Identity, &mat);
  1408. return mat;
  1409. }
  1410. DefineEngineMethod(Entity, setBox, void,
  1411. (Point3F box), (Point3F(1, 1, 1)),
  1412. "@brief Mount objB to this object at the desired slot with optional transform.\n\n"
  1413. "@param objB Object to mount onto us\n"
  1414. "@param slot Mount slot ID\n"
  1415. "@param txfm (optional) mount offset transform\n"
  1416. "@return true if successful, false if failed (objB is not valid)")
  1417. {
  1418. object->setObjectBox(Box3F(-box, box));
  1419. }
  1420. /*DefineConsoleMethod(Entity, callOnComponents, void, (const char* functionName), ,
  1421. "Get the number of static fields on the object.\n"
  1422. "@return The number of static fields defined on the object.")
  1423. {
  1424. object->callOnComponents(functionName);
  1425. }
  1426. ConsoleMethod(Entity, callMethod, void, 3, 64, "(methodName, argi) Calls script defined method\n"
  1427. "@param methodName The method's name as a string\n"
  1428. "@param argi Any arguments to pass to the method\n"
  1429. "@return No return value"
  1430. "@note %obj.callMethod( %methodName, %arg1, %arg2, ... );\n")
  1431. {
  1432. object->callMethodArgList(argc - 1, argv + 2);
  1433. }
  1434. ConsoleMethod(Entity, addComponents, void, 2, 2, "() - Add all fielded behaviors\n"
  1435. "@return No return value")
  1436. {
  1437. object->addComponents();
  1438. }*/
  1439. ConsoleMethod(Entity, addComponent, bool, 3, 3, "(ComponentInstance bi) - Add a behavior to the object\n"
  1440. "@param bi The behavior instance to add"
  1441. "@return (bool success) Whether or not the behavior was successfully added")
  1442. {
  1443. Component *comp = dynamic_cast<Component *>(Sim::findObject(argv[2]));
  1444. if (comp != NULL)
  1445. {
  1446. bool success = object->addComponent(comp);
  1447. if (success)
  1448. {
  1449. //Placed here so we can differentiate against adding a new behavior during runtime, or when we load all
  1450. //fielded behaviors on mission load. This way, we can ensure that we only call the callback
  1451. //once everything is loaded. This avoids any problems with looking for behaviors that haven't been added yet, etc.
  1452. if (comp->isMethod("onBehaviorAdd"))
  1453. Con::executef(comp, "onBehaviorAdd");
  1454. return true;
  1455. }
  1456. }
  1457. return false;
  1458. }
  1459. ConsoleMethod(Entity, removeComponent, bool, 3, 4, "(ComponentInstance bi, [bool deleteBehavior = true])\n"
  1460. "@param bi The behavior instance to remove\n"
  1461. "@param deleteBehavior Whether or not to delete the behavior\n"
  1462. "@return (bool success) Whether the behavior was successfully removed")
  1463. {
  1464. bool deleteComponent = true;
  1465. if (argc > 3)
  1466. deleteComponent = dAtob(argv[3]);
  1467. return object->removeComponent(dynamic_cast<Component *>(Sim::findObject(argv[2])), deleteComponent);
  1468. }
  1469. ConsoleMethod(Entity, clearComponents, void, 2, 2, "() - Clear all behavior instances\n"
  1470. "@return No return value")
  1471. {
  1472. object->clearComponents();
  1473. }
  1474. ConsoleMethod(Entity, getComponentByIndex, S32, 3, 3, "(int index) - Gets a particular behavior\n"
  1475. "@param index The index of the behavior to get\n"
  1476. "@return (ComponentInstance bi) The behavior instance you requested")
  1477. {
  1478. Component *comp = object->getComponent(dAtoi(argv[2]));
  1479. return (comp != NULL) ? comp->getId() : 0;
  1480. }
  1481. DefineConsoleMethod(Entity, getComponent, S32, (String componentName), (""),
  1482. "Get the number of static fields on the object.\n"
  1483. "@return The number of static fields defined on the object.")
  1484. {
  1485. Component *comp = object->getComponent(componentName);
  1486. return (comp != NULL) ? comp->getId() : 0;
  1487. return 0;
  1488. }
  1489. /*ConsoleMethod(Entity, getBehaviorByType, S32, 3, 3, "(string BehaviorTemplateName) - gets a behavior\n"
  1490. "@param BehaviorTemplateName The name of the template of the behavior instance you want\n"
  1491. "@return (ComponentInstance bi) The behavior instance you requested")
  1492. {
  1493. ComponentInstance *bInstance = object->getComponentByType(StringTable->insert(argv[2]));
  1494. return (bInstance != NULL) ? bInstance->getId() : 0;
  1495. }*/
  1496. /*ConsoleMethod(Entity, reOrder, bool, 3, 3, "(ComponentInstance inst, [int desiredIndex = 0])\n"
  1497. "@param inst The behavior instance you want to reorder\n"
  1498. "@param desiredIndex The index you want the behavior instance to be reordered to\n"
  1499. "@return (bool success) Whether or not the behavior instance was successfully reordered")
  1500. {
  1501. Component *inst = dynamic_cast<Component *>(Sim::findObject(argv[1]));
  1502. if (inst == NULL)
  1503. return false;
  1504. U32 idx = 0;
  1505. if (argc > 2)
  1506. idx = dAtoi(argv[2]);
  1507. return object->reOrder(inst, idx);
  1508. }*/
  1509. ConsoleMethod(Entity, getComponentCount, S32, 2, 2, "() - Get the count of behaviors on an object\n"
  1510. "@return (int count) The number of behaviors on an object")
  1511. {
  1512. return object->getComponentCount();
  1513. }
  1514. DefineConsoleMethod(Entity, setComponentDirty, void, (S32 componentID, bool forceUpdate), (0, false),
  1515. "Get the number of static fields on the object.\n"
  1516. "@return The number of static fields defined on the object.")
  1517. {
  1518. /*Component* comp;
  1519. if (Sim::findObject(componentID, comp))
  1520. object->setComponentDirty(comp, forceUpdate);*/
  1521. }
  1522. DefineConsoleMethod(Entity, getMoveVector, VectorF, (),,
  1523. "Get the number of static fields on the object.\n"
  1524. "@return The number of static fields defined on the object.")
  1525. {
  1526. if (object->getControllingClient() != NULL)
  1527. {
  1528. //fetch our last move
  1529. if (object->lastMove.x != 0 || object->lastMove.y != 0 || object->lastMove.z != 0)
  1530. return VectorF(object->lastMove.x, object->lastMove.y, object->lastMove.z);
  1531. }
  1532. return VectorF::Zero;
  1533. }
  1534. DefineConsoleMethod(Entity, getMoveRotation, VectorF, (), ,
  1535. "Get the number of static fields on the object.\n"
  1536. "@return The number of static fields defined on the object.")
  1537. {
  1538. if(object->getControllingClient() != NULL)
  1539. {
  1540. //fetch our last move
  1541. if (object->lastMove.pitch != 0 || object->lastMove.roll != 0 || object->lastMove.yaw != 0)
  1542. return VectorF(object->lastMove.pitch, object->lastMove.roll, object->lastMove.yaw);
  1543. }
  1544. return VectorF::Zero;
  1545. }
  1546. DefineConsoleMethod(Entity, getMoveTrigger, bool, (S32 triggerNum), (0),
  1547. "Get the number of static fields on the object.\n"
  1548. "@return The number of static fields defined on the object.")
  1549. {
  1550. if (object->getControllingClient() != NULL && triggerNum < MaxTriggerKeys)
  1551. {
  1552. return object->lastMove.trigger[triggerNum];
  1553. }
  1554. return false;
  1555. }
  1556. DefineConsoleMethod(Entity, setForwardVector, void, (VectorF newForward), (VectorF(0,0,0)),
  1557. "Get the number of static fields on the object.\n"
  1558. "@return The number of static fields defined on the object.")
  1559. {
  1560. object->setForwardVector(newForward);
  1561. }
  1562. DefineConsoleMethod(Entity, lookAt, void, (Point3F lookPosition),,
  1563. "Get the number of static fields on the object.\n"
  1564. "@return The number of static fields defined on the object.")
  1565. {
  1566. //object->setForwardVector(newForward);
  1567. }
  1568. DefineConsoleMethod(Entity, rotateTo, void, (Point3F lookPosition, F32 degreePerSecond), (1.0),
  1569. "Get the number of static fields on the object.\n"
  1570. "@return The number of static fields defined on the object.")
  1571. {
  1572. //object->setForwardVector(newForward);
  1573. }