par_shapes.h 65 KB

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