Model.bf 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. using System;
  2. using System.Collections;
  3. using System.Text;
  4. using System.Threading.Tasks;
  5. using Beefy;
  6. using Beefy.utils;
  7. using Beefy.geom;
  8. #if STUDIO_CLIENT
  9. using Beefy.ipc;
  10. #endif
  11. namespace Beefy.gfx
  12. {
  13. public class ModelDef
  14. {
  15. public struct JointTranslation
  16. {
  17. public Quaternion mQuat;
  18. public Vector3 mScale;
  19. public Vector3 mTrans;
  20. }
  21. //[StructLayout(LayoutKind.Sequential)]
  22. public struct VertexDef
  23. {
  24. [VertexMember(VertexElementUsage.Position3D)]
  25. public Vector3 mPosition;
  26. [VertexMember(VertexElementUsage.Color)]
  27. public uint32 mColor;
  28. [VertexMember(VertexElementUsage.TextureCoordinate)]
  29. public TexCoords mTexCoords;
  30. [VertexMember(VertexElementUsage.Normal)]
  31. public Vector3 mNormal;
  32. [VertexMember(VertexElementUsage.TextureCoordinate, 1)]
  33. public TexCoords mBumpTexCoords;
  34. [VertexMember(VertexElementUsage.Tangent)]
  35. public Vector3 mTangent;
  36. public static VertexDefinition sVertexDefinition ~ delete _;
  37. public static void Init()
  38. {
  39. sVertexDefinition = new VertexDefinition(typeof(VertexDef));
  40. }
  41. }
  42. }
  43. #if !STUDIO_CLIENT
  44. extension ModelDef
  45. {
  46. public class Animation
  47. {
  48. public void* mNativeModelDefAnimation;
  49. public int32 mFrameCount;
  50. public String mName;
  51. public int32 mAnimIdx;
  52. [CallingConvention(.Stdcall), CLink]
  53. extern static void ModelDefAnimation_GetJointTranslation(void* nativeAnimation, int32 jointIdx, float frame, out JointTranslation jointTranslation);
  54. [CallingConvention(.Stdcall), CLink]
  55. extern static int32 ModelDefAnimation_GetFrameCount(void* nativeAnimation);
  56. [CallingConvention(.Stdcall), CLink]
  57. extern static char8* ModelDefAnimation_GetName(void* nativeAnimation);
  58. [CallingConvention(.Stdcall), CLink]
  59. extern static void ModelDefAnimation_Clip(void* nativeAnimation, int32 startFrame, int32 numFrames);
  60. public this(void* nativeModelDefAnimation)
  61. {
  62. mNativeModelDefAnimation = nativeModelDefAnimation;
  63. mFrameCount = ModelDefAnimation_GetFrameCount(mNativeModelDefAnimation);
  64. mName = new String(ModelDefAnimation_GetName(mNativeModelDefAnimation));
  65. }
  66. public void GetJointTranslation(int32 jointIdx, float frame, out JointTranslation jointTranslation)
  67. {
  68. ModelDefAnimation_GetJointTranslation(mNativeModelDefAnimation, jointIdx, frame, out jointTranslation);
  69. }
  70. public void Clip(int32 startFrame, int32 numFrames)
  71. {
  72. ModelDefAnimation_Clip(mNativeModelDefAnimation, startFrame, numFrames);
  73. mFrameCount = ModelDefAnimation_GetFrameCount(mNativeModelDefAnimation);
  74. }
  75. }
  76. public void* mNativeModelDef;
  77. public float mFrameRate;
  78. public int32 mJointCount;
  79. public Animation[] mAnims ~ DeleteContainerAndItems!(_);
  80. public Dictionary<String, Animation> mAnimMap = new Dictionary<String, Animation>() ~ DeleteDictionaryAndKeys!(_);
  81. [CallingConvention(.Stdcall), CLink]
  82. extern static void* Res_OpenFBX(char8* fileName, void* nativeVertexDef);
  83. [CallingConvention(.Stdcall), CLink]
  84. extern static void* Res_OpenGLTF(char8* fileName, char8* baseDir, void* nativeVertexDef);
  85. [CallingConvention(.Stdcall), CLink]
  86. extern static void* Res_OpenModel(char8* fileName, char8* baseDir, void* nativeVertexDef);
  87. [CallingConvention(.Stdcall), CLink]
  88. extern static void* ModelDef_CreateModelInstance(void* nativeModel);
  89. [CallingConvention(.Stdcall), CLink]
  90. extern static char8* ModelDef_GetInfo(void* nativeModel);
  91. [CallingConvention(.Stdcall), CLink]
  92. extern static float ModelDef_GetFrameRate(void* nativeModel);
  93. [CallingConvention(.Stdcall), CLink]
  94. extern static int32 ModelDef_GetJointCount(void* nativeModel);
  95. [CallingConvention(.Stdcall), CLink]
  96. extern static int32 ModelDef_GetAnimCount(void* nativeModel);
  97. [CallingConvention(.Stdcall), CLink]
  98. extern static void* ModelDef_GetAnimation(void* nativeModel, int32 animIdx);
  99. [CallingConvention(.Stdcall), CLink]
  100. extern static void ModelDef_SetTextures(void* nativeModel, int32 meshIdx, int32 primitivesIdx, char8** paths, int32 pathCount);
  101. [CallingConvention(.Stdcall), CLink]
  102. extern static Span<uint8> Res_SerializeModel(void* nativeModel);
  103. this(void* nativeModelDef)
  104. {
  105. mNativeModelDef = nativeModelDef;
  106. mFrameRate = ModelDef_GetFrameRate(mNativeModelDef);
  107. mJointCount = ModelDef_GetJointCount(mNativeModelDef);
  108. int32 animCount = ModelDef_GetAnimCount(mNativeModelDef);
  109. mAnims = new Animation[animCount];
  110. for (int32 animIdx = 0; animIdx < animCount; animIdx++)
  111. {
  112. var anim = new Animation(ModelDef_GetAnimation(mNativeModelDef, animIdx));
  113. anim.mAnimIdx = animIdx;
  114. mAnims[animIdx] = anim;
  115. mAnimMap[anim.mName] = anim;
  116. }
  117. }
  118. public static ModelDef LoadModel(String fileName, String baseDir)
  119. {
  120. void* nativeModelDef = null;
  121. if (fileName.EndsWith(".bfm", .OrdinalIgnoreCase))
  122. nativeModelDef = Res_OpenModel(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
  123. else if (fileName.EndsWith(".fbx", .OrdinalIgnoreCase))
  124. nativeModelDef = Res_OpenFBX(fileName, VertexDef.sVertexDefinition.mNativeVertexDefinition);
  125. else
  126. nativeModelDef = Res_OpenGLTF(fileName, baseDir, VertexDef.sVertexDefinition.mNativeVertexDefinition);
  127. if (nativeModelDef == null)
  128. return null;
  129. return new ModelDef(nativeModelDef);
  130. }
  131. public ModelInstance CreateInstance()
  132. {
  133. void* nativeModelInstance = ModelDef_CreateModelInstance(mNativeModelDef);
  134. if (nativeModelInstance == null)
  135. return null;
  136. var modelInstance = new ModelInstance(nativeModelInstance, this);
  137. return modelInstance;
  138. }
  139. public Animation GetAnimation(String name)
  140. {
  141. return mAnimMap[name];
  142. }
  143. public void GetInfo(String str)
  144. {
  145. str.Append(ModelDef_GetInfo(mNativeModelDef));
  146. }
  147. public void SetTextures(int meshIdx, int primitivesIdx, Span<char8*> paths)
  148. {
  149. ModelDef_SetTextures(mNativeModelDef, (.)meshIdx, (.)primitivesIdx, paths.Ptr, (.)paths.Length);
  150. }
  151. public void Serialize(List<uint8> data)
  152. {
  153. var span = Res_SerializeModel(mNativeModelDef);
  154. data.AddRange(span);
  155. }
  156. }
  157. public class ModelInstance : RenderCmd
  158. {
  159. [CallingConvention(.Stdcall), CLink]
  160. extern static void ModelInstance_SetJointTranslation(void* nativeModelInstance, int32 jointIdx, ref ModelDef.JointTranslation jointTranslation);
  161. [CallingConvention(.Stdcall), CLink]
  162. extern static void ModelInstance_SetMeshVisibility(void* nativeModelInstance, int32 jointIdx, int32 visibility);
  163. public ModelDef mModelDef;
  164. public ModelDef.Animation mAnim;
  165. public float mFrame;
  166. public float mAnimSpeed = 1.0f;
  167. public bool mLoop;
  168. public this(void* nativeModelInstance, ModelDef modelDef)
  169. {
  170. mNativeRenderCmd = nativeModelInstance;
  171. mModelDef = modelDef;
  172. }
  173. public void RehupAnimState()
  174. {
  175. for (int32 jointIdx = 0; jointIdx < mModelDef.mJointCount; jointIdx++)
  176. {
  177. ModelDef.JointTranslation jointTranslation;
  178. mAnim.GetJointTranslation(jointIdx, mFrame, out jointTranslation);
  179. SetJointTranslation(jointIdx, ref jointTranslation);
  180. }
  181. }
  182. public void Update()
  183. {
  184. if (mAnim == null)
  185. return;
  186. mFrame += mModelDef.mFrameRate * BFApp.sApp.UpdateDelta * mAnimSpeed;
  187. /*if ((mFrame >= 35.0f) || (mFrame < 1.0f))
  188. mFrame = 34.0f;*/
  189. if (mAnim.mFrameCount > 1)
  190. {
  191. float endFrameNum = mAnim.mFrameCount - 1.0f;
  192. while (mFrame >= endFrameNum)
  193. {
  194. if (mLoop)
  195. mFrame -= endFrameNum;
  196. else
  197. mFrame = endFrameNum - 0.00001f;
  198. }
  199. while (mFrame < 0)
  200. mFrame += endFrameNum;
  201. }
  202. RehupAnimState();
  203. }
  204. public void Play(ModelDef.Animation anim, bool loop = false)
  205. {
  206. mLoop = loop;
  207. mAnim = anim;
  208. mFrame = 0;
  209. RehupAnimState();
  210. }
  211. public void Play(String name, bool loop = false)
  212. {
  213. Play(mModelDef.GetAnimation(name), loop);
  214. }
  215. public void Play(bool loop = false)
  216. {
  217. Play(mModelDef.mAnims[0], loop);
  218. }
  219. public void SetJointTranslation(int32 jointIdx, ref ModelDef.JointTranslation jointTranslation)
  220. {
  221. ModelInstance_SetJointTranslation(mNativeRenderCmd, jointIdx, ref jointTranslation);
  222. }
  223. public void SetMeshVisibility(int32 meshIdx, bool visible)
  224. {
  225. ModelInstance_SetMeshVisibility(mNativeRenderCmd, meshIdx, visible ? 1 : 0);
  226. }
  227. }
  228. #else
  229. extension ModelDef
  230. {
  231. public class Animation
  232. {
  233. public void* mNativeModelDefAnimation;
  234. public int mFrameCount;
  235. public string mName;
  236. public int mAnimIdx;
  237. public IPCProxy<IStudioModelDefAnimation> mStudioModelDefAnimation;
  238. internal Animation(IPCProxy<IStudioModelDefAnimation> studioModelDefAnimation)
  239. {
  240. mStudioModelDefAnimation = studioModelDefAnimation;
  241. mFrameCount = mStudioModelDefAnimation.Proxy.GetFrameCount();
  242. mName = mStudioModelDefAnimation.Proxy.GetName();
  243. }
  244. public void Clip(int startFrame, int numFrames)
  245. {
  246. //ModelDefAnimation_Clip(mNativeModelDefAnimation, startFrame, numFrames);
  247. //mFrameCount = ModelDefAnimation_GetFrameCount(mNativeModelDefAnimation);
  248. mStudioModelDefAnimation.Proxy.Clip(startFrame, numFrames);
  249. mFrameCount = mStudioModelDefAnimation.Proxy.GetFrameCount();
  250. }
  251. }
  252. public IPCProxy<IStudioModelDef> mStudioModelDef;
  253. public float mFrameRate;
  254. public int mJointCount;
  255. public Animation[] mAnims;
  256. public Dictionary<string, Animation> mAnimMap = new Dictionary<string, Animation>();
  257. ModelDef(IPCProxy<IStudioModelDef> studioModelDef)
  258. {
  259. mStudioModelDef = studioModelDef;
  260. mFrameRate = mStudioModelDef.Proxy.GetFrameRate();// ModelDef_GetFrameRate(mNativeModelDef);
  261. mJointCount = mStudioModelDef.Proxy.GetJointCount();
  262. int animCount = mStudioModelDef.Proxy.GetAnimCount();
  263. mAnims = new Animation[animCount];
  264. for (int animIdx = 0; animIdx < animCount; animIdx++)
  265. {
  266. var objId = mStudioModelDef.Proxy.GetAnimation(animIdx);
  267. var anim = new Animation(IPCProxy<IStudioModelDefAnimation>.Create(objId));
  268. anim.mAnimIdx = animIdx;
  269. mAnims[animIdx] = anim;
  270. mAnimMap[anim.mName] = anim;
  271. }
  272. }
  273. public static ModelDef LoadModel(string fileName)
  274. {
  275. var objId = BFApp.StudioHostProxy.Res_OpenFBX(fileName, VertexDef.sVertexDefinition.mStudioVertexDefinition);
  276. IPCProxy<IStudioModelDef> studioModelDef = IPCProxy<IStudioModelDef>.Create(objId);
  277. if (studioModelDef == null)
  278. return null;
  279. return new ModelDef(studioModelDef);
  280. }
  281. public ModelInstance CreateInstance()
  282. {
  283. var objId = mStudioModelDef.Proxy.CreateModelInstance();
  284. IPCProxy<IStudioModelInstance> studioModelInstance = IPCProxy<IStudioModelInstance>.Create(objId);
  285. if (studioModelInstance == null)
  286. return null;
  287. var modelInstance = new ModelInstance(studioModelInstance, this);
  288. return modelInstance;
  289. }
  290. public Animation GetAnimation(string name)
  291. {
  292. return mAnimMap[name];
  293. }
  294. }
  295. public class ModelInstance : RenderCmd
  296. {
  297. public ModelDef mModelDef;
  298. public ModelDef.Animation mAnim;
  299. public float mFrame;
  300. public float mAnimSpeed = 1.0f;
  301. public bool mLoop;
  302. public IPCProxy<IStudioModelInstance> mStudioModelInstance;
  303. internal ModelInstance(IPCProxy<IStudioModelInstance> studioModelInstance, ModelDef modelDef)
  304. {
  305. mStudioModelInstance = studioModelInstance;
  306. var objId = studioModelInstance.Proxy.GetAsRenderCmd();
  307. mStudioRenderCmd = IPCProxy<IStudioRenderCmd>.Create(objId);
  308. mModelDef = modelDef;
  309. }
  310. void RehupAnimState()
  311. {
  312. mStudioModelInstance.Proxy.RehupAnimState(mAnim.mAnimIdx, mFrame);
  313. }
  314. public void Update()
  315. {
  316. if (mAnim == null)
  317. return;
  318. mFrame += mModelDef.mFrameRate * BFApp.sApp.UpdateDelta * mAnimSpeed;
  319. /*if ((mFrame >= 35.0f) || (mFrame < 1.0f))
  320. mFrame = 34.0f;*/
  321. if (mAnim.mFrameCount > 1)
  322. {
  323. float endFrameNum = mAnim.mFrameCount - 1.0f;
  324. while (mFrame >= endFrameNum)
  325. {
  326. if (mLoop)
  327. mFrame -= endFrameNum;
  328. else
  329. mFrame = endFrameNum - 0.00001f;
  330. }
  331. while (mFrame < 0)
  332. mFrame += endFrameNum;
  333. }
  334. RehupAnimState();
  335. }
  336. public void Play(ModelDef.Animation anim, bool loop = false)
  337. {
  338. mLoop = loop;
  339. mAnim = anim;
  340. mFrame = 0;
  341. RehupAnimState();
  342. }
  343. public void Play(string name, bool loop = false)
  344. {
  345. Play(mModelDef.GetAnimation(name), loop);
  346. }
  347. public void Play(bool loop = false)
  348. {
  349. Play(mModelDef.mAnims[0], loop);
  350. }
  351. public void SetMeshVisibility(int meshIdx, bool visible)
  352. {
  353. mStudioModelInstance.Proxy.SetMeshVisibility(meshIdx, visible);
  354. }
  355. }
  356. #endif
  357. }