BsScriptAnimationCurves.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsScriptAnimationCurves.h"
  4. #include "BsScriptAnimationCurve.h"
  5. #include "BsMonoUtil.h"
  6. #include "BsMonoClass.h"
  7. #include "BsMonoField.h"
  8. #include "BsAnimationCurve.h"
  9. #include "BsAnimationClip.h"
  10. #include "BsMath.h"
  11. #include "BsVector3.h"
  12. using namespace std::placeholders;
  13. namespace BansheeEngine
  14. {
  15. MonoField* ScriptAnimationCurves::sPositionCurvesField = nullptr;
  16. MonoField* ScriptAnimationCurves::sRotationCurvesField = nullptr;
  17. MonoField* ScriptAnimationCurves::sScaleCurvesField = nullptr;
  18. MonoField* ScriptAnimationCurves::sFloatCurvesField = nullptr;
  19. ScriptAnimationCurves::ScriptAnimationCurves(MonoObject* instance)
  20. :ScriptObject(instance)
  21. { }
  22. void ScriptAnimationCurves::initRuntimeData()
  23. {
  24. sPositionCurvesField = metaData.scriptClass->getField("PositionCurves");
  25. sRotationCurvesField = metaData.scriptClass->getField("RotationCurves");
  26. sScaleCurvesField = metaData.scriptClass->getField("ScaleCurves");
  27. sFloatCurvesField = metaData.scriptClass->getField("FloatCurves");
  28. }
  29. TAnimationCurve<Quaternion> eulerAngleToQuaternionCurve(const TAnimationCurve<Vector3>& inCurve)
  30. {
  31. UINT32 numKeys = (UINT32)inCurve.getNumKeyFrames();
  32. Vector<TKeyframe<Quaternion>> quatKeys(numKeys);
  33. for (UINT32 j = 0; j < numKeys; j++)
  34. {
  35. // TODO - Not implemented. Convert euler angle rotation to quaternion.
  36. }
  37. return TAnimationCurve<Quaternion>(quatKeys);
  38. }
  39. TAnimationCurve<Vector3> quaternionToEulerAngleCurve(const TAnimationCurve<Quaternion>& inCurve)
  40. {
  41. UINT32 numKeys = (UINT32)inCurve.getNumKeyFrames();
  42. Vector<TKeyframe<Vector3>> eulerKeys(numKeys);
  43. for (UINT32 j = 0; j < numKeys; j++)
  44. {
  45. // TODO - Not implemented. Convert quaternion rotation to euler angles.
  46. }
  47. return TAnimationCurve<Vector3>(eulerKeys);
  48. }
  49. SPtr<AnimationCurves> ScriptAnimationCurves::toNative(MonoObject* instance)
  50. {
  51. SPtr<AnimationCurves> output = bs_shared_ptr_new<AnimationCurves>();
  52. MonoArray* monoPosCurves;
  53. sPositionCurvesField->getValue(instance, &monoPosCurves);
  54. if (monoPosCurves != nullptr)
  55. {
  56. ScriptArray scriptCurves(monoPosCurves);
  57. for(UINT32 i = 0; i < scriptCurves.size(); i++)
  58. {
  59. MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
  60. output->position.push_back(ScriptNamedVector3Curve::toNative(monoCurve));
  61. }
  62. }
  63. MonoArray* monoRotCurves;
  64. sRotationCurvesField->getValue(instance, &monoRotCurves);
  65. if (monoRotCurves != nullptr)
  66. {
  67. ScriptArray scriptCurves(monoRotCurves);
  68. for (UINT32 i = 0; i < scriptCurves.size(); i++)
  69. {
  70. MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
  71. TNamedAnimationCurve<Vector3> eulerRotation = ScriptNamedVector3Curve::toNative(monoCurve);
  72. TNamedAnimationCurve<Quaternion> quatRotation;
  73. quatRotation.name = eulerRotation.name;
  74. quatRotation.curve = eulerAngleToQuaternionCurve(eulerRotation.curve);
  75. output->rotation.push_back(quatRotation);
  76. }
  77. }
  78. MonoArray* monoScaleCurves;
  79. sScaleCurvesField->getValue(instance, &monoScaleCurves);
  80. if (monoScaleCurves != nullptr)
  81. {
  82. ScriptArray scriptCurves(monoScaleCurves);
  83. for (UINT32 i = 0; i < scriptCurves.size(); i++)
  84. {
  85. MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
  86. output->scale.push_back(ScriptNamedVector3Curve::toNative(monoCurve));
  87. }
  88. }
  89. MonoArray* monoFloatCurves;
  90. sFloatCurvesField->getValue(instance, &monoFloatCurves);
  91. if (monoFloatCurves != nullptr)
  92. {
  93. ScriptArray scriptCurves(monoFloatCurves);
  94. for (UINT32 i = 0; i < scriptCurves.size(); i++)
  95. {
  96. MonoObject* monoCurve = scriptCurves.get<MonoObject*>(i);
  97. output->generic.push_back(ScriptNamedFloatCurve::toNative(monoCurve));
  98. }
  99. }
  100. return output;
  101. }
  102. MonoObject* ScriptAnimationCurves::toManaged(const SPtr<AnimationCurves>& curves)
  103. {
  104. UINT32 numPosCurves = (UINT32)curves->position.size();
  105. ScriptArray scriptPositionCurves = ScriptArray::create<ScriptNamedVector3Curve>(numPosCurves);
  106. for(UINT32 i = 0; i < numPosCurves; i++)
  107. {
  108. MonoObject* monoCurve = ScriptNamedVector3Curve::toManaged(curves->position[i]);
  109. scriptPositionCurves.set(i, monoCurve);
  110. }
  111. UINT32 numRotCurves = (UINT32)curves->rotation.size();
  112. ScriptArray scriptRotationCurves = ScriptArray::create<ScriptNamedVector3Curve>(numRotCurves);
  113. for (UINT32 i = 0; i < numRotCurves; i++)
  114. {
  115. TNamedAnimationCurve<Vector3> eulerRotationCurve;
  116. eulerRotationCurve.name = curves->rotation[i].name;
  117. eulerRotationCurve.curve = quaternionToEulerAngleCurve(curves->rotation[i].curve);
  118. MonoObject* monoCurve = ScriptNamedVector3Curve::toManaged(eulerRotationCurve);
  119. scriptRotationCurves.set(i, monoCurve);
  120. }
  121. UINT32 numScaleCurves = (UINT32)curves->scale.size();
  122. ScriptArray scriptScaleCurves = ScriptArray::create<ScriptNamedVector3Curve>(numScaleCurves);
  123. for (UINT32 i = 0; i < numScaleCurves; i++)
  124. {
  125. MonoObject* monoCurve = ScriptNamedVector3Curve::toManaged(curves->scale[i]);
  126. scriptScaleCurves.set(i, monoCurve);
  127. }
  128. UINT32 numFloatCurves = (UINT32)curves->generic.size();
  129. ScriptArray scriptFloatCurves = ScriptArray::create<ScriptNamedFloatCurve>(numFloatCurves);
  130. for (UINT32 i = 0; i < numFloatCurves; i++)
  131. {
  132. MonoObject* monoCurve = ScriptNamedFloatCurve::toManaged(curves->generic[i]);
  133. scriptFloatCurves.set(i, monoCurve);
  134. }
  135. MonoObject* instance = metaData.scriptClass->createInstance();
  136. sPositionCurvesField->setValue(instance, scriptPositionCurves.getInternal());
  137. sRotationCurvesField->setValue(instance, scriptRotationCurves.getInternal());
  138. sScaleCurvesField->setValue(instance, scriptScaleCurves.getInternal());
  139. sFloatCurvesField->setValue(instance, scriptFloatCurves.getInternal());
  140. return instance;
  141. }
  142. MonoField* ScriptNamedVector3Curve::sNameField = nullptr;
  143. MonoField* ScriptNamedVector3Curve::sXCurveField = nullptr;
  144. MonoField* ScriptNamedVector3Curve::sYCurveField = nullptr;
  145. MonoField* ScriptNamedVector3Curve::sZCurveField = nullptr;
  146. ScriptNamedVector3Curve::ScriptNamedVector3Curve(MonoObject* instance)
  147. :ScriptObject(instance)
  148. { }
  149. void ScriptNamedVector3Curve::initRuntimeData()
  150. {
  151. sNameField = metaData.scriptClass->getField("Name");
  152. sXCurveField = metaData.scriptClass->getField("X");
  153. sYCurveField = metaData.scriptClass->getField("Y");
  154. sZCurveField = metaData.scriptClass->getField("Z");
  155. }
  156. TNamedAnimationCurve<Vector3> ScriptNamedVector3Curve::toNative(MonoObject* instance)
  157. {
  158. TNamedAnimationCurve<Vector3> output;
  159. MonoString* monoName = nullptr;
  160. sNameField->getValue(instance, &monoName);
  161. output.name = MonoUtil::monoToString(monoName);
  162. // Convert from three separate floating point curves, to a Vector3 curve
  163. MonoObject* monoCurves[3];
  164. sXCurveField->getValue(instance, &monoCurves[0]);
  165. sYCurveField->getValue(instance, &monoCurves[1]);
  166. sZCurveField->getValue(instance, &monoCurves[2]);
  167. SPtr<TAnimationCurve<float>> curves[3];
  168. // Find unique keyframe times
  169. Map<float, TKeyframe<Vector3>> keyFrames;
  170. for(UINT32 i = 0; i < 3; i++)
  171. {
  172. if (monoCurves[i] == nullptr)
  173. {
  174. curves[i] = bs_shared_ptr_new<TAnimationCurve<float>>();
  175. continue;
  176. }
  177. ScriptAnimationCurve* scriptCurve = ScriptAnimationCurve::toNative(monoCurves[i]);
  178. curves[i] = scriptCurve->getInternal();
  179. UINT32 numKeyFrames = curves[i]->getNumKeyFrames();
  180. for (UINT32 j = 0; j < numKeyFrames; j++)
  181. {
  182. const TKeyframe<float>& keyFrame = curves[i]->getKeyFrame(j);
  183. auto iterFind = keyFrames.find(keyFrame.time);
  184. if (iterFind == keyFrames.end())
  185. {
  186. TKeyframe<Vector3> newKeyFrame;
  187. newKeyFrame.time = keyFrame.time;
  188. keyFrames.insert(std::make_pair(keyFrame.time, newKeyFrame));
  189. }
  190. }
  191. }
  192. // Populate keyframe values
  193. Vector<TKeyframe<Vector3>> keyframeList(keyFrames.size());
  194. for(auto& entry : keyFrames)
  195. {
  196. TKeyframe<Vector3>& keyFrame = entry.second;
  197. for(UINT32 j = 0; j < 3; j++)
  198. {
  199. TKeyframe<float> currentKey = curves[j]->evaluateKey(keyFrame.time, false);
  200. keyFrame.value[j] = currentKey.value;
  201. keyFrame.inTangent[j] = currentKey.inTangent;
  202. keyFrame.outTangent[j] = currentKey.outTangent;
  203. }
  204. keyframeList.push_back(keyFrame);
  205. }
  206. output.curve = TAnimationCurve<Vector3>(keyframeList);
  207. return output;
  208. }
  209. MonoObject* ScriptNamedVector3Curve::toManaged(const TNamedAnimationCurve<Vector3>& curve)
  210. {
  211. MonoString* monoString = MonoUtil::stringToMono(curve.name);
  212. UINT32 numKeyFrames = curve.curve.getNumKeyFrames();
  213. Vector<TKeyframe<float>> keyFrames[3];
  214. for (UINT32 i = 0; i < numKeyFrames; i++)
  215. {
  216. const TKeyframe<Vector3>& key = curve.curve.getKeyFrame(i);
  217. TKeyframe<float> newKey;
  218. newKey.time = key.time;
  219. for(UINT32 j = 0; j < 3; j++)
  220. {
  221. bool addNew = true;
  222. if (i > 0)
  223. {
  224. const TKeyframe<float>& prevKey = keyFrames[j].back();
  225. bool isEqual = Math::approxEquals(prevKey.value, key.value[j]) &&
  226. Math::approxEquals(prevKey.outTangent, key.inTangent[j]);
  227. addNew = !isEqual;
  228. }
  229. if (addNew)
  230. {
  231. newKey.value = key.value[j];
  232. newKey.inTangent = key.inTangent[j];
  233. newKey.outTangent = key.outTangent[j];
  234. keyFrames[j].push_back(newKey);
  235. }
  236. }
  237. }
  238. TAnimationCurve<float> xCurve(keyFrames[0]);
  239. TAnimationCurve<float> yCurve(keyFrames[1]);
  240. TAnimationCurve<float> zCurve(keyFrames[2]);
  241. MonoObject* monoXCurve = ScriptAnimationCurve::create(xCurve);
  242. MonoObject* monoYCurve = ScriptAnimationCurve::create(yCurve);
  243. MonoObject* monoZCurve = ScriptAnimationCurve::create(zCurve);
  244. void* params[4] = { monoString, monoXCurve, monoYCurve, monoZCurve };
  245. return metaData.scriptClass->createInstance("string, AnimationCurve, AnimationCurve, AnimationCurve", params);
  246. }
  247. MonoField* ScriptNamedFloatCurve::sNameField = nullptr;
  248. MonoField* ScriptNamedFloatCurve::sCurveField = nullptr;
  249. ScriptNamedFloatCurve::ScriptNamedFloatCurve(MonoObject* instance)
  250. :ScriptObject(instance)
  251. { }
  252. void ScriptNamedFloatCurve::initRuntimeData()
  253. {
  254. sNameField = metaData.scriptClass->getField("Name");
  255. sCurveField = metaData.scriptClass->getField("Curve");
  256. }
  257. TNamedAnimationCurve<float> ScriptNamedFloatCurve::toNative(MonoObject* instance)
  258. {
  259. TNamedAnimationCurve<float> output;
  260. MonoString* monoName = nullptr;
  261. sNameField->getValue(instance, &monoName);
  262. output.name = MonoUtil::monoToString(monoName);
  263. MonoObject* monoCurve = nullptr;
  264. sCurveField->getValue(instance, &monoCurve);
  265. if(monoCurve != nullptr)
  266. {
  267. ScriptAnimationCurve* scriptCurve = ScriptAnimationCurve::toNative(monoCurve);
  268. output.curve = *scriptCurve->getInternal();
  269. }
  270. return output;
  271. }
  272. MonoObject* ScriptNamedFloatCurve::toManaged(const TNamedAnimationCurve<float>& curve)
  273. {
  274. MonoString* monoString = MonoUtil::stringToMono(curve.name);
  275. MonoObject* monoCurve = ScriptAnimationCurve::create(curve.curve);
  276. void* params[2] = { monoString, monoCurve };
  277. return metaData.scriptClass->createInstance("string, AnimationCurve", params);
  278. }
  279. }