MB3_MeshCombinerSimple.cs 119 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623
  1. using UnityEngine;
  2. using System.Collections.Specialized;
  3. using System;
  4. using System.Collections.Generic;
  5. namespace DigitalOpus.MB.Core
  6. {
  7. /// <summary>
  8. /// Manages a single combined mesh.This class is the core of the mesh combining API.
  9. ///
  10. /// It is not a component so it can be can be instantiated and used like a normal c sharp class.
  11. /// </summary>
  12. [System.Serializable]
  13. public partial class MB3_MeshCombinerSingle : MB3_MeshCombiner
  14. {
  15. public override MB2_TextureBakeResults textureBakeResults
  16. {
  17. set
  18. {
  19. if (mbDynamicObjectsInCombinedMesh.Count > 0 && _textureBakeResults != value && _textureBakeResults != null)
  20. {
  21. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("If Texture Bake Result is changed then objects currently in combined mesh may be invalid.");
  22. }
  23. _textureBakeResults = value;
  24. }
  25. }
  26. public override MB_RenderType renderType
  27. {
  28. set
  29. {
  30. if (value == MB_RenderType.skinnedMeshRenderer && _renderType == MB_RenderType.meshRenderer)
  31. {
  32. if (boneWeights.Length != verts.Length) Debug.LogError("Can't set the render type to SkinnedMeshRenderer without clearing the mesh first. Try deleteing the CombinedMesh scene object.");
  33. }
  34. _renderType = value;
  35. }
  36. }
  37. public override GameObject resultSceneObject
  38. {
  39. set
  40. {
  41. if (_resultSceneObject != value)
  42. {
  43. _targetRenderer = null;
  44. if (_mesh != null && LOG_LEVEL >= MB2_LogLevel.warn)
  45. {
  46. Debug.LogWarning("Result Scene Object was changed when this mesh baker component had a reference to a mesh. If mesh is being used by another object make sure to reset the mesh to none before baking to avoid overwriting the other mesh.");
  47. }
  48. }
  49. _resultSceneObject = value;
  50. }
  51. }
  52. //this contains object instances that have been added to the combined mesh through AddDelete
  53. [SerializeField]
  54. protected List<GameObject> objectsInCombinedMesh = new List<GameObject>();
  55. [SerializeField]
  56. int lightmapIndex = -1;
  57. [SerializeField]
  58. List<MB_DynamicGameObject> mbDynamicObjectsInCombinedMesh = new List<MB_DynamicGameObject>();
  59. Dictionary<GameObject, MB_DynamicGameObject> _instance2combined_map = new Dictionary<GameObject, MB_DynamicGameObject>();
  60. [SerializeField]
  61. Vector3[] verts = new Vector3[0];
  62. [SerializeField]
  63. Vector3[] normals = new Vector3[0];
  64. [SerializeField]
  65. Vector4[] tangents = new Vector4[0];
  66. [SerializeField]
  67. Vector2[] uvs = new Vector2[0];
  68. [SerializeField]
  69. float[] uvsSliceIdx = new float[0];
  70. [SerializeField]
  71. Vector2[] uv2s = new Vector2[0];
  72. [SerializeField]
  73. Vector2[] uv3s = new Vector2[0];
  74. [SerializeField]
  75. Vector2[] uv4s = new Vector2[0];
  76. [SerializeField]
  77. Vector2[] uv5s = new Vector2[0];
  78. [SerializeField]
  79. Vector2[] uv6s = new Vector2[0];
  80. [SerializeField]
  81. Vector2[] uv7s = new Vector2[0];
  82. [SerializeField]
  83. Vector2[] uv8s = new Vector2[0];
  84. [SerializeField]
  85. Color[] colors = new Color[0];
  86. [SerializeField]
  87. Matrix4x4[] bindPoses = new Matrix4x4[0];
  88. [SerializeField]
  89. Transform[] bones = new Transform[0];
  90. [SerializeField]
  91. internal MBBlendShape[] blendShapes = new MBBlendShape[0];
  92. [SerializeField]
  93. //these blend shapes are not cleared they are used to build the src to combined blend shape map
  94. internal MBBlendShape[] blendShapesInCombined = new MBBlendShape[0];
  95. [SerializeField]
  96. SerializableIntArray[] submeshTris = new SerializableIntArray[0];
  97. [SerializeField]
  98. MeshCreationConditions _meshBirth = MeshCreationConditions.NoMesh;
  99. [SerializeField]
  100. Mesh _mesh;
  101. //unity won't serialize these
  102. BoneWeight[] boneWeights = new BoneWeight[0];
  103. //used if user passes null in as parameter to AddOrDelete
  104. GameObject[] empty = new GameObject[0];
  105. int[] emptyIDs = new int[0];
  106. MB_DynamicGameObject instance2Combined_MapGet(GameObject gameObjectID)
  107. {
  108. return _instance2combined_map[gameObjectID];
  109. }
  110. void instance2Combined_MapAdd(GameObject gameObjectID, MB_DynamicGameObject dgo)
  111. {
  112. _instance2combined_map.Add(gameObjectID, dgo);
  113. }
  114. void instance2Combined_MapRemove(GameObject gameObjectID)
  115. {
  116. _instance2combined_map.Remove(gameObjectID);
  117. }
  118. bool instance2Combined_MapTryGetValue(GameObject gameObjectID, out MB_DynamicGameObject dgo)
  119. {
  120. return _instance2combined_map.TryGetValue(gameObjectID, out dgo);
  121. }
  122. int instance2Combined_MapCount()
  123. {
  124. return _instance2combined_map.Count;
  125. }
  126. void instance2Combined_MapClear()
  127. {
  128. _instance2combined_map.Clear();
  129. }
  130. bool instance2Combined_MapContainsKey(GameObject gameObjectID)
  131. {
  132. return _instance2combined_map.ContainsKey(gameObjectID);
  133. }
  134. bool InstanceID2DGO(int instanceID, out MB_DynamicGameObject dgoGameObject)
  135. {
  136. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  137. {
  138. if (mbDynamicObjectsInCombinedMesh[i].instanceID == instanceID)
  139. {
  140. dgoGameObject = mbDynamicObjectsInCombinedMesh[i];
  141. return true;
  142. }
  143. }
  144. dgoGameObject = null;
  145. return false;
  146. }
  147. public override int GetNumObjectsInCombined()
  148. {
  149. return mbDynamicObjectsInCombinedMesh.Count;
  150. }
  151. public override List<GameObject> GetObjectsInCombined()
  152. {
  153. List<GameObject> outObs = new List<GameObject>();
  154. outObs.AddRange(objectsInCombinedMesh);
  155. return outObs;
  156. }
  157. public Mesh GetMesh()
  158. {
  159. if (_mesh == null)
  160. {
  161. _mesh = NewMesh();
  162. }
  163. return _mesh;
  164. }
  165. public void SetMesh(Mesh m)
  166. {
  167. if (m == null)
  168. {
  169. _meshBirth = MeshCreationConditions.AssignedByUser;
  170. }
  171. else
  172. {
  173. _meshBirth = MeshCreationConditions.NoMesh;
  174. }
  175. _mesh = m;
  176. }
  177. public Transform[] GetBones()
  178. {
  179. return bones;
  180. }
  181. public override int GetLightmapIndex()
  182. {
  183. if (settings.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout || settings.lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping)
  184. {
  185. return lightmapIndex;
  186. }
  187. else {
  188. return -1;
  189. }
  190. }
  191. public override int GetNumVerticesFor(GameObject go)
  192. {
  193. return GetNumVerticesFor(go.GetInstanceID());
  194. }
  195. public override int GetNumVerticesFor(int instanceID)
  196. {
  197. MB_DynamicGameObject dgo = null;
  198. InstanceID2DGO(instanceID, out dgo);
  199. if (dgo != null)
  200. {
  201. return dgo.numVerts;
  202. }
  203. else {
  204. return -1;
  205. }
  206. }
  207. [System.Obsolete("BuildSourceBlendShapeToCombinedIndexMap is deprecated. The map will be now be attached to the combined SkinnedMeshRenderer object as the MB_BlendShape2CombinedMap Component.")]
  208. public override Dictionary<MBBlendShapeKey, MBBlendShapeValue> BuildSourceBlendShapeToCombinedIndexMap()
  209. {
  210. if (_targetRenderer == null) return new Dictionary<MBBlendShapeKey, MBBlendShapeValue>();
  211. MB_BlendShape2CombinedMap mapComponent = _targetRenderer.GetComponent<MB_BlendShape2CombinedMap>();
  212. if (mapComponent == null) return new Dictionary<MBBlendShapeKey, MBBlendShapeValue>();
  213. return mapComponent.srcToCombinedMap.GenerateMapFromSerializedData();
  214. }
  215. internal void BuildSourceBlendShapeToCombinedSerializableIndexMap(SerializableSourceBlendShape2Combined outMap)
  216. {
  217. Debug.Assert(_targetRenderer.gameObject != null, "Target Renderer was null.");
  218. GameObject[] srcGameObjects = new GameObject[blendShapes.Length];
  219. int[] srcBlendShapeIdxs = new int[blendShapes.Length];
  220. GameObject[] targGameObjects = new GameObject[blendShapes.Length];
  221. int[] targBlendShapeIdxs = new int[blendShapes.Length];
  222. for (int i = 0; i < blendShapesInCombined.Length; i++)
  223. {
  224. srcGameObjects[i] = blendShapesInCombined[i].gameObject;
  225. srcBlendShapeIdxs[i] = blendShapesInCombined[i].indexInSource;
  226. targGameObjects[i] = _targetRenderer.gameObject;
  227. targBlendShapeIdxs[i] = i;
  228. }
  229. outMap.SetBuffers(srcGameObjects, srcBlendShapeIdxs, targGameObjects, targBlendShapeIdxs);
  230. }
  231. bool _Initialize(int numResultMats)
  232. {
  233. if (mbDynamicObjectsInCombinedMesh.Count == 0)
  234. {
  235. lightmapIndex = -1;
  236. }
  237. if (_mesh == null)
  238. {
  239. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("_initialize Creating new Mesh");
  240. _mesh = GetMesh();
  241. }
  242. if (instance2Combined_MapCount() != mbDynamicObjectsInCombinedMesh.Count)
  243. {
  244. //build the instance2Combined map
  245. instance2Combined_MapClear();
  246. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  247. {
  248. if (mbDynamicObjectsInCombinedMesh[i] != null)
  249. {
  250. if (mbDynamicObjectsInCombinedMesh[i].gameObject == null)
  251. {
  252. Debug.LogError("This MeshBaker contains information from a previous bake that is incomlete. It may have been baked by a previous version of Mesh Baker. If you are trying to update/modify a previously baked combined mesh. Try doing the original bake.");
  253. return false;
  254. }
  255. instance2Combined_MapAdd(mbDynamicObjectsInCombinedMesh[i].gameObject, mbDynamicObjectsInCombinedMesh[i]);
  256. }
  257. }
  258. //BoneWeights are not serialized get from combined mesh
  259. boneWeights = _mesh.boneWeights;
  260. }
  261. if (objectsInCombinedMesh.Count == 0)
  262. {
  263. if (submeshTris.Length != numResultMats)
  264. {
  265. submeshTris = new SerializableIntArray[numResultMats];
  266. for (int i = 0; i < submeshTris.Length; i++) submeshTris[i] = new SerializableIntArray(0);
  267. }
  268. }
  269. //MeshBaker was baked using old system that had duplicated bones. Upgrade to new system
  270. //need to build indexesOfBonesUsed maps for dgos
  271. if (mbDynamicObjectsInCombinedMesh.Count > 0 &&
  272. mbDynamicObjectsInCombinedMesh[0].indexesOfBonesUsed.Length == 0 &&
  273. settings.renderType == MB_RenderType.skinnedMeshRenderer &&
  274. boneWeights.Length > 0)
  275. {
  276. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  277. {
  278. MB_DynamicGameObject dgo = mbDynamicObjectsInCombinedMesh[i];
  279. HashSet<int> idxsOfBonesUsed = new HashSet<int>();
  280. for (int j = dgo.vertIdx; j < dgo.vertIdx + dgo.numVerts; j++)
  281. {
  282. if (boneWeights[j].weight0 > 0f) idxsOfBonesUsed.Add(boneWeights[j].boneIndex0);
  283. if (boneWeights[j].weight1 > 0f) idxsOfBonesUsed.Add(boneWeights[j].boneIndex1);
  284. if (boneWeights[j].weight2 > 0f) idxsOfBonesUsed.Add(boneWeights[j].boneIndex2);
  285. if (boneWeights[j].weight3 > 0f) idxsOfBonesUsed.Add(boneWeights[j].boneIndex3);
  286. }
  287. dgo.indexesOfBonesUsed = new int[idxsOfBonesUsed.Count];
  288. idxsOfBonesUsed.CopyTo(dgo.indexesOfBonesUsed);
  289. }
  290. if (LOG_LEVEL >= MB2_LogLevel.debug)
  291. Debug.Log("Baker used old systems that duplicated bones. Upgrading to new system by building indexesOfBonesUsed");
  292. }
  293. if (LOG_LEVEL >= MB2_LogLevel.trace) {
  294. Debug.Log (String.Format ("_initialize numObjsInCombined={0}", mbDynamicObjectsInCombinedMesh.Count));
  295. }
  296. return true;
  297. }
  298. bool _collectMaterialTriangles(Mesh m, MB_DynamicGameObject dgo, Material[] sharedMaterials, OrderedDictionary sourceMats2submeshIdx_map)
  299. {
  300. //everything here applies to the source object being added
  301. int numTriMeshes = m.subMeshCount;
  302. if (sharedMaterials.Length < numTriMeshes) numTriMeshes = sharedMaterials.Length;
  303. dgo._tmpSubmeshTris = new SerializableIntArray[numTriMeshes];
  304. dgo.targetSubmeshIdxs = new int[numTriMeshes];
  305. for (int i = 0; i < numTriMeshes; i++)
  306. {
  307. if (_textureBakeResults.doMultiMaterial || _textureBakeResults.resultType == MB2_TextureBakeResults.ResultType.textureArray)
  308. {
  309. if (!sourceMats2submeshIdx_map.Contains(sharedMaterials[i]))
  310. {
  311. Debug.LogError("Object " + dgo.name + " has a material that was not found in the result materials maping. " + sharedMaterials[i]);
  312. return false;
  313. }
  314. dgo.targetSubmeshIdxs[i] = (int)sourceMats2submeshIdx_map[sharedMaterials[i]];
  315. }
  316. else {
  317. dgo.targetSubmeshIdxs[i] = 0;
  318. }
  319. dgo._tmpSubmeshTris[i] = new SerializableIntArray();
  320. dgo._tmpSubmeshTris[i].data = m.GetTriangles(i);
  321. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Collecting triangles for: " + dgo.name + " submesh:" + i + " maps to submesh:" + dgo.targetSubmeshIdxs[i] + " added:" + dgo._tmpSubmeshTris[i].data.Length, LOG_LEVEL);
  322. }
  323. return true;
  324. }
  325. // if adding many copies of the same mesh want to cache obUVsResults
  326. bool _collectOutOfBoundsUVRects2(Mesh m, MB_DynamicGameObject dgo, Material[] sharedMaterials, OrderedDictionary sourceMats2submeshIdx_map, Dictionary<int, MB_Utility.MeshAnalysisResult[]> meshAnalysisResults, MeshChannelsCache meshChannelCache)
  327. {
  328. if (_textureBakeResults == null)
  329. {
  330. Debug.LogError("Need to bake textures into combined material");
  331. return false;
  332. }
  333. MB_Utility.MeshAnalysisResult[] res;
  334. if (!meshAnalysisResults.TryGetValue(m.GetInstanceID(), out res))
  335. {
  336. // Process the mesh and cache the result.
  337. int numSrcSubMeshes = m.subMeshCount;
  338. res = new MB_Utility.MeshAnalysisResult[numSrcSubMeshes];
  339. Vector2[] uvs = meshChannelCache.GetUv0Raw(m);
  340. for (int submeshIdx = 0; submeshIdx < numSrcSubMeshes; submeshIdx++)
  341. {
  342. MB_Utility.hasOutOfBoundsUVs(uvs, m, ref res[submeshIdx], submeshIdx);
  343. }
  344. meshAnalysisResults.Add(m.GetInstanceID(), res);
  345. }
  346. int numUsedSrcSubMeshes = sharedMaterials.Length;
  347. if (numUsedSrcSubMeshes > m.subMeshCount) numUsedSrcSubMeshes = m.subMeshCount;
  348. dgo.obUVRects = new Rect[numUsedSrcSubMeshes];
  349. // We might have fewer sharedMaterials than submeshes in the mesh.
  350. for (int submeshIdx = 0; submeshIdx < numUsedSrcSubMeshes; submeshIdx++)
  351. {
  352. int idxInResultMats = dgo.targetSubmeshIdxs[submeshIdx];
  353. if (_textureBakeResults.GetConsiderMeshUVs(idxInResultMats, sharedMaterials[submeshIdx]))
  354. {
  355. dgo.obUVRects[submeshIdx] = res[submeshIdx].uvRect;
  356. }
  357. }
  358. return true;
  359. }
  360. bool _validateTextureBakeResults()
  361. {
  362. if (_textureBakeResults == null)
  363. {
  364. Debug.LogError("Texture Bake Results is null. Can't combine meshes.");
  365. return false;
  366. }
  367. if (_textureBakeResults.materialsAndUVRects == null || _textureBakeResults.materialsAndUVRects.Length == 0)
  368. {
  369. Debug.LogError("Texture Bake Results has no materials in material to sourceUVRect map. Try baking materials. Can't combine meshes. " +
  370. "If you are trying to combine meshes without combining materials, try removing the Texture Bake Result.");
  371. return false;
  372. }
  373. if (_textureBakeResults.NumResultMaterials() == 0)
  374. {
  375. Debug.LogError("Texture Bake Results has no result materials. Try baking materials. Can't combine meshes.");
  376. return false;
  377. }
  378. if (settings.doUV && textureBakeResults.resultType == MB2_TextureBakeResults.ResultType.textureArray)
  379. {
  380. if (uvs.Length != uvsSliceIdx.Length)
  381. {
  382. Debug.LogError("uvs buffer and sliceIdx buffer are different sizes. Did you switch texture bake result from atlas to texture array result?");
  383. return false;
  384. }
  385. }
  386. return true;
  387. }
  388. /*
  389. bool _validateMeshFlags()
  390. {
  391. if (mbDynamicObjectsInCombinedMesh.Count > 0)
  392. {
  393. if (settings.doNorm == false && doNorm == true ||
  394. settings.doTan == false && doTan == true ||
  395. settings.doCol == false && doCol == true ||
  396. settings.doUV == false && doUV == true ||
  397. settings.doUV3 == false && doUV3 == true ||
  398. settings.doUV4 == false && doUV4 == true)
  399. {
  400. Debug.LogError("The channels have changed. There are already objects in the combined mesh that were added with a different set of channels.");
  401. return false;
  402. }
  403. }
  404. settings.doNorm = doNorm;
  405. settings.doTan = doTan;
  406. settings.doCol = doCol;
  407. settings.doUV = doUV;
  408. settings.doUV3 = doUV3;
  409. settings.doUV4 = doUV4;
  410. return true;
  411. }
  412. */
  413. bool _showHide(GameObject[] goToShow, GameObject[] goToHide)
  414. {
  415. if (goToShow == null) goToShow = empty;
  416. if (goToHide == null) goToHide = empty;
  417. //calculate amount to hide
  418. int numResultMats = _textureBakeResults.NumResultMaterials();
  419. if (!_Initialize(numResultMats))
  420. {
  421. return false;
  422. }
  423. for (int i = 0; i < goToHide.Length; i++)
  424. {
  425. if (!instance2Combined_MapContainsKey(goToHide[i]))
  426. {
  427. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Trying to hide an object " + goToHide[i] + " that is not in combined mesh. Did you initially bake with 'clear buffers after bake' enabled?");
  428. return false;
  429. }
  430. }
  431. //now to show
  432. for (int i = 0; i < goToShow.Length; i++)
  433. {
  434. if (!instance2Combined_MapContainsKey(goToShow[i]))
  435. {
  436. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Trying to show an object " + goToShow[i] + " that is not in combined mesh. Did you initially bake with 'clear buffers after bake' enabled?");
  437. return false;
  438. }
  439. }
  440. //set flags
  441. for (int i = 0; i < goToHide.Length; i++) _instance2combined_map[goToHide[i]].show = false;
  442. for (int i = 0; i < goToShow.Length; i++) _instance2combined_map[goToShow[i]].show = true;
  443. return true;
  444. }
  445. bool _addToCombined(GameObject[] goToAdd, int[] goToDelete, bool disableRendererInSource)
  446. {
  447. System.Diagnostics.Stopwatch sw = null;
  448. if (LOG_LEVEL >= MB2_LogLevel.debug)
  449. {
  450. sw = new System.Diagnostics.Stopwatch();
  451. sw.Start();
  452. }
  453. GameObject[] _goToAdd;
  454. int[] _goToDelete;
  455. if (!_validateTextureBakeResults()) return false;
  456. if (!ValidateTargRendererAndMeshAndResultSceneObj()) return false;
  457. if (outputOption != MB2_OutputOptions.bakeMeshAssetsInPlace &&
  458. settings.renderType == MB_RenderType.skinnedMeshRenderer)
  459. {
  460. if (_targetRenderer == null || !(_targetRenderer is SkinnedMeshRenderer))
  461. {
  462. Debug.LogError("Target renderer must be set and must be a SkinnedMeshRenderer");
  463. return false;
  464. }
  465. }
  466. if (settings.doBlendShapes && settings.renderType != MB_RenderType.skinnedMeshRenderer)
  467. {
  468. Debug.LogError("If doBlendShapes is set then RenderType must be skinnedMeshRenderer.");
  469. return false;
  470. }
  471. if (goToAdd == null) _goToAdd = empty;
  472. else _goToAdd = (GameObject[])goToAdd.Clone();
  473. if (goToDelete == null) _goToDelete = emptyIDs;
  474. else _goToDelete = (int[])goToDelete.Clone();
  475. if (_mesh == null) DestroyMesh(); //cleanup maps and arrays
  476. //MB2_TextureBakeResults.Material2AtlasRectangleMapper mat2rect_map = new MB2_TextureBakeResults.Material2AtlasRectangleMapper(textureBakeResults);
  477. UVAdjuster_Atlas uvAdjuster = new UVAdjuster_Atlas(textureBakeResults, LOG_LEVEL);
  478. int numResultMats = _textureBakeResults.NumResultMaterials();
  479. if (!_Initialize(numResultMats))
  480. {
  481. return false;
  482. }
  483. if (submeshTris.Length != numResultMats)
  484. {
  485. Debug.LogError("The number of submeshes " + submeshTris.Length + " in the combined mesh was not equal to the number of result materials " + numResultMats + " in the Texture Bake Result");
  486. return false;
  487. }
  488. if (_mesh.vertexCount > 0 && _instance2combined_map.Count == 0)
  489. {
  490. Debug.LogWarning("There were vertices in the combined mesh but nothing in the MeshBaker buffers. If you are trying to bake in the editor and modify at runtime, make sure 'Clear Buffers After Bake' is unchecked.");
  491. }
  492. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("==== Calling _addToCombined objs adding:" + _goToAdd.Length + " objs deleting:" + _goToDelete.Length + " fixOutOfBounds:" + textureBakeResults.DoAnyResultMatsUseConsiderMeshUVs() + " doMultiMaterial:" + textureBakeResults.doMultiMaterial + " disableRenderersInSource:" + disableRendererInSource, LOG_LEVEL);
  493. //backward compatibility set up resultMaterials if it is blank
  494. if (_textureBakeResults.NumResultMaterials() == 0)
  495. {
  496. Debug.LogError("No resultMaterials in this TextureBakeResults. Try baking textures.");
  497. return false;
  498. }
  499. OrderedDictionary sourceMats2submeshIdx_map = BuildSourceMatsToSubmeshIdxMap(numResultMats);
  500. if (sourceMats2submeshIdx_map == null)
  501. {
  502. return false;
  503. }
  504. //STEP 1 update our internal description of objects being added and deleted keep track of changes to buffer sizes as we do.
  505. //calculate amount to delete
  506. int totalDeleteVerts = 0;
  507. int[] totalDeleteSubmeshTris = new int[numResultMats];
  508. int totalDeleteBlendShapes = 0;
  509. //in order to decide if a bone can be deleted need to know which dgos use it so build a map
  510. MB3_MeshCombinerSimpleBones boneProcessor = new MB3_MeshCombinerSimpleBones(this);
  511. boneProcessor.BuildBoneIdx2DGOMapIfNecessary(_goToDelete);
  512. for (int i = 0; i < _goToDelete.Length; i++)
  513. {
  514. MB_DynamicGameObject dgo = null;
  515. InstanceID2DGO(_goToDelete[i], out dgo);
  516. if (dgo != null)
  517. {
  518. totalDeleteVerts += dgo.numVerts;
  519. totalDeleteBlendShapes += dgo.numBlendShapes;
  520. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  521. {
  522. boneProcessor.FindBonesToDelete(dgo);
  523. }
  524. for (int j = 0; j < dgo.submeshNumTris.Length; j++)
  525. {
  526. totalDeleteSubmeshTris[j] += dgo.submeshNumTris[j];
  527. }
  528. }
  529. else {
  530. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Trying to delete an object that is not in combined mesh");
  531. }
  532. }
  533. //now add
  534. List<MB_DynamicGameObject> toAddDGOs = new List<MB_DynamicGameObject>();
  535. Dictionary<int, MB_Utility.MeshAnalysisResult[]> meshAnalysisResultsCache = new Dictionary<int, MB_Utility.MeshAnalysisResult[]>(); //cache results
  536. //we are often adding the same sharedMesh many times. Only want to grab the results once and cache them
  537. MeshChannelsCache meshChannelCache = new MeshChannelsCache(LOG_LEVEL, lightmapOption);
  538. int totalAddVerts = 0;
  539. int[] totalAddSubmeshTris = new int[numResultMats];
  540. int totalAddBlendShapes = 0;
  541. for (int i = 0; i < _goToAdd.Length; i++)
  542. {
  543. // if not already in mesh or we are deleting and re-adding in same operation
  544. if (!instance2Combined_MapContainsKey(_goToAdd[i]) || Array.FindIndex<int>(_goToDelete, o => o == _goToAdd[i].GetInstanceID()) != -1)
  545. {
  546. MB_DynamicGameObject dgo = new MB_DynamicGameObject();
  547. GameObject go = _goToAdd[i];
  548. Material[] sharedMaterials = MB_Utility.GetGOMaterials(go);
  549. if (LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log(String.Format("Getting {0} shared materials for {1}",sharedMaterials.Length, go));
  550. if (sharedMaterials == null)
  551. {
  552. Debug.LogError("Object " + go.name + " does not have a Renderer");
  553. _goToAdd[i] = null;
  554. return false;
  555. }
  556. Mesh m = MB_Utility.GetMesh(go);
  557. if (sharedMaterials.Length > m.subMeshCount)
  558. {
  559. // The extra materials do nothing but could cause bugs.
  560. Array.Resize(ref sharedMaterials, m.subMeshCount);
  561. }
  562. if (m == null)
  563. {
  564. Debug.LogError("Object " + go.name + " MeshFilter or SkinedMeshRenderer had no mesh");
  565. _goToAdd[i] = null;
  566. return false;
  567. }
  568. else if (MBVersion.IsRunningAndMeshNotReadWriteable(m))
  569. {
  570. Debug.LogError("Object " + go.name + " Mesh Importer has read/write flag set to 'false'. This needs to be set to 'true' in order to read data from this mesh.");
  571. _goToAdd[i] = null;
  572. return false;
  573. }
  574. if (!uvAdjuster.MapSharedMaterialsToAtlasRects(sharedMaterials, false, m, meshChannelCache, meshAnalysisResultsCache, sourceMats2submeshIdx_map, go, dgo))
  575. {
  576. _goToAdd[i] = null;
  577. return false;
  578. }
  579. if (_goToAdd[i] != null)
  580. {
  581. toAddDGOs.Add(dgo);
  582. dgo.name = String.Format("{0} {1}", _goToAdd[i].ToString(), _goToAdd[i].GetInstanceID());
  583. dgo.instanceID = _goToAdd[i].GetInstanceID();
  584. dgo.gameObject = _goToAdd[i];
  585. dgo.numVerts = m.vertexCount;
  586. if (settings.doBlendShapes)
  587. {
  588. dgo.numBlendShapes = m.blendShapeCount;
  589. }
  590. Renderer r = MB_Utility.GetRenderer(go);
  591. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  592. {
  593. boneProcessor.CollectBonesToAddForDGO(dgo, r, meshChannelCache);
  594. }
  595. if (lightmapIndex == -1)
  596. {
  597. lightmapIndex = r.lightmapIndex; //initialize
  598. }
  599. if (settings.lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping)
  600. {
  601. if (lightmapIndex != r.lightmapIndex)
  602. {
  603. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Object " + go.name + " has a different lightmap index. Lightmapping will not work.");
  604. }
  605. if (!MBVersion.GetActive(go))
  606. {
  607. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Object " + go.name + " is inactive. Can only get lightmap index of active objects.");
  608. }
  609. if (r.lightmapIndex == -1)
  610. {
  611. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Object " + go.name + " does not have an index to a lightmap.");
  612. }
  613. }
  614. dgo.lightmapIndex = r.lightmapIndex;
  615. dgo.lightmapTilingOffset = MBVersion.GetLightmapTilingOffset(r);
  616. if (!_collectMaterialTriangles(m, dgo, sharedMaterials, sourceMats2submeshIdx_map))
  617. {
  618. return false;
  619. }
  620. dgo.meshSize = r.bounds.size;
  621. dgo.submeshNumTris = new int[numResultMats];
  622. dgo.submeshTriIdxs = new int[numResultMats];
  623. dgo.sourceSharedMaterials = sharedMaterials;
  624. bool doAnyResultsUseConsiderMeshUVs = textureBakeResults.DoAnyResultMatsUseConsiderMeshUVs();
  625. if (doAnyResultsUseConsiderMeshUVs)
  626. {
  627. if (!_collectOutOfBoundsUVRects2(m, dgo, sharedMaterials, sourceMats2submeshIdx_map, meshAnalysisResultsCache, meshChannelCache))
  628. {
  629. return false;
  630. }
  631. }
  632. totalAddVerts += dgo.numVerts;
  633. totalAddBlendShapes += dgo.numBlendShapes;
  634. for (int j = 0; j < dgo._tmpSubmeshTris.Length; j++)
  635. {
  636. totalAddSubmeshTris[dgo.targetSubmeshIdxs[j]] += dgo._tmpSubmeshTris[j].data.Length;
  637. }
  638. dgo.invertTriangles = IsMirrored(go.transform.localToWorldMatrix);
  639. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.uvRects.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  640. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.sourceSharedMaterials.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  641. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.encapsulatingRect.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  642. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.sourceMaterialTiling.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  643. if (doAnyResultsUseConsiderMeshUVs) Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.obUVRects.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  644. }
  645. }
  646. else {
  647. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Object " + _goToAdd[i].name + " has already been added");
  648. _goToAdd[i] = null;
  649. }
  650. }
  651. for (int i = 0; i < _goToAdd.Length; i++)
  652. {
  653. if (_goToAdd[i] != null && disableRendererInSource)
  654. {
  655. MB_Utility.DisableRendererInSource(_goToAdd[i]);
  656. if (LOG_LEVEL == MB2_LogLevel.trace) Debug.Log("Disabling renderer on " + _goToAdd[i].name + " id=" + _goToAdd[i].GetInstanceID());
  657. }
  658. }
  659. //STEP 2 to allocate new buffers and copy everything over
  660. int newVertSize = verts.Length + totalAddVerts - totalDeleteVerts;
  661. int newBonesSize = boneProcessor.GetNewBonesLength();
  662. int[] newSubmeshTrisSize = new int[numResultMats];
  663. int newBlendShapeSize = blendShapes.Length + totalAddBlendShapes - totalDeleteBlendShapes;
  664. if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.Log("Verts adding:" + totalAddVerts + " deleting:" + totalDeleteVerts + " submeshes:" + newSubmeshTrisSize.Length + " bones:" + newBonesSize + " blendShapes:" + newBlendShapeSize);
  665. for (int i = 0; i < newSubmeshTrisSize.Length; i++)
  666. {
  667. newSubmeshTrisSize[i] = submeshTris[i].data.Length + totalAddSubmeshTris[i] - totalDeleteSubmeshTris[i];
  668. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug(" submesh :" + i + " already contains:" + submeshTris[i].data.Length + " tris to be Added:" + totalAddSubmeshTris[i] + " tris to be Deleted:" + totalDeleteSubmeshTris[i]);
  669. }
  670. if (newVertSize >= MBVersion.MaxMeshVertexCount())
  671. {
  672. Debug.LogError("Cannot add objects. Resulting mesh will have more than " + MBVersion.MaxMeshVertexCount() + " vertices. Try using a Multi-MeshBaker component. This will split the combined mesh into several meshes. You don't have to re-configure the MB2_TextureBaker. Just remove the MB2_MeshBaker component and add a MB2_MultiMeshBaker component.");
  673. return false;
  674. }
  675. Vector3[] nnormals = null;
  676. Vector4[] ntangents = null;
  677. Vector2[] nuvs = null, nuv2s = null, nuv3s = null, nuv4s = null, nuv5s = null, nuv6s = null, nuv7s = null, nuv8s = null;
  678. float[] nuvsSliceIdx = null;
  679. Color[] ncolors = null;
  680. MBBlendShape[] nblendShapes = null;
  681. Vector3[] nverts = new Vector3[newVertSize];
  682. if (settings.doNorm) nnormals = new Vector3[newVertSize];
  683. if (settings.doTan) ntangents = new Vector4[newVertSize];
  684. if (settings.doUV) nuvs = new Vector2[newVertSize];
  685. if (settings.doUV && textureBakeResults.resultType == MB2_TextureBakeResults.ResultType.textureArray) nuvsSliceIdx = new float[newVertSize];
  686. if (settings.doUV3) nuv3s = new Vector2[newVertSize];
  687. if (settings.doUV4) nuv4s = new Vector2[newVertSize];
  688. if (settings.doUV5) nuv5s = new Vector2[newVertSize];
  689. if (settings.doUV6) nuv6s = new Vector2[newVertSize];
  690. if (settings.doUV7) nuv7s = new Vector2[newVertSize];
  691. if (settings.doUV8) nuv8s = new Vector2[newVertSize];
  692. if (doUV2())
  693. {
  694. nuv2s = new Vector2[newVertSize];
  695. }
  696. if (settings.doCol) ncolors = new Color[newVertSize];
  697. if (settings.doBlendShapes) nblendShapes = new MBBlendShape[newBlendShapeSize];
  698. BoneWeight[] nboneWeights = new BoneWeight[newVertSize];
  699. Matrix4x4[] nbindPoses = new Matrix4x4[newBonesSize];
  700. Transform[] nbones = new Transform[newBonesSize];
  701. SerializableIntArray[] nsubmeshTris = new SerializableIntArray[numResultMats];
  702. for (int i = 0; i < nsubmeshTris.Length; i++)
  703. {
  704. nsubmeshTris[i] = new SerializableIntArray(newSubmeshTrisSize[i]);
  705. }
  706. for (int i = 0; i < _goToDelete.Length; i++)
  707. {
  708. MB_DynamicGameObject dgo = null;
  709. InstanceID2DGO(_goToDelete[i], out dgo);
  710. if (dgo != null)
  711. {
  712. dgo._beingDeleted = true;
  713. }
  714. }
  715. mbDynamicObjectsInCombinedMesh.Sort();
  716. //copy existing arrays to narrays gameobj by gameobj omitting deleted ones
  717. int targVidx = 0;
  718. int targBlendShapeIdx = 0;
  719. int[] targSubmeshTidx = new int[numResultMats];
  720. int triangleIdxAdjustment = 0;
  721. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  722. {
  723. MB_DynamicGameObject dgo = mbDynamicObjectsInCombinedMesh[i];
  724. if (!dgo._beingDeleted)
  725. {
  726. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Copying obj in combined arrays idx:" + i, LOG_LEVEL);
  727. Array.Copy(verts, dgo.vertIdx, nverts, targVidx, dgo.numVerts);
  728. if (settings.doNorm) { Array.Copy(normals, dgo.vertIdx, nnormals, targVidx, dgo.numVerts); }
  729. if (settings.doTan) { Array.Copy(tangents, dgo.vertIdx, ntangents, targVidx, dgo.numVerts); }
  730. if (settings.doUV) { Array.Copy(uvs, dgo.vertIdx, nuvs, targVidx, dgo.numVerts); }
  731. if (settings.doUV && textureBakeResults.resultType == MB2_TextureBakeResults.ResultType.textureArray) { Array.Copy(uvsSliceIdx, dgo.vertIdx, nuvsSliceIdx, targVidx, dgo.numVerts); }
  732. if (settings.doUV3) { Array.Copy(uv3s, dgo.vertIdx, nuv3s, targVidx, dgo.numVerts); }
  733. if (settings.doUV4) { Array.Copy(uv4s, dgo.vertIdx, nuv4s, targVidx, dgo.numVerts); }
  734. if (settings.doUV5) { Array.Copy(uv5s, dgo.vertIdx, nuv5s, targVidx, dgo.numVerts); }
  735. if (settings.doUV6) { Array.Copy(uv6s, dgo.vertIdx, nuv6s, targVidx, dgo.numVerts); }
  736. if (settings.doUV7) { Array.Copy(uv7s, dgo.vertIdx, nuv7s, targVidx, dgo.numVerts); }
  737. if (settings.doUV8) { Array.Copy(uv8s, dgo.vertIdx, nuv8s, targVidx, dgo.numVerts); }
  738. if (doUV2()) { Array.Copy(uv2s, dgo.vertIdx, nuv2s, targVidx, dgo.numVerts); }
  739. if (settings.doCol) { Array.Copy(colors, dgo.vertIdx, ncolors, targVidx, dgo.numVerts); }
  740. if (settings.doBlendShapes) { Array.Copy(blendShapes, dgo.blendShapeIdx, nblendShapes, targBlendShapeIdx, dgo.numBlendShapes); }
  741. if (settings.renderType == MB_RenderType.skinnedMeshRenderer) { Array.Copy(boneWeights, dgo.vertIdx, nboneWeights, targVidx, dgo.numVerts); }
  742. //adjust triangles, then copy them over
  743. for (int subIdx = 0; subIdx < numResultMats; subIdx++)
  744. {
  745. int[] sTris = submeshTris[subIdx].data;
  746. int sTriIdx = dgo.submeshTriIdxs[subIdx];
  747. int sNumTris = dgo.submeshNumTris[subIdx];
  748. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug(" Adjusting submesh triangles submesh:" + subIdx + " startIdx:" + sTriIdx + " num:" + sNumTris + " nsubmeshTris:" + nsubmeshTris.Length + " targSubmeshTidx:" + targSubmeshTidx.Length, LOG_LEVEL);
  749. for (int j = sTriIdx; j < sTriIdx + sNumTris; j++)
  750. {
  751. sTris[j] = sTris[j] - triangleIdxAdjustment;
  752. }
  753. Array.Copy(sTris, sTriIdx, nsubmeshTris[subIdx].data, targSubmeshTidx[subIdx], sNumTris);
  754. }
  755. dgo.vertIdx = targVidx;
  756. dgo.blendShapeIdx = targBlendShapeIdx;
  757. for (int j = 0; j < targSubmeshTidx.Length; j++)
  758. {
  759. dgo.submeshTriIdxs[j] = targSubmeshTidx[j];
  760. targSubmeshTidx[j] += dgo.submeshNumTris[j];
  761. }
  762. targBlendShapeIdx += dgo.numBlendShapes;
  763. targVidx += dgo.numVerts;
  764. }
  765. else {
  766. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Not copying obj: " + i, LOG_LEVEL);
  767. triangleIdxAdjustment += dgo.numVerts;
  768. }
  769. }
  770. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  771. {
  772. boneProcessor.CopyBonesWeAreKeepingToNewBonesArrayAndAdjustBWIndexes(nbones, nbindPoses, nboneWeights, totalDeleteVerts);
  773. }
  774. //remove objects we are deleting
  775. for (int i = mbDynamicObjectsInCombinedMesh.Count - 1; i >= 0; i--)
  776. {
  777. if (mbDynamicObjectsInCombinedMesh[i]._beingDeleted)
  778. {
  779. instance2Combined_MapRemove(mbDynamicObjectsInCombinedMesh[i].gameObject);
  780. objectsInCombinedMesh.RemoveAt(i);
  781. mbDynamicObjectsInCombinedMesh.RemoveAt(i);
  782. }
  783. }
  784. verts = nverts;
  785. if (settings.doNorm) normals = nnormals;
  786. if (settings.doTan) tangents = ntangents;
  787. if (settings.doUV) uvs = nuvs;
  788. if (settings.doUV && textureBakeResults.resultType == MB2_TextureBakeResults.ResultType.textureArray) uvsSliceIdx = nuvsSliceIdx;
  789. if (settings.doUV3) uv3s = nuv3s;
  790. if (settings.doUV4) uv4s = nuv4s;
  791. if (settings.doUV5) uv5s = nuv5s;
  792. if (settings.doUV6) uv6s = nuv6s;
  793. if (settings.doUV7) uv7s = nuv7s;
  794. if (settings.doUV8) uv8s = nuv8s;
  795. if (doUV2()) uv2s = nuv2s;
  796. if (settings.doCol) colors = ncolors;
  797. if (settings.doBlendShapes) blendShapes = nblendShapes;
  798. if (settings.renderType == MB_RenderType.skinnedMeshRenderer) boneWeights = nboneWeights;
  799. int newBonesStartAtIdx = bones.Length - boneProcessor.GetNumBonesToDelete();
  800. bindPoses = nbindPoses;
  801. bones = nbones;
  802. submeshTris = nsubmeshTris;
  803. //insert the new bones into the bones array
  804. int bidx = 0;
  805. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  806. {
  807. foreach (BoneAndBindpose t in boneProcessor.GetBonesToAdd())
  808. {
  809. nbones[newBonesStartAtIdx + bidx] = t.bone;
  810. nbindPoses[newBonesStartAtIdx + bidx] = t.bindPose;
  811. bidx++;
  812. }
  813. }
  814. //add new
  815. for (int i = 0; i < toAddDGOs.Count; i++)
  816. {
  817. MB_DynamicGameObject dgo = toAddDGOs[i];
  818. GameObject go = _goToAdd[i];
  819. int vertsIdx = targVidx;
  820. int blendShapeIdx = targBlendShapeIdx;
  821. // Profile.StartProfile("TestNewNorm");
  822. Mesh mesh = MB_Utility.GetMesh(go);
  823. Matrix4x4 l2wMat = go.transform.localToWorldMatrix;
  824. // Similar to local2world but with translation removed and we are using the inverse transpose.
  825. // We use this for normals and tangents because it handles scaling correctly.
  826. Matrix4x4 l2wRotScale = l2wMat;
  827. l2wRotScale[0, 3] = l2wRotScale[1, 3] = l2wRotScale[2, 3] = 0f;
  828. l2wRotScale = l2wRotScale.inverse.transpose;
  829. //can't modify the arrays we get from the cache because they will be modified again
  830. nverts = meshChannelCache.GetVertices(mesh);
  831. Vector3[] nnorms = null;
  832. Vector4[] ntangs = null;
  833. if (settings.doNorm) nnorms = meshChannelCache.GetNormals(mesh);
  834. if (settings.doTan) ntangs = meshChannelCache.GetTangents(mesh);
  835. if (settings.renderType != MB_RenderType.skinnedMeshRenderer)
  836. { //for skinned meshes leave in bind pose
  837. for (int j = 0; j < nverts.Length; j++)
  838. {
  839. int vIdx = vertsIdx + j;
  840. verts[vertsIdx + j] = l2wMat.MultiplyPoint3x4(nverts[j]);
  841. if (settings.doNorm)
  842. {
  843. normals[vIdx] = l2wRotScale.MultiplyPoint3x4(nnorms[j]).normalized;
  844. }
  845. if (settings.doTan)
  846. {
  847. float w = ntangs[j].w; //need to preserve the w value
  848. tangents[vIdx] = l2wRotScale.MultiplyPoint3x4(((Vector3) ntangs[j])).normalized;
  849. tangents[vIdx].w = w;
  850. }
  851. }
  852. }
  853. else {
  854. if (settings.doNorm) nnorms.CopyTo(normals, vertsIdx);
  855. if (settings.doTan) ntangs.CopyTo(tangents, vertsIdx);
  856. nverts.CopyTo(verts, vertsIdx);
  857. }
  858. // Profile.EndProfile("TestNewNorm");
  859. int numTriSets = mesh.subMeshCount;
  860. if (dgo.uvRects.Length < numTriSets)
  861. {
  862. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Mesh " + dgo.name + " has more submeshes than materials");
  863. numTriSets = dgo.uvRects.Length;
  864. }
  865. else if (dgo.uvRects.Length > numTriSets)
  866. {
  867. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Mesh " + dgo.name + " has fewer submeshes than materials");
  868. }
  869. if (settings.doUV)
  870. {
  871. uvAdjuster._copyAndAdjustUVsFromMesh(textureBakeResults, dgo, mesh, 0, vertsIdx, uvs, uvsSliceIdx, meshChannelCache);
  872. }
  873. if (doUV2())
  874. {
  875. _copyAndAdjustUV2FromMesh(dgo, mesh, vertsIdx, meshChannelCache);
  876. }
  877. if (settings.doUV3)
  878. {
  879. nuv3s = meshChannelCache.GetUVChannel(3, mesh);
  880. nuv3s.CopyTo(uv3s, vertsIdx);
  881. }
  882. if (settings.doUV4)
  883. {
  884. nuv4s = meshChannelCache.GetUVChannel(4, mesh);
  885. nuv4s.CopyTo(uv4s, vertsIdx);
  886. }
  887. if (settings.doUV5)
  888. {
  889. nuv5s = meshChannelCache.GetUVChannel(5, mesh);
  890. nuv5s.CopyTo(uv5s, vertsIdx);
  891. }
  892. if (settings.doUV6)
  893. {
  894. nuv6s = meshChannelCache.GetUVChannel(6, mesh);
  895. nuv6s.CopyTo(uv6s, vertsIdx);
  896. }
  897. if (settings.doUV7)
  898. {
  899. nuv7s = meshChannelCache.GetUVChannel(7, mesh);
  900. nuv7s.CopyTo(uv7s, vertsIdx);
  901. }
  902. if (settings.doUV8)
  903. {
  904. nuv8s = meshChannelCache.GetUVChannel(8, mesh);
  905. nuv8s.CopyTo(uv8s, vertsIdx);
  906. }
  907. if (settings.doCol)
  908. {
  909. ncolors = meshChannelCache.GetColors(mesh);
  910. ncolors.CopyTo(colors, vertsIdx);
  911. }
  912. if (settings.doBlendShapes)
  913. {
  914. nblendShapes = meshChannelCache.GetBlendShapes(mesh, dgo.instanceID, dgo.gameObject);
  915. nblendShapes.CopyTo(blendShapes, blendShapeIdx);
  916. }
  917. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  918. {
  919. Renderer r = MB_Utility.GetRenderer(go);
  920. MB3_MeshCombinerSimpleBones.AddBonesToNewBonesArrayAndAdjustBWIndexes(this, dgo, r, vertsIdx, nbones, nboneWeights, meshChannelCache);
  921. }
  922. for (int combinedMeshIdx = 0; combinedMeshIdx < targSubmeshTidx.Length; combinedMeshIdx++)
  923. {
  924. dgo.submeshTriIdxs[combinedMeshIdx] = targSubmeshTidx[combinedMeshIdx];
  925. }
  926. for (int j = 0; j < dgo._tmpSubmeshTris.Length; j++)
  927. {
  928. int[] sts = dgo._tmpSubmeshTris[j].data;
  929. for (int k = 0; k < sts.Length; k++)
  930. {
  931. sts[k] = sts[k] + vertsIdx;
  932. }
  933. if (dgo.invertTriangles)
  934. {
  935. //need to reverse winding order
  936. for (int k = 0; k < sts.Length; k += 3)
  937. {
  938. int tmp = sts[k];
  939. sts[k] = sts[k + 1];
  940. sts[k + 1] = tmp;
  941. }
  942. }
  943. int combinedMeshIdx = dgo.targetSubmeshIdxs[j];
  944. sts.CopyTo(submeshTris[combinedMeshIdx].data, targSubmeshTidx[combinedMeshIdx]);
  945. dgo.submeshNumTris[combinedMeshIdx] += sts.Length;
  946. targSubmeshTidx[combinedMeshIdx] += sts.Length;
  947. }
  948. dgo.vertIdx = targVidx;
  949. dgo.blendShapeIdx = targBlendShapeIdx;
  950. instance2Combined_MapAdd(go, dgo);
  951. objectsInCombinedMesh.Add(go);
  952. mbDynamicObjectsInCombinedMesh.Add(dgo);
  953. targVidx += nverts.Length;
  954. if (settings.doBlendShapes)
  955. {
  956. targBlendShapeIdx += nblendShapes.Length;
  957. }
  958. for (int j = 0; j < dgo._tmpSubmeshTris.Length; j++) dgo._tmpSubmeshTris[j] = null;
  959. dgo._tmpSubmeshTris = null;
  960. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Added to combined:" + dgo.name + " verts:" + nverts.Length + " bindPoses:" + nbindPoses.Length, LOG_LEVEL);
  961. }
  962. if (settings.lightmapOption == MB2_LightmapOptions.copy_UV2_unchanged_to_separate_rects)
  963. {
  964. _copyUV2unchangedToSeparateRects();
  965. }
  966. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("===== _addToCombined completed. Verts in buffer: " + verts.Length + " time(ms): " + sw.ElapsedMilliseconds, LOG_LEVEL);
  967. return true;
  968. }
  969. void _copyAndAdjustUV2FromMesh(MB_DynamicGameObject dgo, Mesh mesh, int vertsIdx, MeshChannelsCache meshChannelsCache)
  970. {
  971. Vector2[] nuv2s = meshChannelsCache.GetUVChannel(2,mesh);
  972. if (settings.lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping)
  973. { //has a lightmap
  974. //this does not work in Unity 5. the lightmapTilingOffset is always 1,1,0,0 for all objects
  975. //lightMap index is always 1
  976. Vector2 uvscale2;
  977. Vector4 lightmapTilingOffset = dgo.lightmapTilingOffset;
  978. Vector2 uvscale = new Vector2(lightmapTilingOffset.x, lightmapTilingOffset.y);
  979. Vector2 uvoffset = new Vector2(lightmapTilingOffset.z, lightmapTilingOffset.w);
  980. for (int j = 0; j < nuv2s.Length; j++)
  981. {
  982. uvscale2.x = uvscale.x * nuv2s[j].x;
  983. uvscale2.y = uvscale.y * nuv2s[j].y;
  984. uv2s[vertsIdx + j] = uvoffset + uvscale2;
  985. }
  986. if (LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log("_copyAndAdjustUV2FromMesh copied and modify for preserve current lightmapping " + nuv2s.Length);
  987. }
  988. else
  989. {
  990. nuv2s.CopyTo(uv2s, vertsIdx);
  991. if (LOG_LEVEL >= MB2_LogLevel.trace)
  992. {
  993. Debug.Log("_copyAndAdjustUV2FromMesh copied without modifying " + nuv2s.Length);
  994. }
  995. }
  996. }
  997. public override void UpdateSkinnedMeshApproximateBounds()
  998. {
  999. UpdateSkinnedMeshApproximateBoundsFromBounds();
  1000. }
  1001. public override void UpdateSkinnedMeshApproximateBoundsFromBones()
  1002. {
  1003. if (outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace)
  1004. {
  1005. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Can't UpdateSkinnedMeshApproximateBounds when output type is bakeMeshAssetsInPlace");
  1006. return;
  1007. }
  1008. if (bones.Length == 0)
  1009. {
  1010. if (verts.Length > 0) if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("No bones in SkinnedMeshRenderer. Could not UpdateSkinnedMeshApproximateBounds.");
  1011. return;
  1012. }
  1013. if (_targetRenderer == null)
  1014. {
  1015. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Target Renderer is not set. No point in calling UpdateSkinnedMeshApproximateBounds.");
  1016. return;
  1017. }
  1018. if (!_targetRenderer.GetType().Equals(typeof(SkinnedMeshRenderer)))
  1019. {
  1020. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Target Renderer is not a SkinnedMeshRenderer. No point in calling UpdateSkinnedMeshApproximateBounds.");
  1021. return;
  1022. }
  1023. UpdateSkinnedMeshApproximateBoundsFromBonesStatic(bones, (SkinnedMeshRenderer)targetRenderer);
  1024. }
  1025. public override void UpdateSkinnedMeshApproximateBoundsFromBounds()
  1026. {
  1027. if (outputOption == MB2_OutputOptions.bakeMeshAssetsInPlace)
  1028. {
  1029. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Can't UpdateSkinnedMeshApproximateBoundsFromBounds when output type is bakeMeshAssetsInPlace");
  1030. return;
  1031. }
  1032. if (verts.Length == 0 || mbDynamicObjectsInCombinedMesh.Count == 0)
  1033. {
  1034. if (verts.Length > 0) if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Nothing in SkinnedMeshRenderer. Could not UpdateSkinnedMeshApproximateBoundsFromBounds.");
  1035. return;
  1036. }
  1037. if (_targetRenderer == null)
  1038. {
  1039. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Target Renderer is not set. No point in calling UpdateSkinnedMeshApproximateBoundsFromBounds.");
  1040. return;
  1041. }
  1042. if (!_targetRenderer.GetType().Equals(typeof(SkinnedMeshRenderer)))
  1043. {
  1044. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("Target Renderer is not a SkinnedMeshRenderer. No point in calling UpdateSkinnedMeshApproximateBoundsFromBounds.");
  1045. return;
  1046. }
  1047. UpdateSkinnedMeshApproximateBoundsFromBoundsStatic(objectsInCombinedMesh, (SkinnedMeshRenderer)targetRenderer);
  1048. }
  1049. Transform[] _getBones(Renderer r)
  1050. {
  1051. return MBVersion.GetBones(r);
  1052. }
  1053. public override void Apply(GenerateUV2Delegate uv2GenerationMethod)
  1054. {
  1055. bool doBones = false;
  1056. if (settings.renderType == MB_RenderType.skinnedMeshRenderer) doBones = true;
  1057. Apply(true, true, settings.doNorm, settings.doTan,
  1058. settings.doUV, doUV2(), settings.doUV3, settings.doUV4, settings.doUV5, settings.doUV6, settings.doUV7, settings.doUV8,
  1059. settings.doCol, doBones, settings.doBlendShapes, uv2GenerationMethod);
  1060. }
  1061. public virtual void ApplyShowHide()
  1062. {
  1063. if (_validationLevel >= MB2_ValidationLevel.quick && !ValidateTargRendererAndMeshAndResultSceneObj()) return;
  1064. if (_mesh != null)
  1065. {
  1066. if (settings.renderType == MB_RenderType.meshRenderer)
  1067. {
  1068. //for MeshRenderer meshes this is needed for adding. It breaks skinnedMeshRenderers
  1069. MBVersion.MeshClear(_mesh, true);
  1070. _mesh.vertices = verts;
  1071. }
  1072. SerializableIntArray[] submeshTrisToUse = GetSubmeshTrisWithShowHideApplied();
  1073. if (textureBakeResults.doMultiMaterial)
  1074. {
  1075. //submeshes with zero length tris cause error messages. must exclude these
  1076. int numNonZero = _mesh.subMeshCount = _numNonZeroLengthSubmeshTris(submeshTrisToUse);// submeshTrisToUse.Length;
  1077. int submeshIdx = 0;
  1078. for (int i = 0; i < submeshTrisToUse.Length; i++)
  1079. {
  1080. if (submeshTrisToUse[i].data.Length != 0)
  1081. {
  1082. _mesh.SetTriangles(submeshTrisToUse[i].data, submeshIdx);
  1083. submeshIdx++;
  1084. }
  1085. }
  1086. _updateMaterialsOnTargetRenderer(submeshTrisToUse, numNonZero);
  1087. }
  1088. else {
  1089. _mesh.triangles = submeshTrisToUse[0].data;
  1090. }
  1091. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  1092. {
  1093. if (verts.Length == 0)
  1094. {
  1095. //disable mesh renderer to avoid skinning warning
  1096. targetRenderer.enabled = false;
  1097. }
  1098. else
  1099. {
  1100. targetRenderer.enabled = true;
  1101. }
  1102. //needed so that updating local bounds will take affect
  1103. bool uwos = ((SkinnedMeshRenderer)targetRenderer).updateWhenOffscreen;
  1104. ((SkinnedMeshRenderer)targetRenderer).updateWhenOffscreen = true;
  1105. ((SkinnedMeshRenderer)targetRenderer).updateWhenOffscreen = uwos;
  1106. }
  1107. if (LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log("ApplyShowHide");
  1108. }
  1109. else {
  1110. Debug.LogError("Need to add objects to this meshbaker before calling ApplyShowHide");
  1111. }
  1112. }
  1113. public override void Apply(bool triangles,
  1114. bool vertices,
  1115. bool normals,
  1116. bool tangents,
  1117. bool uvs,
  1118. bool uv2,
  1119. bool uv3,
  1120. bool uv4,
  1121. bool colors,
  1122. bool bones = false,
  1123. bool blendShapesFlag = false,
  1124. GenerateUV2Delegate uv2GenerationMethod = null)
  1125. {
  1126. Apply(triangles, vertices, normals, tangents,
  1127. uvs, uv2, uv3, uv4,
  1128. false, false, false, false,
  1129. colors, bones, blendShapesFlag, uv2GenerationMethod);
  1130. }
  1131. public override void Apply(bool triangles,
  1132. bool vertices,
  1133. bool normals,
  1134. bool tangents,
  1135. bool uvs,
  1136. bool uv2,
  1137. bool uv3,
  1138. bool uv4,
  1139. bool uv5,
  1140. bool uv6,
  1141. bool uv7,
  1142. bool uv8,
  1143. bool colors,
  1144. bool bones = false,
  1145. bool blendShapesFlag = false,
  1146. GenerateUV2Delegate uv2GenerationMethod = null)
  1147. {
  1148. System.Diagnostics.Stopwatch sw = null;
  1149. if (LOG_LEVEL >= MB2_LogLevel.debug)
  1150. {
  1151. sw = new System.Diagnostics.Stopwatch();
  1152. sw.Start();
  1153. }
  1154. if (_validationLevel >= MB2_ValidationLevel.quick && !ValidateTargRendererAndMeshAndResultSceneObj()) return;
  1155. if (_mesh != null)
  1156. {
  1157. if (LOG_LEVEL >= MB2_LogLevel.trace)
  1158. {
  1159. Debug.Log(String.Format("Apply called tri={0} vert={1} norm={2} tan={3} uv={4} col={5} uv3={6} uv4={7} uv2={8} bone={9} blendShape{10} meshID={11}",
  1160. triangles, vertices, normals, tangents, uvs, colors, uv3, uv4, uv2, bones, blendShapes, _mesh.GetInstanceID()));
  1161. }
  1162. if (triangles || _mesh.vertexCount != verts.Length)
  1163. {
  1164. bool justClearTriangles = triangles && !vertices && !normals && !tangents && !uvs && !colors && !uv3 && !uv4 && !uv2 && !bones;
  1165. MBVersion.SetMeshIndexFormatAndClearMesh(_mesh, verts.Length, vertices, justClearTriangles);
  1166. }
  1167. if (vertices)
  1168. {
  1169. Vector3[] verts2Write = verts;
  1170. if (verts.Length > 0) {
  1171. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  1172. {
  1173. targetRenderer.transform.position = Vector3.zero;
  1174. } else if (settings.pivotLocationType == MB_MeshPivotLocation.worldOrigin)
  1175. {
  1176. targetRenderer.transform.position = Vector3.zero;
  1177. }
  1178. else if(settings.pivotLocationType == MB_MeshPivotLocation.boundsCenter)
  1179. {
  1180. Vector3 max = verts[0], min = verts[0];
  1181. for (int i = 1; i < verts.Length; i++)
  1182. {
  1183. Vector3 v = verts[i];
  1184. if (max.x < v.x) max.x = v.x;
  1185. if (max.y < v.y) max.y = v.y;
  1186. if (max.z < v.z) max.z = v.z;
  1187. if (min.x > v.x) min.x = v.x;
  1188. if (min.y > v.y) min.y = v.y;
  1189. if (min.z > v.z) min.z = v.z;
  1190. }
  1191. Vector3 center = (max + min) / 2f;
  1192. verts2Write = new Vector3[verts.Length];
  1193. for (int i = 0; i < verts.Length; i++)
  1194. {
  1195. verts2Write[i] = verts[i] - center;
  1196. }
  1197. targetRenderer.transform.position = center;
  1198. } else if (settings.pivotLocationType == MB_MeshPivotLocation.customLocation)
  1199. {
  1200. Vector3 center = settings.pivotLocation;
  1201. for (int i = 0; i < verts.Length; i++)
  1202. {
  1203. verts2Write[i] = verts[i] - center;
  1204. }
  1205. targetRenderer.transform.position = center;
  1206. }
  1207. }
  1208. _mesh.vertices = verts2Write;
  1209. }
  1210. if (triangles && _textureBakeResults)
  1211. {
  1212. if (_textureBakeResults == null)
  1213. {
  1214. Debug.LogError("Texture Bake Result was not set.");
  1215. }
  1216. else {
  1217. SerializableIntArray[] submeshTrisToUse = GetSubmeshTrisWithShowHideApplied();
  1218. //submeshes with zero length tris cause error messages. must exclude these
  1219. int numNonZero = _mesh.subMeshCount = _numNonZeroLengthSubmeshTris(submeshTrisToUse);// submeshTrisToUse.Length;
  1220. int submeshIdx = 0;
  1221. for (int i = 0; i < submeshTrisToUse.Length; i++)
  1222. {
  1223. if (submeshTrisToUse[i].data.Length != 0)
  1224. {
  1225. _mesh.SetTriangles(submeshTrisToUse[i].data, submeshIdx);
  1226. submeshIdx++;
  1227. }
  1228. }
  1229. _updateMaterialsOnTargetRenderer(submeshTrisToUse, numNonZero);
  1230. }
  1231. }
  1232. if (normals)
  1233. {
  1234. if (settings.doNorm) {
  1235. _mesh.normals = this.normals; }
  1236. else { Debug.LogError("normal flag was set in Apply but MeshBaker didn't generate normals"); }
  1237. }
  1238. if (tangents)
  1239. {
  1240. if (settings.doTan) { _mesh.tangents = this.tangents; }
  1241. else { Debug.LogError("tangent flag was set in Apply but MeshBaker didn't generate tangents"); }
  1242. }
  1243. if (colors)
  1244. {
  1245. if (settings.doCol)
  1246. {
  1247. if (settings.assignToMeshCustomizer == null)
  1248. {
  1249. _mesh.colors = this.colors;
  1250. }
  1251. else
  1252. {
  1253. settings.assignToMeshCustomizer.meshAssign_colors(settings, textureBakeResults, _mesh, this.colors, this.uvsSliceIdx);
  1254. }
  1255. }
  1256. else { Debug.LogError("color flag was set in Apply but MeshBaker didn't generate colors"); }
  1257. }
  1258. if (uvs)
  1259. {
  1260. if (settings.doUV)
  1261. {
  1262. if (settings.assignToMeshCustomizer == null)
  1263. {
  1264. _mesh.uv = this.uvs;
  1265. }
  1266. else
  1267. {
  1268. settings.assignToMeshCustomizer.meshAssign_UV0(0, settings, textureBakeResults, _mesh, this.uvs, this.uvsSliceIdx);
  1269. }
  1270. }
  1271. else { Debug.LogError("uv flag was set in Apply but MeshBaker didn't generate uvs"); }
  1272. }
  1273. if (uv2)
  1274. {
  1275. if (doUV2())
  1276. {
  1277. if (settings.assignToMeshCustomizer == null)
  1278. {
  1279. _mesh.uv2 = this.uv2s;
  1280. }
  1281. else
  1282. {
  1283. settings.assignToMeshCustomizer.meshAssign_UV2(2, settings, textureBakeResults, _mesh, this.uv2s, this.uvsSliceIdx);
  1284. }
  1285. }
  1286. else { Debug.LogError("uv2 flag was set in Apply but lightmapping option was set to " + settings.lightmapOption); }
  1287. }
  1288. if (uv3)
  1289. {
  1290. if (settings.doUV3)
  1291. {
  1292. if (settings.assignToMeshCustomizer == null)
  1293. {
  1294. MBVersion.MeshAssignUVChannel(3, _mesh, this.uv3s);
  1295. } else
  1296. {
  1297. settings.assignToMeshCustomizer.meshAssign_UV3(3, settings, textureBakeResults, _mesh, this.uv3s, this.uvsSliceIdx);
  1298. }
  1299. }
  1300. else { Debug.LogError("uv3 flag was set in Apply but MeshBaker didn't generate uv3s"); }
  1301. }
  1302. if (uv4)
  1303. {
  1304. if (settings.doUV4)
  1305. {
  1306. if (settings.assignToMeshCustomizer == null)
  1307. {
  1308. MBVersion.MeshAssignUVChannel(4, _mesh, this.uv4s);
  1309. }
  1310. else
  1311. {
  1312. settings.assignToMeshCustomizer.meshAssign_UV4(4, settings, textureBakeResults, _mesh, this.uv4s, this.uvsSliceIdx);
  1313. }
  1314. }
  1315. else { Debug.LogError("uv4 flag was set in Apply but MeshBaker didn't generate uv4s"); }
  1316. }
  1317. if (uv5)
  1318. {
  1319. if (settings.doUV5)
  1320. {
  1321. if (settings.assignToMeshCustomizer == null)
  1322. {
  1323. MBVersion.MeshAssignUVChannel(5, _mesh, this.uv5s);
  1324. }
  1325. else
  1326. {
  1327. settings.assignToMeshCustomizer.meshAssign_UV5(5, settings, textureBakeResults, _mesh, this.uv5s, this.uvsSliceIdx);
  1328. }
  1329. }
  1330. else { Debug.LogError("uv5 flag was set in Apply but MeshBaker didn't generate uv5s"); }
  1331. }
  1332. if (uv6)
  1333. {
  1334. if (settings.doUV6)
  1335. {
  1336. if (settings.assignToMeshCustomizer == null)
  1337. {
  1338. MBVersion.MeshAssignUVChannel(6, _mesh, this.uv6s);
  1339. }
  1340. else
  1341. {
  1342. settings.assignToMeshCustomizer.meshAssign_UV6(6, settings, textureBakeResults, _mesh, this.uv6s, this.uvsSliceIdx);
  1343. }
  1344. }
  1345. else { Debug.LogError("uv6 flag was set in Apply but MeshBaker didn't generate uv6s"); }
  1346. }
  1347. if (uv7)
  1348. {
  1349. if (settings.doUV7)
  1350. {
  1351. if (settings.assignToMeshCustomizer == null)
  1352. {
  1353. MBVersion.MeshAssignUVChannel(7, _mesh, this.uv7s);
  1354. }
  1355. else
  1356. {
  1357. settings.assignToMeshCustomizer.meshAssign_UV7(7, settings, textureBakeResults, _mesh, this.uv7s, this.uvsSliceIdx);
  1358. }
  1359. }
  1360. else { Debug.LogError("uv7 flag was set in Apply but MeshBaker didn't generate uv7s"); }
  1361. }
  1362. if (uv8)
  1363. {
  1364. if (settings.doUV8)
  1365. {
  1366. if (settings.assignToMeshCustomizer == null)
  1367. {
  1368. MBVersion.MeshAssignUVChannel(8, _mesh, this.uv8s);
  1369. }
  1370. else
  1371. {
  1372. settings.assignToMeshCustomizer.meshAssign_UV8(8, settings, textureBakeResults, _mesh, this.uv8s, this.uvsSliceIdx);
  1373. }
  1374. }
  1375. else { Debug.LogError("uv8 flag was set in Apply but MeshBaker didn't generate uv8s"); }
  1376. }
  1377. bool do_generate_new_UV2_layout = false;
  1378. if (settings.renderType != MB_RenderType.skinnedMeshRenderer && settings.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
  1379. {
  1380. if (uv2GenerationMethod != null)
  1381. {
  1382. uv2GenerationMethod(_mesh, settings.uv2UnwrappingParamsHardAngle, settings.uv2UnwrappingParamsPackMargin);
  1383. if (LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log("generating new UV2 layout for the combined mesh ");
  1384. }
  1385. else {
  1386. Debug.LogError("No GenerateUV2Delegate method was supplied. UV2 cannot be generated.");
  1387. }
  1388. do_generate_new_UV2_layout = true;
  1389. }
  1390. else if (settings.renderType == MB_RenderType.skinnedMeshRenderer && settings.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
  1391. {
  1392. if (LOG_LEVEL >= MB2_LogLevel.warn) Debug.LogWarning("UV2 cannot be generated for SkinnedMeshRenderer objects.");
  1393. }
  1394. if (settings.renderType != MB_RenderType.skinnedMeshRenderer && settings.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout && do_generate_new_UV2_layout == false)
  1395. {
  1396. Debug.LogError("Failed to generate new UV2 layout. Only works in editor.");
  1397. }
  1398. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  1399. {
  1400. if (verts.Length == 0)
  1401. {
  1402. //disable mesh renderer to avoid skinning warning
  1403. targetRenderer.enabled = false;
  1404. }
  1405. else {
  1406. targetRenderer.enabled = true;
  1407. }
  1408. //needed so that updating local bounds will take affect
  1409. bool uwos = ((SkinnedMeshRenderer)targetRenderer).updateWhenOffscreen;
  1410. ((SkinnedMeshRenderer)targetRenderer).updateWhenOffscreen = true;
  1411. ((SkinnedMeshRenderer)targetRenderer).updateWhenOffscreen = uwos;
  1412. }
  1413. if (bones)
  1414. {
  1415. _mesh.bindposes = this.bindPoses;
  1416. _mesh.boneWeights = this.boneWeights;
  1417. }
  1418. if (blendShapesFlag)
  1419. {
  1420. if (MBVersion.GetMajorVersion() > 5 ||
  1421. (MBVersion.GetMajorVersion() == 5 && MBVersion.GetMinorVersion() >= 3))
  1422. {
  1423. if (blendShapesInCombined.Length != blendShapes.Length) blendShapesInCombined = new MBBlendShape[blendShapes.Length];
  1424. Vector3[] vs = new UnityEngine.Vector3[verts.Length];
  1425. Vector3[] ns = new UnityEngine.Vector3[verts.Length];
  1426. Vector3[] ts = new UnityEngine.Vector3[verts.Length];
  1427. MBVersion.ClearBlendShapes(_mesh);
  1428. for (int i = 0; i < blendShapes.Length; i++)
  1429. {
  1430. MB_DynamicGameObject dgo = instance2Combined_MapGet(blendShapes[i].gameObject);
  1431. if (dgo != null)
  1432. {
  1433. for (int j = 0; j < blendShapes[i].frames.Length; j++)
  1434. {
  1435. MBBlendShapeFrame frame = blendShapes[i].frames[j];
  1436. int destIdx = dgo.vertIdx;
  1437. Array.Copy(frame.vertices, 0, vs, destIdx, blendShapes[i].frames[j].vertices.Length);
  1438. Array.Copy(frame.normals, 0, ns, destIdx, blendShapes[i].frames[j].normals.Length);
  1439. Array.Copy(frame.tangents, 0, ts, destIdx, blendShapes[i].frames[j].tangents.Length);
  1440. MBVersion.AddBlendShapeFrame(_mesh,blendShapes[i].name + blendShapes[i].gameObjectID, frame.frameWeight, vs, ns, ts);
  1441. _ZeroArray(vs, destIdx, blendShapes[i].frames[j].vertices.Length);
  1442. _ZeroArray(ns, destIdx, blendShapes[i].frames[j].normals.Length);
  1443. _ZeroArray(ts, destIdx, blendShapes[i].frames[j].tangents.Length);
  1444. }
  1445. }
  1446. else
  1447. {
  1448. Debug.LogError("InstanceID in blend shape that was not in instance2combinedMap");
  1449. }
  1450. blendShapesInCombined[i] = blendShapes[i];
  1451. }
  1452. //this is necessary to get the renderer to refresh its data about the blendshapes.
  1453. ((SkinnedMeshRenderer)_targetRenderer).sharedMesh = null;
  1454. ((SkinnedMeshRenderer)_targetRenderer).sharedMesh = _mesh;
  1455. // Add the map to the target renderer.
  1456. if (settings.doBlendShapes)
  1457. {
  1458. MB_BlendShape2CombinedMap mapComponent = _targetRenderer.GetComponent<MB_BlendShape2CombinedMap>();
  1459. if (mapComponent == null) mapComponent = _targetRenderer.gameObject.AddComponent<MB_BlendShape2CombinedMap>();
  1460. SerializableSourceBlendShape2Combined map = mapComponent.GetMap();
  1461. BuildSourceBlendShapeToCombinedSerializableIndexMap(map);
  1462. }
  1463. }
  1464. }
  1465. if (triangles || vertices)
  1466. {
  1467. if (LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log("recalculating bounds on mesh.");
  1468. _mesh.RecalculateBounds();
  1469. } if (settings.optimizeAfterBake && !Application.isPlaying)
  1470. {
  1471. MBVersion.OptimizeMesh(_mesh);
  1472. }
  1473. }
  1474. else {
  1475. Debug.LogError("Need to add objects to this meshbaker before calling Apply or ApplyAll");
  1476. }
  1477. if (LOG_LEVEL >= MB2_LogLevel.debug)
  1478. {
  1479. Debug.Log("Apply Complete time: " + sw.ElapsedMilliseconds + " vertices: " + _mesh.vertexCount);
  1480. }
  1481. }
  1482. int _numNonZeroLengthSubmeshTris(SerializableIntArray[] subTris)
  1483. {
  1484. int num = 0;
  1485. for (int i = 0; i < subTris.Length; i++) { if (subTris[i].data.Length > 0) num++;}
  1486. return num;
  1487. }
  1488. private void _updateMaterialsOnTargetRenderer(SerializableIntArray[] subTris, int numNonZeroLengthSubmeshTris)
  1489. {
  1490. //zero length triangle arrays in mesh cause errors. have excluded these sumbeshes so must exclude these materials
  1491. if (subTris.Length != textureBakeResults.NumResultMaterials()) Debug.LogError("Mismatch between number of submeshes and number of result materials");
  1492. Material[] resMats = new Material[numNonZeroLengthSubmeshTris];
  1493. int submeshIdx = 0;
  1494. for (int i = 0; i < subTris.Length; i++)
  1495. {
  1496. if (subTris[i].data.Length > 0) {
  1497. resMats[submeshIdx] = _textureBakeResults.GetCombinedMaterialForSubmesh(i);
  1498. submeshIdx++;
  1499. }
  1500. }
  1501. targetRenderer.materials = resMats;
  1502. }
  1503. public SerializableIntArray[] GetSubmeshTrisWithShowHideApplied()
  1504. {
  1505. bool containsHiddenObjects = false;
  1506. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  1507. {
  1508. if (mbDynamicObjectsInCombinedMesh[i].show == false)
  1509. {
  1510. containsHiddenObjects = true;
  1511. break;
  1512. }
  1513. }
  1514. if (containsHiddenObjects)
  1515. {
  1516. int[] newLengths = new int[submeshTris.Length];
  1517. SerializableIntArray[] newSubmeshTris = new SerializableIntArray[submeshTris.Length];
  1518. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  1519. {
  1520. MB_DynamicGameObject dgo = mbDynamicObjectsInCombinedMesh[i];
  1521. if (dgo.show)
  1522. {
  1523. for (int j = 0; j < dgo.submeshNumTris.Length; j++)
  1524. {
  1525. newLengths[j] += dgo.submeshNumTris[j];
  1526. }
  1527. }
  1528. }
  1529. for (int i = 0; i < newSubmeshTris.Length; i++)
  1530. {
  1531. newSubmeshTris[i] = new SerializableIntArray(newLengths[i]);
  1532. }
  1533. int[] idx = new int[newSubmeshTris.Length];
  1534. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  1535. {
  1536. MB_DynamicGameObject dgo = mbDynamicObjectsInCombinedMesh[i];
  1537. if (dgo.show)
  1538. {
  1539. for (int j = 0; j < submeshTris.Length; j++)
  1540. { //for each submesh
  1541. int[] triIdxs = submeshTris[j].data;
  1542. int startIdx = dgo.submeshTriIdxs[j];
  1543. int endIdx = startIdx + dgo.submeshNumTris[j];
  1544. for (int k = startIdx; k < endIdx; k++)
  1545. {
  1546. newSubmeshTris[j].data[idx[j]] = triIdxs[k];
  1547. idx[j] = idx[j] + 1;
  1548. }
  1549. }
  1550. }
  1551. }
  1552. return newSubmeshTris;
  1553. }
  1554. else {
  1555. return submeshTris;
  1556. }
  1557. }
  1558. public override bool UpdateGameObjects(GameObject[] gos, bool recalcBounds,
  1559. bool updateVertices, bool updateNormals, bool updateTangents,
  1560. bool updateUV, bool updateUV2, bool updateUV3, bool updateUV4,
  1561. bool updateColors, bool updateSkinningInfo)
  1562. {
  1563. return _updateGameObjects(gos, recalcBounds, updateVertices, updateNormals, updateTangents, updateUV, updateUV2, updateUV3, updateUV4,
  1564. false, false, false, false, updateColors, updateSkinningInfo);
  1565. }
  1566. public override bool UpdateGameObjects(GameObject[] gos, bool recalcBounds,
  1567. bool updateVertices, bool updateNormals, bool updateTangents,
  1568. bool updateUV, bool updateUV2, bool updateUV3, bool updateUV4,
  1569. bool updateUV5, bool updateUV6, bool updateUV7, bool updateUV8,
  1570. bool updateColors, bool updateSkinningInfo)
  1571. {
  1572. return _updateGameObjects(gos, recalcBounds, updateVertices, updateNormals, updateTangents, updateUV, updateUV2, updateUV3, updateUV4,
  1573. updateUV5, updateUV6, updateUV7, updateUV8, updateColors, updateSkinningInfo);
  1574. }
  1575. bool _updateGameObjects(GameObject[] gos, bool recalcBounds,
  1576. bool updateVertices, bool updateNormals, bool updateTangents,
  1577. bool updateUV, bool updateUV2, bool updateUV3, bool updateUV4, bool updateUV5, bool updateUV6, bool updateUV7, bool updateUV8,
  1578. bool updateColors, bool updateSkinningInfo)
  1579. {
  1580. if (LOG_LEVEL >= MB2_LogLevel.debug) Debug.Log("UpdateGameObjects called on " + gos.Length + " objects.");
  1581. int numResultMats = 1;
  1582. if (textureBakeResults.doMultiMaterial) numResultMats = textureBakeResults.NumResultMaterials();
  1583. if (!_Initialize(numResultMats))
  1584. {
  1585. return false;
  1586. }
  1587. if (_mesh.vertexCount > 0 && _instance2combined_map.Count == 0)
  1588. {
  1589. Debug.LogWarning("There were vertices in the combined mesh but nothing in the MeshBaker buffers. If you are trying to bake in the editor and modify at runtime, make sure 'Clear Buffers After Bake' is unchecked.");
  1590. }
  1591. bool success = true;
  1592. MeshChannelsCache meshChannelCache = new MeshChannelsCache(LOG_LEVEL, lightmapOption);
  1593. UVAdjuster_Atlas uvAdjuster = null;
  1594. OrderedDictionary sourceMats2submeshIdx_map = null;
  1595. Dictionary<int, MB_Utility.MeshAnalysisResult[]> meshAnalysisResultsCache = null;
  1596. if (updateUV){
  1597. sourceMats2submeshIdx_map = BuildSourceMatsToSubmeshIdxMap(numResultMats);
  1598. if (sourceMats2submeshIdx_map == null)
  1599. {
  1600. return false;
  1601. }
  1602. uvAdjuster = new UVAdjuster_Atlas(textureBakeResults, LOG_LEVEL);
  1603. meshAnalysisResultsCache = new Dictionary<int, MB_Utility.MeshAnalysisResult[]>();
  1604. }
  1605. for (int i = 0; i < gos.Length; i++)
  1606. {
  1607. success = success && _updateGameObject(gos[i], updateVertices, updateNormals, updateTangents, updateUV, updateUV2, updateUV3, updateUV4, updateUV5, updateUV6, updateUV7, updateUV8, updateColors, updateSkinningInfo,
  1608. meshChannelCache, meshAnalysisResultsCache, sourceMats2submeshIdx_map, uvAdjuster);
  1609. }
  1610. if (recalcBounds)
  1611. _mesh.RecalculateBounds();
  1612. return success;
  1613. }
  1614. bool _updateGameObject(GameObject go, bool updateVertices, bool updateNormals, bool updateTangents,
  1615. bool updateUV, bool updateUV2, bool updateUV3, bool updateUV4, bool updateUV5, bool updateUV6, bool updateUV7, bool updateUV8,
  1616. bool updateColors, bool updateSkinningInfo,
  1617. MeshChannelsCache meshChannelCache, Dictionary<int, MB_Utility.MeshAnalysisResult[]> meshAnalysisResultsCache,
  1618. OrderedDictionary sourceMats2submeshIdx_map, UVAdjuster_Atlas uVAdjuster)
  1619. {
  1620. MB_DynamicGameObject dgo = null;
  1621. if (!instance2Combined_MapTryGetValue(go, out dgo))
  1622. {
  1623. Debug.LogError("Object " + go.name + " has not been added");
  1624. return false;
  1625. }
  1626. Mesh mesh = MB_Utility.GetMesh(go);
  1627. if (dgo.numVerts != mesh.vertexCount)
  1628. {
  1629. Debug.LogError("Object " + go.name + " source mesh has been modified since being added. To update it must have the same number of verts");
  1630. return false;
  1631. }
  1632. if (settings.doUV && updateUV)
  1633. {
  1634. // updating UVs is a bit more complicated because most likely the user has changed
  1635. // the material on the source mesh which is why they are calling update. We need to
  1636. // find the UV rect for this.
  1637. Material[] sharedMaterials = MB_Utility.GetGOMaterials(go);
  1638. if (!uVAdjuster.MapSharedMaterialsToAtlasRects(sharedMaterials, true, mesh, meshChannelCache, meshAnalysisResultsCache, sourceMats2submeshIdx_map, go, dgo))
  1639. {
  1640. return false;
  1641. }
  1642. uVAdjuster._copyAndAdjustUVsFromMesh(textureBakeResults, dgo, mesh, 0, dgo.vertIdx, uvs, uvsSliceIdx, meshChannelCache);
  1643. }
  1644. if (doUV2() && updateUV2) _copyAndAdjustUV2FromMesh(dgo, mesh, dgo.vertIdx, meshChannelCache);
  1645. if (settings.renderType == MB_RenderType.skinnedMeshRenderer && updateSkinningInfo)
  1646. {
  1647. //only does BoneWeights. Used to do Bones and BindPoses but it doesn't make sence.
  1648. //if updating Bones and Bindposes should remove and re-add
  1649. Renderer r = MB_Utility.GetRenderer(go);
  1650. BoneWeight[] bws = meshChannelCache.GetBoneWeights(r, dgo.numVerts);
  1651. Transform[] bs = _getBones(r);
  1652. //assumes that the bones and boneweights have not been reeordered
  1653. int bwIdx = dgo.vertIdx; //the index in the verts array
  1654. bool switchedBonesDetected = false;
  1655. for (int i = 0; i < bws.Length; i++)
  1656. {
  1657. if (bs[bws[i].boneIndex0] != bones[boneWeights[bwIdx].boneIndex0])
  1658. {
  1659. switchedBonesDetected = true;
  1660. break;
  1661. }
  1662. boneWeights[bwIdx].weight0 = bws[i].weight0;
  1663. boneWeights[bwIdx].weight1 = bws[i].weight1;
  1664. boneWeights[bwIdx].weight2 = bws[i].weight2;
  1665. boneWeights[bwIdx].weight3 = bws[i].weight3;
  1666. bwIdx++;
  1667. }
  1668. if (switchedBonesDetected)
  1669. {
  1670. Debug.LogError("Detected that some of the boneweights reference different bones than when initial added. Boneweights must reference the same bones " + dgo.name);
  1671. }
  1672. }
  1673. //now do verts, norms, tangents, colors and uv1
  1674. Matrix4x4 l2wMat = go.transform.localToWorldMatrix;
  1675. // We use the inverse transpose for normals and tangents because it handles scaling of normals the same way that
  1676. // The shaders do.
  1677. Matrix4x4 l2wRotScale = l2wMat;
  1678. l2wRotScale[0, 3] = l2wRotScale[1, 3] = l2wRotScale[2, 3] = 0f;
  1679. l2wRotScale = l2wRotScale.inverse.transpose;
  1680. if (updateVertices)
  1681. {
  1682. Vector3[] nverts = meshChannelCache.GetVertices(mesh);
  1683. for (int j = 0; j < nverts.Length; j++)
  1684. {
  1685. verts[dgo.vertIdx + j] = l2wMat.MultiplyPoint3x4(nverts[j]);
  1686. }
  1687. }
  1688. l2wMat[0, 3] = l2wMat[1, 3] = l2wMat[2, 3] = 0f;
  1689. if (settings.doNorm && updateNormals)
  1690. {
  1691. Vector3[] nnorms = meshChannelCache.GetNormals(mesh);
  1692. for (int j = 0; j < nnorms.Length; j++)
  1693. {
  1694. int vIdx = dgo.vertIdx + j;
  1695. normals[vIdx] = l2wRotScale.MultiplyPoint3x4(nnorms[j]).normalized;
  1696. }
  1697. }
  1698. if (settings.doTan && updateTangents)
  1699. {
  1700. Vector4[] ntangs = meshChannelCache.GetTangents(mesh);
  1701. for (int j = 0; j < ntangs.Length; j++)
  1702. {
  1703. int vIdx = dgo.vertIdx + j;
  1704. float w = ntangs[j].w; //need to preserve the w value
  1705. tangents[vIdx] = l2wRotScale.MultiplyPoint3x4(((Vector3)ntangs[j])).normalized;
  1706. tangents[vIdx].w = w;
  1707. }
  1708. }
  1709. if (settings.doCol && updateColors)
  1710. {
  1711. Color[] ncolors = meshChannelCache.GetColors(mesh);
  1712. for (int j = 0; j < ncolors.Length; j++) colors[dgo.vertIdx + j] = ncolors[j];
  1713. }
  1714. if (settings.doUV3 && updateUV3)
  1715. {
  1716. Vector2[] nuv3 = meshChannelCache.GetUVChannel(3, mesh);
  1717. for (int j = 0; j < nuv3.Length; j++) uv3s[dgo.vertIdx + j] = nuv3[j];
  1718. }
  1719. if (settings.doUV4 && updateUV4)
  1720. {
  1721. Vector2[] nuv4 = meshChannelCache.GetUVChannel(4, mesh);
  1722. for (int j = 0; j < nuv4.Length; j++) uv4s[dgo.vertIdx + j] = nuv4[j];
  1723. }
  1724. if (settings.doUV5 && updateUV5)
  1725. {
  1726. Vector2[] nuv5 = meshChannelCache.GetUVChannel(5, mesh);
  1727. for (int j = 0; j < nuv5.Length; j++) uv5s[dgo.vertIdx + j] = nuv5[j];
  1728. }
  1729. if (settings.doUV6 && updateUV6)
  1730. {
  1731. Vector2[] nuv6 = meshChannelCache.GetUVChannel(6, mesh);
  1732. for (int j = 0; j < nuv6.Length; j++) uv6s[dgo.vertIdx + j] = nuv6[j];
  1733. }
  1734. if (settings.doUV7 && updateUV7)
  1735. {
  1736. Vector2[] nuv7 = meshChannelCache.GetUVChannel(7, mesh);
  1737. for (int j = 0; j < nuv7.Length; j++) uv7s[dgo.vertIdx + j] = nuv7[j];
  1738. }
  1739. if (settings.doUV8 && updateUV8)
  1740. {
  1741. Vector2[] nuv8 = meshChannelCache.GetUVChannel(8, mesh);
  1742. for (int j = 0; j < nuv8.Length; j++) uv8s[dgo.vertIdx + j] = nuv8[j];
  1743. }
  1744. return true;
  1745. }
  1746. public bool ShowHideGameObjects(GameObject[] toShow, GameObject[] toHide)
  1747. {
  1748. if (textureBakeResults == null)
  1749. {
  1750. Debug.LogError("TextureBakeResults must be set.");
  1751. return false;
  1752. }
  1753. return _showHide(toShow, toHide);
  1754. }
  1755. public override bool AddDeleteGameObjects(GameObject[] gos, GameObject[] deleteGOs, bool disableRendererInSource = true)
  1756. {
  1757. int[] delInstanceIDs = null;
  1758. if (deleteGOs != null)
  1759. {
  1760. delInstanceIDs = new int[deleteGOs.Length];
  1761. for (int i = 0; i < deleteGOs.Length; i++)
  1762. {
  1763. if (deleteGOs[i] == null)
  1764. {
  1765. Debug.LogError("The " + i + "th object on the list of objects to delete is 'Null'");
  1766. }
  1767. else {
  1768. delInstanceIDs[i] = deleteGOs[i].GetInstanceID();
  1769. }
  1770. }
  1771. }
  1772. return AddDeleteGameObjectsByID(gos, delInstanceIDs, disableRendererInSource);
  1773. }
  1774. public override bool AddDeleteGameObjectsByID(GameObject[] gos, int[] deleteGOinstanceIDs, bool disableRendererInSource)
  1775. {
  1776. // Profile.StartProfile("AddDeleteGameObjectsByID");
  1777. if (validationLevel > MB2_ValidationLevel.none)
  1778. {
  1779. //check for duplicates
  1780. if (gos != null)
  1781. {
  1782. for (int i = 0; i < gos.Length; i++)
  1783. {
  1784. if (gos[i] == null)
  1785. {
  1786. Debug.LogError("The " + i + "th object on the list of objects to combine is 'None'. Use Command-Delete on Mac OS X; Delete or Shift-Delete on Windows to remove this one element.");
  1787. return false;
  1788. }
  1789. if (validationLevel >= MB2_ValidationLevel.robust)
  1790. {
  1791. for (int j = i + 1; j < gos.Length; j++)
  1792. {
  1793. if (gos[i] == gos[j])
  1794. {
  1795. Debug.LogError("GameObject " + gos[i] + " appears twice in list of game objects to add");
  1796. return false;
  1797. }
  1798. }
  1799. }
  1800. }
  1801. }
  1802. if (deleteGOinstanceIDs != null && validationLevel >= MB2_ValidationLevel.robust)
  1803. {
  1804. for (int i = 0; i < deleteGOinstanceIDs.Length; i++)
  1805. {
  1806. for (int j = i + 1; j < deleteGOinstanceIDs.Length; j++)
  1807. {
  1808. if (deleteGOinstanceIDs[i] == deleteGOinstanceIDs[j])
  1809. {
  1810. Debug.LogError("GameObject " + deleteGOinstanceIDs[i] + "appears twice in list of game objects to delete");
  1811. return false;
  1812. }
  1813. }
  1814. }
  1815. }
  1816. }
  1817. if (_usingTemporaryTextureBakeResult && gos != null && gos.Length > 0)
  1818. {
  1819. MB_Utility.Destroy(_textureBakeResults);
  1820. _textureBakeResults = null;
  1821. _usingTemporaryTextureBakeResult = false;
  1822. }
  1823. //create a temporary _textureBakeResults if needed
  1824. if (_textureBakeResults == null && gos != null && gos.Length > 0 && gos[0] != null)
  1825. {
  1826. if (!_CreateTemporaryTextrueBakeResult(gos, GetMaterialsOnTargetRenderer()))
  1827. {
  1828. return false;
  1829. }
  1830. }
  1831. BuildSceneMeshObject(gos);
  1832. if (!_addToCombined(gos, deleteGOinstanceIDs, disableRendererInSource))
  1833. {
  1834. Debug.LogError("Failed to add/delete objects to combined mesh");
  1835. return false;
  1836. }
  1837. if (targetRenderer != null)
  1838. {
  1839. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  1840. {
  1841. SkinnedMeshRenderer smr = (SkinnedMeshRenderer)targetRenderer;
  1842. smr.sharedMesh = _mesh;
  1843. smr.bones = bones;
  1844. UpdateSkinnedMeshApproximateBoundsFromBounds();
  1845. }
  1846. targetRenderer.lightmapIndex = GetLightmapIndex();
  1847. }
  1848. // Profile.EndProfile("AddDeleteGameObjectsByID");
  1849. // Profile.PrintResults();
  1850. return true;
  1851. }
  1852. public override bool CombinedMeshContains(GameObject go)
  1853. {
  1854. return objectsInCombinedMesh.Contains(go);
  1855. }
  1856. public override void ClearBuffers()
  1857. {
  1858. verts = new Vector3[0];
  1859. normals = new Vector3[0];
  1860. tangents = new Vector4[0];
  1861. uvs = new Vector2[0];
  1862. uvsSliceIdx = new float[0];
  1863. uv2s = new Vector2[0];
  1864. uv3s = new Vector2[0];
  1865. uv4s = new Vector2[0];
  1866. uv5s = new Vector2[0];
  1867. uv6s = new Vector2[0];
  1868. uv7s = new Vector2[0];
  1869. uv8s = new Vector2[0];
  1870. colors = new Color[0];
  1871. bones = new Transform[0];
  1872. bindPoses = new Matrix4x4[0];
  1873. boneWeights = new BoneWeight[0];
  1874. submeshTris = new SerializableIntArray[0];
  1875. blendShapes = new MBBlendShape[0];
  1876. blendShapesInCombined = new MBBlendShape[0];
  1877. mbDynamicObjectsInCombinedMesh.Clear();
  1878. objectsInCombinedMesh.Clear();
  1879. instance2Combined_MapClear();
  1880. if (_usingTemporaryTextureBakeResult)
  1881. {
  1882. MB_Utility.Destroy(_textureBakeResults);
  1883. _textureBakeResults = null;
  1884. _usingTemporaryTextureBakeResult = false;
  1885. }
  1886. if (LOG_LEVEL >= MB2_LogLevel.trace) MB2_Log.LogDebug("ClearBuffers called");
  1887. }
  1888. private Mesh NewMesh()
  1889. {
  1890. if (Application.isPlaying)
  1891. {
  1892. _meshBirth = MeshCreationConditions.CreatedAtRuntime;
  1893. } else {
  1894. _meshBirth = MeshCreationConditions.CreatedInEditor;
  1895. }
  1896. Mesh m = new Mesh();
  1897. return m;
  1898. }
  1899. /*
  1900. * Empties all channels and clears the mesh
  1901. */
  1902. public override void ClearMesh()
  1903. {
  1904. if (_mesh != null)
  1905. {
  1906. MBVersion.MeshClear(_mesh, false);
  1907. }
  1908. else {
  1909. _mesh = NewMesh();
  1910. }
  1911. ClearBuffers();
  1912. }
  1913. public override void DisposeRuntimeCreated()
  1914. {
  1915. if (Application.isPlaying)
  1916. {
  1917. if (_meshBirth == MeshCreationConditions.CreatedAtRuntime)
  1918. {
  1919. GameObject.Destroy(_mesh);
  1920. }
  1921. else if (_meshBirth == MeshCreationConditions.AssignedByUser)
  1922. {
  1923. _mesh = null;
  1924. }
  1925. ClearBuffers();
  1926. }
  1927. }
  1928. /*
  1929. * Empties all channels, destroys the mesh and replaces it with a new mesh
  1930. */
  1931. public override void DestroyMesh()
  1932. {
  1933. if (_mesh != null)
  1934. {
  1935. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Destroying Mesh");
  1936. MB_Utility.Destroy(_mesh);
  1937. _meshBirth = MeshCreationConditions.NoMesh;
  1938. }
  1939. ClearBuffers();
  1940. }
  1941. public override void DestroyMeshEditor(MB2_EditorMethodsInterface editorMethods)
  1942. {
  1943. if (_mesh != null && editorMethods != null && !Application.isPlaying)
  1944. {
  1945. if (LOG_LEVEL >= MB2_LogLevel.debug) MB2_Log.LogDebug("Destroying Mesh");
  1946. editorMethods.Destroy(_mesh);
  1947. }
  1948. ClearBuffers();
  1949. }
  1950. public bool ValidateTargRendererAndMeshAndResultSceneObj()
  1951. {
  1952. if (_resultSceneObject == null)
  1953. {
  1954. if (_LOG_LEVEL >= MB2_LogLevel.error) Debug.LogError("Result Scene Object was not set.");
  1955. return false;
  1956. }
  1957. else {
  1958. if (_targetRenderer == null)
  1959. {
  1960. if (_LOG_LEVEL >= MB2_LogLevel.error) Debug.LogError("Target Renderer was not set.");
  1961. return false;
  1962. }
  1963. else {
  1964. if (_targetRenderer.transform.parent != _resultSceneObject.transform)
  1965. {
  1966. if (_LOG_LEVEL >= MB2_LogLevel.error) Debug.LogError("Target Renderer game object is not a child of Result Scene Object was not set.");
  1967. return false;
  1968. }
  1969. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  1970. {
  1971. if (!(_targetRenderer is SkinnedMeshRenderer))
  1972. {
  1973. if (_LOG_LEVEL >= MB2_LogLevel.error) Debug.LogError("Render Type is skinned mesh renderer but Target Renderer is not.");
  1974. return false;
  1975. }
  1976. /*
  1977. if (((SkinnedMeshRenderer)_targetRenderer).sharedMesh != _mesh)
  1978. {
  1979. if (_LOG_LEVEL >= MB2_LogLevel.error) Debug.LogError("Target renderer mesh is not equal to mesh.");
  1980. return false;
  1981. }
  1982. */
  1983. }
  1984. if (settings.renderType == MB_RenderType.meshRenderer)
  1985. {
  1986. if (!(_targetRenderer is MeshRenderer))
  1987. {
  1988. if (_LOG_LEVEL >= MB2_LogLevel.error) Debug.LogError("Render Type is mesh renderer but Target Renderer is not.");
  1989. return false;
  1990. }
  1991. MeshFilter mf = _targetRenderer.GetComponent<MeshFilter>();
  1992. if (_mesh != mf.sharedMesh)
  1993. {
  1994. if (_LOG_LEVEL >= MB2_LogLevel.error) Debug.LogError("Target renderer mesh is not equal to mesh.");
  1995. return false;
  1996. }
  1997. }
  1998. }
  1999. }
  2000. return true;
  2001. }
  2002. OrderedDictionary BuildSourceMatsToSubmeshIdxMap(int numResultMats)
  2003. {
  2004. OrderedDictionary sourceMats2submeshIdx_map = new OrderedDictionary();
  2005. //build the sourceMats to submesh index map
  2006. for (int resultMatIdx = 0; resultMatIdx < numResultMats; resultMatIdx++)
  2007. {
  2008. List<Material> sourceMats = _textureBakeResults.GetSourceMaterialsUsedByResultMaterial(resultMatIdx);
  2009. for (int j = 0; j < sourceMats.Count; j++)
  2010. {
  2011. if (sourceMats[j] == null)
  2012. {
  2013. Debug.LogError("Found null material in source materials for combined mesh materials " + resultMatIdx);
  2014. return null;
  2015. }
  2016. if (!sourceMats2submeshIdx_map.Contains(sourceMats[j]))
  2017. {
  2018. sourceMats2submeshIdx_map.Add(sourceMats[j], resultMatIdx);
  2019. }
  2020. }
  2021. }
  2022. return sourceMats2submeshIdx_map;
  2023. }
  2024. internal Renderer BuildSceneHierarchPreBake(MB3_MeshCombinerSingle mom, GameObject root, Mesh m, bool createNewChild = false, GameObject[] objsToBeAdded = null)
  2025. {
  2026. if (mom._LOG_LEVEL >= MB2_LogLevel.trace) Debug.Log("Building Scene Hierarchy createNewChild=" + createNewChild);
  2027. GameObject meshGO;
  2028. MeshFilter mf = null;
  2029. MeshRenderer mr = null;
  2030. SkinnedMeshRenderer smr = null;
  2031. Transform mt = null;
  2032. if (root == null)
  2033. {
  2034. Debug.LogError("root was null.");
  2035. return null;
  2036. }
  2037. if (mom.textureBakeResults == null)
  2038. {
  2039. Debug.LogError("textureBakeResults must be set.");
  2040. return null;
  2041. }
  2042. if (root.GetComponent<Renderer>() != null)
  2043. {
  2044. Debug.LogError("root game object cannot have a renderer component");
  2045. return null;
  2046. }
  2047. if (!createNewChild)
  2048. {
  2049. //try to find an existing child
  2050. if (mom.targetRenderer != null && mom.targetRenderer.transform.parent == root.transform)
  2051. {
  2052. mt = mom.targetRenderer.transform; //good setup
  2053. }
  2054. else
  2055. {
  2056. Renderer[] rs = (Renderer[])root.GetComponentsInChildren<Renderer>(true);
  2057. if (rs.Length == 1)
  2058. {
  2059. if (rs[0].transform.parent != root.transform)
  2060. {
  2061. Debug.LogError("Target Renderer is not an immediate child of Result Scene Object. Try using a game object with no children as the Result Scene Object..");
  2062. }
  2063. mt = rs[0].transform;
  2064. }
  2065. }
  2066. }
  2067. if (mt != null && mt.parent != root.transform)
  2068. { //target renderer must be a child of root
  2069. mt = null;
  2070. }
  2071. if (mt == null)
  2072. {
  2073. meshGO = new GameObject(mom.name + "-mesh");
  2074. meshGO.transform.parent = root.transform;
  2075. mt = meshGO.transform;
  2076. }
  2077. mt.parent = root.transform;
  2078. meshGO = mt.gameObject;
  2079. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2080. {
  2081. MeshRenderer r = meshGO.GetComponent<MeshRenderer>();
  2082. if (r != null) MB_Utility.Destroy(r);
  2083. MeshFilter f = meshGO.GetComponent<MeshFilter>();
  2084. if (f != null) MB_Utility.Destroy(f);
  2085. smr = meshGO.GetComponent<SkinnedMeshRenderer>();
  2086. if (smr == null) smr = meshGO.AddComponent<SkinnedMeshRenderer>();
  2087. }
  2088. else
  2089. {
  2090. SkinnedMeshRenderer r = meshGO.GetComponent<SkinnedMeshRenderer>();
  2091. if (r != null) MB_Utility.Destroy(r);
  2092. mf = meshGO.GetComponent<MeshFilter>();
  2093. if (mf == null) mf = meshGO.AddComponent<MeshFilter>();
  2094. mr = meshGO.GetComponent<MeshRenderer>();
  2095. if (mr == null) mr = meshGO.AddComponent<MeshRenderer>();
  2096. }
  2097. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2098. {
  2099. smr.bones = mom.GetBones();
  2100. bool origVal = smr.updateWhenOffscreen;
  2101. smr.updateWhenOffscreen = true;
  2102. smr.updateWhenOffscreen = origVal;
  2103. }
  2104. _ConfigureSceneHierarch(mom, root, mr, mf, smr, m, objsToBeAdded);
  2105. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2106. {
  2107. return smr;
  2108. }
  2109. else
  2110. {
  2111. return mr;
  2112. }
  2113. }
  2114. /*
  2115. could be building for a multiMeshBaker or a singleMeshBaker, targetRenderer will be a scene object.
  2116. */
  2117. public static void BuildPrefabHierarchy(MB3_MeshCombinerSingle mom, GameObject instantiatedPrefabRoot, Mesh m, bool createNewChild = false, GameObject[] objsToBeAdded = null)
  2118. {
  2119. SkinnedMeshRenderer smr = null;
  2120. MeshRenderer mr = null;
  2121. MeshFilter mf = null;
  2122. GameObject meshGO = new GameObject(mom.name + "-mesh");
  2123. meshGO.transform.parent = instantiatedPrefabRoot.transform;
  2124. Transform mt = meshGO.transform;
  2125. mt.parent = instantiatedPrefabRoot.transform;
  2126. meshGO = mt.gameObject;
  2127. if (mom.settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2128. {
  2129. MeshRenderer r = meshGO.GetComponent<MeshRenderer>();
  2130. if (r != null) MB_Utility.Destroy(r);
  2131. MeshFilter f = meshGO.GetComponent<MeshFilter>();
  2132. if (f != null) MB_Utility.Destroy(f);
  2133. smr = meshGO.GetComponent<SkinnedMeshRenderer>();
  2134. if (smr == null) smr = meshGO.AddComponent<SkinnedMeshRenderer>();
  2135. }
  2136. else
  2137. {
  2138. SkinnedMeshRenderer r = meshGO.GetComponent<SkinnedMeshRenderer>();
  2139. if (r != null) MB_Utility.Destroy(r);
  2140. mf = meshGO.GetComponent<MeshFilter>();
  2141. if (mf == null) mf = meshGO.AddComponent<MeshFilter>();
  2142. mr = meshGO.GetComponent<MeshRenderer>();
  2143. if (mr == null) mr = meshGO.AddComponent<MeshRenderer>();
  2144. }
  2145. if (mom.settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2146. {
  2147. smr.bones = mom.GetBones();
  2148. bool origVal = smr.updateWhenOffscreen;
  2149. smr.updateWhenOffscreen = true;
  2150. smr.updateWhenOffscreen = origVal;
  2151. smr.sharedMesh = m;
  2152. MB_BlendShape2CombinedMap srcMap = mom._targetRenderer.GetComponent<MB_BlendShape2CombinedMap>();
  2153. if (srcMap != null)
  2154. {
  2155. MB_BlendShape2CombinedMap targMap = meshGO.GetComponent<MB_BlendShape2CombinedMap>();
  2156. if (targMap == null) targMap = meshGO.AddComponent<MB_BlendShape2CombinedMap>();
  2157. targMap.srcToCombinedMap = srcMap.srcToCombinedMap;
  2158. for (int i = 0; i < targMap.srcToCombinedMap.combinedMeshTargetGameObject.Length; i++)
  2159. {
  2160. targMap.srcToCombinedMap.combinedMeshTargetGameObject[i] = meshGO;
  2161. }
  2162. }
  2163. }
  2164. _ConfigureSceneHierarch(mom, instantiatedPrefabRoot, mr, mf, smr, m, objsToBeAdded);
  2165. //First try to get the materials from the target renderer. This is because the mesh may have fewer submeshes than number of result materials if some of the submeshes had zero length tris.
  2166. //If we have just baked then materials on the target renderer will be correct wheras materials on the textureBakeResult may not be correct.
  2167. if (mom.targetRenderer != null)
  2168. {
  2169. Material[] sharedMats = new Material[mom.targetRenderer.sharedMaterials.Length];
  2170. for (int i = 0; i < sharedMats.Length; i++)
  2171. {
  2172. sharedMats[i] = mom.targetRenderer.sharedMaterials[i];
  2173. }
  2174. if (mom.settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2175. {
  2176. smr.sharedMaterial = null;
  2177. smr.sharedMaterials = sharedMats;
  2178. }
  2179. else
  2180. {
  2181. mr.sharedMaterial = null;
  2182. mr.sharedMaterials = sharedMats;
  2183. }
  2184. }
  2185. }
  2186. private static void _ConfigureSceneHierarch(MB3_MeshCombinerSingle mom, GameObject root, MeshRenderer mr, MeshFilter mf, SkinnedMeshRenderer smr, Mesh m, GameObject[] objsToBeAdded = null)
  2187. {
  2188. //assumes everything is set up correctly
  2189. GameObject meshGO;
  2190. if (mom.settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2191. {
  2192. meshGO = smr.gameObject;
  2193. //smr.sharedMesh = m; can't assign mesh for skinned mesh until it has skinning information
  2194. smr.lightmapIndex = mom.GetLightmapIndex();
  2195. }
  2196. else {
  2197. meshGO = mr.gameObject;
  2198. mf.sharedMesh = m;
  2199. mr.lightmapIndex = mom.GetLightmapIndex();
  2200. }
  2201. if (mom.settings.lightmapOption == MB2_LightmapOptions.preserve_current_lightmapping || mom.settings.lightmapOption == MB2_LightmapOptions.generate_new_UV2_layout)
  2202. {
  2203. meshGO.isStatic = true;
  2204. }
  2205. //set layer and tag of combined object if all source objs have same layer
  2206. if (objsToBeAdded != null && objsToBeAdded.Length > 0 && objsToBeAdded[0] != null)
  2207. {
  2208. bool tagsAreSame = true;
  2209. bool layersAreSame = true;
  2210. string tag = objsToBeAdded[0].tag;
  2211. int layer = objsToBeAdded[0].layer;
  2212. for (int i = 0; i < objsToBeAdded.Length; i++)
  2213. {
  2214. if (objsToBeAdded[i] != null)
  2215. {
  2216. if (!objsToBeAdded[i].tag.Equals(tag)) tagsAreSame = false;
  2217. if (objsToBeAdded[i].layer != layer) layersAreSame = false;
  2218. }
  2219. }
  2220. if (tagsAreSame)
  2221. {
  2222. root.tag = tag;
  2223. meshGO.tag = tag;
  2224. }
  2225. if (layersAreSame)
  2226. {
  2227. root.layer = layer;
  2228. meshGO.layer = layer;
  2229. }
  2230. }
  2231. }
  2232. public void BuildSceneMeshObject(GameObject[] gos = null, bool createNewChild = false)
  2233. {
  2234. if (_resultSceneObject == null)
  2235. {
  2236. _resultSceneObject = new GameObject("CombinedMesh-" + name);
  2237. }
  2238. _targetRenderer = BuildSceneHierarchPreBake(this, _resultSceneObject, GetMesh(), createNewChild, gos);
  2239. }
  2240. //tests if a matrix has been mirrored
  2241. bool IsMirrored(Matrix4x4 tm)
  2242. {
  2243. Vector3 x = tm.GetRow(0);
  2244. Vector3 y = tm.GetRow(1);
  2245. Vector3 z = tm.GetRow(2);
  2246. x.Normalize(); y.Normalize(); z.Normalize();
  2247. float an = Vector3.Dot(Vector3.Cross(x, y), z);
  2248. return an >= 0 ? false : true;
  2249. }
  2250. public override void CheckIntegrity()
  2251. {
  2252. if (!MB_Utility.DO_INTEGRITY_CHECKS) return;
  2253. //check bones.
  2254. if (settings.renderType == MB_RenderType.skinnedMeshRenderer)
  2255. {
  2256. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  2257. {
  2258. MB_DynamicGameObject dgo = mbDynamicObjectsInCombinedMesh[i];
  2259. HashSet<int> usedBonesWeights = new HashSet<int>();
  2260. HashSet<int> usedBonesIndexes = new HashSet<int>();
  2261. for (int j = dgo.vertIdx; j < dgo.vertIdx + dgo.numVerts; j++)
  2262. {
  2263. usedBonesWeights.Add(boneWeights[j].boneIndex0);
  2264. usedBonesWeights.Add(boneWeights[j].boneIndex1);
  2265. usedBonesWeights.Add(boneWeights[j].boneIndex2);
  2266. usedBonesWeights.Add(boneWeights[j].boneIndex3);
  2267. }
  2268. for (int j = 0; j < dgo.indexesOfBonesUsed.Length; j++)
  2269. {
  2270. usedBonesIndexes.Add(dgo.indexesOfBonesUsed[j]);
  2271. }
  2272. usedBonesIndexes.ExceptWith(usedBonesWeights);
  2273. if (usedBonesIndexes.Count > 0)
  2274. {
  2275. Debug.LogError("The bone indexes were not the same. " + usedBonesWeights.Count + " " + usedBonesIndexes.Count);
  2276. }
  2277. for (int j = 0; j < dgo.indexesOfBonesUsed.Length; j++)
  2278. {
  2279. if (j < 0 || j > bones.Length)
  2280. Debug.LogError("Bone index was out of bounds.");
  2281. }
  2282. if (settings.renderType == MB_RenderType.skinnedMeshRenderer && dgo.indexesOfBonesUsed.Length < 1)
  2283. Debug.Log("DGO had no bones");
  2284. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.uvRects.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  2285. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.sourceSharedMaterials.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  2286. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.encapsulatingRect.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  2287. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.sourceMaterialTiling.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  2288. Debug.Assert(dgo.targetSubmeshIdxs.Length == dgo.obUVRects.Length, "Array length mismatch targetSubmeshIdxs, uvRects");
  2289. }
  2290. }
  2291. //check blend shapes
  2292. if (settings.doBlendShapes)
  2293. {
  2294. if (settings.renderType != MB_RenderType.skinnedMeshRenderer)
  2295. {
  2296. Debug.LogError("Blend shapes can only be used with skinned meshes.");
  2297. }
  2298. }
  2299. }
  2300. void _ZeroArray(Vector3[] arr, int idx, int length)
  2301. {
  2302. int bound = idx + length;
  2303. for (int i = idx; i < bound; i++)
  2304. {
  2305. arr[i] = Vector3.zero;
  2306. }
  2307. }
  2308. void _copyUV2unchangedToSeparateRects()
  2309. {
  2310. int uv2Padding = 16; //todo
  2311. //todo meshSize
  2312. List<Vector2> uv2AtlasSizes = new List<Vector2>();
  2313. float minSize = 10e10f;
  2314. float maxSize = 0f;
  2315. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  2316. {
  2317. float zz = mbDynamicObjectsInCombinedMesh[i].meshSize.magnitude;
  2318. if (zz > maxSize) maxSize = zz;
  2319. if (zz < minSize) minSize = zz;
  2320. }
  2321. //normalize size so all values lie between these two values
  2322. float MAX_UV_VAL = 1000f;
  2323. float MIN_UV_VAL = 10f;
  2324. float offset = 0;
  2325. float scale = 1;
  2326. if (maxSize - minSize > MAX_UV_VAL - MIN_UV_VAL)
  2327. {
  2328. //need to compress the range. Scale until is MAX_UV_VAL - MIN_UV_VAL in size and shift
  2329. scale = (MAX_UV_VAL - MIN_UV_VAL) / (maxSize - minSize);
  2330. offset = MIN_UV_VAL - minSize * scale;
  2331. } else
  2332. {
  2333. scale = MAX_UV_VAL / maxSize;
  2334. }
  2335. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  2336. {
  2337. float zz = mbDynamicObjectsInCombinedMesh[i].meshSize.magnitude;
  2338. zz = zz * scale + offset;
  2339. Vector2 sz = Vector2.one * zz;
  2340. uv2AtlasSizes.Add(sz);
  2341. }
  2342. //run texture packer on these rects
  2343. MB2_TexturePacker tp = new MB2_TexturePackerRegular();
  2344. tp.atlasMustBePowerOfTwo = false;
  2345. AtlasPackingResult[] uv2Rects = tp.GetRects(uv2AtlasSizes, 8192, 8192, uv2Padding);
  2346. //Debug.Assert(uv2Rects.Length == 1);
  2347. //adjust UV2s
  2348. for (int i = 0; i < mbDynamicObjectsInCombinedMesh.Count; i++)
  2349. {
  2350. MB_DynamicGameObject dgo = mbDynamicObjectsInCombinedMesh[i];
  2351. float minx, maxx, miny, maxy;
  2352. minx = maxx = uv2s[dgo.vertIdx].x;
  2353. miny = maxy = uv2s[dgo.vertIdx].y;
  2354. int endIdx = dgo.vertIdx + dgo.numVerts;
  2355. for (int j = dgo.vertIdx; j < endIdx; j++)
  2356. {
  2357. if (uv2s[j].x < minx) minx = uv2s[j].x;
  2358. if (uv2s[j].x > maxx) maxx = uv2s[j].x;
  2359. if (uv2s[j].y < miny) miny = uv2s[j].y;
  2360. if (uv2s[j].y > maxy) maxy = uv2s[j].y;
  2361. }
  2362. // scale it to fit the rect
  2363. Rect r = uv2Rects[0].rects[i];
  2364. for (int j = dgo.vertIdx; j < endIdx; j++)
  2365. {
  2366. float width = maxx - minx;
  2367. float height = maxy - miny;
  2368. if (width == 0f) width = 1f;
  2369. if (height == 0f) height = 1f;
  2370. uv2s[j].x = ((uv2s[j].x - minx) / width) * r.width + r.x;
  2371. uv2s[j].y = ((uv2s[j].y - miny) / height) * r.height + r.y;
  2372. }
  2373. }
  2374. }
  2375. public override List<Material> GetMaterialsOnTargetRenderer()
  2376. {
  2377. List<Material> outMats = new List<Material>();
  2378. if (_targetRenderer != null)
  2379. {
  2380. outMats.AddRange(_targetRenderer.sharedMaterials);
  2381. }
  2382. return outMats;
  2383. }
  2384. }
  2385. }