MB3_TextureCombinerAtlasRect.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5. using System.Text;
  6. namespace DigitalOpus.MB.Core
  7. {
  8. /*
  9. Like a material but also stores its tiling info since the same texture
  10. with different tiling may need to be baked to a separate spot in the atlas
  11. note that it is sometimes possible for textures with different tiling to share an atlas rectangle
  12. To accomplish this need to store:
  13. uvTiling per TexSet (can be set to 0,0,1,1 by pushing tiling down into material tiling)
  14. matTiling per MeshBakerMaterialTexture (this is the total tiling baked into the atlas)
  15. matSubrectInFullSamplingRect per material (a MeshBakerMaterialTexture can be used by multiple materials. This is the subrect in the atlas)
  16. Normally UVTilings is applied first then material tiling after. This is difficult for us to use when baking meshes. It is better to apply material
  17. tiling first then UV Tiling. There is a transform for modifying the material tiling to handle this.
  18. once the material tiling is applied first then the uvTiling can be pushed down into the material tiling.
  19. Also note that this can wrap a procedural texture. The procedural texture is converted to a Texture2D in Step2 NOT BEFORE. This is important so that can
  20. build packing layout quickly.
  21. Should always check if texture is null using 'isNull' function since Texture2D could be null but ProceduralTexture not
  22. Should not call GetTexture2D before procedural textures are created
  23. there will be one of these per material texture property (maintex, bump etc...)
  24. */
  25. public class MeshBakerMaterialTexture
  26. {
  27. //private ProceduralTexture _procT;
  28. private Texture2D _t;
  29. public Texture2D t
  30. {
  31. set { _t = value; }
  32. }
  33. public float texelDensity; //how many pixels per polygon area
  34. internal static bool readyToBuildAtlases = false;
  35. //if these are the same for all properties then these can be merged
  36. /// <summary>
  37. /// sampling rect including both material tiling and uv Tiling. Most of the time this is the
  38. /// same for maintex, bumpmap, etc... but it does not need to be. Could have maintex with one
  39. /// tiling and bumpmap with another. If these are the same for all properties then these can be merged
  40. /// </summary>
  41. private DRect encapsulatingSamplingRect;
  42. /// <summary>
  43. /// IMPORTANT: There are two materialTilingRects. These ones are stored per result-material-texture-property.
  44. /// The are used when baking atlases, NOT for mapping materials to atlas rects and transforming UVs.
  45. /// The material tiling for a texture. These can be different for different properties: maintex, bumpmap etc....
  46. /// If these are the same for all properties then the MB_TexSets can be merged.
  47. /// </summary>
  48. public DRect matTilingRect { get; private set; }
  49. /// <summary>
  50. /// Returns -1 if this texture was imported as a normal map
  51. /// Returns 1 if this texture was not imported as a normal map
  52. /// Returns 0 if unknown
  53. /// </summary>
  54. public int isImportedAsNormalMap { get; private set; }
  55. public MeshBakerMaterialTexture() { }
  56. public MeshBakerMaterialTexture(Texture tx)
  57. {
  58. if (tx is Texture2D)
  59. {
  60. _t = (Texture2D)tx;
  61. }
  62. //else if (tx is ProceduralTexture)
  63. //{
  64. // _procT = (ProceduralTexture)tx;
  65. //}
  66. else if (tx == null)
  67. {
  68. //do nothing
  69. }
  70. else
  71. {
  72. Debug.LogError("An error occured. Texture must be Texture2D " + tx);
  73. }
  74. }
  75. public MeshBakerMaterialTexture(Texture tx, Vector2 matTilingOffset, Vector2 matTilingScale, float texelDens, int isImportedAsNormalMap)
  76. {
  77. if (tx is Texture2D)
  78. {
  79. _t = (Texture2D)tx;
  80. }
  81. //else if (tx is ProceduralTexture)
  82. //{
  83. // _procT = (ProceduralTexture)tx;
  84. //}
  85. else if (tx == null)
  86. {
  87. //do nothing
  88. }
  89. else
  90. {
  91. Debug.LogError("An error occured. Texture must be Texture2D " + tx);
  92. }
  93. matTilingRect = new DRect(matTilingOffset, matTilingScale);
  94. texelDensity = texelDens;
  95. this.isImportedAsNormalMap = isImportedAsNormalMap;
  96. }
  97. public DRect GetEncapsulatingSamplingRect()
  98. {
  99. return encapsulatingSamplingRect;
  100. }
  101. /*
  102. public void SetMaterialTilingTo0011()
  103. {
  104. matTilingRect = new DRect(0, 0, 1, 1);
  105. }
  106. */
  107. /// <summary>
  108. /// The ts variable serves no functional purpose. I would like this method to ONLY be called from
  109. /// MB_TexSet but there is no way in C# to enforce that. If you want to use this
  110. /// outside of MB_TexSet then add a method to MB_TexSet that does the add on your
  111. /// behalf. The new method should assert that MB_TexSet is in the correct state and should
  112. /// do any necessary stated changes to MB_TexSet depending on the context.
  113. ///
  114. /// After you are done you should "FindAllReferences" for this function to ensure that it is only
  115. /// called by MB_TexSet.
  116. /// </summary>
  117. /// <param name="ts">
  118. /// Not used, provided as an indicator to developers that all
  119. /// access to this must go through MB_TexSet.
  120. /// </param>
  121. public void SetEncapsulatingSamplingRect(MB_TexSet ts, DRect r)
  122. {
  123. encapsulatingSamplingRect = r;
  124. }
  125. // This should never be called until we are readyToBuildAtlases. The reason is that the textures
  126. // may not exist, temporary textures may need to be created.
  127. public Texture2D GetTexture2D()
  128. {
  129. if (!readyToBuildAtlases)
  130. {
  131. Debug.LogError("This function should not be called before Step3. For steps 1 and 2 should always call methods like isNull, width, height");
  132. throw new Exception("GetTexture2D called before ready to build atlases");
  133. }
  134. return _t;
  135. }
  136. public bool isNull
  137. {
  138. get { return _t == null/* && _procT == null*/; }
  139. }
  140. public int width
  141. {
  142. get
  143. {
  144. if (_t != null) return _t.width;
  145. //else if (_procT != null) return _procT.width;
  146. throw new Exception("Texture was null. can't get width");
  147. }
  148. }
  149. public int height
  150. {
  151. get
  152. {
  153. if (_t != null) return _t.height;
  154. //else if (_procT != null) return _procT.height;
  155. throw new Exception("Texture was null. can't get height");
  156. }
  157. }
  158. public string GetTexName()
  159. {
  160. if (_t != null) return _t.name;
  161. //else if (_procT != null) return _procT.name;
  162. return "null";
  163. }
  164. public bool AreTexturesEqual(MeshBakerMaterialTexture b)
  165. {
  166. if (_t == b._t /*&& _procT == b._procT*/) return true;
  167. return false;
  168. }
  169. /*
  170. public bool IsProceduralTexture()
  171. {
  172. return (_procT != null);
  173. }
  174. public ProceduralTexture GetProceduralTexture()
  175. {
  176. return _procT;
  177. }
  178. public Texture2D ConvertProceduralToTexture2D(List<Texture2D> temporaryTextures)
  179. {
  180. int w = _procT.width;
  181. int h = _procT.height;
  182. bool mips = true;
  183. bool isLinear = false;
  184. GC.Collect(3, GCCollectionMode.Forced);
  185. Texture2D tex = new Texture2D(w, h, TextureFormat.ARGB32, mips, isLinear);
  186. Color32[] pixels = _procT.GetPixels32(0, 0, w, h);
  187. tex.SetPixels32(0, 0, w, h, pixels);
  188. tex.Apply();
  189. tex.name = _procT.name;
  190. temporaryTextures.Add(tex);
  191. return tex;
  192. }
  193. */
  194. }
  195. public class MatAndTransformToMerged
  196. {
  197. public Material mat;
  198. /// <summary>
  199. /// If considerUVs = true is set to the UV rect of the source mesh
  200. /// otherwise if considerUVs = false is set to 0,0,1,1
  201. /// </summary>
  202. public DRect obUVRectIfTilingSame { get; private set; }
  203. public DRect samplingRectMatAndUVTiling { get; private set; }
  204. /// <summary>
  205. /// IMPORTANT: There are two materialTilingRects. These ones are stored per source material.
  206. /// For mapping materials to atlas rects and transforming UVs, NOT for baking atlases.
  207. /// Is set to materialTiling if allTexturesUseSameMatTiling otherwise
  208. /// is set to 0,0,1,1
  209. /// </summary>
  210. public DRect materialTiling { get; private set; }
  211. public string objName;
  212. public MatAndTransformToMerged(DRect obUVrect, bool fixOutOfBoundsUVs)
  213. {
  214. _init(obUVrect, fixOutOfBoundsUVs, null);
  215. }
  216. public MatAndTransformToMerged(DRect obUVrect, bool fixOutOfBoundsUVs, Material m)
  217. {
  218. _init(obUVrect, fixOutOfBoundsUVs, m);
  219. }
  220. private void _init(DRect obUVrect, bool fixOutOfBoundsUVs, Material m)
  221. {
  222. if (fixOutOfBoundsUVs)
  223. {
  224. obUVRectIfTilingSame = obUVrect;
  225. }
  226. else
  227. {
  228. obUVRectIfTilingSame = new DRect(0, 0, 1, 1);
  229. }
  230. mat = m;
  231. }
  232. public override bool Equals(object obj)
  233. {
  234. if (obj is MatAndTransformToMerged)
  235. {
  236. MatAndTransformToMerged o = (MatAndTransformToMerged)obj;
  237. if (o.mat == mat && o.obUVRectIfTilingSame == obUVRectIfTilingSame)
  238. {
  239. return true;
  240. }
  241. }
  242. return false;
  243. }
  244. public override int GetHashCode()
  245. {
  246. return mat.GetHashCode() ^ obUVRectIfTilingSame.GetHashCode() ^ samplingRectMatAndUVTiling.GetHashCode();
  247. }
  248. public string GetMaterialName()
  249. {
  250. if (mat != null)
  251. {
  252. return mat.name;
  253. }
  254. else if (objName != null)
  255. {
  256. return string.Format("[matFor: {0}]", objName);
  257. }
  258. else
  259. {
  260. return "Unknown";
  261. }
  262. }
  263. public void AssignInitialValuesForMaterialTilingAndSamplingRectMatAndUVTiling(bool allTexturesUseSameMatTiling, DRect matTiling)
  264. {
  265. if (allTexturesUseSameMatTiling)
  266. {
  267. materialTiling = matTiling;
  268. }
  269. else
  270. {
  271. materialTiling = new DRect(0f, 0f, 1f, 1f);
  272. }
  273. DRect tmpMatTiling = materialTiling;
  274. DRect obUVrect = obUVRectIfTilingSame;
  275. samplingRectMatAndUVTiling = MB3_UVTransformUtility.CombineTransforms(ref obUVrect, ref tmpMatTiling);
  276. }
  277. }
  278. public class MatsAndGOs
  279. {
  280. public List<MatAndTransformToMerged> mats;
  281. public List<GameObject> gos;
  282. }
  283. /// <summary>
  284. /// A set of textures one for each "maintex","bump" that one or more materials use. These
  285. /// Will be baked into a rectangle in the atlas.
  286. /// </summary>
  287. public class MB_TexSet
  288. {
  289. /// <summary>
  290. /// There is different handing of how things are baked into atlases depending on:
  291. /// do all TexturesUseSameMaterialTiling
  292. /// are the textures edge to edge.
  293. /// We try to capture those differences a clearly defined way.
  294. /// </summary>
  295. private interface PipelineVariation{
  296. void GetRectsForTextureBakeResults(out Rect allPropsUseSameTiling_encapsulatingSamplingRect,
  297. out Rect propsUseDifferntTiling_obUVRect);
  298. void SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(MB_TextureTilingTreatment newTilingTreatment);
  299. Rect GetMaterialTilingRectForTextureBakerResults(int materialIndex);
  300. void AdjustResultMaterialNonTextureProperties(Material resultMaterial, List<ShaderTextureProperty> props);
  301. }
  302. private class PipelineVariationAllTexturesUseSameMatTiling : PipelineVariation
  303. {
  304. private MB_TexSet texSet;
  305. public PipelineVariationAllTexturesUseSameMatTiling(MB_TexSet ts)
  306. {
  307. texSet = ts;
  308. Debug.Assert(texSet.allTexturesUseSameMatTiling == true);
  309. }
  310. public void GetRectsForTextureBakeResults(out Rect allPropsUseSameTiling_encapsulatingSamplingRect,
  311. out Rect propsUseDifferntTiling_obUVRect)
  312. {
  313. Debug.Assert(texSet.allTexturesUseSameMatTiling == true);
  314. propsUseDifferntTiling_obUVRect = new Rect(0, 0, 0, 0);
  315. allPropsUseSameTiling_encapsulatingSamplingRect = texSet.GetEncapsulatingSamplingRectIfTilingSame();
  316. //adjust for tilingTreatment
  317. if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeX)
  318. {
  319. allPropsUseSameTiling_encapsulatingSamplingRect.x = 0;
  320. allPropsUseSameTiling_encapsulatingSamplingRect.width = 1;
  321. }
  322. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeY)
  323. {
  324. allPropsUseSameTiling_encapsulatingSamplingRect.y = 0;
  325. allPropsUseSameTiling_encapsulatingSamplingRect.height = 1;
  326. }
  327. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeXY)
  328. {
  329. allPropsUseSameTiling_encapsulatingSamplingRect = new Rect(0, 0, 1, 1);
  330. }
  331. }
  332. public void SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(MB_TextureTilingTreatment newTilingTreatment)
  333. {
  334. Debug.Assert(texSet.allTexturesUseSameMatTiling == true);
  335. if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeX)
  336. {
  337. foreach (MeshBakerMaterialTexture t in texSet.ts)
  338. {
  339. DRect r = t.GetEncapsulatingSamplingRect();
  340. r.width = 1;
  341. t.SetEncapsulatingSamplingRect(texSet, r);
  342. }
  343. }
  344. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeY)
  345. {
  346. foreach (MeshBakerMaterialTexture t in texSet.ts)
  347. {
  348. DRect r = t.GetEncapsulatingSamplingRect();
  349. r.height = 1;
  350. t.SetEncapsulatingSamplingRect(texSet, r);
  351. }
  352. }
  353. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeXY)
  354. {
  355. foreach (MeshBakerMaterialTexture t in texSet.ts)
  356. {
  357. DRect r = t.GetEncapsulatingSamplingRect();
  358. r.height = 1;
  359. r.width = 1;
  360. t.SetEncapsulatingSamplingRect(texSet, r);
  361. }
  362. }
  363. }
  364. public Rect GetMaterialTilingRectForTextureBakerResults(int materialIndex)
  365. {
  366. Debug.Assert(texSet.allTexturesUseSameMatTiling == true);
  367. return texSet.matsAndGOs.mats[materialIndex].materialTiling.GetRect();
  368. }
  369. public void AdjustResultMaterialNonTextureProperties(Material resultMaterial, List<ShaderTextureProperty> props)
  370. {
  371. Debug.Assert(texSet.allTexturesUseSameMatTiling == true);
  372. }
  373. }
  374. private class PipelineVariationSomeTexturesUseDifferentMatTiling : PipelineVariation
  375. {
  376. private MB_TexSet texSet;
  377. public PipelineVariationSomeTexturesUseDifferentMatTiling(MB_TexSet ts)
  378. {
  379. texSet = ts;
  380. Debug.Assert(texSet.allTexturesUseSameMatTiling == false);
  381. }
  382. public void GetRectsForTextureBakeResults(out Rect allPropsUseSameTiling_encapsulatingSamplingRect,
  383. out Rect propsUseDifferntTiling_obUVRect)
  384. {
  385. Debug.Assert(texSet.allTexturesUseSameMatTiling == false);
  386. allPropsUseSameTiling_encapsulatingSamplingRect = new Rect(0,0,0,0);
  387. propsUseDifferntTiling_obUVRect = texSet.obUVrect.GetRect();
  388. //adjust for tilingTreatment
  389. if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeX)
  390. {
  391. propsUseDifferntTiling_obUVRect.x = 0;
  392. propsUseDifferntTiling_obUVRect.width = 1;
  393. }
  394. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeY)
  395. {
  396. propsUseDifferntTiling_obUVRect.y = 0;
  397. propsUseDifferntTiling_obUVRect.height = 1;
  398. }
  399. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeXY)
  400. {
  401. propsUseDifferntTiling_obUVRect = new Rect(0, 0, 1, 1);
  402. }
  403. }
  404. public void SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(MB_TextureTilingTreatment newTilingTreatment)
  405. {
  406. Debug.Assert(texSet.allTexturesUseSameMatTiling == false);
  407. if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeX)
  408. {
  409. foreach (MeshBakerMaterialTexture t in texSet.ts)
  410. {
  411. DRect r = t.GetEncapsulatingSamplingRect();
  412. r.width = 1;
  413. t.SetEncapsulatingSamplingRect(texSet, r);
  414. }
  415. }
  416. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeY)
  417. {
  418. foreach (MeshBakerMaterialTexture t in texSet.ts)
  419. {
  420. DRect r = t.GetEncapsulatingSamplingRect();
  421. r.height = 1;
  422. t.SetEncapsulatingSamplingRect(texSet, r);
  423. }
  424. }
  425. else if (texSet.tilingTreatment == MB_TextureTilingTreatment.edgeToEdgeXY)
  426. {
  427. foreach (MeshBakerMaterialTexture t in texSet.ts)
  428. {
  429. DRect r = t.GetEncapsulatingSamplingRect();
  430. r.height = 1;
  431. r.width = 1;
  432. t.SetEncapsulatingSamplingRect(texSet, r);
  433. }
  434. }
  435. }
  436. public Rect GetMaterialTilingRectForTextureBakerResults(int materialIndex)
  437. {
  438. Debug.Assert(texSet.allTexturesUseSameMatTiling == false);
  439. return new Rect(0,0,0,0);
  440. }
  441. public void AdjustResultMaterialNonTextureProperties(Material resultMaterial, List<ShaderTextureProperty> props)
  442. {
  443. Debug.Assert(texSet.allTexturesUseSameMatTiling == false);
  444. if (texSet.thisIsOnlyTexSetInAtlas)
  445. {
  446. for (int i = 0; i < props.Count; i++)
  447. {
  448. if (resultMaterial.HasProperty(props[i].name))
  449. {
  450. resultMaterial.SetTextureOffset(props[i].name, texSet.ts[i].matTilingRect.min);
  451. resultMaterial.SetTextureScale(props[i].name, texSet.ts[i].matTilingRect.size);
  452. }
  453. }
  454. }
  455. }
  456. }
  457. /// <summary>
  458. /// One per "maintex", "bump".
  459. /// Stores encapsulatingSamplingRect (can be different for maintex, bump...)
  460. /// Stores materialTiling for mapping materials to atlas rects and transforming UVs not for baking atlases
  461. ///
  462. /// </summary>
  463. public MeshBakerMaterialTexture[] ts;
  464. public MatsAndGOs matsAndGOs;
  465. public bool allTexturesUseSameMatTiling { get; private set; }
  466. public bool thisIsOnlyTexSetInAtlas { get; private set; }
  467. public MB_TextureTilingTreatment tilingTreatment { get; private set; }
  468. public Vector2 obUVoffset { get; private set; }
  469. public Vector2 obUVscale { get; private set; }
  470. public int idealWidth; //all textures will be resized to this size
  471. public int idealHeight;
  472. private PipelineVariation pipelineVariation;
  473. internal DRect obUVrect
  474. {
  475. get { return new DRect(obUVoffset, obUVscale); }
  476. }
  477. public MB_TexSet(MeshBakerMaterialTexture[] tss, Vector2 uvOffset, Vector2 uvScale, MB_TextureTilingTreatment treatment)
  478. {
  479. ts = tss;
  480. tilingTreatment = treatment;
  481. obUVoffset = uvOffset;
  482. obUVscale = uvScale;
  483. allTexturesUseSameMatTiling = false;
  484. thisIsOnlyTexSetInAtlas = false;
  485. matsAndGOs = new MatsAndGOs();
  486. matsAndGOs.mats = new List<MatAndTransformToMerged>();
  487. matsAndGOs.gos = new List<GameObject>();
  488. pipelineVariation = new PipelineVariationSomeTexturesUseDifferentMatTiling(this);
  489. }
  490. // The two texture sets are equal if they are using the same
  491. // textures/color properties for each map and have the same
  492. // tiling for each of those color properties
  493. internal bool IsEqual(object obj, bool fixOutOfBoundsUVs, MB3_TextureCombinerNonTextureProperties resultMaterialTextureBlender)
  494. {
  495. if (!(obj is MB_TexSet))
  496. {
  497. return false;
  498. }
  499. MB_TexSet other = (MB_TexSet)obj;
  500. if (other.ts.Length != ts.Length)
  501. {
  502. return false;
  503. }
  504. else
  505. {
  506. for (int i = 0; i < ts.Length; i++)
  507. {
  508. if (ts[i].matTilingRect != other.ts[i].matTilingRect)
  509. return false;
  510. if (!ts[i].AreTexturesEqual(other.ts[i]))
  511. return false;
  512. if (!resultMaterialTextureBlender.NonTexturePropertiesAreEqual(matsAndGOs.mats[0].mat, other.matsAndGOs.mats[0].mat))
  513. {
  514. return false;
  515. }
  516. }
  517. //IMPORTANT don't use Vector2 != Vector2 because it is only acurate to about 5 decimal places
  518. //this can lead to tiled rectangles that can't accept rectangles.
  519. if (fixOutOfBoundsUVs && (obUVoffset.x != other.obUVoffset.x ||
  520. obUVoffset.y != other.obUVoffset.y))
  521. return false;
  522. if (fixOutOfBoundsUVs && (obUVscale.x != other.obUVscale.x ||
  523. obUVscale.y != other.obUVscale.y))
  524. return false;
  525. return true;
  526. }
  527. }
  528. public Vector2 GetMaxRawTextureHeightWidth()
  529. {
  530. Vector2 max = new Vector2(0, 0);
  531. for (int propIdx = 0; propIdx < ts.Length; propIdx++)
  532. {
  533. MeshBakerMaterialTexture tx = ts[propIdx];
  534. if (!tx.isNull)
  535. {
  536. max.x = Mathf.Max(max.x, tx.width);
  537. max.y = Mathf.Max(max.y, tx.height);
  538. }
  539. }
  540. return max;
  541. }
  542. private Rect GetEncapsulatingSamplingRectIfTilingSame()
  543. {
  544. Debug.Assert(allTexturesUseSameMatTiling, "This should never be called if different properties use different tiling. ");
  545. if (ts.Length > 0)
  546. {
  547. return ts[0].GetEncapsulatingSamplingRect().GetRect();
  548. }
  549. return new Rect(0, 0, 1, 1);
  550. }
  551. public void SetEncapsulatingSamplingRectWhenMergingTexSets(DRect newEncapsulatingSamplingRect)
  552. {
  553. Debug.Assert(allTexturesUseSameMatTiling, "This should never be called if different properties use different tiling. ");
  554. for (int propIdx = 0; propIdx < ts.Length; propIdx++)
  555. {
  556. ts[propIdx].SetEncapsulatingSamplingRect(this, newEncapsulatingSamplingRect);
  557. }
  558. }
  559. public void SetEncapsulatingSamplingRectForTesting(int propIdx, DRect newEncapsulatingSamplingRect)
  560. {
  561. ts[propIdx].SetEncapsulatingSamplingRect(this, newEncapsulatingSamplingRect);
  562. }
  563. public void SetEncapsulatingRect(int propIdx, bool considerMeshUVs)
  564. {
  565. if (considerMeshUVs)
  566. {
  567. ts[propIdx].SetEncapsulatingSamplingRect(this, obUVrect);
  568. }
  569. else
  570. {
  571. ts[propIdx].SetEncapsulatingSamplingRect(this, new DRect(0, 0, 1, 1));
  572. }
  573. }
  574. public void CreateColoredTexToReplaceNull(string propName, int propIdx, bool considerMeshUVs, MB3_TextureCombiner combiner, Color col)
  575. {
  576. MeshBakerMaterialTexture matTex = ts[propIdx];
  577. matTex.t = combiner._createTemporaryTexture(propName, 16, 16, TextureFormat.ARGB32, true);
  578. MB_Utility.setSolidColor(matTex.GetTexture2D(), col);
  579. }
  580. public void SetThisIsOnlyTexSetInAtlasTrue()
  581. {
  582. Debug.Assert(thisIsOnlyTexSetInAtlas == false);
  583. thisIsOnlyTexSetInAtlas = true;
  584. }
  585. public void SetAllTexturesUseSameMatTilingTrue()
  586. {
  587. Debug.Assert(allTexturesUseSameMatTiling == false);
  588. allTexturesUseSameMatTiling = true;
  589. pipelineVariation = new PipelineVariationAllTexturesUseSameMatTiling(this);
  590. }
  591. public void AdjustResultMaterialNonTextureProperties(Material resultMaterial, List<ShaderTextureProperty> props)
  592. {
  593. pipelineVariation.AdjustResultMaterialNonTextureProperties(resultMaterial, props);
  594. }
  595. public void SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(MB_TextureTilingTreatment newTilingTreatment)
  596. {
  597. tilingTreatment = newTilingTreatment;
  598. pipelineVariation.SetTilingTreatmentAndAdjustEncapsulatingSamplingRect(newTilingTreatment);
  599. }
  600. internal void GetRectsForTextureBakeResults(out Rect allPropsUseSameTiling_encapsulatingSamplingRect,
  601. out Rect propsUseDifferntTiling_obUVRect)
  602. {
  603. pipelineVariation.GetRectsForTextureBakeResults(out allPropsUseSameTiling_encapsulatingSamplingRect, out propsUseDifferntTiling_obUVRect);
  604. }
  605. /// <summary>
  606. ///
  607. /// </summary>
  608. /// <param name="materialIndex">Should be an index in matsAndGOs.mats List</param>
  609. /// <returns></returns>
  610. internal Rect GetMaterialTilingRectForTextureBakerResults(int materialIndex)
  611. {
  612. return pipelineVariation.GetMaterialTilingRectForTextureBakerResults(materialIndex);
  613. }
  614. //assumes all materials use the same obUVrects.
  615. internal void CalcInitialFullSamplingRects(bool fixOutOfBoundsUVs)
  616. {
  617. DRect validFullSamplingRect = new Core.DRect(0, 0, 1, 1);
  618. if (fixOutOfBoundsUVs)
  619. {
  620. validFullSamplingRect = obUVrect;
  621. }
  622. for (int propIdx = 0; propIdx < ts.Length; propIdx++)
  623. {
  624. if (!ts[propIdx].isNull)
  625. {
  626. DRect matTiling = ts[propIdx].matTilingRect;
  627. DRect ruv;
  628. if (fixOutOfBoundsUVs)
  629. {
  630. ruv = obUVrect;
  631. }
  632. else
  633. {
  634. ruv = new DRect(0.0, 0.0, 1.0, 1.0);
  635. }
  636. ts[propIdx].SetEncapsulatingSamplingRect(this, MB3_UVTransformUtility.CombineTransforms(ref ruv, ref matTiling));
  637. validFullSamplingRect = ts[propIdx].GetEncapsulatingSamplingRect();
  638. }
  639. }
  640. //if some of the textures were null make them match the sampling of one of the other textures
  641. for (int propIdx = 0; propIdx < ts.Length; propIdx++)
  642. {
  643. if (ts[propIdx].isNull)
  644. {
  645. ts[propIdx].SetEncapsulatingSamplingRect(this, validFullSamplingRect);
  646. }
  647. }
  648. }
  649. internal void CalcMatAndUVSamplingRects()
  650. {
  651. DRect matTiling = new DRect(0f, 0f, 1f, 1f);
  652. if (allTexturesUseSameMatTiling)
  653. {
  654. for (int propIdx = 0; propIdx < ts.Length; propIdx++)
  655. {
  656. if (!ts[propIdx].isNull)
  657. {
  658. matTiling = ts[propIdx].matTilingRect;
  659. break;
  660. }
  661. }
  662. }
  663. for (int matIdx = 0; matIdx < matsAndGOs.mats.Count; matIdx++)
  664. {
  665. matsAndGOs.mats[matIdx].AssignInitialValuesForMaterialTilingAndSamplingRectMatAndUVTiling(allTexturesUseSameMatTiling, matTiling);
  666. }
  667. }
  668. public bool AllTexturesAreSameForMerge(MB_TexSet other, bool considerNonTextureProperties, MB3_TextureCombinerNonTextureProperties resultMaterialTextureBlender)
  669. {
  670. if (other.ts.Length != ts.Length)
  671. {
  672. return false;
  673. }
  674. else
  675. {
  676. if (!other.allTexturesUseSameMatTiling || !allTexturesUseSameMatTiling)
  677. {
  678. return false;
  679. }
  680. // must use same set of textures
  681. int idxOfFirstNoneNull = -1;
  682. for (int i = 0; i < ts.Length; i++)
  683. {
  684. if (!ts[i].AreTexturesEqual(other.ts[i]))
  685. return false;
  686. if (idxOfFirstNoneNull == -1 && !ts[i].isNull)
  687. {
  688. idxOfFirstNoneNull = i;
  689. }
  690. if (considerNonTextureProperties)
  691. {
  692. if (!resultMaterialTextureBlender.NonTexturePropertiesAreEqual(matsAndGOs.mats[0].mat, other.matsAndGOs.mats[0].mat))
  693. {
  694. return false;
  695. }
  696. }
  697. }
  698. if (idxOfFirstNoneNull != -1)
  699. {
  700. //check that all textures are the same. Have already checked all tiling is same
  701. for (int i = 0; i < ts.Length; i++)
  702. {
  703. if (!ts[i].AreTexturesEqual(other.ts[i]))
  704. {
  705. return false;
  706. }
  707. }
  708. }
  709. return true;
  710. }
  711. }
  712. public void DrawRectsToMergeGizmos(Color encC, Color innerC)
  713. {
  714. DRect r = ts[0].GetEncapsulatingSamplingRect();
  715. r.Expand(.05f);
  716. Gizmos.color = encC;
  717. Gizmos.DrawWireCube(r.center.GetVector2(), r.size);
  718. for (int i = 0; i < matsAndGOs.mats.Count; i++)
  719. {
  720. DRect rr = matsAndGOs.mats[i].samplingRectMatAndUVTiling;
  721. DRect trans = MB3_UVTransformUtility.GetShiftTransformToFitBinA(ref r, ref rr);
  722. Vector2 xy = MB3_UVTransformUtility.TransformPoint(ref trans, rr.min);
  723. rr.x = xy.x;
  724. rr.y = xy.y;
  725. //Debug.Log("r " + r + " rr" + rr);
  726. Gizmos.color = innerC;
  727. Gizmos.DrawWireCube(rr.center.GetVector2(), rr.size);
  728. }
  729. }
  730. internal string GetDescription()
  731. {
  732. StringBuilder sb = new StringBuilder();
  733. sb.AppendFormat("[GAME_OBJS=");
  734. for (int i = 0; i < matsAndGOs.gos.Count; i++)
  735. {
  736. sb.AppendFormat("{0},", matsAndGOs.gos[i].name);
  737. }
  738. sb.AppendFormat("MATS=");
  739. for (int i = 0; i < matsAndGOs.mats.Count; i++)
  740. {
  741. sb.AppendFormat("{0},", matsAndGOs.mats[i].GetMaterialName());
  742. }
  743. sb.Append("]");
  744. return sb.ToString();
  745. }
  746. internal string GetMatSubrectDescriptions()
  747. {
  748. StringBuilder sb = new StringBuilder();
  749. for (int i = 0; i < matsAndGOs.mats.Count; i++)
  750. {
  751. sb.AppendFormat("\n {0}={1},", matsAndGOs.mats[i].GetMaterialName(), matsAndGOs.mats[i].samplingRectMatAndUVTiling);
  752. }
  753. return sb.ToString();
  754. }
  755. }
  756. /*
  757. class ProceduralMaterialInfo
  758. {
  759. //public ProceduralMaterial proceduralMat;
  760. public bool originalIsReadableVal;
  761. }
  762. */
  763. }