Meshmerizer.cs 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using OpenSim.Framework;
  30. using OpenSim.Region.Physics.Manager;
  31. using libsecondlife;
  32. namespace OpenSim.Region.Physics.Meshing
  33. {
  34. public class MeshmerizerPlugin : IMeshingPlugin
  35. {
  36. public MeshmerizerPlugin()
  37. {
  38. }
  39. public string GetName()
  40. {
  41. return "Meshmerizer";
  42. }
  43. public IMesher GetMesher()
  44. {
  45. return new Meshmerizer();
  46. }
  47. }
  48. public class Meshmerizer : IMesher
  49. {
  50. //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  51. // Setting baseDir to a path will enable the dumping of raw files
  52. // raw files can be imported by blender so a visual inspection of the results can be done
  53. // const string baseDir = "rawFiles";
  54. private const string baseDir = null; //"rawFiles";
  55. private const float DEG_TO_RAD = 0.01745329238f;
  56. // TODO: unused
  57. // private static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2,
  58. // PhysicsVector r2, ref float lambda, ref float mu)
  59. // {
  60. // // p1, p2, points on the straight
  61. // // r1, r2, directional vectors of the straight. Not necessarily of length 1!
  62. // // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
  63. // // thus allowing to decide whether an intersection is between two points
  64. // float r1x = r1.X;
  65. // float r1y = r1.Y;
  66. // float r2x = r2.X;
  67. // float r2y = r2.Y;
  68. // float denom = r1y*r2x - r1x*r2y;
  69. // if (denom == 0.0)
  70. // {
  71. // lambda = Single.NaN;
  72. // mu = Single.NaN;
  73. // return;
  74. // }
  75. // float p1x = p1.X;
  76. // float p1y = p1.Y;
  77. // float p2x = p2.X;
  78. // float p2y = p2.Y;
  79. // lambda = (-p2x*r2y + p1x*r2y + (p2y - p1y)*r2x)/denom;
  80. // mu = (-p2x*r1y + p1x*r1y + (p2y - p1y)*r1x)/denom;
  81. // }
  82. private static List<Triangle> FindInfluencedTriangles(List<Triangle> triangles, Vertex v)
  83. {
  84. List<Triangle> influenced = new List<Triangle>();
  85. foreach (Triangle t in triangles)
  86. {
  87. if (t.isInCircle(v.X, v.Y))
  88. {
  89. influenced.Add(t);
  90. }
  91. }
  92. return influenced;
  93. }
  94. private static void InsertVertices(List<Vertex> vertices, int usedForSeed, List<Triangle> triangles)
  95. {
  96. // This is a variant of the delaunay algorithm
  97. // each time a new vertex is inserted, all triangles that are influenced by it are deleted
  98. // and replaced by new ones including the new vertex
  99. // It is not very time efficient but easy to implement.
  100. int iCurrentVertex;
  101. int iMaxVertex = vertices.Count;
  102. for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
  103. {
  104. // Background: A triangle mesh fulfills the delaunay condition if (iff!)
  105. // each circumlocutory circle (i.e. the circle that touches all three corners)
  106. // of each triangle is empty of other vertices.
  107. // Obviously a single (seeding) triangle fulfills this condition.
  108. // If we now add one vertex, we need to reconstruct all triangles, that
  109. // do not fulfill this condition with respect to the new triangle
  110. // Find the triangles that are influenced by the new vertex
  111. Vertex v = vertices[iCurrentVertex];
  112. if (v == null)
  113. continue; // Null is polygon stop marker. Ignore it
  114. List<Triangle> influencedTriangles = FindInfluencedTriangles(triangles, v);
  115. List<Simplex> simplices = new List<Simplex>();
  116. // Reconstruction phase. First step, dissolve each triangle into it's simplices,
  117. // i.e. it's "border lines"
  118. // Goal is to find "inner" borders and delete them, while the hull gets conserved.
  119. // Inner borders are special in the way that they always come twice, which is how we detect them
  120. foreach (Triangle t in influencedTriangles)
  121. {
  122. List<Simplex> newSimplices = t.GetSimplices();
  123. simplices.AddRange(newSimplices);
  124. triangles.Remove(t);
  125. }
  126. // Now sort the simplices. That will make identical ones reside side by side in the list
  127. simplices.Sort();
  128. // Look for duplicate simplices here.
  129. // Remember, they are directly side by side in the list right now,
  130. // So we only check directly neighbours
  131. int iSimplex;
  132. List<Simplex> innerSimplices = new List<Simplex>();
  133. for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
  134. {
  135. if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
  136. {
  137. innerSimplices.Add(simplices[iSimplex - 1]);
  138. innerSimplices.Add(simplices[iSimplex]);
  139. }
  140. }
  141. foreach (Simplex s in innerSimplices)
  142. {
  143. simplices.Remove(s);
  144. }
  145. // each simplex still in the list belongs to the hull of the region in question
  146. // The new vertex (yes, we still deal with verices here :-)) forms a triangle
  147. // with each of these simplices. Build the new triangles and add them to the list
  148. foreach (Simplex s in simplices)
  149. {
  150. Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
  151. if (!t.isDegraded())
  152. {
  153. triangles.Add(t);
  154. }
  155. }
  156. }
  157. }
  158. private static SimpleHull BuildHoleHull(PrimitiveBaseShape pbs, ProfileShape pshape, HollowShape hshape, UInt16 hollowFactor)
  159. {
  160. // Tackle HollowShape.Same
  161. float fhollowFactor = (float)hollowFactor;
  162. switch (pshape)
  163. {
  164. case ProfileShape.Square:
  165. if (hshape == HollowShape.Same)
  166. hshape= HollowShape.Square;
  167. break;
  168. case ProfileShape.EquilateralTriangle:
  169. fhollowFactor = ((float)hollowFactor / 1.9f);
  170. if (hshape == HollowShape.Same)
  171. {
  172. hshape = HollowShape.Triangle;
  173. }
  174. break;
  175. case ProfileShape.HalfCircle:
  176. case ProfileShape.Circle:
  177. if (pbs.PathCurve == (byte)Extrusion.Straight)
  178. {
  179. if (hshape == HollowShape.Same)
  180. {
  181. hshape = HollowShape.Circle;
  182. }
  183. }
  184. break;
  185. default:
  186. if (hshape == HollowShape.Same)
  187. hshape= HollowShape.Square;
  188. break;
  189. }
  190. SimpleHull holeHull = null;
  191. if (hshape == HollowShape.Square)
  192. {
  193. float hollowFactorF = (float)fhollowFactor / (float)50000;
  194. Vertex IMM;
  195. Vertex IPM;
  196. Vertex IPP;
  197. Vertex IMP;
  198. if (pshape == ProfileShape.Circle)
  199. { // square cutout in cylinder is 45 degress rotated
  200. IMM = new Vertex(0.0f, -0.707f * hollowFactorF, 0.0f);
  201. IPM = new Vertex(0.707f * hollowFactorF, 0.0f, 0.0f);
  202. IPP = new Vertex(0.0f, 0.707f * hollowFactorF, 0.0f);
  203. IMP = new Vertex(-0.707f * hollowFactorF, 0.0f, 0.0f);
  204. }
  205. else if (pshape == ProfileShape.EquilateralTriangle)
  206. {
  207. IMM = new Vertex(0.0f, -0.667f * hollowFactorF, 0.0f);
  208. IPM = new Vertex(0.667f * hollowFactorF, 0.0f, 0.0f);
  209. IPP = new Vertex(0.0f, 0.667f * hollowFactorF, 0.0f);
  210. IMP = new Vertex(-0.667f * hollowFactorF, 0.0f, 0.0f);
  211. }
  212. else
  213. {
  214. IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
  215. IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
  216. IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
  217. IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
  218. }
  219. holeHull = new SimpleHull();
  220. holeHull.AddVertex(IMM);
  221. holeHull.AddVertex(IMP);
  222. holeHull.AddVertex(IPP);
  223. holeHull.AddVertex(IPM);
  224. }
  225. //if (hshape == HollowShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
  226. if (hshape == HollowShape.Circle)
  227. {
  228. float hollowFactorF = (float)fhollowFactor / (float)50000;
  229. //Vertex IQ1Q15 = new Vertex(-0.35f * hollowFactorF, -0.35f * hollowFactorF, 0.0f);
  230. //Vertex IQ1Q16 = new Vertex(-0.30f * hollowFactorF, -0.40f * hollowFactorF, 0.0f);
  231. //Vertex IQ1Q17 = new Vertex(-0.24f * hollowFactorF, -0.43f * hollowFactorF, 0.0f);
  232. //Vertex IQ1Q18 = new Vertex(-0.18f * hollowFactorF, -0.46f * hollowFactorF, 0.0f);
  233. //Vertex IQ1Q19 = new Vertex(-0.11f * hollowFactorF, -0.48f * hollowFactorF, 0.0f);
  234. //Vertex IQ2Q10 = new Vertex(+0.0f * hollowFactorF, -0.50f * hollowFactorF, 0.0f);
  235. //Vertex IQ2Q11 = new Vertex(+0.11f * hollowFactorF, -0.48f * hollowFactorF, 0.0f);
  236. //Vertex IQ2Q12 = new Vertex(+0.18f * hollowFactorF, -0.46f * hollowFactorF, 0.0f);
  237. //Vertex IQ2Q13 = new Vertex(+0.24f * hollowFactorF, -0.43f * hollowFactorF, 0.0f);
  238. //Vertex IQ2Q14 = new Vertex(+0.30f * hollowFactorF, -0.40f * hollowFactorF, 0.0f);
  239. //Vertex IQ2Q15 = new Vertex(+0.35f * hollowFactorF, -0.35f * hollowFactorF, 0.0f);
  240. //Vertex IQ2Q16 = new Vertex(+0.40f * hollowFactorF, -0.30f * hollowFactorF, 0.0f);
  241. //Vertex IQ2Q17 = new Vertex(+0.43f * hollowFactorF, -0.24f * hollowFactorF, 0.0f);
  242. //Vertex IQ2Q18 = new Vertex(+0.46f * hollowFactorF, -0.18f * hollowFactorF, 0.0f);
  243. //Vertex IQ2Q19 = new Vertex(+0.48f * hollowFactorF, -0.11f * hollowFactorF, 0.0f);
  244. //Vertex IQ2Q20 = new Vertex(+0.50f * hollowFactorF, +0.0f * hollowFactorF, 0.0f);
  245. //Vertex IQ2Q21 = new Vertex(+0.48f * hollowFactorF, +0.11f * hollowFactorF, 0.0f);
  246. //Vertex IQ2Q22 = new Vertex(+0.46f * hollowFactorF, +0.18f * hollowFactorF, 0.0f);
  247. //Vertex IQ2Q23 = new Vertex(+0.43f * hollowFactorF, +0.24f * hollowFactorF, 0.0f);
  248. //Vertex IQ2Q24 = new Vertex(+0.40f * hollowFactorF, +0.30f * hollowFactorF, 0.0f);
  249. //Vertex IQ2Q25 = new Vertex(+0.35f * hollowFactorF, +0.35f * hollowFactorF, 0.0f);
  250. //Vertex IQ2Q26 = new Vertex(+0.30f * hollowFactorF, +0.40f * hollowFactorF, 0.0f);
  251. //Vertex IQ2Q27 = new Vertex(+0.24f * hollowFactorF, +0.43f * hollowFactorF, 0.0f);
  252. //Vertex IQ2Q28 = new Vertex(+0.18f * hollowFactorF, +0.46f * hollowFactorF, 0.0f);
  253. //Vertex IQ2Q29 = new Vertex(+0.11f * hollowFactorF, +0.48f * hollowFactorF, 0.0f);
  254. //Vertex IQ1Q20 = new Vertex(+0.0f * hollowFactorF, +0.50f * hollowFactorF, 0.0f);
  255. //Vertex IQ1Q21 = new Vertex(-0.11f * hollowFactorF, +0.48f * hollowFactorF, 0.0f);
  256. //Vertex IQ1Q22 = new Vertex(-0.18f * hollowFactorF, +0.46f * hollowFactorF, 0.0f);
  257. //Vertex IQ1Q23 = new Vertex(-0.24f * hollowFactorF, +0.43f * hollowFactorF, 0.0f);
  258. //Vertex IQ1Q24 = new Vertex(-0.30f * hollowFactorF, +0.40f * hollowFactorF, 0.0f);
  259. //Vertex IQ1Q25 = new Vertex(-0.35f * hollowFactorF, +0.35f * hollowFactorF, 0.0f);
  260. //Vertex IQ1Q26 = new Vertex(-0.40f * hollowFactorF, +0.30f * hollowFactorF, 0.0f);
  261. //Vertex IQ1Q27 = new Vertex(-0.43f * hollowFactorF, +0.24f * hollowFactorF, 0.0f);
  262. //Vertex IQ1Q28 = new Vertex(-0.46f * hollowFactorF, +0.18f * hollowFactorF, 0.0f);
  263. //Vertex IQ1Q29 = new Vertex(-0.48f * hollowFactorF, +0.11f * hollowFactorF, 0.0f);
  264. //Vertex IQ1Q10 = new Vertex(-0.50f * hollowFactorF, +0.0f * hollowFactorF, 0.0f);
  265. //Vertex IQ1Q11 = new Vertex(-0.48f * hollowFactorF, -0.11f * hollowFactorF, 0.0f);
  266. //Vertex IQ1Q12 = new Vertex(-0.46f * hollowFactorF, -0.18f * hollowFactorF, 0.0f);
  267. //Vertex IQ1Q13 = new Vertex(-0.43f * hollowFactorF, -0.24f * hollowFactorF, 0.0f);
  268. //Vertex IQ1Q14 = new Vertex(-0.40f * hollowFactorF, -0.30f * hollowFactorF, 0.0f);
  269. //Counter clockwise around the quadrants
  270. holeHull = new SimpleHull();
  271. //holeHull.AddVertex(IQ1Q15);
  272. //holeHull.AddVertex(IQ1Q14);
  273. //holeHull.AddVertex(IQ1Q13);
  274. //holeHull.AddVertex(IQ1Q12);
  275. //holeHull.AddVertex(IQ1Q11);
  276. //holeHull.AddVertex(IQ1Q10);
  277. //holeHull.AddVertex(IQ1Q29);
  278. //holeHull.AddVertex(IQ1Q28);
  279. //holeHull.AddVertex(IQ1Q27);
  280. //holeHull.AddVertex(IQ1Q26);
  281. //holeHull.AddVertex(IQ1Q25);
  282. //holeHull.AddVertex(IQ1Q24);
  283. //holeHull.AddVertex(IQ1Q23);
  284. //holeHull.AddVertex(IQ1Q22);
  285. //holeHull.AddVertex(IQ1Q21);
  286. //holeHull.AddVertex(IQ1Q20);
  287. //holeHull.AddVertex(IQ2Q29);
  288. //holeHull.AddVertex(IQ2Q28);
  289. //holeHull.AddVertex(IQ2Q27);
  290. //holeHull.AddVertex(IQ2Q26);
  291. //holeHull.AddVertex(IQ2Q25);
  292. //holeHull.AddVertex(IQ2Q24);
  293. //holeHull.AddVertex(IQ2Q23);
  294. //holeHull.AddVertex(IQ2Q22);
  295. //holeHull.AddVertex(IQ2Q21);
  296. //holeHull.AddVertex(IQ2Q20);
  297. //holeHull.AddVertex(IQ2Q19);
  298. //holeHull.AddVertex(IQ2Q18);
  299. //holeHull.AddVertex(IQ2Q17);
  300. //holeHull.AddVertex(IQ2Q16);
  301. //holeHull.AddVertex(IQ2Q15);
  302. //holeHull.AddVertex(IQ2Q14);
  303. //holeHull.AddVertex(IQ2Q13);
  304. //holeHull.AddVertex(IQ2Q12);
  305. //holeHull.AddVertex(IQ2Q11);
  306. //holeHull.AddVertex(IQ2Q10);
  307. //holeHull.AddVertex(IQ1Q19);
  308. //holeHull.AddVertex(IQ1Q18);
  309. //holeHull.AddVertex(IQ1Q17);
  310. //holeHull.AddVertex(IQ1Q16);
  311. holeHull.AddVertex(new Vertex(0.353553f * hollowFactorF, 0.353553f * hollowFactorF, 0.0f)); // 45 degrees
  312. holeHull.AddVertex(new Vertex(0.433013f * hollowFactorF, 0.250000f * hollowFactorF, 0.0f)); // 30 degrees
  313. holeHull.AddVertex(new Vertex(0.482963f * hollowFactorF, 0.129410f * hollowFactorF, 0.0f)); // 15 degrees
  314. holeHull.AddVertex(new Vertex(0.500000f * hollowFactorF, 0.000000f * hollowFactorF, 0.0f)); // 0 degrees
  315. holeHull.AddVertex(new Vertex(0.482963f * hollowFactorF, -0.129410f * hollowFactorF, 0.0f)); // 345 degrees
  316. holeHull.AddVertex(new Vertex(0.433013f * hollowFactorF, -0.250000f * hollowFactorF, 0.0f)); // 330 degrees
  317. holeHull.AddVertex(new Vertex(0.353553f * hollowFactorF, -0.353553f * hollowFactorF, 0.0f)); // 315 degrees
  318. holeHull.AddVertex(new Vertex(0.250000f * hollowFactorF, -0.433013f * hollowFactorF, 0.0f)); // 300 degrees
  319. holeHull.AddVertex(new Vertex(0.129410f * hollowFactorF, -0.482963f * hollowFactorF, 0.0f)); // 285 degrees
  320. holeHull.AddVertex(new Vertex(0.000000f * hollowFactorF, -0.500000f * hollowFactorF, 0.0f)); // 270 degrees
  321. holeHull.AddVertex(new Vertex(-0.129410f * hollowFactorF, -0.482963f * hollowFactorF, 0.0f)); // 255 degrees
  322. holeHull.AddVertex(new Vertex(-0.250000f * hollowFactorF, -0.433013f * hollowFactorF, 0.0f)); // 240 degrees
  323. holeHull.AddVertex(new Vertex(-0.353553f * hollowFactorF, -0.353553f * hollowFactorF, 0.0f)); // 225 degrees
  324. holeHull.AddVertex(new Vertex(-0.433013f * hollowFactorF, -0.250000f * hollowFactorF, 0.0f)); // 210 degrees
  325. holeHull.AddVertex(new Vertex(-0.482963f * hollowFactorF, -0.129410f * hollowFactorF, 0.0f)); // 195 degrees
  326. holeHull.AddVertex(new Vertex(-0.500000f * hollowFactorF, 0.000000f * hollowFactorF, 0.0f)); // 180 degrees
  327. holeHull.AddVertex(new Vertex(-0.482963f * hollowFactorF, 0.129410f * hollowFactorF, 0.0f)); // 165 degrees
  328. holeHull.AddVertex(new Vertex(-0.433013f * hollowFactorF, 0.250000f * hollowFactorF, 0.0f)); // 150 degrees
  329. holeHull.AddVertex(new Vertex(-0.353553f * hollowFactorF, 0.353553f * hollowFactorF, 0.0f)); // 135 degrees
  330. holeHull.AddVertex(new Vertex(-0.250000f * hollowFactorF, 0.433013f * hollowFactorF, 0.0f)); // 120 degrees
  331. holeHull.AddVertex(new Vertex(-0.129410f * hollowFactorF, 0.482963f * hollowFactorF, 0.0f)); // 105 degrees
  332. holeHull.AddVertex(new Vertex(0.000000f * hollowFactorF, 0.500000f * hollowFactorF, 0.0f)); // 90 degrees
  333. holeHull.AddVertex(new Vertex(0.129410f * hollowFactorF, 0.482963f * hollowFactorF, 0.0f)); // 75 degrees
  334. holeHull.AddVertex(new Vertex(0.250000f * hollowFactorF, 0.433013f * hollowFactorF, 0.0f)); // 60 degrees
  335. holeHull.AddVertex(new Vertex(0.353553f * hollowFactorF, 0.353553f * hollowFactorF, 0.0f)); // 45 degrees
  336. }
  337. if (hshape == HollowShape.Triangle)
  338. {
  339. float hollowFactorF = (float)fhollowFactor / (float)50000;
  340. Vertex IMM;
  341. Vertex IPM;
  342. Vertex IPP;
  343. if (pshape == ProfileShape.Square)
  344. {
  345. // corner points are at 345, 105, and 225 degrees for the triangle within a box
  346. //IMM = new Vertex(((float)Math.Cos(345.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, ((float)Math.Sin(345.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, 0.0f);
  347. //IPM = new Vertex(((float)Math.Cos(105.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, ((float)Math.Sin(105.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, 0.0f);
  348. //IPP = new Vertex(((float)Math.Cos(225.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, ((float)Math.Sin(225.0 * DEG_TO_RAD) * 0.5f) * hollowFactorF, 0.0f);
  349. // hard coded here for speed, the equations are in the commented out lines above
  350. IMM = new Vertex(0.48296f * hollowFactorF, -0.12941f * hollowFactorF, 0.0f);
  351. IPM = new Vertex(-0.12941f * hollowFactorF, 0.48296f * hollowFactorF, 0.0f);
  352. IPP = new Vertex(-0.35355f * hollowFactorF, -0.35355f * hollowFactorF, 0.0f);
  353. }
  354. else
  355. {
  356. IMM = new Vertex(-0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f);
  357. IPM = new Vertex(+0.5f * hollowFactorF, +0f * hollowFactorF, 0.0f);
  358. IPP = new Vertex(-0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f);
  359. }
  360. holeHull = new SimpleHull();
  361. holeHull.AddVertex(IMM);
  362. holeHull.AddVertex(IPP);
  363. holeHull.AddVertex(IPM);
  364. }
  365. return holeHull;
  366. }
  367. private static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
  368. // Builds the z (+ and -) surfaces of a box shaped prim
  369. {
  370. UInt16 hollowFactor = primShape.ProfileHollow;
  371. UInt16 profileBegin = primShape.ProfileBegin;
  372. UInt16 profileEnd = primShape.ProfileEnd;
  373. UInt16 taperX = primShape.PathScaleX;
  374. UInt16 taperY = primShape.PathScaleY;
  375. UInt16 pathShearX = primShape.PathShearX;
  376. UInt16 pathShearY = primShape.PathShearY;
  377. Int16 twistTop = primShape.PathTwistBegin;
  378. Int16 twistBot = primShape.PathTwist;
  379. //m_log.Error("pathShear:" + primShape.PathShearX.ToString() + "," + primShape.PathShearY.ToString());
  380. //m_log.Error("pathTaper:" + primShape.PathTaperX.ToString() + "," + primShape.PathTaperY.ToString());
  381. //m_log.Error("ProfileBegin:" + primShape.ProfileBegin.ToString() + "," + primShape.ProfileBegin.ToString());
  382. //m_log.Error("PathScale:" + primShape.PathScaleX.ToString() + "," + primShape.PathScaleY.ToString());
  383. // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
  384. // of a block are basically the same
  385. // They may be warped differently but the shape is identical
  386. // So we only create one surface as a model and derive both plus and minus surface of the block from it
  387. // This is done in a model space where the block spans from -.5 to +.5 in X and Y
  388. // The mapping to Scene space is done later during the "extrusion" phase
  389. // Base
  390. Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
  391. Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
  392. Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
  393. Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
  394. SimpleHull outerHull = new SimpleHull();
  395. //outerHull.AddVertex(MM);
  396. //outerHull.AddVertex(PM);
  397. //outerHull.AddVertex(PP);
  398. //outerHull.AddVertex(MP);
  399. outerHull.AddVertex(PP);
  400. outerHull.AddVertex(MP);
  401. outerHull.AddVertex(MM);
  402. outerHull.AddVertex(PM);
  403. // Deal with cuts now
  404. if ((profileBegin != 0) || (profileEnd != 0))
  405. {
  406. double fProfileBeginAngle = profileBegin/50000.0*360.0;
  407. // In degree, for easier debugging and understanding
  408. fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
  409. double fProfileEndAngle = 360.0 - profileEnd/50000.0*360.0; // Pathend comes as complement to 1.0
  410. fProfileEndAngle -= (90.0 + 45.0);
  411. if (fProfileBeginAngle < fProfileEndAngle)
  412. fProfileEndAngle -= 360.0;
  413. // Note, that we don't want to cut out a triangle, even if this is a
  414. // good approximation for small cuts. Indeed we want to cut out an arc
  415. // and we approximate this arc by a polygon chain
  416. // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
  417. // So it can easily be subtracted from the outer hull
  418. int iSteps = (int) (((fProfileBeginAngle - fProfileEndAngle)/45.0) + .5);
  419. // how many steps do we need with approximately 45 degree
  420. double dStepWidth = (fProfileBeginAngle - fProfileEndAngle)/iSteps;
  421. Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
  422. // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
  423. SimpleHull cutHull = new SimpleHull();
  424. cutHull.AddVertex(origin);
  425. for (int i = 0; i < iSteps; i++)
  426. {
  427. double angle = fProfileBeginAngle - i*dStepWidth; // we count against the angle orientation!!!!
  428. Vertex v = Vertex.FromAngle(angle*Math.PI/180.0);
  429. cutHull.AddVertex(v);
  430. }
  431. Vertex legEnd = Vertex.FromAngle(fProfileEndAngle*Math.PI/180.0);
  432. // Calculated separately to avoid errors
  433. cutHull.AddVertex(legEnd);
  434. //m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
  435. SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
  436. outerHull = cuttedHull;
  437. }
  438. // Deal with the hole here
  439. if (hollowFactor > 0)
  440. {
  441. SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
  442. if (holeHull != null)
  443. {
  444. SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
  445. outerHull = hollowedHull;
  446. }
  447. }
  448. Mesh m = new Mesh();
  449. Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
  450. Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
  451. Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
  452. m.Add(Seed1);
  453. m.Add(Seed2);
  454. m.Add(Seed3);
  455. m.Add(new Triangle(Seed1, Seed2, Seed3));
  456. m.Add(outerHull.getVertices());
  457. InsertVertices(m.vertices, 3, m.triangles);
  458. m.DumpRaw(baseDir, primName, "Proto first Mesh");
  459. m.Remove(Seed1);
  460. m.Remove(Seed2);
  461. m.Remove(Seed3);
  462. m.DumpRaw(baseDir, primName, "Proto seeds removed");
  463. m.RemoveTrianglesOutside(outerHull);
  464. m.DumpRaw(baseDir, primName, "Proto outsides removed");
  465. foreach (Triangle t in m.triangles)
  466. {
  467. PhysicsVector n = t.getNormal();
  468. if (n.Z < 0.0)
  469. t.invertNormal();
  470. }
  471. Extruder extr = new Extruder();
  472. extr.size = size;
  473. if (taperX != 100)
  474. {
  475. if (taperX > 100)
  476. {
  477. extr.taperTopFactorX = 1.0f - ((float)taperX / 200);
  478. //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
  479. }
  480. else
  481. {
  482. extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
  483. //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
  484. }
  485. }
  486. if (taperY != 100)
  487. {
  488. if (taperY > 100)
  489. {
  490. extr.taperTopFactorY = 1.0f - ((float)taperY / 200);
  491. //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
  492. }
  493. else
  494. {
  495. extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
  496. //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
  497. }
  498. }
  499. if (pathShearX != 0)
  500. {
  501. if (pathShearX > 50)
  502. {
  503. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  504. extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
  505. // m_log.Warn("pushX: " + extr.pushX);
  506. }
  507. else
  508. {
  509. extr.pushX = (float)pathShearX / 100;
  510. // m_log.Warn("pushX: " + extr.pushX);
  511. }
  512. }
  513. if (pathShearY != 0)
  514. {
  515. if (pathShearY > 50)
  516. {
  517. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  518. extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
  519. //m_log.Warn("pushY: " + extr.pushY);
  520. }
  521. else
  522. {
  523. extr.pushY = (float)pathShearY / 100;
  524. //m_log.Warn("pushY: " + extr.pushY);
  525. }
  526. }
  527. if (twistTop != 0)
  528. {
  529. extr.twistTop = 180 * ((float)twistTop / 100);
  530. if (extr.twistTop > 0)
  531. {
  532. extr.twistTop = 360 - (-1 * extr.twistTop);
  533. }
  534. extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
  535. }
  536. float twistMid = ((twistTop + twistBot) * 0.5f);
  537. if (twistMid != 0)
  538. {
  539. extr.twistMid = 180 * ((float)twistMid / 100);
  540. if (extr.twistMid > 0)
  541. {
  542. extr.twistMid = 360 - (-1 * extr.twistMid);
  543. }
  544. extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
  545. }
  546. if (twistBot != 0)
  547. {
  548. extr.twistBot = 180 * ((float)twistBot / 100);
  549. if (extr.twistBot > 0)
  550. {
  551. extr.twistBot = 360 - (-1 * extr.twistBot);
  552. }
  553. extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
  554. }
  555. Mesh result = extr.Extrude(m);
  556. result.DumpRaw(baseDir, primName, "Z extruded");
  557. return result;
  558. }
  559. private static Mesh CreateCylinderMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
  560. // Builds the z (+ and -) surfaces of a box shaped prim
  561. {
  562. UInt16 hollowFactor = primShape.ProfileHollow;
  563. UInt16 profileBegin = primShape.ProfileBegin;
  564. UInt16 profileEnd = primShape.ProfileEnd;
  565. UInt16 taperX = primShape.PathScaleX;
  566. UInt16 taperY = primShape.PathScaleY;
  567. UInt16 pathShearX = primShape.PathShearX;
  568. UInt16 pathShearY = primShape.PathShearY;
  569. Int16 twistBot = primShape.PathTwist;
  570. Int16 twistTop = primShape.PathTwistBegin;
  571. // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
  572. // of a block are basically the same
  573. // They may be warped differently but the shape is identical
  574. // So we only create one surface as a model and derive both plus and minus surface of the block from it
  575. // This is done in a model space where the block spans from -.5 to +.5 in X and Y
  576. // The mapping to Scene space is done later during the "extrusion" phase
  577. // Base
  578. // Q1Q15 = Quadrant 1, Quadrant1, Vertex 5
  579. //Vertex Q1Q15 = new Vertex(-0.35f, -0.35f, 0.0f);
  580. //Vertex Q1Q16 = new Vertex(-0.30f, -0.40f, 0.0f);
  581. //Vertex Q1Q17 = new Vertex(-0.24f, -0.43f, 0.0f);
  582. //Vertex Q1Q18 = new Vertex(-0.18f, -0.46f, 0.0f);
  583. //Vertex Q1Q19 = new Vertex(-0.11f, -0.48f, 0.0f);
  584. //Vertex Q2Q10 = new Vertex(+0.0f, -0.50f, 0.0f);
  585. //Vertex Q2Q11 = new Vertex(+0.11f, -0.48f, 0.0f);
  586. //Vertex Q2Q12 = new Vertex(+0.18f, -0.46f, 0.0f);
  587. //Vertex Q2Q13 = new Vertex(+0.24f, -0.43f, 0.0f);
  588. //Vertex Q2Q14 = new Vertex(+0.30f, -0.40f, 0.0f);
  589. //Vertex Q2Q15 = new Vertex(+0.35f, -0.35f, 0.0f);
  590. //Vertex Q2Q16 = new Vertex(+0.40f, -0.30f, 0.0f);
  591. //Vertex Q2Q17 = new Vertex(+0.43f, -0.24f, 0.0f);
  592. //Vertex Q2Q18 = new Vertex(+0.46f, -0.18f, 0.0f);
  593. //Vertex Q2Q19 = new Vertex(+0.48f, -0.11f, 0.0f);
  594. //Vertex Q2Q20 = new Vertex(+0.50f, +0.0f, 0.0f);
  595. //Vertex Q2Q21 = new Vertex(+0.48f, +0.11f, 0.0f);
  596. //Vertex Q2Q22 = new Vertex(+0.46f, +0.18f, 0.0f);
  597. //Vertex Q2Q23 = new Vertex(+0.43f, +0.24f, 0.0f);
  598. //Vertex Q2Q24 = new Vertex(+0.40f, +0.30f, 0.0f);
  599. //Vertex Q2Q25 = new Vertex(+0.35f, +0.35f, 0.0f);
  600. //Vertex Q2Q26 = new Vertex(+0.30f, +0.40f, 0.0f);
  601. //Vertex Q2Q27 = new Vertex(+0.24f, +0.43f, 0.0f);
  602. //Vertex Q2Q28 = new Vertex(+0.18f, +0.46f, 0.0f);
  603. //Vertex Q2Q29 = new Vertex(+0.11f, +0.48f, 0.0f);
  604. //Vertex Q1Q20 = new Vertex(+0.0f, +0.50f, 0.0f);
  605. //Vertex Q1Q21 = new Vertex(-0.11f, +0.48f, 0.0f);
  606. //Vertex Q1Q22 = new Vertex(-0.18f, +0.46f, 0.0f);
  607. //Vertex Q1Q23 = new Vertex(-0.24f, +0.43f, 0.0f);
  608. //Vertex Q1Q24 = new Vertex(-0.30f, +0.40f, 0.0f);
  609. //Vertex Q1Q25 = new Vertex(-0.35f, +0.35f, 0.0f);
  610. //Vertex Q1Q26 = new Vertex(-0.40f, +0.30f, 0.0f);
  611. //Vertex Q1Q27 = new Vertex(-0.43f, +0.24f, 0.0f);
  612. //Vertex Q1Q28 = new Vertex(-0.46f, +0.18f, 0.0f);
  613. //Vertex Q1Q29 = new Vertex(-0.48f, +0.11f, 0.0f);
  614. //Vertex Q1Q10 = new Vertex(-0.50f, +0.0f, 0.0f);
  615. //Vertex Q1Q11 = new Vertex(-0.48f, -0.11f, 0.0f);
  616. //Vertex Q1Q12 = new Vertex(-0.46f, -0.18f, 0.0f);
  617. //Vertex Q1Q13 = new Vertex(-0.43f, -0.24f, 0.0f);
  618. //Vertex Q1Q14 = new Vertex(-0.40f, -0.30f, 0.0f);
  619. SimpleHull outerHull = new SimpleHull();
  620. //Clockwise around the quadrants
  621. //outerHull.AddVertex(Q1Q15);
  622. //outerHull.AddVertex(Q1Q16);
  623. //outerHull.AddVertex(Q1Q17);
  624. //outerHull.AddVertex(Q1Q18);
  625. //outerHull.AddVertex(Q1Q19);
  626. //outerHull.AddVertex(Q2Q10);
  627. //outerHull.AddVertex(Q2Q11);
  628. //outerHull.AddVertex(Q2Q12);
  629. //outerHull.AddVertex(Q2Q13);
  630. //outerHull.AddVertex(Q2Q14);
  631. //outerHull.AddVertex(Q2Q15);
  632. //outerHull.AddVertex(Q2Q16);
  633. //outerHull.AddVertex(Q2Q17);
  634. //outerHull.AddVertex(Q2Q18);
  635. //outerHull.AddVertex(Q2Q19);
  636. //outerHull.AddVertex(Q2Q20);
  637. //outerHull.AddVertex(Q2Q21);
  638. //outerHull.AddVertex(Q2Q22);
  639. //outerHull.AddVertex(Q2Q23);
  640. //outerHull.AddVertex(Q2Q24);
  641. //outerHull.AddVertex(Q2Q25);
  642. //outerHull.AddVertex(Q2Q26);
  643. //outerHull.AddVertex(Q2Q27);
  644. //outerHull.AddVertex(Q2Q28);
  645. //outerHull.AddVertex(Q2Q29);
  646. //outerHull.AddVertex(Q1Q20);
  647. //outerHull.AddVertex(Q1Q21);
  648. //outerHull.AddVertex(Q1Q22);
  649. //outerHull.AddVertex(Q1Q23);
  650. //outerHull.AddVertex(Q1Q24);
  651. //outerHull.AddVertex(Q1Q25);
  652. //outerHull.AddVertex(Q1Q26);
  653. //outerHull.AddVertex(Q1Q27);
  654. //outerHull.AddVertex(Q1Q28);
  655. //outerHull.AddVertex(Q1Q29);
  656. //outerHull.AddVertex(Q1Q10);
  657. //outerHull.AddVertex(Q1Q11);
  658. //outerHull.AddVertex(Q1Q12);
  659. //outerHull.AddVertex(Q1Q13);
  660. //outerHull.AddVertex(Q1Q14);
  661. // counter-clockwise around the quadrants, start at 45 degrees
  662. outerHull.AddVertex(new Vertex(0.353553f, 0.353553f, 0.0f)); // 45 degrees
  663. outerHull.AddVertex(new Vertex(0.250000f, 0.433013f, 0.0f)); // 60 degrees
  664. outerHull.AddVertex(new Vertex(0.129410f, 0.482963f, 0.0f)); // 75 degrees
  665. outerHull.AddVertex(new Vertex(0.000000f, 0.500000f, 0.0f)); // 90 degrees
  666. outerHull.AddVertex(new Vertex(-0.129410f, 0.482963f, 0.0f)); // 105 degrees
  667. outerHull.AddVertex(new Vertex(-0.250000f, 0.433013f, 0.0f)); // 120 degrees
  668. outerHull.AddVertex(new Vertex(-0.353553f, 0.353553f, 0.0f)); // 135 degrees
  669. outerHull.AddVertex(new Vertex(-0.433013f, 0.250000f, 0.0f)); // 150 degrees
  670. outerHull.AddVertex(new Vertex(-0.482963f, 0.129410f, 0.0f)); // 165 degrees
  671. outerHull.AddVertex(new Vertex(-0.500000f, 0.000000f, 0.0f)); // 180 degrees
  672. outerHull.AddVertex(new Vertex(-0.482963f, -0.129410f, 0.0f)); // 195 degrees
  673. outerHull.AddVertex(new Vertex(-0.433013f, -0.250000f, 0.0f)); // 210 degrees
  674. outerHull.AddVertex(new Vertex(-0.353553f, -0.353553f, 0.0f)); // 225 degrees
  675. outerHull.AddVertex(new Vertex(-0.250000f, -0.433013f, 0.0f)); // 240 degrees
  676. outerHull.AddVertex(new Vertex(-0.129410f, -0.482963f, 0.0f)); // 255 degrees
  677. outerHull.AddVertex(new Vertex(0.000000f, -0.500000f, 0.0f)); // 270 degrees
  678. outerHull.AddVertex(new Vertex(0.129410f, -0.482963f, 0.0f)); // 285 degrees
  679. outerHull.AddVertex(new Vertex(0.250000f, -0.433013f, 0.0f)); // 300 degrees
  680. outerHull.AddVertex(new Vertex(0.353553f, -0.353553f, 0.0f)); // 315 degrees
  681. outerHull.AddVertex(new Vertex(0.433013f, -0.250000f, 0.0f)); // 330 degrees
  682. outerHull.AddVertex(new Vertex(0.482963f, -0.129410f, 0.0f)); // 345 degrees
  683. outerHull.AddVertex(new Vertex(0.500000f, 0.000000f, 0.0f)); // 0 degrees
  684. outerHull.AddVertex(new Vertex(0.482963f, 0.129410f, 0.0f)); // 15 degrees
  685. outerHull.AddVertex(new Vertex(0.433013f, 0.250000f, 0.0f)); // 30 degrees
  686. // Deal with cuts now
  687. if ((profileBegin != 0) || (profileEnd != 0))
  688. {
  689. double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
  690. // In degree, for easier debugging and understanding
  691. //fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
  692. double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
  693. //fProfileEndAngle -= (90.0 + 45.0);
  694. if (fProfileBeginAngle < fProfileEndAngle)
  695. fProfileEndAngle -= 360.0;
  696. // Note, that we don't want to cut out a triangle, even if this is a
  697. // good approximation for small cuts. Indeed we want to cut out an arc
  698. // and we approximate this arc by a polygon chain
  699. // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
  700. // So it can easily be subtracted from the outer hull
  701. int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5);
  702. // how many steps do we need with approximately 45 degree
  703. double dStepWidth = (fProfileBeginAngle - fProfileEndAngle) / iSteps;
  704. Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
  705. // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
  706. SimpleHull cutHull = new SimpleHull();
  707. cutHull.AddVertex(origin);
  708. for (int i = 0; i < iSteps; i++)
  709. {
  710. double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
  711. Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
  712. cutHull.AddVertex(v);
  713. }
  714. Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
  715. // Calculated separately to avoid errors
  716. cutHull.AddVertex(legEnd);
  717. // m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
  718. SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
  719. outerHull = cuttedHull;
  720. }
  721. // Deal with the hole here
  722. if (hollowFactor > 0)
  723. {
  724. SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
  725. if (holeHull != null)
  726. {
  727. SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
  728. outerHull = hollowedHull;
  729. }
  730. }
  731. Mesh m = new Mesh();
  732. Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
  733. Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
  734. Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
  735. m.Add(Seed1);
  736. m.Add(Seed2);
  737. m.Add(Seed3);
  738. m.Add(new Triangle(Seed1, Seed2, Seed3));
  739. m.Add(outerHull.getVertices());
  740. InsertVertices(m.vertices, 3, m.triangles);
  741. m.DumpRaw(baseDir, primName, "Proto first Mesh");
  742. m.Remove(Seed1);
  743. m.Remove(Seed2);
  744. m.Remove(Seed3);
  745. m.DumpRaw(baseDir, primName, "Proto seeds removed");
  746. m.RemoveTrianglesOutside(outerHull);
  747. m.DumpRaw(baseDir, primName, "Proto outsides removed");
  748. foreach (Triangle t in m.triangles)
  749. {
  750. PhysicsVector n = t.getNormal();
  751. if (n.Z < 0.0)
  752. t.invertNormal();
  753. }
  754. Extruder extr = new Extruder();
  755. extr.size = size;
  756. //System.Console.WriteLine("taperFactorX: " + taperX.ToString());
  757. //System.Console.WriteLine("taperFactorY: " + taperY.ToString());
  758. if (taperX != 100)
  759. {
  760. if (taperX > 100)
  761. {
  762. extr.taperTopFactorX = 1.0f - ((float)(taperX - 100) / 100);
  763. //System.Console.WriteLine("taperTopFactorX: " + extr.taperTopFactorX.ToString());
  764. }
  765. else
  766. {
  767. extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
  768. //System.Console.WriteLine("taperBotFactorX: " + extr.taperBotFactorX.ToString());
  769. }
  770. }
  771. if (taperY != 100)
  772. {
  773. if (taperY > 100)
  774. {
  775. extr.taperTopFactorY = 1.0f - ((float)(taperY - 100) / 200);
  776. // System.Console.WriteLine("taperTopFactorY: " + extr.taperTopFactorY.ToString());
  777. }
  778. else
  779. {
  780. extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
  781. //System.Console.WriteLine("taperBotFactorY: " + extr.taperBotFactorY.ToString());
  782. }
  783. }
  784. if (pathShearX != 0)
  785. {
  786. if (pathShearX > 50)
  787. {
  788. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  789. extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
  790. //m_log.Warn("pushX: " + extr.pushX);
  791. }
  792. else
  793. {
  794. extr.pushX = (float)pathShearX / 100;
  795. //m_log.Warn("pushX: " + extr.pushX);
  796. }
  797. }
  798. if (pathShearY != 0)
  799. {
  800. if (pathShearY > 50)
  801. {
  802. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  803. extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
  804. //m_log.Warn("pushY: " + extr.pushY);
  805. }
  806. else
  807. {
  808. extr.pushY = (float)pathShearY / 100;
  809. //m_log.Warn("pushY: " + extr.pushY);
  810. }
  811. }
  812. if (twistTop != 0)
  813. {
  814. extr.twistTop = 180 * ((float)twistTop / 100);
  815. if (extr.twistTop > 0)
  816. {
  817. extr.twistTop = 360 - (-1 * extr.twistTop);
  818. }
  819. extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
  820. }
  821. float twistMid = ((twistTop + twistBot) * 0.5f);
  822. if (twistMid != 0)
  823. {
  824. extr.twistMid = 180 * ((float)twistMid / 100);
  825. if (extr.twistMid > 0)
  826. {
  827. extr.twistMid = 360 - (-1 * extr.twistMid);
  828. }
  829. extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
  830. }
  831. if (twistBot != 0)
  832. {
  833. extr.twistBot = 180 * ((float)twistBot / 100);
  834. if (extr.twistBot > 0)
  835. {
  836. extr.twistBot = 360 - (-1 * extr.twistBot);
  837. }
  838. extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
  839. }
  840. //System.Console.WriteLine("[MESH]: twistTop = " + twistTop.ToString() + "|" + extr.twistTop.ToString() + ", twistMid = " + twistMid.ToString() + "|" + extr.twistMid.ToString() + ", twistbot = " + twistBot.ToString() + "|" + extr.twistBot.ToString());
  841. Mesh result = extr.Extrude(m);
  842. result.DumpRaw(baseDir, primName, "Z extruded");
  843. return result;
  844. }
  845. private static Mesh CreatePrismMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
  846. // Builds the z (+ and -) surfaces of a box shaped prim
  847. {
  848. UInt16 hollowFactor = primShape.ProfileHollow;
  849. UInt16 profileBegin = primShape.ProfileBegin;
  850. UInt16 profileEnd = primShape.ProfileEnd;
  851. UInt16 taperX = primShape.PathScaleX;
  852. UInt16 taperY = primShape.PathScaleY;
  853. UInt16 pathShearX = primShape.PathShearX;
  854. UInt16 pathShearY = primShape.PathShearY;
  855. Int16 twistTop = primShape.PathTwistBegin;
  856. Int16 twistBot = primShape.PathTwist;
  857. //m_log.Error("pathShear:" + primShape.PathShearX.ToString() + "," + primShape.PathShearY.ToString());
  858. //m_log.Error("pathTaper:" + primShape.PathTaperX.ToString() + "," + primShape.PathTaperY.ToString());
  859. //m_log.Error("ProfileBegin:" + primShape.ProfileBegin.ToString() + "," + primShape.ProfileBegin.ToString());
  860. //m_log.Error("PathScale:" + primShape.PathScaleX.ToString() + "," + primShape.PathScaleY.ToString());
  861. // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
  862. // of a block are basically the same
  863. // They may be warped differently but the shape is identical
  864. // So we only create one surface as a model and derive both plus and minus surface of the block from it
  865. // This is done in a model space where the block spans from -.5 to +.5 in X and Y
  866. // The mapping to Scene space is done later during the "extrusion" phase
  867. // Base
  868. Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
  869. Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
  870. Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
  871. SimpleHull outerHull = new SimpleHull();
  872. //outerHull.AddVertex(MM);
  873. //outerHull.AddVertex(PM);
  874. //outerHull.AddVertex(PP);
  875. outerHull.AddVertex(PP);
  876. outerHull.AddVertex(MM);
  877. outerHull.AddVertex(PM);
  878. // Deal with cuts now
  879. if ((profileBegin != 0) || (profileEnd != 0))
  880. {
  881. double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
  882. // In degree, for easier debugging and understanding
  883. //fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
  884. double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
  885. //fProfileEndAngle -= (90.0 + 45.0);
  886. if (fProfileBeginAngle < fProfileEndAngle)
  887. fProfileEndAngle -= 360.0;
  888. // Note, that we don't want to cut out a triangle, even if this is a
  889. // good approximation for small cuts. Indeed we want to cut out an arc
  890. // and we approximate this arc by a polygon chain
  891. // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
  892. // So it can easily be subtracted from the outer hull
  893. int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5);
  894. // how many steps do we need with approximately 45 degree
  895. double dStepWidth = (fProfileBeginAngle - fProfileEndAngle) / iSteps;
  896. Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
  897. // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
  898. SimpleHull cutHull = new SimpleHull();
  899. cutHull.AddVertex(origin);
  900. for (int i = 0; i < iSteps; i++)
  901. {
  902. double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
  903. Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
  904. cutHull.AddVertex(v);
  905. }
  906. Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
  907. // Calculated separately to avoid errors
  908. cutHull.AddVertex(legEnd);
  909. //m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
  910. SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
  911. outerHull = cuttedHull;
  912. }
  913. // Deal with the hole here
  914. if (hollowFactor > 0)
  915. {
  916. SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
  917. if (holeHull != null)
  918. {
  919. SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
  920. outerHull = hollowedHull;
  921. }
  922. }
  923. Mesh m = new Mesh();
  924. Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
  925. Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
  926. Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
  927. m.Add(Seed1);
  928. m.Add(Seed2);
  929. m.Add(Seed3);
  930. m.Add(new Triangle(Seed1, Seed2, Seed3));
  931. m.Add(outerHull.getVertices());
  932. InsertVertices(m.vertices, 3, m.triangles);
  933. m.DumpRaw(baseDir, primName, "Proto first Mesh");
  934. m.Remove(Seed1);
  935. m.Remove(Seed2);
  936. m.Remove(Seed3);
  937. m.DumpRaw(baseDir, primName, "Proto seeds removed");
  938. m.RemoveTrianglesOutside(outerHull);
  939. m.DumpRaw(baseDir, primName, "Proto outsides removed");
  940. foreach (Triangle t in m.triangles)
  941. {
  942. PhysicsVector n = t.getNormal();
  943. if (n.Z < 0.0)
  944. t.invertNormal();
  945. }
  946. Extruder extr = new Extruder();
  947. extr.size = size;
  948. if (taperX != 100)
  949. {
  950. if (taperX > 100)
  951. {
  952. extr.taperTopFactorX = 1.0f - ((float)taperX / 200);
  953. //System.Console.WriteLine("taperTopFactorX: " + extr.taperTopFactorX.ToString());
  954. }
  955. else
  956. {
  957. extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
  958. //System.Console.WriteLine("taperBotFactorX: " + extr.taperBotFactorX.ToString());
  959. }
  960. }
  961. if (taperY != 100)
  962. {
  963. if (taperY > 100)
  964. {
  965. extr.taperTopFactorY = 1.0f - ((float)taperY / 200);
  966. //System.Console.WriteLine("taperTopFactorY: " + extr.taperTopFactorY.ToString());
  967. }
  968. else
  969. {
  970. extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
  971. //System.Console.WriteLine("taperBotFactorY: " + extr.taperBotFactorY.ToString());
  972. }
  973. }
  974. if (pathShearX != 0)
  975. {
  976. if (pathShearX > 50)
  977. {
  978. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  979. extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
  980. // m_log.Warn("pushX: " + extr.pushX);
  981. }
  982. else
  983. {
  984. extr.pushX = (float)pathShearX / 100;
  985. // m_log.Warn("pushX: " + extr.pushX);
  986. }
  987. }
  988. if (pathShearY != 0)
  989. {
  990. if (pathShearY > 50)
  991. {
  992. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  993. extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
  994. //m_log.Warn("pushY: " + extr.pushY);
  995. }
  996. else
  997. {
  998. extr.pushY = (float)pathShearY / 100;
  999. //m_log.Warn("pushY: " + extr.pushY);
  1000. }
  1001. }
  1002. if (twistTop != 0)
  1003. {
  1004. extr.twistTop = 180 * ((float)twistTop / 100);
  1005. if (extr.twistTop > 0)
  1006. {
  1007. extr.twistTop = 360 - (-1 * extr.twistTop);
  1008. }
  1009. extr.twistTop = (float)(extr.twistTop * DEG_TO_RAD);
  1010. }
  1011. float twistMid = ((twistTop + twistBot) * 0.5f);
  1012. if (twistMid != 0)
  1013. {
  1014. extr.twistMid = 180 * ((float)twistMid / 100);
  1015. if (extr.twistMid > 0)
  1016. {
  1017. extr.twistMid = 360 - (-1 * extr.twistMid);
  1018. }
  1019. extr.twistMid = (float)(extr.twistMid * DEG_TO_RAD);
  1020. }
  1021. if (twistBot != 0)
  1022. {
  1023. extr.twistBot = 180 * ((float)twistBot / 100);
  1024. if (extr.twistBot > 0)
  1025. {
  1026. extr.twistBot = 360 - (-1 * extr.twistBot);
  1027. }
  1028. extr.twistBot = (float)(extr.twistBot * DEG_TO_RAD);
  1029. }
  1030. Mesh result = extr.Extrude(m);
  1031. result.DumpRaw(baseDir, primName, "Z extruded");
  1032. return result;
  1033. }
  1034. private static Mesh CreateSphereMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
  1035. {
  1036. // Builds an icosahedral geodesic sphere
  1037. // based on an article by Paul Bourke
  1038. // http://local.wasp.uwa.edu.au/~pbourke/
  1039. // articles:
  1040. // http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonmesh/
  1041. // and
  1042. // http://local.wasp.uwa.edu.au/~pbourke/geometry/polyhedra/index.html
  1043. // Still have more to do here.
  1044. UInt16 hollowFactor = primShape.ProfileHollow;
  1045. UInt16 profileBegin = primShape.ProfileBegin;
  1046. UInt16 profileEnd = primShape.ProfileEnd;
  1047. UInt16 taperX = primShape.PathScaleX;
  1048. UInt16 taperY = primShape.PathScaleY;
  1049. UInt16 pathShearX = primShape.PathShearX;
  1050. UInt16 pathShearY = primShape.PathShearY;
  1051. Mesh m = new Mesh();
  1052. float LOD = 0.2f;
  1053. float diameter = 0.5f;// Our object will result in -0.5 to 0.5
  1054. float sq5 = (float) Math.Sqrt(5.0);
  1055. float phi = (1 + sq5) * 0.5f;
  1056. float rat = (float) Math.Sqrt(10f + (2f * sq5)) / (4f * phi);
  1057. float a = (diameter / rat) * 0.5f;
  1058. float b = (diameter / rat) / (2.0f * phi);
  1059. // 12 Icosahedron vertexes
  1060. Vertex v1 = new Vertex(0f, b, -a);
  1061. Vertex v2 = new Vertex(b, a, 0f);
  1062. Vertex v3 = new Vertex(-b, a, 0f);
  1063. Vertex v4 = new Vertex(0f, b, a);
  1064. Vertex v5 = new Vertex(0f, -b, a);
  1065. Vertex v6 = new Vertex(-a, 0f, b);
  1066. Vertex v7 = new Vertex(0f, -b, -a);
  1067. Vertex v8 = new Vertex(a, 0f, -b);
  1068. Vertex v9 = new Vertex(a, 0f, b);
  1069. Vertex v10 = new Vertex(-a, 0f, -b);
  1070. Vertex v11 = new Vertex(b, -a, 0);
  1071. Vertex v12 = new Vertex(-b, -a, 0);
  1072. // Base Faces of the Icosahedron (20)
  1073. SphereLODTriangle(v1, v2, v3, diameter, LOD, m);
  1074. SphereLODTriangle(v4, v3, v2, diameter, LOD, m);
  1075. SphereLODTriangle(v4, v5, v6, diameter, LOD, m);
  1076. SphereLODTriangle(v4, v9, v5, diameter, LOD, m);
  1077. SphereLODTriangle(v1, v7, v8, diameter, LOD, m);
  1078. SphereLODTriangle(v1, v10, v7, diameter, LOD, m);
  1079. SphereLODTriangle(v5, v11, v12, diameter, LOD, m);
  1080. SphereLODTriangle(v7, v12, v11, diameter, LOD, m);
  1081. SphereLODTriangle(v3, v6, v10, diameter, LOD, m);
  1082. SphereLODTriangle(v12, v10, v6, diameter, LOD, m);
  1083. SphereLODTriangle(v2, v8, v9, diameter, LOD, m);
  1084. SphereLODTriangle(v11, v9, v8, diameter, LOD, m);
  1085. SphereLODTriangle(v4, v6, v3, diameter, LOD, m);
  1086. SphereLODTriangle(v4, v2, v9, diameter, LOD, m);
  1087. SphereLODTriangle(v1, v3, v10, diameter, LOD, m);
  1088. SphereLODTriangle(v1, v8, v2, diameter, LOD, m);
  1089. SphereLODTriangle(v7, v10, v12, diameter, LOD, m);
  1090. SphereLODTriangle(v7, v11, v8, diameter, LOD, m);
  1091. SphereLODTriangle(v5, v12, v6, diameter, LOD, m);
  1092. SphereLODTriangle(v5, v9, v11, diameter, LOD, m);
  1093. // Scale the mesh based on our prim scale
  1094. foreach (Vertex v in m.vertices)
  1095. {
  1096. v.X *= size.X;
  1097. v.Y *= size.Y;
  1098. v.Z *= size.Z;
  1099. }
  1100. // This was built with the normals pointing inside..
  1101. // therefore we have to invert the normals
  1102. foreach (Triangle t in m.triangles)
  1103. {
  1104. t.invertNormal();
  1105. }
  1106. // Dump the faces for visualization in blender.
  1107. m.DumpRaw(baseDir, primName, "Icosahedron");
  1108. return m;
  1109. }
  1110. private SculptMesh CreateSculptMesh(string primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
  1111. {
  1112. SculptMesh sm = new SculptMesh(primShape.SculptData, lod);
  1113. // Scale the mesh based on our prim scale
  1114. foreach (Vertex v in sm.vertices)
  1115. {
  1116. v.X *= 0.5f;
  1117. v.Y *= 0.5f;
  1118. v.Z *= 0.5f;
  1119. v.X *= size.X;
  1120. v.Y *= size.Y;
  1121. v.Z *= size.Z;
  1122. }
  1123. // This was built with the normals pointing inside..
  1124. // therefore we have to invert the normals
  1125. foreach (Triangle t in sm.triangles)
  1126. {
  1127. t.invertNormal();
  1128. }
  1129. sm.DumpRaw(baseDir, primName, "Sculpt");
  1130. return sm;
  1131. }
  1132. private static Mesh CreateCircularProfileMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
  1133. {
  1134. UInt16 hollowFactor = primShape.ProfileHollow;
  1135. UInt16 profileBegin = primShape.ProfileBegin;
  1136. UInt16 profileEnd = primShape.ProfileEnd;
  1137. UInt16 taperX = primShape.PathScaleX;
  1138. UInt16 taperY = primShape.PathScaleY;
  1139. UInt16 pathShearX = primShape.PathShearX;
  1140. UInt16 pathShearY = primShape.PathShearY;
  1141. Int16 twistBot = primShape.PathTwist;
  1142. Int16 twistTop = primShape.PathTwistBegin;
  1143. HollowShape hollowShape = primShape.HollowShape;
  1144. //Console.WriteLine("pathTwist: " + primShape.PathTwist.ToString() + " pathTwistBegin: " + primShape.PathTwistBegin.ToString());
  1145. SimpleHull outerHull = new SimpleHull();
  1146. //Console.WriteLine("primShape.ProfileCurve & 0x07: " + Convert.ToString(primShape.ProfileCurve & 0x07));
  1147. if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
  1148. //if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle
  1149. // || (primShape.ProfileCurve & 0x07) == (byte) ProfileShape.Square)
  1150. {
  1151. //Console.WriteLine("Meshmerizer thinks " + primName + " is a TORUS");
  1152. if (hollowShape == HollowShape.Same)
  1153. hollowShape = HollowShape.Circle;
  1154. // build the profile shape
  1155. // counter-clockwise around the quadrants, start at 45 degrees
  1156. outerHull.AddVertex(new Vertex(0.353553f, 0.353553f, 0.0f)); // 45 degrees
  1157. outerHull.AddVertex(new Vertex(0.250000f, 0.433013f, 0.0f)); // 60 degrees
  1158. outerHull.AddVertex(new Vertex(0.129410f, 0.482963f, 0.0f)); // 75 degrees
  1159. outerHull.AddVertex(new Vertex(0.000000f, 0.500000f, 0.0f)); // 90 degrees
  1160. outerHull.AddVertex(new Vertex(-0.129410f, 0.482963f, 0.0f)); // 105 degrees
  1161. outerHull.AddVertex(new Vertex(-0.250000f, 0.433013f, 0.0f)); // 120 degrees
  1162. outerHull.AddVertex(new Vertex(-0.353553f, 0.353553f, 0.0f)); // 135 degrees
  1163. outerHull.AddVertex(new Vertex(-0.433013f, 0.250000f, 0.0f)); // 150 degrees
  1164. outerHull.AddVertex(new Vertex(-0.482963f, 0.129410f, 0.0f)); // 165 degrees
  1165. outerHull.AddVertex(new Vertex(-0.500000f, 0.000000f, 0.0f)); // 180 degrees
  1166. outerHull.AddVertex(new Vertex(-0.482963f, -0.129410f, 0.0f)); // 195 degrees
  1167. outerHull.AddVertex(new Vertex(-0.433013f, -0.250000f, 0.0f)); // 210 degrees
  1168. outerHull.AddVertex(new Vertex(-0.353553f, -0.353553f, 0.0f)); // 225 degrees
  1169. outerHull.AddVertex(new Vertex(-0.250000f, -0.433013f, 0.0f)); // 240 degrees
  1170. outerHull.AddVertex(new Vertex(-0.129410f, -0.482963f, 0.0f)); // 255 degrees
  1171. outerHull.AddVertex(new Vertex(0.000000f, -0.500000f, 0.0f)); // 270 degrees
  1172. outerHull.AddVertex(new Vertex(0.129410f, -0.482963f, 0.0f)); // 285 degrees
  1173. outerHull.AddVertex(new Vertex(0.250000f, -0.433013f, 0.0f)); // 300 degrees
  1174. outerHull.AddVertex(new Vertex(0.353553f, -0.353553f, 0.0f)); // 315 degrees
  1175. outerHull.AddVertex(new Vertex(0.433013f, -0.250000f, 0.0f)); // 330 degrees
  1176. outerHull.AddVertex(new Vertex(0.482963f, -0.129410f, 0.0f)); // 345 degrees
  1177. outerHull.AddVertex(new Vertex(0.500000f, 0.000000f, 0.0f)); // 0 degrees
  1178. outerHull.AddVertex(new Vertex(0.482963f, 0.129410f, 0.0f)); // 15 degrees
  1179. outerHull.AddVertex(new Vertex(0.433013f, 0.250000f, 0.0f)); // 30 degrees
  1180. }
  1181. else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Square) // a ring
  1182. {
  1183. //Console.WriteLine("Meshmerizer thinks " + primName + " is a TUBE");
  1184. if (hollowShape == HollowShape.Same)
  1185. hollowShape = HollowShape.Square;
  1186. outerHull.AddVertex(new Vertex(+0.5f, +0.5f, 0.0f));
  1187. outerHull.AddVertex(new Vertex(-0.5f, +0.5f, 0.0f));
  1188. outerHull.AddVertex(new Vertex(-0.5f, -0.5f, 0.0f));
  1189. outerHull.AddVertex(new Vertex(+0.5f, -0.5f, 0.0f));
  1190. }
  1191. else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
  1192. {
  1193. //Console.WriteLine("Meshmerizer thinks " + primName + " is a RING");
  1194. if (hollowShape == HollowShape.Same)
  1195. hollowShape = HollowShape.Triangle;
  1196. outerHull.AddVertex(new Vertex(+0.255f, -0.375f, 0.0f));
  1197. outerHull.AddVertex(new Vertex(+0.25f, +0.375f, 0.0f));
  1198. outerHull.AddVertex(new Vertex(-0.5f, +0.0f, 0.0f));
  1199. }
  1200. else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
  1201. {
  1202. //Console.WriteLine("Meshmerizer thinks " + primName + " is a SPHERE");
  1203. if (hollowShape == HollowShape.Same)
  1204. hollowShape = HollowShape.Circle;
  1205. // not implemented here, use old routine
  1206. return CreateSphereMesh(primName, primShape, size);
  1207. }
  1208. // Deal with cuts now
  1209. if ((profileBegin != 0) || (profileEnd != 0))
  1210. {
  1211. double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
  1212. // In degree, for easier debugging and understanding
  1213. //fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
  1214. double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
  1215. //fProfileEndAngle -= (90.0 + 45.0);
  1216. if (fProfileBeginAngle < fProfileEndAngle)
  1217. fProfileEndAngle -= 360.0;
  1218. // Note, that we don't want to cut out a triangle, even if this is a
  1219. // good approximation for small cuts. Indeed we want to cut out an arc
  1220. // and we approximate this arc by a polygon chain
  1221. // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
  1222. // So it can easily be subtracted from the outer hull
  1223. int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5);
  1224. // how many steps do we need with approximately 45 degree
  1225. double dStepWidth = (fProfileBeginAngle - fProfileEndAngle) / iSteps;
  1226. Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
  1227. // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
  1228. SimpleHull cutHull = new SimpleHull();
  1229. cutHull.AddVertex(origin);
  1230. for (int i = 0; i < iSteps; i++)
  1231. {
  1232. double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
  1233. Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
  1234. cutHull.AddVertex(v);
  1235. }
  1236. Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
  1237. // Calculated separately to avoid errors
  1238. cutHull.AddVertex(legEnd);
  1239. // m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
  1240. SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
  1241. if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
  1242. {
  1243. Quaternion zFlip = new Quaternion(new Vertex(0.0f, 0.0f, 1.0f), (float)Math.PI);
  1244. Vertex vTmp = new Vertex(0.0f, 0.0f, 0.0f);
  1245. foreach (Vertex v in cuttedHull.getVertices())
  1246. if (v != null)
  1247. {
  1248. vTmp = v * zFlip;
  1249. v.X = vTmp.X;
  1250. v.Y = vTmp.Y;
  1251. v.Z = vTmp.Z;
  1252. }
  1253. }
  1254. outerHull = cuttedHull;
  1255. }
  1256. // Deal with the hole here
  1257. if (hollowFactor > 0)
  1258. {
  1259. SimpleHull holeHull;
  1260. if (hollowShape == HollowShape.Triangle)
  1261. {
  1262. holeHull = new SimpleHull();
  1263. float hollowFactorF = (float) hollowFactor / 50000.0f;
  1264. if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
  1265. {
  1266. holeHull.AddVertex(new Vertex(+0.125f * hollowFactorF, -0.1875f * hollowFactorF, 0.0f));
  1267. holeHull.AddVertex(new Vertex(-0.25f * hollowFactorF, -0f * hollowFactorF, 0.0f));
  1268. holeHull.AddVertex(new Vertex(+0.125f * hollowFactorF, +0.1875f * hollowFactorF, 0.0f));
  1269. }
  1270. else
  1271. {
  1272. holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f));
  1273. holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, -0f * hollowFactorF, 0.0f));
  1274. holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f));
  1275. ////holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, -0f * hollowFactorF, 0.0f));
  1276. ////holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f));
  1277. ////holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f));
  1278. //holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, +0f * hollowFactorF, 0.0f));
  1279. //holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f));
  1280. //holeHull.AddVertex(new Vertex(+0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f));
  1281. ////holeHull.AddVertex(new Vertex(-0.5f * hollowFactorF, +0f * hollowFactorF, 0.0f));
  1282. }
  1283. }
  1284. else
  1285. {
  1286. holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
  1287. }
  1288. if (holeHull != null)
  1289. {
  1290. SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
  1291. outerHull = hollowedHull;
  1292. }
  1293. }
  1294. Mesh m = new Mesh();
  1295. Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
  1296. Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
  1297. Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
  1298. m.Add(Seed1);
  1299. m.Add(Seed2);
  1300. m.Add(Seed3);
  1301. m.Add(new Triangle(Seed1, Seed2, Seed3));
  1302. m.Add(outerHull.getVertices());
  1303. InsertVertices(m.vertices, 3, m.triangles);
  1304. m.DumpRaw(baseDir, primName, "Proto first Mesh");
  1305. m.Remove(Seed1);
  1306. m.Remove(Seed2);
  1307. m.Remove(Seed3);
  1308. m.DumpRaw(baseDir, primName, "Proto seeds removed");
  1309. m.RemoveTrianglesOutside(outerHull);
  1310. m.DumpRaw(baseDir, primName, "Proto outsides removed");
  1311. foreach (Triangle t in m.triangles)
  1312. t.invertNormal();
  1313. Vertex vTemp = new Vertex(0.0f, 0.0f, 0.0f);
  1314. //Console.WriteLine("primShape.PathScaleX: " + primShape.PathScaleX.ToString() + " primShape.PathScaleY: " + primShape.PathScaleY.ToString());
  1315. //Console.WriteLine("primShape.PathSkew: " + primShape.PathSkew.ToString() + " primShape.PathRadiusOffset: " + primShape.PathRadiusOffset.ToString() + " primShape.pathRevolutions: " + primShape.PathRevolutions.ToString());
  1316. float skew = primShape.PathSkew * 0.01f;
  1317. float pathScaleX = (float)(200 - primShape.PathScaleX) * 0.01f;
  1318. float pathScaleY = (float)(200 - primShape.PathScaleY) * 0.01f;
  1319. //Console.WriteLine("PathScaleX: " + pathScaleX.ToString() + " pathScaleY: " + pathScaleY.ToString());
  1320. float profileXComp = pathScaleX * (1.0f - Math.Abs(skew));
  1321. foreach (Vertex v in m.vertices)
  1322. if (v != null)
  1323. {
  1324. v.X *= profileXComp;
  1325. v.Y *= pathScaleY;
  1326. //v.Y *= 0.5f; // torus profile is scaled in y axis
  1327. }
  1328. Extruder extr = new Extruder();
  1329. extr.size = size;
  1330. extr.pathScaleX = pathScaleX;
  1331. extr.pathScaleY = pathScaleY;
  1332. extr.pathCutBegin = 0.00002f * primShape.PathBegin;
  1333. extr.pathCutEnd = 0.00002f * (50000 - primShape.PathEnd);
  1334. extr.pathBegin = primShape.PathBegin;
  1335. extr.pathEnd = primShape.PathEnd;
  1336. extr.skew = skew;
  1337. extr.revolutions = 1.0f + (float)primShape.PathRevolutions * 3.0f / 200.0f;
  1338. //System.Console.WriteLine("primShape.PathBegin: " + primShape.PathBegin.ToString() + " primShape.PathEnd: " + primShape.PathEnd.ToString());
  1339. //System.Console.WriteLine("extr.pathCutBegin: " + extr.pathCutBegin.ToString() + " extr.pathCutEnd: " + extr.pathCutEnd.ToString());
  1340. //System.Console.WriteLine("extr.revolutions: " + extr.revolutions.ToString());
  1341. //System.Console.WriteLine("primShape.PathTaperX: " + primShape.PathTaperX.ToString());
  1342. //System.Console.WriteLine("primShape.PathTaperY: " + primShape.PathTaperY.ToString());
  1343. extr.pathTaperX = 0.01f * (float)primShape.PathTaperX;
  1344. extr.pathTaperY = 0.01f * (float)primShape.PathTaperY;
  1345. extr.radius = 0.01f * (float)primShape.PathRadiusOffset;
  1346. //System.Console.WriteLine("primShape.PathRadiusOffset: " + primShape.PathRadiusOffset.ToString());
  1347. if (pathShearX != 0)
  1348. {
  1349. if (pathShearX > 50)
  1350. {
  1351. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  1352. extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
  1353. //m_log.Warn("pushX: " + extr.pushX);
  1354. }
  1355. else
  1356. {
  1357. extr.pushX = (float)pathShearX / 100;
  1358. //m_log.Warn("pushX: " + extr.pushX);
  1359. }
  1360. }
  1361. if (pathShearY != 0)
  1362. {
  1363. if (pathShearY > 50)
  1364. {
  1365. // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
  1366. extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
  1367. //m_log.Warn("pushY: " + extr.pushY);
  1368. }
  1369. else
  1370. {
  1371. extr.pushY = (float)pathShearY / 100;
  1372. //m_log.Warn("pushY: " + extr.pushY);
  1373. }
  1374. }
  1375. extr.twistTop = (float)primShape.PathTwist * (float)Math.PI * 0.02f;
  1376. extr.twistBot = (float)primShape.PathTwistBegin * (float)Math.PI * 0.02f;
  1377. //System.Console.WriteLine("[MESH]: twistTop = " + twistTop.ToString() + "|" + extr.twistTop.ToString() + ", twistMid = " + twistMid.ToString() + "|" + extr.twistMid.ToString() + ", twistbot = " + twistBot.ToString() + "|" + extr.twistBot.ToString());
  1378. Mesh result = extr.ExtrudeCircularPath(m);
  1379. result.DumpRaw(baseDir, primName, "Z extruded");
  1380. return result;
  1381. }
  1382. public static void CalcNormals(Mesh mesh)
  1383. {
  1384. int iTriangles = mesh.triangles.Count;
  1385. mesh.normals = new float[iTriangles*3];
  1386. int i = 0;
  1387. foreach (Triangle t in mesh.triangles)
  1388. {
  1389. float ux, uy, uz;
  1390. float vx, vy, vz;
  1391. float wx, wy, wz;
  1392. ux = t.v1.X;
  1393. uy = t.v1.Y;
  1394. uz = t.v1.Z;
  1395. vx = t.v2.X;
  1396. vy = t.v2.Y;
  1397. vz = t.v2.Z;
  1398. wx = t.v3.X;
  1399. wy = t.v3.Y;
  1400. wz = t.v3.Z;
  1401. // Vectors for edges
  1402. float e1x, e1y, e1z;
  1403. float e2x, e2y, e2z;
  1404. e1x = ux - vx;
  1405. e1y = uy - vy;
  1406. e1z = uz - vz;
  1407. e2x = ux - wx;
  1408. e2y = uy - wy;
  1409. e2z = uz - wz;
  1410. // Cross product for normal
  1411. float nx, ny, nz;
  1412. nx = e1y*e2z - e1z*e2y;
  1413. ny = e1z*e2x - e1x*e2z;
  1414. nz = e1x*e2y - e1y*e2x;
  1415. // Length
  1416. float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
  1417. // Normalized "normal"
  1418. nx /= l;
  1419. ny /= l;
  1420. nz /= l;
  1421. mesh.normals[i] = nx;
  1422. mesh.normals[i + 1] = ny;
  1423. mesh.normals[i + 2] = nz;
  1424. i += 3;
  1425. }
  1426. }
  1427. public static Vertex midUnitRadialPoint(Vertex a, Vertex b, float radius)
  1428. {
  1429. Vertex midpoint = new Vertex(a + b) * 0.5f;
  1430. return (midpoint.normalize() * radius);
  1431. }
  1432. public static void SphereLODTriangle(Vertex a, Vertex b, Vertex c, float diameter, float LOD, Mesh m)
  1433. {
  1434. Vertex aa = a - b;
  1435. Vertex ba = b - c;
  1436. Vertex da = c - a;
  1437. if (((aa.length() < LOD) && (ba.length() < LOD) && (da.length() < LOD)))
  1438. {
  1439. // We don't want duplicate verticies. Duplicates cause the scale algorithm to produce a spikeball
  1440. // spikes are novel, but we want ellipsoids.
  1441. if (!m.vertices.Contains(a))
  1442. m.Add(a);
  1443. if (!m.vertices.Contains(b))
  1444. m.Add(b);
  1445. if (!m.vertices.Contains(c))
  1446. m.Add(c);
  1447. // Add the triangle to the mesh
  1448. Triangle t = new Triangle(a, b, c);
  1449. m.Add(t);
  1450. }
  1451. else
  1452. {
  1453. Vertex ab = midUnitRadialPoint(a, b, diameter);
  1454. Vertex bc = midUnitRadialPoint(b, c, diameter);
  1455. Vertex ca = midUnitRadialPoint(c, a, diameter);
  1456. // Recursive! Splits the triangle up into 4 smaller triangles
  1457. SphereLODTriangle(a, ab, ca, diameter, LOD, m);
  1458. SphereLODTriangle(ab, b, bc, diameter, LOD, m);
  1459. SphereLODTriangle(ca, bc, c, diameter, LOD, m);
  1460. SphereLODTriangle(ab, bc, ca, diameter, LOD, m);
  1461. }
  1462. }
  1463. public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size, float lod)
  1464. {
  1465. Mesh mesh = null;
  1466. if (primShape.SculptEntry && primShape.SculptType != (byte)0 && primShape.SculptData.Length > 0)
  1467. {
  1468. SculptMesh smesh = CreateSculptMesh(primName, primShape, size, lod);
  1469. mesh = (Mesh)smesh;
  1470. CalcNormals(mesh);
  1471. }
  1472. else if ((primShape.ProfileCurve & (byte)ProfileShape.Square) == (byte)ProfileShape.Square)
  1473. {
  1474. if (primShape.PathCurve == (byte)LLObject.PathCurve.Line)
  1475. { // its a box
  1476. mesh = CreateBoxMesh(primName, primShape, size);
  1477. CalcNormals(mesh);
  1478. }
  1479. else if (primShape.PathCurve == (byte)LLObject.PathCurve.Circle)
  1480. { // tube
  1481. // do a cylinder for now
  1482. //mesh = CreateCylinderMesh(primName, primShape, size);
  1483. mesh = CreateCircularProfileMesh(primName, primShape, size);
  1484. CalcNormals(mesh);
  1485. }
  1486. }
  1487. else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
  1488. {
  1489. if (primShape.PathCurve == (byte)Extrusion.Straight)
  1490. {
  1491. mesh = CreateCylinderMesh(primName, primShape, size);
  1492. CalcNormals(mesh);
  1493. }
  1494. // look at LLObject.cs in libsecondlife for how to know the prim type
  1495. // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
  1496. else if (primShape.PathCurve == (byte) Extrusion.Curve1 && LLObject.UnpackPathScale(primShape.PathScaleY) <= 0.75f)
  1497. { // dahlia's favorite, a torus :)
  1498. mesh = CreateCircularProfileMesh(primName, primShape, size);
  1499. CalcNormals(mesh);
  1500. }
  1501. }
  1502. else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
  1503. {
  1504. if (primShape.PathCurve == (byte)Extrusion.Curve1 || primShape.PathCurve == (byte) Extrusion.Curve2)
  1505. {
  1506. mesh = CreateSphereMesh(primName, primShape, size);
  1507. CalcNormals(mesh);
  1508. }
  1509. }
  1510. else if ((primShape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
  1511. {
  1512. if (primShape.PathCurve == (byte)Extrusion.Straight)
  1513. {
  1514. mesh = CreatePrismMesh(primName, primShape, size);
  1515. CalcNormals(mesh);
  1516. }
  1517. else if (primShape.PathCurve == (byte) Extrusion.Curve1)
  1518. { // a ring - do a cylinder for now
  1519. //mesh = CreateCylinderMesh(primName, primShape, size);
  1520. mesh = CreateCircularProfileMesh(primName, primShape, size);
  1521. CalcNormals(mesh);
  1522. }
  1523. }
  1524. else // just do a box
  1525. {
  1526. mesh = CreateBoxMesh(primName, primShape, size);
  1527. CalcNormals(mesh);
  1528. }
  1529. //else
  1530. //{
  1531. // switch (primShape.ProfileShape)
  1532. // {
  1533. // case ProfileShape.Square:
  1534. // mesh = CreateBoxMesh(primName, primShape, size);
  1535. // CalcNormals(mesh);
  1536. // break;
  1537. // case ProfileShape.Circle:
  1538. // if (primShape.PathCurve == (byte)Extrusion.Straight)
  1539. // {
  1540. // mesh = CreateCylinderMesh(primName, primShape, size);
  1541. // CalcNormals(mesh);
  1542. // }
  1543. // // look at LLObject.cs in libsecondlife for how to know the prim type
  1544. // // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
  1545. // else if ((primShape.ProfileCurve & 0x07) == (byte)LLObject.ProfileCurve.Circle && LLObject.UnpackPathScale(primShape.PathScaleY) <= 0.75f)
  1546. // { // dahlia's favorite, a torus :)
  1547. // mesh = CreateCylinderMesh(primName, primShape, size);
  1548. // CalcNormals(mesh);
  1549. // }
  1550. // break;
  1551. // case ProfileShape.HalfCircle:
  1552. // if (primShape.PathCurve == (byte)Extrusion.Curve1)
  1553. // {
  1554. // mesh = CreateSphereMesh(primName, primShape, size);
  1555. // CalcNormals(mesh);
  1556. // }
  1557. // break;
  1558. // case ProfileShape.EquilateralTriangle:
  1559. // mesh = CreatePrismMesh(primName, primShape, size);
  1560. // CalcNormals(mesh);
  1561. // break;
  1562. // default:
  1563. // mesh = CreateBoxMesh(primName, primShape, size);
  1564. // CalcNormals(mesh);
  1565. // //Set default mesh to cube otherwise it'll return
  1566. // // null and crash on the 'setMesh' method in the physics plugins.
  1567. // //mesh = null;
  1568. // break;
  1569. // }
  1570. //}
  1571. return mesh;
  1572. }
  1573. }
  1574. }