par_shapes.h 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152
  1. // SHAPES :: https://github.com/prideout/par
  2. // Simple C library for creation and manipulation of triangle meshes.
  3. //
  4. // The API is divided into three sections:
  5. //
  6. // - Generators. Create parametric surfaces, platonic solids, etc.
  7. // - Queries. Ask a mesh for its axis-aligned bounding box, etc.
  8. // - Transforms. Rotate a mesh, merge it with another, add normals, etc.
  9. //
  10. // In addition to the comment block above each function declaration, the API
  11. // has informal documentation here:
  12. //
  13. // https://prideout.net/shapes
  14. //
  15. // For our purposes, a "mesh" is a list of points and a list of triangles; the
  16. // former is a flattened list of three-tuples (32-bit floats) and the latter is
  17. // also a flattened list of three-tuples (16-bit uints). Triangles are always
  18. // oriented such that their front face winds counter-clockwise.
  19. //
  20. // Optionally, meshes can contain 3D normals (one per vertex), and 2D texture
  21. // coordinates (one per vertex). That's it! If you need something fancier,
  22. // look elsewhere.
  23. //
  24. // Distributed under the MIT License, see bottom of file.
  25. #ifndef PAR_SHAPES_H
  26. #define PAR_SHAPES_H
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif
  30. #include <stdint.h>
  31. #if !defined(_MSC_VER)
  32. # include <stdbool.h>
  33. #else // MSVC
  34. # if _MSC_VER >= 1800
  35. # include <stdbool.h>
  36. # else // stdbool.h missing prior to MSVC++ 12.0 (VS2013)
  37. # define bool int
  38. # define true 1
  39. # define false 0
  40. # endif
  41. #endif
  42. #ifndef PAR_SHAPES_T
  43. #define PAR_SHAPES_T uint16_t
  44. #endif
  45. typedef struct par_shapes_mesh_s {
  46. float* points; // Flat list of 3-tuples (X Y Z X Y Z...)
  47. int npoints; // Number of points
  48. PAR_SHAPES_T* triangles; // Flat list of 3-tuples (I J K I J K...)
  49. int ntriangles; // Number of triangles
  50. float* normals; // Optional list of 3-tuples (X Y Z X Y Z...)
  51. float* tcoords; // Optional list of 2-tuples (U V U V U V...)
  52. } par_shapes_mesh;
  53. void par_shapes_free_mesh(par_shapes_mesh*);
  54. // Generators ------------------------------------------------------------------
  55. // Instance a cylinder that sits on the Z=0 plane using the given tessellation
  56. // levels across the UV domain. Think of "slices" like a number of pizza
  57. // slices, and "stacks" like a number of stacked rings. Height and radius are
  58. // both 1.0, but they can easily be changed with par_shapes_scale.
  59. par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks);
  60. // Cone is similar to cylinder but the radius diminishes to zero as Z increases.
  61. // Again, height and radius are 1.0, but can be changed with par_shapes_scale.
  62. par_shapes_mesh* par_shapes_create_cone(int slices, int stacks);
  63. // Create a disk of radius 1.0 with texture coordinates and normals by squashing
  64. // a cone flat on the Z=0 plane.
  65. par_shapes_mesh* par_shapes_create_parametric_disk(int slices, int stacks);
  66. // Create a donut that sits on the Z=0 plane with the specified inner radius.
  67. // The outer radius can be controlled with par_shapes_scale.
  68. par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius);
  69. // Create a sphere with texture coordinates and small triangles near the poles.
  70. par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks);
  71. // Approximate a sphere with a subdivided icosahedron, which produces a nice
  72. // distribution of triangles, but no texture coordinates. Each subdivision
  73. // level scales the number of triangles by four, so use a very low number.
  74. par_shapes_mesh* par_shapes_create_subdivided_sphere(int nsubdivisions);
  75. // More parametric surfaces.
  76. par_shapes_mesh* par_shapes_create_klein_bottle(int slices, int stacks);
  77. par_shapes_mesh* par_shapes_create_trefoil_knot(int slices, int stacks,
  78. float radius);
  79. par_shapes_mesh* par_shapes_create_hemisphere(int slices, int stacks);
  80. par_shapes_mesh* par_shapes_create_plane(int slices, int stacks);
  81. // Create a parametric surface from a callback function that consumes a 2D
  82. // point in [0,1] and produces a 3D point.
  83. typedef void (*par_shapes_fn)(float const*, float*, void*);
  84. par_shapes_mesh* par_shapes_create_parametric(par_shapes_fn, int slices,
  85. int stacks, void* userdata);
  86. // Generate points for a 20-sided polyhedron that fits in the unit sphere.
  87. // Texture coordinates and normals are not generated.
  88. par_shapes_mesh* par_shapes_create_icosahedron();
  89. // Generate points for a 12-sided polyhedron that fits in the unit sphere.
  90. // Again, texture coordinates and normals are not generated.
  91. par_shapes_mesh* par_shapes_create_dodecahedron();
  92. // More platonic solids.
  93. par_shapes_mesh* par_shapes_create_octahedron();
  94. par_shapes_mesh* par_shapes_create_tetrahedron();
  95. par_shapes_mesh* par_shapes_create_cube();
  96. // Generate an orientable disk shape in 3-space. Does not include normals or
  97. // texture coordinates.
  98. par_shapes_mesh* par_shapes_create_disk(float radius, int slices,
  99. float const* center, float const* normal);
  100. // Create an empty shape. Useful for building scenes with merge_and_free.
  101. par_shapes_mesh* par_shapes_create_empty();
  102. // Generate a rock shape that sits on the Y=0 plane, and sinks into it a bit.
  103. // This includes smooth normals but no texture coordinates. Each subdivision
  104. // level scales the number of triangles by four, so use a very low number.
  105. par_shapes_mesh* par_shapes_create_rock(int seed, int nsubdivisions);
  106. // Create trees or vegetation by executing a recursive turtle graphics program.
  107. // The program is a list of command-argument pairs. See the unit test for
  108. // an example. Texture coordinates and normals are not generated.
  109. par_shapes_mesh* par_shapes_create_lsystem(char const* program, int slices,
  110. int maxdepth);
  111. // Queries ---------------------------------------------------------------------
  112. // Dump out a text file conforming to the venerable OBJ format.
  113. void par_shapes_export(par_shapes_mesh const*, char const* objfile);
  114. // Take a pointer to 6 floats and set them to min xyz, max xyz.
  115. void par_shapes_compute_aabb(par_shapes_mesh const* mesh, float* aabb);
  116. // Make a deep copy of a mesh. To make a brand new copy, pass null to "target".
  117. // To avoid memory churn, pass an existing mesh to "target".
  118. par_shapes_mesh* par_shapes_clone(par_shapes_mesh const* mesh,
  119. par_shapes_mesh* target);
  120. // Transformations -------------------------------------------------------------
  121. void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src);
  122. void par_shapes_translate(par_shapes_mesh*, float x, float y, float z);
  123. void par_shapes_rotate(par_shapes_mesh*, float radians, float const* axis);
  124. void par_shapes_scale(par_shapes_mesh*, float x, float y, float z);
  125. void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src);
  126. // Reverse the winding of a run of faces. Useful when drawing the inside of
  127. // a Cornell Box. Pass 0 for nfaces to reverse every face in the mesh.
  128. void par_shapes_invert(par_shapes_mesh*, int startface, int nfaces);
  129. // Remove all triangles whose area is less than minarea.
  130. void par_shapes_remove_degenerate(par_shapes_mesh*, float minarea);
  131. // Dereference the entire index buffer and replace the point list.
  132. // This creates an inefficient structure, but is useful for drawing facets.
  133. // If create_indices is true, a trivial "0 1 2 3..." index buffer is generated.
  134. void par_shapes_unweld(par_shapes_mesh* mesh, bool create_indices);
  135. // Merge colocated verts, build a new index buffer, and return the
  136. // optimized mesh. Epsilon is the maximum distance to consider when
  137. // welding vertices. The mapping argument can be null, or a pointer to
  138. // npoints integers, which gets filled with the mapping from old vertex
  139. // indices to new indices.
  140. par_shapes_mesh* par_shapes_weld(par_shapes_mesh const*, float epsilon,
  141. PAR_SHAPES_T* mapping);
  142. // Compute smooth normals by averaging adjacent facet normals.
  143. void par_shapes_compute_normals(par_shapes_mesh* m);
  144. // Global Config ---------------------------------------------------------------
  145. void par_shapes_set_epsilon_welded_normals(float epsilon);
  146. void par_shapes_set_epsilon_degenerate_sphere(float epsilon);
  147. // Advanced --------------------------------------------------------------------
  148. void par_shapes__compute_welded_normals(par_shapes_mesh* m);
  149. void par_shapes__connect(par_shapes_mesh* scene, par_shapes_mesh* cylinder,
  150. int slices);
  151. #ifndef PAR_PI
  152. #define PAR_PI (3.14159265359)
  153. #define PAR_MIN(a, b) (a > b ? b : a)
  154. #define PAR_MAX(a, b) (a > b ? a : b)
  155. #define PAR_CLAMP(v, lo, hi) PAR_MAX(lo, PAR_MIN(hi, v))
  156. #define PAR_SWAP(T, A, B) { T tmp = B; B = A; A = tmp; }
  157. #define PAR_SQR(a) ((a) * (a))
  158. #endif
  159. #ifndef PAR_MALLOC
  160. #define PAR_MALLOC(T, N) ((T*) malloc(N * sizeof(T)))
  161. #define PAR_CALLOC(T, N) ((T*) calloc(N * sizeof(T), 1))
  162. #define PAR_REALLOC(T, BUF, N) ((T*) realloc(BUF, sizeof(T) * (N)))
  163. #define PAR_FREE(BUF) free(BUF)
  164. #endif
  165. #ifdef __cplusplus
  166. }
  167. #endif
  168. // -----------------------------------------------------------------------------
  169. // END PUBLIC API
  170. // -----------------------------------------------------------------------------
  171. #ifdef PAR_SHAPES_IMPLEMENTATION
  172. #include <stdlib.h>
  173. #include <stdio.h>
  174. #include <assert.h>
  175. #include <float.h>
  176. #include <string.h>
  177. #include <math.h>
  178. #include <errno.h>
  179. static float par_shapes__epsilon_welded_normals = 0.001;
  180. static float par_shapes__epsilon_degenerate_sphere = 0.0001;
  181. static void par_shapes__sphere(float const* uv, float* xyz, void*);
  182. static void par_shapes__hemisphere(float const* uv, float* xyz, void*);
  183. static void par_shapes__plane(float const* uv, float* xyz, void*);
  184. static void par_shapes__klein(float const* uv, float* xyz, void*);
  185. static void par_shapes__cylinder(float const* uv, float* xyz, void*);
  186. static void par_shapes__cone(float const* uv, float* xyz, void*);
  187. static void par_shapes__torus(float const* uv, float* xyz, void*);
  188. static void par_shapes__trefoil(float const* uv, float* xyz, void*);
  189. struct osn_context;
  190. static int par__simplex_noise(int64_t seed, struct osn_context** ctx);
  191. static void par__simplex_noise_free(struct osn_context* ctx);
  192. static double par__simplex_noise2(struct osn_context* ctx, double x, double y);
  193. static void par_shapes__copy3(float* result, float const* a)
  194. {
  195. result[0] = a[0];
  196. result[1] = a[1];
  197. result[2] = a[2];
  198. }
  199. static float par_shapes__dot3(float const* a, float const* b)
  200. {
  201. return b[0] * a[0] + b[1] * a[1] + b[2] * a[2];
  202. }
  203. static void par_shapes__transform3(float* p, float const* x, float const* y,
  204. float const* z)
  205. {
  206. float px = par_shapes__dot3(p, x);
  207. float py = par_shapes__dot3(p, y);
  208. float pz = par_shapes__dot3(p, z);
  209. p[0] = px;
  210. p[1] = py;
  211. p[2] = pz;
  212. }
  213. static void par_shapes__cross3(float* result, float const* a, float const* b)
  214. {
  215. float x = (a[1] * b[2]) - (a[2] * b[1]);
  216. float y = (a[2] * b[0]) - (a[0] * b[2]);
  217. float z = (a[0] * b[1]) - (a[1] * b[0]);
  218. result[0] = x;
  219. result[1] = y;
  220. result[2] = z;
  221. }
  222. static void par_shapes__mix3(float* d, float const* a, float const* b, float t)
  223. {
  224. float x = b[0] * t + a[0] * (1 - t);
  225. float y = b[1] * t + a[1] * (1 - t);
  226. float z = b[2] * t + a[2] * (1 - t);
  227. d[0] = x;
  228. d[1] = y;
  229. d[2] = z;
  230. }
  231. static void par_shapes__scale3(float* result, float a)
  232. {
  233. result[0] *= a;
  234. result[1] *= a;
  235. result[2] *= a;
  236. }
  237. static void par_shapes__normalize3(float* v)
  238. {
  239. float lsqr = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  240. if (lsqr > 0) {
  241. par_shapes__scale3(v, 1.0f / lsqr);
  242. }
  243. }
  244. static void par_shapes__subtract3(float* result, float const* a)
  245. {
  246. result[0] -= a[0];
  247. result[1] -= a[1];
  248. result[2] -= a[2];
  249. }
  250. static void par_shapes__add3(float* result, float const* a)
  251. {
  252. result[0] += a[0];
  253. result[1] += a[1];
  254. result[2] += a[2];
  255. }
  256. static float par_shapes__sqrdist3(float const* a, float const* b)
  257. {
  258. float dx = a[0] - b[0];
  259. float dy = a[1] - b[1];
  260. float dz = a[2] - b[2];
  261. return dx * dx + dy * dy + dz * dz;
  262. }
  263. void par_shapes__compute_welded_normals(par_shapes_mesh* m)
  264. {
  265. const float epsilon = par_shapes__epsilon_welded_normals;
  266. m->normals = PAR_MALLOC(float, m->npoints * 3);
  267. PAR_SHAPES_T* weldmap = PAR_MALLOC(PAR_SHAPES_T, m->npoints);
  268. par_shapes_mesh* welded = par_shapes_weld(m, epsilon, weldmap);
  269. par_shapes_compute_normals(welded);
  270. float* pdst = m->normals;
  271. for (int i = 0; i < m->npoints; i++, pdst += 3) {
  272. int d = weldmap[i];
  273. float const* pnormal = welded->normals + d * 3;
  274. pdst[0] = pnormal[0];
  275. pdst[1] = pnormal[1];
  276. pdst[2] = pnormal[2];
  277. }
  278. PAR_FREE(weldmap);
  279. par_shapes_free_mesh(welded);
  280. }
  281. par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks)
  282. {
  283. if (slices < 3 || stacks < 1) {
  284. return 0;
  285. }
  286. return par_shapes_create_parametric(par_shapes__cylinder, slices,
  287. stacks, 0);
  288. }
  289. par_shapes_mesh* par_shapes_create_cone(int slices, int stacks)
  290. {
  291. if (slices < 3 || stacks < 1) {
  292. return 0;
  293. }
  294. return par_shapes_create_parametric(par_shapes__cone, slices,
  295. stacks, 0);
  296. }
  297. par_shapes_mesh* par_shapes_create_parametric_disk(int slices, int stacks)
  298. {
  299. par_shapes_mesh* m = par_shapes_create_cone(slices, stacks);
  300. if (m) {
  301. par_shapes_scale(m, 1.0f, 1.0f, 0.0f);
  302. }
  303. return m;
  304. }
  305. par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks)
  306. {
  307. if (slices < 3 || stacks < 3) {
  308. return 0;
  309. }
  310. par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__sphere,
  311. slices, stacks, 0);
  312. par_shapes_remove_degenerate(m, par_shapes__epsilon_degenerate_sphere);
  313. return m;
  314. }
  315. par_shapes_mesh* par_shapes_create_hemisphere(int slices, int stacks)
  316. {
  317. if (slices < 3 || stacks < 3) {
  318. return 0;
  319. }
  320. par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__hemisphere,
  321. slices, stacks, 0);
  322. par_shapes_remove_degenerate(m, par_shapes__epsilon_degenerate_sphere);
  323. return m;
  324. }
  325. par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius)
  326. {
  327. if (slices < 3 || stacks < 3) {
  328. return 0;
  329. }
  330. assert(radius <= 1.0 && "Use smaller radius to avoid self-intersection.");
  331. assert(radius >= 0.1 && "Use larger radius to avoid self-intersection.");
  332. void* userdata = (void*) &radius;
  333. return par_shapes_create_parametric(par_shapes__torus, slices,
  334. stacks, userdata);
  335. }
  336. par_shapes_mesh* par_shapes_create_klein_bottle(int slices, int stacks)
  337. {
  338. if (slices < 3 || stacks < 3) {
  339. return 0;
  340. }
  341. par_shapes_mesh* mesh = par_shapes_create_parametric(
  342. par_shapes__klein, slices, stacks, 0);
  343. int face = 0;
  344. for (int stack = 0; stack < stacks; stack++) {
  345. for (int slice = 0; slice < slices; slice++, face += 2) {
  346. if (stack < 27 * stacks / 32) {
  347. par_shapes_invert(mesh, face, 2);
  348. }
  349. }
  350. }
  351. par_shapes__compute_welded_normals(mesh);
  352. return mesh;
  353. }
  354. par_shapes_mesh* par_shapes_create_trefoil_knot(int slices, int stacks,
  355. float radius)
  356. {
  357. if (slices < 3 || stacks < 3) {
  358. return 0;
  359. }
  360. assert(radius <= 3.0 && "Use smaller radius to avoid self-intersection.");
  361. assert(radius >= 0.5 && "Use larger radius to avoid self-intersection.");
  362. void* userdata = (void*) &radius;
  363. return par_shapes_create_parametric(par_shapes__trefoil, slices,
  364. stacks, userdata);
  365. }
  366. par_shapes_mesh* par_shapes_create_plane(int slices, int stacks)
  367. {
  368. if (slices < 1 || stacks < 1) {
  369. return 0;
  370. }
  371. return par_shapes_create_parametric(par_shapes__plane, slices,
  372. stacks, 0);
  373. }
  374. par_shapes_mesh* par_shapes_create_parametric(par_shapes_fn fn,
  375. int slices, int stacks, void* userdata)
  376. {
  377. par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
  378. // Generate verts.
  379. mesh->npoints = (slices + 1) * (stacks + 1);
  380. mesh->points = PAR_CALLOC(float, 3 * mesh->npoints);
  381. float uv[2];
  382. float xyz[3];
  383. float* points = mesh->points;
  384. for (int stack = 0; stack < stacks + 1; stack++) {
  385. uv[0] = (float) stack / stacks;
  386. for (int slice = 0; slice < slices + 1; slice++) {
  387. uv[1] = (float) slice / slices;
  388. fn(uv, xyz, userdata);
  389. *points++ = xyz[0];
  390. *points++ = xyz[1];
  391. *points++ = xyz[2];
  392. }
  393. }
  394. // Generate texture coordinates.
  395. mesh->tcoords = PAR_CALLOC(float, 2 * mesh->npoints);
  396. float* uvs = mesh->tcoords;
  397. for (int stack = 0; stack < stacks + 1; stack++) {
  398. uv[0] = (float) stack / stacks;
  399. for (int slice = 0; slice < slices + 1; slice++) {
  400. uv[1] = (float) slice / slices;
  401. *uvs++ = uv[0];
  402. *uvs++ = uv[1];
  403. }
  404. }
  405. // Generate faces.
  406. mesh->ntriangles = 2 * slices * stacks;
  407. mesh->triangles = PAR_CALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
  408. int v = 0;
  409. PAR_SHAPES_T* face = mesh->triangles;
  410. for (int stack = 0; stack < stacks; stack++) {
  411. for (int slice = 0; slice < slices; slice++) {
  412. int next = slice + 1;
  413. *face++ = v + slice + slices + 1;
  414. *face++ = v + next;
  415. *face++ = v + slice;
  416. *face++ = v + slice + slices + 1;
  417. *face++ = v + next + slices + 1;
  418. *face++ = v + next;
  419. }
  420. v += slices + 1;
  421. }
  422. par_shapes__compute_welded_normals(mesh);
  423. return mesh;
  424. }
  425. void par_shapes_free_mesh(par_shapes_mesh* mesh)
  426. {
  427. PAR_FREE(mesh->points);
  428. PAR_FREE(mesh->triangles);
  429. PAR_FREE(mesh->normals);
  430. PAR_FREE(mesh->tcoords);
  431. PAR_FREE(mesh);
  432. }
  433. void par_shapes_export(par_shapes_mesh const* mesh, char const* filename)
  434. {
  435. FILE* objfile = fopen(filename, "wt");
  436. float const* points = mesh->points;
  437. float const* tcoords = mesh->tcoords;
  438. float const* norms = mesh->normals;
  439. PAR_SHAPES_T const* indices = mesh->triangles;
  440. if (tcoords && norms) {
  441. for (int nvert = 0; nvert < mesh->npoints; nvert++) {
  442. fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
  443. fprintf(objfile, "vt %f %f\n", tcoords[0], tcoords[1]);
  444. fprintf(objfile, "vn %f %f %f\n", norms[0], norms[1], norms[2]);
  445. points += 3;
  446. norms += 3;
  447. tcoords += 2;
  448. }
  449. for (int nface = 0; nface < mesh->ntriangles; nface++) {
  450. int a = 1 + *indices++;
  451. int b = 1 + *indices++;
  452. int c = 1 + *indices++;
  453. fprintf(objfile, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
  454. a, a, a, b, b, b, c, c, c);
  455. }
  456. } else if (norms) {
  457. for (int nvert = 0; nvert < mesh->npoints; nvert++) {
  458. fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
  459. fprintf(objfile, "vn %f %f %f\n", norms[0], norms[1], norms[2]);
  460. points += 3;
  461. norms += 3;
  462. }
  463. for (int nface = 0; nface < mesh->ntriangles; nface++) {
  464. int a = 1 + *indices++;
  465. int b = 1 + *indices++;
  466. int c = 1 + *indices++;
  467. fprintf(objfile, "f %d//%d %d//%d %d//%d\n", a, a, b, b, c, c);
  468. }
  469. } else if (tcoords) {
  470. for (int nvert = 0; nvert < mesh->npoints; nvert++) {
  471. fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
  472. fprintf(objfile, "vt %f %f\n", tcoords[0], tcoords[1]);
  473. points += 3;
  474. tcoords += 2;
  475. }
  476. for (int nface = 0; nface < mesh->ntriangles; nface++) {
  477. int a = 1 + *indices++;
  478. int b = 1 + *indices++;
  479. int c = 1 + *indices++;
  480. fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
  481. }
  482. } else {
  483. for (int nvert = 0; nvert < mesh->npoints; nvert++) {
  484. fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
  485. points += 3;
  486. }
  487. for (int nface = 0; nface < mesh->ntriangles; nface++) {
  488. int a = 1 + *indices++;
  489. int b = 1 + *indices++;
  490. int c = 1 + *indices++;
  491. fprintf(objfile, "f %d %d %d\n", a, b, c);
  492. }
  493. }
  494. fclose(objfile);
  495. }
  496. static void par_shapes__sphere(float const* uv, float* xyz, void* userdata)
  497. {
  498. float phi = uv[0] * PAR_PI;
  499. float theta = uv[1] * 2 * PAR_PI;
  500. xyz[0] = cosf(theta) * sinf(phi);
  501. xyz[1] = sinf(theta) * sinf(phi);
  502. xyz[2] = cosf(phi);
  503. }
  504. static void par_shapes__hemisphere(float const* uv, float* xyz, void* userdata)
  505. {
  506. float phi = uv[0] * PAR_PI;
  507. float theta = uv[1] * PAR_PI;
  508. xyz[0] = cosf(theta) * sinf(phi);
  509. xyz[1] = sinf(theta) * sinf(phi);
  510. xyz[2] = cosf(phi);
  511. }
  512. static void par_shapes__plane(float const* uv, float* xyz, void* userdata)
  513. {
  514. xyz[0] = uv[0];
  515. xyz[1] = uv[1];
  516. xyz[2] = 0;
  517. }
  518. static void par_shapes__klein(float const* uv, float* xyz, void* userdata)
  519. {
  520. float u = uv[0] * PAR_PI;
  521. float v = uv[1] * 2 * PAR_PI;
  522. u = u * 2;
  523. if (u < PAR_PI) {
  524. xyz[0] = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) *
  525. cosf(u) * cosf(v);
  526. xyz[2] = -8 * sinf(u) - 2 * (1 - cosf(u) / 2) * sinf(u) * cosf(v);
  527. } else {
  528. xyz[0] = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) *
  529. cosf(v + PAR_PI);
  530. xyz[2] = -8 * sinf(u);
  531. }
  532. xyz[1] = -2 * (1 - cosf(u) / 2) * sinf(v);
  533. }
  534. static void par_shapes__cylinder(float const* uv, float* xyz, void* userdata)
  535. {
  536. float theta = uv[1] * 2 * PAR_PI;
  537. xyz[0] = sinf(theta);
  538. xyz[1] = cosf(theta);
  539. xyz[2] = uv[0];
  540. }
  541. static void par_shapes__cone(float const* uv, float* xyz, void* userdata)
  542. {
  543. float r = 1.0f - uv[0];
  544. float theta = uv[1] * 2 * PAR_PI;
  545. xyz[0] = r * sinf(theta);
  546. xyz[1] = r * cosf(theta);
  547. xyz[2] = uv[0];
  548. }
  549. static void par_shapes__torus(float const* uv, float* xyz, void* userdata)
  550. {
  551. float major = 1;
  552. float minor = *((float*) userdata);
  553. float theta = uv[0] * 2 * PAR_PI;
  554. float phi = uv[1] * 2 * PAR_PI;
  555. float beta = major + minor * cosf(phi);
  556. xyz[0] = cosf(theta) * beta;
  557. xyz[1] = sinf(theta) * beta;
  558. xyz[2] = sinf(phi) * minor;
  559. }
  560. static void par_shapes__trefoil(float const* uv, float* xyz, void* userdata)
  561. {
  562. float minor = *((float*) userdata);
  563. const float a = 0.5f;
  564. const float b = 0.3f;
  565. const float c = 0.5f;
  566. const float d = minor * 0.1f;
  567. const float u = (1 - uv[0]) * 4 * PAR_PI;
  568. const float v = uv[1] * 2 * PAR_PI;
  569. const float r = a + b * cos(1.5f * u);
  570. const float x = r * cos(u);
  571. const float y = r * sin(u);
  572. const float z = c * sin(1.5f * u);
  573. float q[3];
  574. q[0] =
  575. -1.5f * b * sin(1.5f * u) * cos(u) - (a + b * cos(1.5f * u)) * sin(u);
  576. q[1] =
  577. -1.5f * b * sin(1.5f * u) * sin(u) + (a + b * cos(1.5f * u)) * cos(u);
  578. q[2] = 1.5f * c * cos(1.5f * u);
  579. par_shapes__normalize3(q);
  580. float qvn[3] = {q[1], -q[0], 0};
  581. par_shapes__normalize3(qvn);
  582. float ww[3];
  583. par_shapes__cross3(ww, q, qvn);
  584. xyz[0] = x + d * (qvn[0] * cos(v) + ww[0] * sin(v));
  585. xyz[1] = y + d * (qvn[1] * cos(v) + ww[1] * sin(v));
  586. xyz[2] = z + d * ww[2] * sin(v);
  587. }
  588. void par_shapes_set_epsilon_welded_normals(float epsilon) {
  589. par_shapes__epsilon_welded_normals = epsilon;
  590. }
  591. void par_shapes_set_epsilon_degenerate_sphere(float epsilon) {
  592. par_shapes__epsilon_degenerate_sphere = epsilon;
  593. }
  594. void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src)
  595. {
  596. PAR_SHAPES_T offset = dst->npoints;
  597. int npoints = dst->npoints + src->npoints;
  598. int vecsize = sizeof(float) * 3;
  599. dst->points = PAR_REALLOC(float, dst->points, 3 * npoints);
  600. memcpy(dst->points + 3 * dst->npoints, src->points, vecsize * src->npoints);
  601. dst->npoints = npoints;
  602. if (src->normals || dst->normals) {
  603. dst->normals = PAR_REALLOC(float, dst->normals, 3 * npoints);
  604. if (src->normals) {
  605. memcpy(dst->normals + 3 * offset, src->normals,
  606. vecsize * src->npoints);
  607. }
  608. }
  609. if (src->tcoords || dst->tcoords) {
  610. int uvsize = sizeof(float) * 2;
  611. dst->tcoords = PAR_REALLOC(float, dst->tcoords, 2 * npoints);
  612. if (src->tcoords) {
  613. memcpy(dst->tcoords + 2 * offset, src->tcoords,
  614. uvsize * src->npoints);
  615. }
  616. }
  617. int ntriangles = dst->ntriangles + src->ntriangles;
  618. dst->triangles = PAR_REALLOC(PAR_SHAPES_T, dst->triangles, 3 * ntriangles);
  619. PAR_SHAPES_T* ptriangles = dst->triangles + 3 * dst->ntriangles;
  620. PAR_SHAPES_T const* striangles = src->triangles;
  621. for (int i = 0; i < src->ntriangles; i++) {
  622. *ptriangles++ = offset + *striangles++;
  623. *ptriangles++ = offset + *striangles++;
  624. *ptriangles++ = offset + *striangles++;
  625. }
  626. dst->ntriangles = ntriangles;
  627. }
  628. par_shapes_mesh* par_shapes_create_disk(float radius, int slices,
  629. float const* center, float const* normal)
  630. {
  631. par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
  632. mesh->npoints = slices + 1;
  633. mesh->points = PAR_MALLOC(float, 3 * mesh->npoints);
  634. float* points = mesh->points;
  635. *points++ = 0;
  636. *points++ = 0;
  637. *points++ = 0;
  638. for (int i = 0; i < slices; i++) {
  639. float theta = i * PAR_PI * 2 / slices;
  640. *points++ = radius * cos(theta);
  641. *points++ = radius * sin(theta);
  642. *points++ = 0;
  643. }
  644. float nnormal[3] = {normal[0], normal[1], normal[2]};
  645. par_shapes__normalize3(nnormal);
  646. mesh->normals = PAR_MALLOC(float, 3 * mesh->npoints);
  647. float* norms = mesh->normals;
  648. for (int i = 0; i < mesh->npoints; i++) {
  649. *norms++ = nnormal[0];
  650. *norms++ = nnormal[1];
  651. *norms++ = nnormal[2];
  652. }
  653. mesh->ntriangles = slices;
  654. mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
  655. PAR_SHAPES_T* triangles = mesh->triangles;
  656. for (int i = 0; i < slices; i++) {
  657. *triangles++ = 0;
  658. *triangles++ = 1 + i;
  659. *triangles++ = 1 + (i + 1) % slices;
  660. }
  661. float k[3] = {0, 0, -1};
  662. float axis[3];
  663. par_shapes__cross3(axis, nnormal, k);
  664. par_shapes__normalize3(axis);
  665. par_shapes_rotate(mesh, acos(nnormal[2]), axis);
  666. par_shapes_translate(mesh, center[0], center[1], center[2]);
  667. return mesh;
  668. }
  669. par_shapes_mesh* par_shapes_create_empty()
  670. {
  671. return PAR_CALLOC(par_shapes_mesh, 1);
  672. }
  673. void par_shapes_translate(par_shapes_mesh* m, float x, float y, float z)
  674. {
  675. float* points = m->points;
  676. for (int i = 0; i < m->npoints; i++) {
  677. *points++ += x;
  678. *points++ += y;
  679. *points++ += z;
  680. }
  681. }
  682. void par_shapes_rotate(par_shapes_mesh* mesh, float radians, float const* axis)
  683. {
  684. float s = sinf(radians);
  685. float c = cosf(radians);
  686. float x = axis[0];
  687. float y = axis[1];
  688. float z = axis[2];
  689. float xy = x * y;
  690. float yz = y * z;
  691. float zx = z * x;
  692. float oneMinusC = 1.0f - c;
  693. float col0[3] = {
  694. (((x * x) * oneMinusC) + c),
  695. ((xy * oneMinusC) + (z * s)), ((zx * oneMinusC) - (y * s))
  696. };
  697. float col1[3] = {
  698. ((xy * oneMinusC) - (z * s)),
  699. (((y * y) * oneMinusC) + c), ((yz * oneMinusC) + (x * s))
  700. };
  701. float col2[3] = {
  702. ((zx * oneMinusC) + (y * s)),
  703. ((yz * oneMinusC) - (x * s)), (((z * z) * oneMinusC) + c)
  704. };
  705. float* p = mesh->points;
  706. for (int i = 0; i < mesh->npoints; i++, p += 3) {
  707. float x = col0[0] * p[0] + col1[0] * p[1] + col2[0] * p[2];
  708. float y = col0[1] * p[0] + col1[1] * p[1] + col2[1] * p[2];
  709. float z = col0[2] * p[0] + col1[2] * p[1] + col2[2] * p[2];
  710. p[0] = x;
  711. p[1] = y;
  712. p[2] = z;
  713. }
  714. float* n = mesh->normals;
  715. if (n) {
  716. for (int i = 0; i < mesh->npoints; i++, n += 3) {
  717. float x = col0[0] * n[0] + col1[0] * n[1] + col2[0] * n[2];
  718. float y = col0[1] * n[0] + col1[1] * n[1] + col2[1] * n[2];
  719. float z = col0[2] * n[0] + col1[2] * n[1] + col2[2] * n[2];
  720. n[0] = x;
  721. n[1] = y;
  722. n[2] = z;
  723. }
  724. }
  725. }
  726. void par_shapes_scale(par_shapes_mesh* m, float x, float y, float z)
  727. {
  728. float* points = m->points;
  729. for (int i = 0; i < m->npoints; i++) {
  730. *points++ *= x;
  731. *points++ *= y;
  732. *points++ *= z;
  733. }
  734. float* n = m->normals;
  735. if (n && !(x == y && y == z)) {
  736. bool x_zero = x == 0;
  737. bool y_zero = y == 0;
  738. bool z_zero = z == 0;
  739. if (!x_zero && !y_zero && !z_zero) {
  740. x = 1.0f / x;
  741. y = 1.0f / y;
  742. z = 1.0f / z;
  743. } else {
  744. x = x_zero && !y_zero && !z_zero;
  745. y = y_zero && !x_zero && !z_zero;
  746. z = z_zero && !x_zero && !y_zero;
  747. }
  748. for (int i = 0; i < m->npoints; i++, n += 3) {
  749. n[0] *= x;
  750. n[1] *= y;
  751. n[2] *= z;
  752. par_shapes__normalize3(n);
  753. }
  754. }
  755. }
  756. void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src)
  757. {
  758. par_shapes_merge(dst, src);
  759. par_shapes_free_mesh(src);
  760. }
  761. void par_shapes_compute_aabb(par_shapes_mesh const* m, float* aabb)
  762. {
  763. float* points = m->points;
  764. aabb[0] = aabb[3] = points[0];
  765. aabb[1] = aabb[4] = points[1];
  766. aabb[2] = aabb[5] = points[2];
  767. points += 3;
  768. for (int i = 1; i < m->npoints; i++, points += 3) {
  769. aabb[0] = PAR_MIN(points[0], aabb[0]);
  770. aabb[1] = PAR_MIN(points[1], aabb[1]);
  771. aabb[2] = PAR_MIN(points[2], aabb[2]);
  772. aabb[3] = PAR_MAX(points[0], aabb[3]);
  773. aabb[4] = PAR_MAX(points[1], aabb[4]);
  774. aabb[5] = PAR_MAX(points[2], aabb[5]);
  775. }
  776. }
  777. void par_shapes_invert(par_shapes_mesh* m, int face, int nfaces)
  778. {
  779. nfaces = nfaces ? nfaces : m->ntriangles;
  780. PAR_SHAPES_T* tri = m->triangles + face * 3;
  781. for (int i = 0; i < nfaces; i++) {
  782. PAR_SWAP(PAR_SHAPES_T, tri[0], tri[2]);
  783. tri += 3;
  784. }
  785. }
  786. par_shapes_mesh* par_shapes_create_icosahedron()
  787. {
  788. static float verts[] = {
  789. 0.000, 0.000, 1.000,
  790. 0.894, 0.000, 0.447,
  791. 0.276, 0.851, 0.447,
  792. -0.724, 0.526, 0.447,
  793. -0.724, -0.526, 0.447,
  794. 0.276, -0.851, 0.447,
  795. 0.724, 0.526, -0.447,
  796. -0.276, 0.851, -0.447,
  797. -0.894, 0.000, -0.447,
  798. -0.276, -0.851, -0.447,
  799. 0.724, -0.526, -0.447,
  800. 0.000, 0.000, -1.000
  801. };
  802. static PAR_SHAPES_T faces[] = {
  803. 0,1,2,
  804. 0,2,3,
  805. 0,3,4,
  806. 0,4,5,
  807. 0,5,1,
  808. 7,6,11,
  809. 8,7,11,
  810. 9,8,11,
  811. 10,9,11,
  812. 6,10,11,
  813. 6,2,1,
  814. 7,3,2,
  815. 8,4,3,
  816. 9,5,4,
  817. 10,1,5,
  818. 6,7,2,
  819. 7,8,3,
  820. 8,9,4,
  821. 9,10,5,
  822. 10,6,1
  823. };
  824. par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
  825. mesh->npoints = sizeof(verts) / sizeof(verts[0]) / 3;
  826. mesh->points = PAR_MALLOC(float, sizeof(verts) / 4);
  827. memcpy(mesh->points, verts, sizeof(verts));
  828. mesh->ntriangles = sizeof(faces) / sizeof(faces[0]) / 3;
  829. mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, sizeof(faces) / 2);
  830. memcpy(mesh->triangles, faces, sizeof(faces));
  831. return mesh;
  832. }
  833. par_shapes_mesh* par_shapes_create_dodecahedron()
  834. {
  835. static float verts[20 * 3] = {
  836. 0.607, 0.000, 0.795,
  837. 0.188, 0.577, 0.795,
  838. -0.491, 0.357, 0.795,
  839. -0.491, -0.357, 0.795,
  840. 0.188, -0.577, 0.795,
  841. 0.982, 0.000, 0.188,
  842. 0.304, 0.934, 0.188,
  843. -0.795, 0.577, 0.188,
  844. -0.795, -0.577, 0.188,
  845. 0.304, -0.934, 0.188,
  846. 0.795, 0.577, -0.188,
  847. -0.304, 0.934, -0.188,
  848. -0.982, 0.000, -0.188,
  849. -0.304, -0.934, -0.188,
  850. 0.795, -0.577, -0.188,
  851. 0.491, 0.357, -0.795,
  852. -0.188, 0.577, -0.795,
  853. -0.607, 0.000, -0.795,
  854. -0.188, -0.577, -0.795,
  855. 0.491, -0.357, -0.795,
  856. };
  857. static PAR_SHAPES_T pentagons[12 * 5] = {
  858. 0,1,2,3,4,
  859. 5,10,6,1,0,
  860. 6,11,7,2,1,
  861. 7,12,8,3,2,
  862. 8,13,9,4,3,
  863. 9,14,5,0,4,
  864. 15,16,11,6,10,
  865. 16,17,12,7,11,
  866. 17,18,13,8,12,
  867. 18,19,14,9,13,
  868. 19,15,10,5,14,
  869. 19,18,17,16,15
  870. };
  871. int npentagons = sizeof(pentagons) / sizeof(pentagons[0]) / 5;
  872. par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
  873. int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
  874. mesh->npoints = ncorners;
  875. mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
  876. memcpy(mesh->points, verts, sizeof(verts));
  877. PAR_SHAPES_T const* pentagon = pentagons;
  878. mesh->ntriangles = npentagons * 3;
  879. mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
  880. PAR_SHAPES_T* tris = mesh->triangles;
  881. for (int p = 0; p < npentagons; p++, pentagon += 5) {
  882. *tris++ = pentagon[0];
  883. *tris++ = pentagon[1];
  884. *tris++ = pentagon[2];
  885. *tris++ = pentagon[0];
  886. *tris++ = pentagon[2];
  887. *tris++ = pentagon[3];
  888. *tris++ = pentagon[0];
  889. *tris++ = pentagon[3];
  890. *tris++ = pentagon[4];
  891. }
  892. return mesh;
  893. }
  894. par_shapes_mesh* par_shapes_create_octahedron()
  895. {
  896. static float verts[6 * 3] = {
  897. 0.000, 0.000, 1.000,
  898. 1.000, 0.000, 0.000,
  899. 0.000, 1.000, 0.000,
  900. -1.000, 0.000, 0.000,
  901. 0.000, -1.000, 0.000,
  902. 0.000, 0.000, -1.000
  903. };
  904. static PAR_SHAPES_T triangles[8 * 3] = {
  905. 0,1,2,
  906. 0,2,3,
  907. 0,3,4,
  908. 0,4,1,
  909. 2,1,5,
  910. 3,2,5,
  911. 4,3,5,
  912. 1,4,5,
  913. };
  914. int ntris = sizeof(triangles) / sizeof(triangles[0]) / 3;
  915. par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
  916. int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
  917. mesh->npoints = ncorners;
  918. mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
  919. memcpy(mesh->points, verts, sizeof(verts));
  920. PAR_SHAPES_T const* triangle = triangles;
  921. mesh->ntriangles = ntris;
  922. mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
  923. PAR_SHAPES_T* tris = mesh->triangles;
  924. for (int p = 0; p < ntris; p++) {
  925. *tris++ = *triangle++;
  926. *tris++ = *triangle++;
  927. *tris++ = *triangle++;
  928. }
  929. return mesh;
  930. }
  931. par_shapes_mesh* par_shapes_create_tetrahedron()
  932. {
  933. static float verts[4 * 3] = {
  934. 0.000, 1.333, 0,
  935. 0.943, 0, 0,
  936. -0.471, 0, 0.816,
  937. -0.471, 0, -0.816,
  938. };
  939. static PAR_SHAPES_T triangles[4 * 3] = {
  940. 2,1,0,
  941. 3,2,0,
  942. 1,3,0,
  943. 1,2,3,
  944. };
  945. int ntris = sizeof(triangles) / sizeof(triangles[0]) / 3;
  946. par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
  947. int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
  948. mesh->npoints = ncorners;
  949. mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
  950. memcpy(mesh->points, verts, sizeof(verts));
  951. PAR_SHAPES_T const* triangle = triangles;
  952. mesh->ntriangles = ntris;
  953. mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
  954. PAR_SHAPES_T* tris = mesh->triangles;
  955. for (int p = 0; p < ntris; p++) {
  956. *tris++ = *triangle++;
  957. *tris++ = *triangle++;
  958. *tris++ = *triangle++;
  959. }
  960. return mesh;
  961. }
  962. par_shapes_mesh* par_shapes_create_cube()
  963. {
  964. static float verts[8 * 3] = {
  965. 0, 0, 0, // 0
  966. 0, 1, 0, // 1
  967. 1, 1, 0, // 2
  968. 1, 0, 0, // 3
  969. 0, 0, 1, // 4
  970. 0, 1, 1, // 5
  971. 1, 1, 1, // 6
  972. 1, 0, 1, // 7
  973. };
  974. static PAR_SHAPES_T quads[6 * 4] = {
  975. 7,6,5,4, // front
  976. 0,1,2,3, // back
  977. 6,7,3,2, // right
  978. 5,6,2,1, // top
  979. 4,5,1,0, // left
  980. 7,4,0,3, // bottom
  981. };
  982. int nquads = sizeof(quads) / sizeof(quads[0]) / 4;
  983. par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
  984. int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
  985. mesh->npoints = ncorners;
  986. mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
  987. memcpy(mesh->points, verts, sizeof(verts));
  988. PAR_SHAPES_T const* quad = quads;
  989. mesh->ntriangles = nquads * 2;
  990. mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
  991. PAR_SHAPES_T* tris = mesh->triangles;
  992. for (int p = 0; p < nquads; p++, quad += 4) {
  993. *tris++ = quad[0];
  994. *tris++ = quad[1];
  995. *tris++ = quad[2];
  996. *tris++ = quad[2];
  997. *tris++ = quad[3];
  998. *tris++ = quad[0];
  999. }
  1000. return mesh;
  1001. }
  1002. typedef struct {
  1003. char* cmd;
  1004. char* arg;
  1005. } par_shapes__command;
  1006. typedef struct {
  1007. char const* name;
  1008. int weight;
  1009. int ncommands;
  1010. par_shapes__command* commands;
  1011. } par_shapes__rule;
  1012. typedef struct {
  1013. int pc;
  1014. float position[3];
  1015. float scale[3];
  1016. par_shapes_mesh* orientation;
  1017. par_shapes__rule* rule;
  1018. } par_shapes__stackframe;
  1019. static par_shapes__rule* par_shapes__pick_rule(const char* name,
  1020. par_shapes__rule* rules, int nrules)
  1021. {
  1022. par_shapes__rule* rule = 0;
  1023. int total = 0;
  1024. for (int i = 0; i < nrules; i++) {
  1025. rule = rules + i;
  1026. if (!strcmp(rule->name, name)) {
  1027. total += rule->weight;
  1028. }
  1029. }
  1030. float r = (float) rand() / RAND_MAX;
  1031. float t = 0;
  1032. for (int i = 0; i < nrules; i++) {
  1033. rule = rules + i;
  1034. if (!strcmp(rule->name, name)) {
  1035. t += (float) rule->weight / total;
  1036. if (t >= r) {
  1037. return rule;
  1038. }
  1039. }
  1040. }
  1041. return rule;
  1042. }
  1043. static par_shapes_mesh* par_shapes__create_turtle()
  1044. {
  1045. const float xaxis[] = {1, 0, 0};
  1046. const float yaxis[] = {0, 1, 0};
  1047. const float zaxis[] = {0, 0, 1};
  1048. par_shapes_mesh* turtle = PAR_CALLOC(par_shapes_mesh, 1);
  1049. turtle->npoints = 3;
  1050. turtle->points = PAR_CALLOC(float, turtle->npoints * 3);
  1051. par_shapes__copy3(turtle->points + 0, xaxis);
  1052. par_shapes__copy3(turtle->points + 3, yaxis);
  1053. par_shapes__copy3(turtle->points + 6, zaxis);
  1054. return turtle;
  1055. }
  1056. static par_shapes_mesh* par_shapes__apply_turtle(par_shapes_mesh* mesh,
  1057. par_shapes_mesh* turtle, float const* pos, float const* scale)
  1058. {
  1059. par_shapes_mesh* m = par_shapes_clone(mesh, 0);
  1060. for (int p = 0; p < m->npoints; p++) {
  1061. float* pt = m->points + p * 3;
  1062. pt[0] *= scale[0];
  1063. pt[1] *= scale[1];
  1064. pt[2] *= scale[2];
  1065. par_shapes__transform3(pt,
  1066. turtle->points + 0, turtle->points + 3, turtle->points + 6);
  1067. pt[0] += pos[0];
  1068. pt[1] += pos[1];
  1069. pt[2] += pos[2];
  1070. }
  1071. return m;
  1072. }
  1073. void par_shapes__connect(par_shapes_mesh* scene, par_shapes_mesh* cylinder,
  1074. int slices)
  1075. {
  1076. int stacks = 1;
  1077. int npoints = (slices + 1) * (stacks + 1);
  1078. assert(scene->npoints >= npoints && "Cannot connect to empty scene.");
  1079. // Create the new point list.
  1080. npoints = scene->npoints + (slices + 1);
  1081. float* points = PAR_MALLOC(float, npoints * 3);
  1082. memcpy(points, scene->points, sizeof(float) * scene->npoints * 3);
  1083. float* newpts = points + scene->npoints * 3;
  1084. memcpy(newpts, cylinder->points + (slices + 1) * 3,
  1085. sizeof(float) * (slices + 1) * 3);
  1086. PAR_FREE(scene->points);
  1087. scene->points = points;
  1088. // Create the new triangle list.
  1089. int ntriangles = scene->ntriangles + 2 * slices * stacks;
  1090. PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, ntriangles * 3);
  1091. memcpy(triangles, scene->triangles,
  1092. sizeof(PAR_SHAPES_T) * scene->ntriangles * 3);
  1093. int v = scene->npoints - (slices + 1);
  1094. PAR_SHAPES_T* face = triangles + scene->ntriangles * 3;
  1095. for (int stack = 0; stack < stacks; stack++) {
  1096. for (int slice = 0; slice < slices; slice++) {
  1097. int next = slice + 1;
  1098. *face++ = v + slice + slices + 1;
  1099. *face++ = v + next;
  1100. *face++ = v + slice;
  1101. *face++ = v + slice + slices + 1;
  1102. *face++ = v + next + slices + 1;
  1103. *face++ = v + next;
  1104. }
  1105. v += slices + 1;
  1106. }
  1107. PAR_FREE(scene->triangles);
  1108. scene->triangles = triangles;
  1109. scene->npoints = npoints;
  1110. scene->ntriangles = ntriangles;
  1111. }
  1112. par_shapes_mesh* par_shapes_create_lsystem(char const* text, int slices,
  1113. int maxdepth)
  1114. {
  1115. char* program;
  1116. program = PAR_MALLOC(char, strlen(text) + 1);
  1117. // The first pass counts the number of rules and commands.
  1118. strcpy(program, text);
  1119. char *cmd = strtok(program, " ");
  1120. int nrules = 1;
  1121. int ncommands = 0;
  1122. while (cmd) {
  1123. char *arg = strtok(0, " ");
  1124. if (!arg) {
  1125. puts("lsystem error: unexpected end of program.");
  1126. break;
  1127. }
  1128. if (!strcmp(cmd, "rule")) {
  1129. nrules++;
  1130. } else {
  1131. ncommands++;
  1132. }
  1133. cmd = strtok(0, " ");
  1134. }
  1135. // Allocate space.
  1136. par_shapes__rule* rules = PAR_MALLOC(par_shapes__rule, nrules);
  1137. par_shapes__command* commands = PAR_MALLOC(par_shapes__command, ncommands);
  1138. // Initialize the entry rule.
  1139. par_shapes__rule* current_rule = &rules[0];
  1140. par_shapes__command* current_command = &commands[0];
  1141. current_rule->name = "entry";
  1142. current_rule->weight = 1;
  1143. current_rule->ncommands = 0;
  1144. current_rule->commands = current_command;
  1145. // The second pass fills in the structures.
  1146. strcpy(program, text);
  1147. cmd = strtok(program, " ");
  1148. while (cmd) {
  1149. char *arg = strtok(0, " ");
  1150. if (!strcmp(cmd, "rule")) {
  1151. current_rule++;
  1152. // Split the argument into a rule name and weight.
  1153. char* dot = strchr(arg, '.');
  1154. if (dot) {
  1155. current_rule->weight = atoi(dot + 1);
  1156. *dot = 0;
  1157. } else {
  1158. current_rule->weight = 1;
  1159. }
  1160. current_rule->name = arg;
  1161. current_rule->ncommands = 0;
  1162. current_rule->commands = current_command;
  1163. } else {
  1164. current_rule->ncommands++;
  1165. current_command->cmd = cmd;
  1166. current_command->arg = arg;
  1167. current_command++;
  1168. }
  1169. cmd = strtok(0, " ");
  1170. }
  1171. // For testing purposes, dump out the parsed program.
  1172. #ifdef TEST_PARSE
  1173. for (int i = 0; i < nrules; i++) {
  1174. par_shapes__rule rule = rules[i];
  1175. printf("rule %s.%d\n", rule.name, rule.weight);
  1176. for (int c = 0; c < rule.ncommands; c++) {
  1177. par_shapes__command cmd = rule.commands[c];
  1178. printf("\t%s %s\n", cmd.cmd, cmd.arg);
  1179. }
  1180. }
  1181. #endif
  1182. // Instantiate the aggregated shape and the template shapes.
  1183. par_shapes_mesh* scene = PAR_CALLOC(par_shapes_mesh, 1);
  1184. par_shapes_mesh* tube = par_shapes_create_cylinder(slices, 1);
  1185. par_shapes_mesh* turtle = par_shapes__create_turtle();
  1186. // We're not attempting to support texture coordinates and normals
  1187. // with L-systems, so remove them from the template shape.
  1188. PAR_FREE(tube->normals);
  1189. PAR_FREE(tube->tcoords);
  1190. tube->normals = 0;
  1191. tube->tcoords = 0;
  1192. const float xaxis[] = {1, 0, 0};
  1193. const float yaxis[] = {0, 1, 0};
  1194. const float zaxis[] = {0, 0, 1};
  1195. const float units[] = {1, 1, 1};
  1196. // Execute the L-system program until the stack size is 0.
  1197. par_shapes__stackframe* stack =
  1198. PAR_CALLOC(par_shapes__stackframe, maxdepth);
  1199. int stackptr = 0;
  1200. stack[0].orientation = turtle;
  1201. stack[0].rule = &rules[0];
  1202. par_shapes__copy3(stack[0].scale, units);
  1203. while (stackptr >= 0) {
  1204. par_shapes__stackframe* frame = &stack[stackptr];
  1205. par_shapes__rule* rule = frame->rule;
  1206. par_shapes_mesh* turtle = frame->orientation;
  1207. float* position = frame->position;
  1208. float* scale = frame->scale;
  1209. if (frame->pc >= rule->ncommands) {
  1210. par_shapes_free_mesh(turtle);
  1211. stackptr--;
  1212. continue;
  1213. }
  1214. par_shapes__command* cmd = rule->commands + (frame->pc++);
  1215. #ifdef DUMP_TRACE
  1216. printf("%5s %5s %5s:%d %03d\n", cmd->cmd, cmd->arg, rule->name,
  1217. frame->pc - 1, stackptr);
  1218. #endif
  1219. float value;
  1220. if (!strcmp(cmd->cmd, "shape")) {
  1221. par_shapes_mesh* m = par_shapes__apply_turtle(tube, turtle,
  1222. position, scale);
  1223. if (!strcmp(cmd->arg, "connect")) {
  1224. par_shapes__connect(scene, m, slices);
  1225. } else {
  1226. par_shapes_merge(scene, m);
  1227. }
  1228. par_shapes_free_mesh(m);
  1229. } else if (!strcmp(cmd->cmd, "call") && stackptr < maxdepth - 1) {
  1230. rule = par_shapes__pick_rule(cmd->arg, rules, nrules);
  1231. frame = &stack[++stackptr];
  1232. frame->rule = rule;
  1233. frame->orientation = par_shapes_clone(turtle, 0);
  1234. frame->pc = 0;
  1235. par_shapes__copy3(frame->scale, scale);
  1236. par_shapes__copy3(frame->position, position);
  1237. continue;
  1238. } else {
  1239. value = atof(cmd->arg);
  1240. if (!strcmp(cmd->cmd, "rx")) {
  1241. par_shapes_rotate(turtle, value * PAR_PI / 180.0, xaxis);
  1242. } else if (!strcmp(cmd->cmd, "ry")) {
  1243. par_shapes_rotate(turtle, value * PAR_PI / 180.0, yaxis);
  1244. } else if (!strcmp(cmd->cmd, "rz")) {
  1245. par_shapes_rotate(turtle, value * PAR_PI / 180.0, zaxis);
  1246. } else if (!strcmp(cmd->cmd, "tx")) {
  1247. float vec[3] = {value, 0, 0};
  1248. float t[3] = {
  1249. par_shapes__dot3(turtle->points + 0, vec),
  1250. par_shapes__dot3(turtle->points + 3, vec),
  1251. par_shapes__dot3(turtle->points + 6, vec)
  1252. };
  1253. par_shapes__add3(position, t);
  1254. } else if (!strcmp(cmd->cmd, "ty")) {
  1255. float vec[3] = {0, value, 0};
  1256. float t[3] = {
  1257. par_shapes__dot3(turtle->points + 0, vec),
  1258. par_shapes__dot3(turtle->points + 3, vec),
  1259. par_shapes__dot3(turtle->points + 6, vec)
  1260. };
  1261. par_shapes__add3(position, t);
  1262. } else if (!strcmp(cmd->cmd, "tz")) {
  1263. float vec[3] = {0, 0, value};
  1264. float t[3] = {
  1265. par_shapes__dot3(turtle->points + 0, vec),
  1266. par_shapes__dot3(turtle->points + 3, vec),
  1267. par_shapes__dot3(turtle->points + 6, vec)
  1268. };
  1269. par_shapes__add3(position, t);
  1270. } else if (!strcmp(cmd->cmd, "sx")) {
  1271. scale[0] *= value;
  1272. } else if (!strcmp(cmd->cmd, "sy")) {
  1273. scale[1] *= value;
  1274. } else if (!strcmp(cmd->cmd, "sz")) {
  1275. scale[2] *= value;
  1276. } else if (!strcmp(cmd->cmd, "sa")) {
  1277. scale[0] *= value;
  1278. scale[1] *= value;
  1279. scale[2] *= value;
  1280. }
  1281. }
  1282. }
  1283. PAR_FREE(stack);
  1284. PAR_FREE(program);
  1285. PAR_FREE(rules);
  1286. PAR_FREE(commands);
  1287. return scene;
  1288. }
  1289. void par_shapes_unweld(par_shapes_mesh* mesh, bool create_indices)
  1290. {
  1291. int npoints = mesh->ntriangles * 3;
  1292. float* points = PAR_MALLOC(float, 3 * npoints);
  1293. float* dst = points;
  1294. PAR_SHAPES_T const* index = mesh->triangles;
  1295. for (int i = 0; i < npoints; i++) {
  1296. float const* src = mesh->points + 3 * (*index++);
  1297. *dst++ = src[0];
  1298. *dst++ = src[1];
  1299. *dst++ = src[2];
  1300. }
  1301. PAR_FREE(mesh->points);
  1302. mesh->points = points;
  1303. mesh->npoints = npoints;
  1304. if (create_indices) {
  1305. PAR_SHAPES_T* tris = PAR_MALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
  1306. PAR_SHAPES_T* index = tris;
  1307. for (int i = 0; i < mesh->ntriangles * 3; i++) {
  1308. *index++ = i;
  1309. }
  1310. PAR_FREE(mesh->triangles);
  1311. mesh->triangles = tris;
  1312. }
  1313. }
  1314. void par_shapes_compute_normals(par_shapes_mesh* m)
  1315. {
  1316. PAR_FREE(m->normals);
  1317. m->normals = PAR_CALLOC(float, m->npoints * 3);
  1318. PAR_SHAPES_T const* triangle = m->triangles;
  1319. float next[3], prev[3], cp[3];
  1320. for (int f = 0; f < m->ntriangles; f++, triangle += 3) {
  1321. float const* pa = m->points + 3 * triangle[0];
  1322. float const* pb = m->points + 3 * triangle[1];
  1323. float const* pc = m->points + 3 * triangle[2];
  1324. par_shapes__copy3(next, pb);
  1325. par_shapes__subtract3(next, pa);
  1326. par_shapes__copy3(prev, pc);
  1327. par_shapes__subtract3(prev, pa);
  1328. par_shapes__cross3(cp, next, prev);
  1329. par_shapes__add3(m->normals + 3 * triangle[0], cp);
  1330. par_shapes__copy3(next, pc);
  1331. par_shapes__subtract3(next, pb);
  1332. par_shapes__copy3(prev, pa);
  1333. par_shapes__subtract3(prev, pb);
  1334. par_shapes__cross3(cp, next, prev);
  1335. par_shapes__add3(m->normals + 3 * triangle[1], cp);
  1336. par_shapes__copy3(next, pa);
  1337. par_shapes__subtract3(next, pc);
  1338. par_shapes__copy3(prev, pb);
  1339. par_shapes__subtract3(prev, pc);
  1340. par_shapes__cross3(cp, next, prev);
  1341. par_shapes__add3(m->normals + 3 * triangle[2], cp);
  1342. }
  1343. float* normal = m->normals;
  1344. for (int p = 0; p < m->npoints; p++, normal += 3) {
  1345. par_shapes__normalize3(normal);
  1346. }
  1347. }
  1348. static void par_shapes__subdivide(par_shapes_mesh* mesh)
  1349. {
  1350. assert(mesh->npoints == mesh->ntriangles * 3 && "Must be unwelded.");
  1351. int ntriangles = mesh->ntriangles * 4;
  1352. int npoints = ntriangles * 3;
  1353. float* points = PAR_CALLOC(float, npoints * 3);
  1354. float* dpoint = points;
  1355. float const* spoint = mesh->points;
  1356. for (int t = 0; t < mesh->ntriangles; t++, spoint += 9, dpoint += 3) {
  1357. float const* a = spoint;
  1358. float const* b = spoint + 3;
  1359. float const* c = spoint + 6;
  1360. float const* p0 = dpoint;
  1361. float const* p1 = dpoint + 3;
  1362. float const* p2 = dpoint + 6;
  1363. par_shapes__mix3(dpoint, a, b, 0.5);
  1364. par_shapes__mix3(dpoint += 3, b, c, 0.5);
  1365. par_shapes__mix3(dpoint += 3, a, c, 0.5);
  1366. par_shapes__add3(dpoint += 3, a);
  1367. par_shapes__add3(dpoint += 3, p0);
  1368. par_shapes__add3(dpoint += 3, p2);
  1369. par_shapes__add3(dpoint += 3, p0);
  1370. par_shapes__add3(dpoint += 3, b);
  1371. par_shapes__add3(dpoint += 3, p1);
  1372. par_shapes__add3(dpoint += 3, p2);
  1373. par_shapes__add3(dpoint += 3, p1);
  1374. par_shapes__add3(dpoint += 3, c);
  1375. }
  1376. PAR_FREE(mesh->points);
  1377. mesh->points = points;
  1378. mesh->npoints = npoints;
  1379. mesh->ntriangles = ntriangles;
  1380. }
  1381. par_shapes_mesh* par_shapes_create_subdivided_sphere(int nsubd)
  1382. {
  1383. par_shapes_mesh* mesh = par_shapes_create_icosahedron();
  1384. par_shapes_unweld(mesh, false);
  1385. PAR_FREE(mesh->triangles);
  1386. mesh->triangles = 0;
  1387. while (nsubd--) {
  1388. par_shapes__subdivide(mesh);
  1389. }
  1390. for (int i = 0; i < mesh->npoints; i++) {
  1391. par_shapes__normalize3(mesh->points + i * 3);
  1392. }
  1393. mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
  1394. for (int i = 0; i < mesh->ntriangles * 3; i++) {
  1395. mesh->triangles[i] = i;
  1396. }
  1397. par_shapes_mesh* tmp = mesh;
  1398. mesh = par_shapes_weld(mesh, 0.01, 0);
  1399. par_shapes_free_mesh(tmp);
  1400. par_shapes_compute_normals(mesh);
  1401. return mesh;
  1402. }
  1403. par_shapes_mesh* par_shapes_create_rock(int seed, int subd)
  1404. {
  1405. par_shapes_mesh* mesh = par_shapes_create_subdivided_sphere(subd);
  1406. struct osn_context* ctx;
  1407. par__simplex_noise(seed, &ctx);
  1408. for (int p = 0; p < mesh->npoints; p++) {
  1409. float* pt = mesh->points + p * 3;
  1410. float a = 0.25, f = 1.0;
  1411. double n = a * par__simplex_noise2(ctx, f * pt[0], f * pt[2]);
  1412. a *= 0.5; f *= 2;
  1413. n += a * par__simplex_noise2(ctx, f * pt[0], f * pt[2]);
  1414. pt[0] *= 1 + 2 * n;
  1415. pt[1] *= 1 + n;
  1416. pt[2] *= 1 + 2 * n;
  1417. if (pt[1] < 0) {
  1418. pt[1] = -pow(-pt[1], 0.5) / 2;
  1419. }
  1420. }
  1421. par__simplex_noise_free(ctx);
  1422. par_shapes_compute_normals(mesh);
  1423. return mesh;
  1424. }
  1425. par_shapes_mesh* par_shapes_clone(par_shapes_mesh const* mesh,
  1426. par_shapes_mesh* clone)
  1427. {
  1428. if (!clone) {
  1429. clone = PAR_CALLOC(par_shapes_mesh, 1);
  1430. }
  1431. clone->npoints = mesh->npoints;
  1432. clone->points = PAR_REALLOC(float, clone->points, 3 * clone->npoints);
  1433. memcpy(clone->points, mesh->points, sizeof(float) * 3 * clone->npoints);
  1434. clone->ntriangles = mesh->ntriangles;
  1435. clone->triangles = PAR_REALLOC(PAR_SHAPES_T, clone->triangles, 3 *
  1436. clone->ntriangles);
  1437. memcpy(clone->triangles, mesh->triangles,
  1438. sizeof(PAR_SHAPES_T) * 3 * clone->ntriangles);
  1439. if (mesh->normals) {
  1440. clone->normals = PAR_REALLOC(float, clone->normals, 3 * clone->npoints);
  1441. memcpy(clone->normals, mesh->normals,
  1442. sizeof(float) * 3 * clone->npoints);
  1443. }
  1444. if (mesh->tcoords) {
  1445. clone->tcoords = PAR_REALLOC(float, clone->tcoords, 2 * clone->npoints);
  1446. memcpy(clone->tcoords, mesh->tcoords,
  1447. sizeof(float) * 2 * clone->npoints);
  1448. }
  1449. return clone;
  1450. }
  1451. static struct {
  1452. float const* points;
  1453. int gridsize;
  1454. } par_shapes__sort_context;
  1455. static int par_shapes__cmp1(const void *arg0, const void *arg1)
  1456. {
  1457. const int g = par_shapes__sort_context.gridsize;
  1458. // Convert arg0 into a flattened grid index.
  1459. PAR_SHAPES_T d0 = *(const PAR_SHAPES_T*) arg0;
  1460. float const* p0 = par_shapes__sort_context.points + d0 * 3;
  1461. int i0 = (int) p0[0];
  1462. int j0 = (int) p0[1];
  1463. int k0 = (int) p0[2];
  1464. int index0 = i0 + g * j0 + g * g * k0;
  1465. // Convert arg1 into a flattened grid index.
  1466. PAR_SHAPES_T d1 = *(const PAR_SHAPES_T*) arg1;
  1467. float const* p1 = par_shapes__sort_context.points + d1 * 3;
  1468. int i1 = (int) p1[0];
  1469. int j1 = (int) p1[1];
  1470. int k1 = (int) p1[2];
  1471. int index1 = i1 + g * j1 + g * g * k1;
  1472. // Return the ordering.
  1473. if (index0 < index1) return -1;
  1474. if (index0 > index1) return 1;
  1475. return 0;
  1476. }
  1477. static void par_shapes__sort_points(par_shapes_mesh* mesh, int gridsize,
  1478. PAR_SHAPES_T* sortmap)
  1479. {
  1480. // Run qsort over a list of consecutive integers that get deferenced
  1481. // within the comparator function; this creates a reorder mapping.
  1482. for (int i = 0; i < mesh->npoints; i++) {
  1483. sortmap[i] = i;
  1484. }
  1485. par_shapes__sort_context.gridsize = gridsize;
  1486. par_shapes__sort_context.points = mesh->points;
  1487. qsort(sortmap, mesh->npoints, sizeof(PAR_SHAPES_T), par_shapes__cmp1);
  1488. // Apply the reorder mapping to the XYZ coordinate data.
  1489. float* newpts = PAR_MALLOC(float, mesh->npoints * 3);
  1490. PAR_SHAPES_T* invmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
  1491. float* dstpt = newpts;
  1492. for (int i = 0; i < mesh->npoints; i++) {
  1493. invmap[sortmap[i]] = i;
  1494. float const* srcpt = mesh->points + 3 * sortmap[i];
  1495. *dstpt++ = *srcpt++;
  1496. *dstpt++ = *srcpt++;
  1497. *dstpt++ = *srcpt++;
  1498. }
  1499. PAR_FREE(mesh->points);
  1500. mesh->points = newpts;
  1501. // Apply the inverse reorder mapping to the triangle indices.
  1502. PAR_SHAPES_T* newinds = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
  1503. PAR_SHAPES_T* dstind = newinds;
  1504. PAR_SHAPES_T const* srcind = mesh->triangles;
  1505. for (int i = 0; i < mesh->ntriangles * 3; i++) {
  1506. *dstind++ = invmap[*srcind++];
  1507. }
  1508. PAR_FREE(mesh->triangles);
  1509. mesh->triangles = newinds;
  1510. // Cleanup.
  1511. memcpy(sortmap, invmap, sizeof(PAR_SHAPES_T) * mesh->npoints);
  1512. PAR_FREE(invmap);
  1513. }
  1514. static void par_shapes__weld_points(par_shapes_mesh* mesh, int gridsize,
  1515. float epsilon, PAR_SHAPES_T* weldmap)
  1516. {
  1517. // Each bin contains a "pointer" (really an index) to its first point.
  1518. // We add 1 because 0 is reserved to mean that the bin is empty.
  1519. // Since the points are spatially sorted, there's no need to store
  1520. // a point count in each bin.
  1521. PAR_SHAPES_T* bins = PAR_CALLOC(PAR_SHAPES_T,
  1522. gridsize * gridsize * gridsize);
  1523. int prev_binindex = -1;
  1524. for (int p = 0; p < mesh->npoints; p++) {
  1525. float const* pt = mesh->points + p * 3;
  1526. int i = (int) pt[0];
  1527. int j = (int) pt[1];
  1528. int k = (int) pt[2];
  1529. int this_binindex = i + gridsize * j + gridsize * gridsize * k;
  1530. if (this_binindex != prev_binindex) {
  1531. bins[this_binindex] = 1 + p;
  1532. }
  1533. prev_binindex = this_binindex;
  1534. }
  1535. // Examine all bins that intersect the epsilon-sized cube centered at each
  1536. // point, and check for colocated points within those bins.
  1537. float const* pt = mesh->points;
  1538. int nremoved = 0;
  1539. for (int p = 0; p < mesh->npoints; p++, pt += 3) {
  1540. // Skip if this point has already been welded.
  1541. if (weldmap[p] != p) {
  1542. continue;
  1543. }
  1544. // Build a list of bins that intersect the epsilon-sized cube.
  1545. int nearby[8];
  1546. int nbins = 0;
  1547. int minp[3], maxp[3];
  1548. for (int c = 0; c < 3; c++) {
  1549. minp[c] = (int) (pt[c] - epsilon);
  1550. maxp[c] = (int) (pt[c] + epsilon);
  1551. }
  1552. for (int i = minp[0]; i <= maxp[0]; i++) {
  1553. for (int j = minp[1]; j <= maxp[1]; j++) {
  1554. for (int k = minp[2]; k <= maxp[2]; k++) {
  1555. int binindex = i + gridsize * j + gridsize * gridsize * k;
  1556. PAR_SHAPES_T binvalue = *(bins + binindex);
  1557. if (binvalue > 0) {
  1558. if (nbins == 8) {
  1559. printf("Epsilon value is too large.\n");
  1560. break;
  1561. }
  1562. nearby[nbins++] = binindex;
  1563. }
  1564. }
  1565. }
  1566. }
  1567. // Check for colocated points in each nearby bin.
  1568. for (int b = 0; b < nbins; b++) {
  1569. int binindex = nearby[b];
  1570. PAR_SHAPES_T binvalue = bins[binindex];
  1571. PAR_SHAPES_T nindex = binvalue - 1;
  1572. assert(nindex < mesh->npoints);
  1573. while (true) {
  1574. // If this isn't "self" and it's colocated, then weld it!
  1575. if (nindex != p && weldmap[nindex] == nindex) {
  1576. float const* thatpt = mesh->points + nindex * 3;
  1577. float dist2 = par_shapes__sqrdist3(thatpt, pt);
  1578. if (dist2 < epsilon) {
  1579. weldmap[nindex] = p;
  1580. nremoved++;
  1581. }
  1582. }
  1583. // Advance to the next point if possible.
  1584. if (++nindex >= mesh->npoints) {
  1585. break;
  1586. }
  1587. // If the next point is outside the bin, then we're done.
  1588. float const* nextpt = mesh->points + nindex * 3;
  1589. int i = (int) nextpt[0];
  1590. int j = (int) nextpt[1];
  1591. int k = (int) nextpt[2];
  1592. int nextbinindex = i + gridsize * j + gridsize * gridsize * k;
  1593. if (nextbinindex != binindex) {
  1594. break;
  1595. }
  1596. }
  1597. }
  1598. }
  1599. PAR_FREE(bins);
  1600. // Apply the weldmap to the vertices.
  1601. int npoints = mesh->npoints - nremoved;
  1602. float* newpts = PAR_MALLOC(float, 3 * npoints);
  1603. float* dst = newpts;
  1604. PAR_SHAPES_T* condensed_map = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
  1605. PAR_SHAPES_T* cmap = condensed_map;
  1606. float const* src = mesh->points;
  1607. int ci = 0;
  1608. for (int p = 0; p < mesh->npoints; p++, src += 3) {
  1609. if (weldmap[p] == p) {
  1610. *dst++ = src[0];
  1611. *dst++ = src[1];
  1612. *dst++ = src[2];
  1613. *cmap++ = ci++;
  1614. } else {
  1615. *cmap++ = condensed_map[weldmap[p]];
  1616. }
  1617. }
  1618. assert(ci == npoints);
  1619. PAR_FREE(mesh->points);
  1620. memcpy(weldmap, condensed_map, mesh->npoints * sizeof(PAR_SHAPES_T));
  1621. PAR_FREE(condensed_map);
  1622. mesh->points = newpts;
  1623. mesh->npoints = npoints;
  1624. // Apply the weldmap to the triangle indices and skip the degenerates.
  1625. PAR_SHAPES_T const* tsrc = mesh->triangles;
  1626. PAR_SHAPES_T* tdst = mesh->triangles;
  1627. int ntriangles = 0;
  1628. for (int i = 0; i < mesh->ntriangles; i++, tsrc += 3) {
  1629. PAR_SHAPES_T a = weldmap[tsrc[0]];
  1630. PAR_SHAPES_T b = weldmap[tsrc[1]];
  1631. PAR_SHAPES_T c = weldmap[tsrc[2]];
  1632. if (a != b && a != c && b != c) {
  1633. assert(a < mesh->npoints);
  1634. assert(b < mesh->npoints);
  1635. assert(c < mesh->npoints);
  1636. *tdst++ = a;
  1637. *tdst++ = b;
  1638. *tdst++ = c;
  1639. ntriangles++;
  1640. }
  1641. }
  1642. mesh->ntriangles = ntriangles;
  1643. }
  1644. par_shapes_mesh* par_shapes_weld(par_shapes_mesh const* mesh, float epsilon,
  1645. PAR_SHAPES_T* weldmap)
  1646. {
  1647. par_shapes_mesh* clone = par_shapes_clone(mesh, 0);
  1648. float aabb[6];
  1649. int gridsize = 20;
  1650. float maxcell = gridsize - 1;
  1651. par_shapes_compute_aabb(clone, aabb);
  1652. float scale[3] = {
  1653. aabb[3] == aabb[0] ? 1.0f : maxcell / (aabb[3] - aabb[0]),
  1654. aabb[4] == aabb[1] ? 1.0f : maxcell / (aabb[4] - aabb[1]),
  1655. aabb[5] == aabb[2] ? 1.0f : maxcell / (aabb[5] - aabb[2]),
  1656. };
  1657. par_shapes_translate(clone, -aabb[0], -aabb[1], -aabb[2]);
  1658. par_shapes_scale(clone, scale[0], scale[1], scale[2]);
  1659. PAR_SHAPES_T* sortmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
  1660. par_shapes__sort_points(clone, gridsize, sortmap);
  1661. bool owner = false;
  1662. if (!weldmap) {
  1663. owner = true;
  1664. weldmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
  1665. }
  1666. for (int i = 0; i < mesh->npoints; i++) {
  1667. weldmap[i] = i;
  1668. }
  1669. par_shapes__weld_points(clone, gridsize, epsilon, weldmap);
  1670. if (owner) {
  1671. PAR_FREE(weldmap);
  1672. } else {
  1673. PAR_SHAPES_T* newmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
  1674. for (int i = 0; i < mesh->npoints; i++) {
  1675. newmap[i] = weldmap[sortmap[i]];
  1676. }
  1677. memcpy(weldmap, newmap, sizeof(PAR_SHAPES_T) * mesh->npoints);
  1678. PAR_FREE(newmap);
  1679. }
  1680. PAR_FREE(sortmap);
  1681. par_shapes_scale(clone, 1.0 / scale[0], 1.0 / scale[1], 1.0 / scale[2]);
  1682. par_shapes_translate(clone, aabb[0], aabb[1], aabb[2]);
  1683. return clone;
  1684. }
  1685. // -----------------------------------------------------------------------------
  1686. // BEGIN OPEN SIMPLEX NOISE
  1687. // -----------------------------------------------------------------------------
  1688. #define STRETCH_CONSTANT_2D (-0.211324865405187) // (1 / sqrt(2 + 1) - 1 ) / 2;
  1689. #define SQUISH_CONSTANT_2D (0.366025403784439) // (sqrt(2 + 1) -1) / 2;
  1690. #define STRETCH_CONSTANT_3D (-1.0 / 6.0) // (1 / sqrt(3 + 1) - 1) / 3;
  1691. #define SQUISH_CONSTANT_3D (1.0 / 3.0) // (sqrt(3+1)-1)/3;
  1692. #define STRETCH_CONSTANT_4D (-0.138196601125011) // (1 / sqrt(4 + 1) - 1) / 4;
  1693. #define SQUISH_CONSTANT_4D (0.309016994374947) // (sqrt(4 + 1) - 1) / 4;
  1694. #define NORM_CONSTANT_2D (47.0)
  1695. #define NORM_CONSTANT_3D (103.0)
  1696. #define NORM_CONSTANT_4D (30.0)
  1697. #define DEFAULT_SEED (0LL)
  1698. struct osn_context {
  1699. int16_t* perm;
  1700. int16_t* permGradIndex3D;
  1701. };
  1702. #define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
  1703. /*
  1704. * Gradients for 2D. They approximate the directions to the
  1705. * vertices of an octagon from the center.
  1706. */
  1707. static const int8_t gradients2D[] = {
  1708. 5, 2, 2, 5, -5, 2, -2, 5, 5, -2, 2, -5, -5, -2, -2, -5,
  1709. };
  1710. /*
  1711. * Gradients for 3D. They approximate the directions to the
  1712. * vertices of a rhombicuboctahedron from the center, skewed so
  1713. * that the triangular and square facets can be inscribed inside
  1714. * circles of the same radius.
  1715. */
  1716. static const signed char gradients3D[] = {
  1717. -11, 4, 4, -4, 11, 4, -4, 4, 11, 11, 4, 4, 4, 11, 4, 4, 4, 11, -11, -4, 4,
  1718. -4, -11, 4, -4, -4, 11, 11, -4, 4, 4, -11, 4, 4, -4, 11, -11, 4, -4, -4, 11,
  1719. -4, -4, 4, -11, 11, 4, -4, 4, 11, -4, 4, 4, -11, -11, -4, -4, -4, -11, -4,
  1720. -4, -4, -11, 11, -4, -4, 4, -11, -4, 4, -4, -11,
  1721. };
  1722. /*
  1723. * Gradients for 4D. They approximate the directions to the
  1724. * vertices of a disprismatotesseractihexadecachoron from the center,
  1725. * skewed so that the tetrahedral and cubic facets can be inscribed inside
  1726. * spheres of the same radius.
  1727. */
  1728. static const signed char gradients4D[] = {
  1729. 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, -3, 1, 1, 1, -1, 3, 1, 1,
  1730. -1, 1, 3, 1, -1, 1, 1, 3, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1,
  1731. 3, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, 3, 1, -1, 1, 1,
  1732. 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3,
  1733. 1, -1, 1, -1, 3, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, -3,
  1734. -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, 3, 1, 1, -1, 1, 3,
  1735. 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1,
  1736. -1, 1, 1, -3, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, -3,
  1737. -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, 3, 1, -1, -1, 1, 3,
  1738. -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3,
  1739. -1, -1, 1, -1, -3, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1,
  1740. -3, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3,
  1741. };
  1742. static double extrapolate2(
  1743. struct osn_context* ctx, int xsb, int ysb, double dx, double dy)
  1744. {
  1745. int16_t* perm = ctx->perm;
  1746. int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E;
  1747. return gradients2D[index] * dx + gradients2D[index + 1] * dy;
  1748. }
  1749. static inline int fastFloor(double x)
  1750. {
  1751. int xi = (int) x;
  1752. return x < xi ? xi - 1 : xi;
  1753. }
  1754. static int allocate_perm(struct osn_context* ctx, int nperm, int ngrad)
  1755. {
  1756. PAR_FREE(ctx->perm);
  1757. PAR_FREE(ctx->permGradIndex3D);
  1758. ctx->perm = PAR_MALLOC(int16_t, nperm);
  1759. if (!ctx->perm) {
  1760. return -ENOMEM;
  1761. }
  1762. ctx->permGradIndex3D = PAR_MALLOC(int16_t, ngrad);
  1763. if (!ctx->permGradIndex3D) {
  1764. PAR_FREE(ctx->perm);
  1765. return -ENOMEM;
  1766. }
  1767. return 0;
  1768. }
  1769. static int par__simplex_noise(int64_t seed, struct osn_context** ctx)
  1770. {
  1771. int rc;
  1772. int16_t source[256];
  1773. int i;
  1774. int16_t* perm;
  1775. int16_t* permGradIndex3D;
  1776. *ctx = PAR_MALLOC(struct osn_context, 1);
  1777. if (!(*ctx)) {
  1778. return -ENOMEM;
  1779. }
  1780. (*ctx)->perm = NULL;
  1781. (*ctx)->permGradIndex3D = NULL;
  1782. rc = allocate_perm(*ctx, 256, 256);
  1783. if (rc) {
  1784. PAR_FREE(*ctx);
  1785. return rc;
  1786. }
  1787. perm = (*ctx)->perm;
  1788. permGradIndex3D = (*ctx)->permGradIndex3D;
  1789. for (i = 0; i < 256; i++) {
  1790. source[i] = (int16_t) i;
  1791. }
  1792. seed = seed * 6364136223846793005LL + 1442695040888963407LL;
  1793. seed = seed * 6364136223846793005LL + 1442695040888963407LL;
  1794. seed = seed * 6364136223846793005LL + 1442695040888963407LL;
  1795. for (i = 255; i >= 0; i--) {
  1796. seed = seed * 6364136223846793005LL + 1442695040888963407LL;
  1797. int r = (int) ((seed + 31) % (i + 1));
  1798. if (r < 0)
  1799. r += (i + 1);
  1800. perm[i] = source[r];
  1801. permGradIndex3D[i] =
  1802. (short) ((perm[i] % (ARRAYSIZE(gradients3D) / 3)) * 3);
  1803. source[r] = source[i];
  1804. }
  1805. return 0;
  1806. }
  1807. static void par__simplex_noise_free(struct osn_context* ctx)
  1808. {
  1809. if (!ctx)
  1810. return;
  1811. if (ctx->perm) {
  1812. PAR_FREE(ctx->perm);
  1813. ctx->perm = NULL;
  1814. }
  1815. if (ctx->permGradIndex3D) {
  1816. PAR_FREE(ctx->permGradIndex3D);
  1817. ctx->permGradIndex3D = NULL;
  1818. }
  1819. PAR_FREE(ctx);
  1820. }
  1821. static double par__simplex_noise2(struct osn_context* ctx, double x, double y)
  1822. {
  1823. // Place input coordinates onto grid.
  1824. double stretchOffset = (x + y) * STRETCH_CONSTANT_2D;
  1825. double xs = x + stretchOffset;
  1826. double ys = y + stretchOffset;
  1827. // Floor to get grid coordinates of rhombus (stretched square) super-cell
  1828. // origin.
  1829. int xsb = fastFloor(xs);
  1830. int ysb = fastFloor(ys);
  1831. // Skew out to get actual coordinates of rhombus origin. We'll need these
  1832. // later.
  1833. double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D;
  1834. double xb = xsb + squishOffset;
  1835. double yb = ysb + squishOffset;
  1836. // Compute grid coordinates relative to rhombus origin.
  1837. double xins = xs - xsb;
  1838. double yins = ys - ysb;
  1839. // Sum those together to get a value that determines which region we're in.
  1840. double inSum = xins + yins;
  1841. // Positions relative to origin point.
  1842. double dx0 = x - xb;
  1843. double dy0 = y - yb;
  1844. // We'll be defining these inside the next block and using them afterwards.
  1845. double dx_ext, dy_ext;
  1846. int xsv_ext, ysv_ext;
  1847. double value = 0;
  1848. // Contribution (1,0)
  1849. double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D;
  1850. double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D;
  1851. double attn1 = 2 - dx1 * dx1 - dy1 * dy1;
  1852. if (attn1 > 0) {
  1853. attn1 *= attn1;
  1854. value += attn1 * attn1 * extrapolate2(ctx, xsb + 1, ysb + 0, dx1, dy1);
  1855. }
  1856. // Contribution (0,1)
  1857. double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D;
  1858. double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D;
  1859. double attn2 = 2 - dx2 * dx2 - dy2 * dy2;
  1860. if (attn2 > 0) {
  1861. attn2 *= attn2;
  1862. value += attn2 * attn2 * extrapolate2(ctx, xsb + 0, ysb + 1, dx2, dy2);
  1863. }
  1864. if (inSum <= 1) { // We're inside the triangle (2-Simplex) at (0,0)
  1865. double zins = 1 - inSum;
  1866. if (zins > xins || zins > yins) {
  1867. if (xins > yins) {
  1868. xsv_ext = xsb + 1;
  1869. ysv_ext = ysb - 1;
  1870. dx_ext = dx0 - 1;
  1871. dy_ext = dy0 + 1;
  1872. } else {
  1873. xsv_ext = xsb - 1;
  1874. ysv_ext = ysb + 1;
  1875. dx_ext = dx0 + 1;
  1876. dy_ext = dy0 - 1;
  1877. }
  1878. } else { //(1,0) and (0,1) are the closest two vertices.
  1879. xsv_ext = xsb + 1;
  1880. ysv_ext = ysb + 1;
  1881. dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D;
  1882. dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D;
  1883. }
  1884. } else { // We're inside the triangle (2-Simplex) at (1,1)
  1885. double zins = 2 - inSum;
  1886. if (zins < xins || zins < yins) {
  1887. if (xins > yins) {
  1888. xsv_ext = xsb + 2;
  1889. ysv_ext = ysb + 0;
  1890. dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D;
  1891. dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D;
  1892. } else {
  1893. xsv_ext = xsb + 0;
  1894. ysv_ext = ysb + 2;
  1895. dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D;
  1896. dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D;
  1897. }
  1898. } else { //(1,0) and (0,1) are the closest two vertices.
  1899. dx_ext = dx0;
  1900. dy_ext = dy0;
  1901. xsv_ext = xsb;
  1902. ysv_ext = ysb;
  1903. }
  1904. xsb += 1;
  1905. ysb += 1;
  1906. dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D;
  1907. dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D;
  1908. }
  1909. // Contribution (0,0) or (1,1)
  1910. double attn0 = 2 - dx0 * dx0 - dy0 * dy0;
  1911. if (attn0 > 0) {
  1912. attn0 *= attn0;
  1913. value += attn0 * attn0 * extrapolate2(ctx, xsb, ysb, dx0, dy0);
  1914. }
  1915. // Extra Vertex
  1916. double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext;
  1917. if (attn_ext > 0) {
  1918. attn_ext *= attn_ext;
  1919. value += attn_ext * attn_ext *
  1920. extrapolate2(ctx, xsv_ext, ysv_ext, dx_ext, dy_ext);
  1921. }
  1922. return value / NORM_CONSTANT_2D;
  1923. }
  1924. void par_shapes_remove_degenerate(par_shapes_mesh* mesh, float mintriarea)
  1925. {
  1926. int ntriangles = 0;
  1927. PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
  1928. PAR_SHAPES_T* dst = triangles;
  1929. PAR_SHAPES_T const* src = mesh->triangles;
  1930. float next[3], prev[3], cp[3];
  1931. float mincplen2 = (mintriarea * 2) * (mintriarea * 2);
  1932. for (int f = 0; f < mesh->ntriangles; f++, src += 3) {
  1933. float const* pa = mesh->points + 3 * src[0];
  1934. float const* pb = mesh->points + 3 * src[1];
  1935. float const* pc = mesh->points + 3 * src[2];
  1936. par_shapes__copy3(next, pb);
  1937. par_shapes__subtract3(next, pa);
  1938. par_shapes__copy3(prev, pc);
  1939. par_shapes__subtract3(prev, pa);
  1940. par_shapes__cross3(cp, next, prev);
  1941. float cplen2 = par_shapes__dot3(cp, cp);
  1942. if (cplen2 >= mincplen2) {
  1943. *dst++ = src[0];
  1944. *dst++ = src[1];
  1945. *dst++ = src[2];
  1946. ntriangles++;
  1947. }
  1948. }
  1949. mesh->ntriangles = ntriangles;
  1950. PAR_FREE(mesh->triangles);
  1951. mesh->triangles = triangles;
  1952. }
  1953. #endif // PAR_SHAPES_IMPLEMENTATION
  1954. #endif // PAR_SHAPES_H
  1955. // par_shapes is distributed under the MIT license:
  1956. //
  1957. // Copyright (c) 2019 Philip Rideout
  1958. //
  1959. // Permission is hereby granted, free of charge, to any person obtaining a copy
  1960. // of this software and associated documentation files (the "Software"), to deal
  1961. // in the Software without restriction, including without limitation the rights
  1962. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  1963. // copies of the Software, and to permit persons to whom the Software is
  1964. // furnished to do so, subject to the following conditions:
  1965. //
  1966. // The above copyright notice and this permission notice shall be included in
  1967. // all copies or substantial portions of the Software.
  1968. //
  1969. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  1970. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  1971. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  1972. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  1973. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  1974. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  1975. // SOFTWARE.