MB3_MeshCombiner.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Specialized;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Text;
  7. using DigitalOpus.MB.Core;
  8. namespace DigitalOpus.MB.Core{
  9. /*
  10. [System.Serializable]
  11. public class MB_UnwrappingParams{
  12. public float packMargin = .01f; //0..1
  13. public float hardAngle = 60f; //degrees
  14. }
  15. */
  16. //TODO bug with triangles if using showHide with AddDelete reproduce by using the AddDeleteParts script and changeing some of it to show hide
  17. [System.Serializable]
  18. public abstract class MB3_MeshCombiner{
  19. public delegate void GenerateUV2Delegate(Mesh m, float hardAngle, float packMargin);
  20. public class MBBlendShapeKey
  21. {
  22. public int gameObjecID;
  23. public int blendShapeIndexInSrc;
  24. public MBBlendShapeKey(int srcSkinnedMeshRenderGameObjectID, int blendShapeIndexInSource)
  25. {
  26. gameObjecID = srcSkinnedMeshRenderGameObjectID;
  27. blendShapeIndexInSrc = blendShapeIndexInSource;
  28. }
  29. public override bool Equals(object obj)
  30. {
  31. if (!(obj is MBBlendShapeKey) || obj == null)
  32. {
  33. return false;
  34. }
  35. MBBlendShapeKey other = (MBBlendShapeKey)obj;
  36. return (gameObjecID == other.gameObjecID && blendShapeIndexInSrc == other.blendShapeIndexInSrc);
  37. }
  38. public override int GetHashCode()
  39. {
  40. int hash = 23;
  41. unchecked
  42. {
  43. hash = hash * 31 + gameObjecID;
  44. hash = hash * 31 + blendShapeIndexInSrc;
  45. }
  46. return hash;
  47. }
  48. }
  49. public class MBBlendShapeValue
  50. {
  51. public GameObject combinedMeshGameObject;
  52. public int blendShapeIndex;
  53. }
  54. public static bool EVAL_VERSION{
  55. get {return false;}
  56. }
  57. [SerializeField] protected MB2_LogLevel _LOG_LEVEL = MB2_LogLevel.info;
  58. public virtual MB2_LogLevel LOG_LEVEL{
  59. get{return _LOG_LEVEL;}
  60. set{ _LOG_LEVEL = value; }
  61. }
  62. [SerializeField] protected MB2_ValidationLevel _validationLevel = MB2_ValidationLevel.robust;
  63. public virtual MB2_ValidationLevel validationLevel{
  64. get {return _validationLevel;}
  65. set {_validationLevel = value;}
  66. }
  67. [SerializeField] protected string _name;
  68. public string name {
  69. get{return _name;}
  70. set{_name = value;}
  71. }
  72. [SerializeField] protected MB2_TextureBakeResults _textureBakeResults;
  73. public virtual MB2_TextureBakeResults textureBakeResults {
  74. get{return _textureBakeResults;}
  75. set{_textureBakeResults = value;}
  76. }
  77. [SerializeField] protected GameObject _resultSceneObject;
  78. public virtual GameObject resultSceneObject {
  79. get{return _resultSceneObject;}
  80. set{_resultSceneObject = value;}
  81. }
  82. [SerializeField] protected UnityEngine.Renderer _targetRenderer;
  83. public virtual Renderer targetRenderer {
  84. get{return _targetRenderer;}
  85. set{
  86. if (_targetRenderer != null && _targetRenderer != value){
  87. Debug.LogWarning("Previous targetRenderer was not null. Combined mesh may be being used by more than one Renderer");
  88. }
  89. _targetRenderer = value;
  90. }
  91. }
  92. [SerializeField] protected MB_RenderType _renderType;
  93. public virtual MB_RenderType renderType {
  94. get{return _renderType;}
  95. set{ _renderType = value;}
  96. }
  97. [SerializeField] protected MB2_OutputOptions _outputOption;
  98. public virtual MB2_OutputOptions outputOption {
  99. get{return _outputOption;}
  100. set{_outputOption = value;}
  101. }
  102. [SerializeField] protected MB2_LightmapOptions _lightmapOption = MB2_LightmapOptions.ignore_UV2;
  103. public virtual MB2_LightmapOptions lightmapOption {
  104. get{return _lightmapOption;}
  105. set{_lightmapOption = value;}
  106. }
  107. [SerializeField] protected bool _doNorm = true;
  108. public virtual bool doNorm {
  109. get{return _doNorm;}
  110. set{_doNorm = value;}
  111. }
  112. [SerializeField] protected bool _doTan = true;
  113. public virtual bool doTan {
  114. get{return _doTan;}
  115. set{_doTan = value;}
  116. }
  117. [SerializeField] protected bool _doCol;
  118. public virtual bool doCol {
  119. get{return _doCol;}
  120. set{_doCol = value;}
  121. }
  122. [SerializeField] protected bool _doUV = true;
  123. public virtual bool doUV {
  124. get{return _doUV;}
  125. set{_doUV = value;}
  126. }
  127. //only included for backward compatibility. Does nothing
  128. public virtual bool doUV1 {
  129. get { return false; }
  130. set { }
  131. }
  132. public virtual bool doUV2(){
  133. return _lightmapOption == MB2_LightmapOptions.copy_UV2_unchanged || _lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping || _lightmapOption == MB2_LightmapOptions.copy_UV2_unchanged_to_separate_rects;
  134. }
  135. [SerializeField] protected bool _doUV3;
  136. public virtual bool doUV3 {
  137. get { return _doUV3; }
  138. set { _doUV3 = value; }
  139. }
  140. [SerializeField] protected bool _doUV4;
  141. public virtual bool doUV4 {
  142. get { return _doUV4; }
  143. set { _doUV4 = value; }
  144. }
  145. [SerializeField]
  146. protected bool _doBlendShapes;
  147. public virtual bool doBlendShapes
  148. {
  149. get { return _doBlendShapes; }
  150. set { _doBlendShapes = value; }
  151. }
  152. [SerializeField]
  153. protected bool _recenterVertsToBoundsCenter = false;
  154. public virtual bool recenterVertsToBoundsCenter
  155. {
  156. get { return _recenterVertsToBoundsCenter; }
  157. set { _recenterVertsToBoundsCenter = value; }
  158. }
  159. [SerializeField]
  160. public bool _optimizeAfterBake = true;
  161. public bool optimizeAfterBake
  162. {
  163. get { return _optimizeAfterBake; }
  164. set { _optimizeAfterBake = value; }
  165. }
  166. [SerializeField]
  167. public float uv2UnwrappingParamsHardAngle = 60f;
  168. [SerializeField]
  169. public float uv2UnwrappingParamsPackMargin = .005f;
  170. protected bool _usingTemporaryTextureBakeResult;
  171. public abstract int GetLightmapIndex();
  172. public abstract void ClearBuffers();
  173. public abstract void ClearMesh();
  174. public abstract void DestroyMesh();
  175. public abstract void DestroyMeshEditor(MB2_EditorMethodsInterface editorMethods);
  176. public abstract List<GameObject> GetObjectsInCombined();
  177. public abstract int GetNumObjectsInCombined();
  178. public abstract int GetNumVerticesFor(GameObject go);
  179. public abstract int GetNumVerticesFor(int instanceID);
  180. public abstract Dictionary<MBBlendShapeKey, MBBlendShapeValue> BuildSourceBlendShapeToCombinedIndexMap();
  181. /// <summary>
  182. /// Copies Mesh Baker internal data to the mesh.
  183. /// </summary>
  184. public virtual void Apply(){
  185. Apply(null);
  186. }
  187. /// <summary>
  188. /// Copies Mesh Baker internal data to the mesh.
  189. /// </summary>
  190. /// <param name='uv2GenerationMethod'>
  191. /// Uv2 generation method. This is normally editor class method Unwrapping.GenerateSecondaryUVSet
  192. /// </param>
  193. public abstract void Apply(GenerateUV2Delegate uv2GenerationMethod);
  194. /// <summary>
  195. /// Apply the specified triangles, vertices, normals, tangents, uvs, colors, uv1, uv2, bones and uv2GenerationMethod.
  196. /// </summary>
  197. /// <param name='triangles'>
  198. /// Triangles.
  199. /// </param>
  200. /// <param name='vertices'>
  201. /// Vertices.
  202. /// </param>
  203. /// <param name='normals'>
  204. /// Normals.
  205. /// </param>
  206. /// <param name='tangents'>
  207. /// Tangents.
  208. /// </param>
  209. /// <param name='uvs'>
  210. /// Uvs.
  211. /// </param>
  212. /// <param name='colors'>
  213. /// Colors.
  214. /// </param>
  215. /// <param name='uv3'>
  216. /// Uv3.
  217. /// </param>
  218. /// <param name='uv4'>
  219. /// Uv4.
  220. /// </param>
  221. /// <param name='uv2'>
  222. /// Uv2.
  223. /// </param>
  224. /// <param name='bones'>
  225. /// Bones.
  226. /// </param>
  227. /// <param name='uv2GenerationMethod'>
  228. /// Uv2 generation method. This is normally method Unwrapping.GenerateSecondaryUVSet. This should be null when calling Apply at runtime.
  229. /// </param>
  230. public abstract void Apply(bool triangles,
  231. bool vertices,
  232. bool normals,
  233. bool tangents,
  234. bool uvs,
  235. bool uv2,
  236. bool uv3,
  237. bool uv4,
  238. bool colors,
  239. bool bones=false,
  240. bool blendShapeFlag=false,
  241. GenerateUV2Delegate uv2GenerationMethod = null);
  242. /// <summary>
  243. /// Updates the data in the combined mesh for meshes that are already in the combined mesh.
  244. /// This is faster than adding and removing a mesh and has a much lower memory footprint.
  245. /// This method can only be used if the meshes being updated have the same layout(number of
  246. /// vertices, triangles, submeshes).
  247. /// This is faster than removing and re-adding
  248. /// For efficiency update as few channels as possible.
  249. /// Apply must be called to apply the changes to the combined mesh
  250. /// </summary>
  251. public abstract void UpdateGameObjects(GameObject[] gos, bool recalcBounds = true,
  252. bool updateVertices = true, bool updateNormals = true, bool updateTangents = true,
  253. bool updateUV = false, bool updateUV2 = false, bool updateUV3 = false, bool updateUV4 = false,
  254. bool updateColors = false, bool updateSkinningInfo = false);
  255. public abstract bool AddDeleteGameObjects(GameObject[] gos, GameObject[] deleteGOs, bool disableRendererInSource=true);
  256. public abstract bool AddDeleteGameObjectsByID(GameObject[] gos, int[] deleteGOinstanceIDs, bool disableRendererInSource);
  257. public abstract bool CombinedMeshContains(GameObject go);
  258. public abstract void UpdateSkinnedMeshApproximateBounds();
  259. public abstract void UpdateSkinnedMeshApproximateBoundsFromBones();
  260. public abstract void CheckIntegrity();
  261. /// <summary>
  262. /// Updates the skinned mesh approximate bounds from the bounds of the source objects.
  263. /// </summary>
  264. public abstract void UpdateSkinnedMeshApproximateBoundsFromBounds();
  265. /// <summary>
  266. /// Updates the skinned mesh bounds by creating a bounding box that contains the bones (skeleton) of the source objects.
  267. /// </summary>
  268. public static void UpdateSkinnedMeshApproximateBoundsFromBonesStatic(Transform[] bs, SkinnedMeshRenderer smr){
  269. Vector3 max, min;
  270. max = bs[0].position;
  271. min = bs[0].position;
  272. for (int i = 1; i < bs.Length; i++){
  273. Vector3 v = bs[i].position;
  274. if (v.x < min.x) min.x = v.x;
  275. if (v.y < min.y) min.y = v.y;
  276. if (v.z < min.z) min.z = v.z;
  277. if (v.x > max.x) max.x = v.x;
  278. if (v.y > max.y) max.y = v.y;
  279. if (v.z > max.z) max.z = v.z;
  280. }
  281. Vector3 center = (max + min)/2f;
  282. Vector3 size = max - min;
  283. Matrix4x4 w2l = smr.worldToLocalMatrix;
  284. Bounds b = new Bounds(w2l * center, w2l * size);
  285. smr.localBounds = b;
  286. }
  287. public static void UpdateSkinnedMeshApproximateBoundsFromBoundsStatic(List<GameObject> objectsInCombined,SkinnedMeshRenderer smr){
  288. Bounds b = new Bounds();
  289. Bounds bigB = new Bounds();
  290. if (MB_Utility.GetBounds(objectsInCombined[0],out b)){
  291. bigB = b;
  292. } else {
  293. Debug.LogError("Could not get bounds. Not updating skinned mesh bounds");
  294. return;
  295. }
  296. for (int i = 1; i < objectsInCombined.Count; i++){
  297. if (MB_Utility.GetBounds(objectsInCombined[i],out b)){
  298. bigB.Encapsulate(b);
  299. } else {
  300. Debug.LogError("Could not get bounds. Not updating skinned mesh bounds");
  301. return;
  302. }
  303. }
  304. smr.localBounds = bigB;
  305. }
  306. protected virtual bool _CreateTemporaryTextrueBakeResult(GameObject[] gos, List<Material> matsOnTargetRenderer){
  307. if (GetNumObjectsInCombined() > 0)
  308. {
  309. Debug.LogError("Can't add objects if there are already objects in combined mesh when 'Texture Bake Result' is not set. Perhaps enable 'Clear Buffers After Bake'");
  310. return false;
  311. }
  312. _usingTemporaryTextureBakeResult = true;
  313. _textureBakeResults = MB2_TextureBakeResults.CreateForMaterialsOnRenderer(gos, matsOnTargetRenderer);
  314. return true;
  315. }
  316. public abstract List<Material> GetMaterialsOnTargetRenderer();
  317. }
  318. }