chorama 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/.configs/tsconfig.lib.json +43 -0
  2. package/.configs/tsconfig.website.json +34 -0
  3. package/.github/workflows/static.yml +88 -0
  4. package/.vscode/launch.json +29 -0
  5. package/.vscode/tasks.json +19 -0
  6. package/README.md +127 -0
  7. package/assets/images/disappointed.jpg +0 -0
  8. package/assets/images/skybox/grimmnight_back.png +0 -0
  9. package/assets/images/skybox/grimmnight_bottom.png +0 -0
  10. package/assets/images/skybox/grimmnight_front.png +0 -0
  11. package/assets/images/skybox/grimmnight_left.png +0 -0
  12. package/assets/images/skybox/grimmnight_right.png +0 -0
  13. package/assets/images/skybox/grimmnight_top.png +0 -0
  14. package/assets/images/skybox/miramar_back.png +0 -0
  15. package/assets/images/skybox/miramar_bottom.png +0 -0
  16. package/assets/images/skybox/miramar_front.png +0 -0
  17. package/assets/images/skybox/miramar_left.png +0 -0
  18. package/assets/images/skybox/miramar_right.png +0 -0
  19. package/assets/images/skybox/miramar_top.png +0 -0
  20. package/assets/images/uv.jpg +0 -0
  21. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_BaseColor.png +0 -0
  22. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_Normal.png +0 -0
  23. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_GlassPlasticMat_OcclusionRoughMetal.png +0 -0
  24. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_BaseColor.png +0 -0
  25. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_Normal.png +0 -0
  26. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LeatherPartsMat_OcclusionRoughMetal.png +0 -0
  27. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_BaseColor.png +0 -0
  28. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_Normal.png +0 -0
  29. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_LensesMat_OcclusionRoughMetal.png +0 -0
  30. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_BaseColor.png +0 -0
  31. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_Normal.png +0 -0
  32. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_MetalPartsMat_OcclusionRoughMetal.png +0 -0
  33. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_BaseColor.png +0 -0
  34. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_Normal.png +0 -0
  35. package/assets/models/gltf/flight_helmet/FlightHelmet_Materials_RubberWoodMat_OcclusionRoughMetal.png +0 -0
  36. package/assets/models/gltf/flight_helmet/index.bin +0 -0
  37. package/assets/models/gltf/flight_helmet/index.gltf +705 -0
  38. package/assets/models/gltf/object.gltf +23 -0
  39. package/assets/models/gltf/pirate_girl/index.bin +0 -0
  40. package/assets/models/gltf/pirate_girl/index.gltf +2082 -0
  41. package/assets/models/obj/pirate_girl/pirate_girl.obj +18459 -0
  42. package/assets/models/obj/pirate_girl/pirate_girl.png +0 -0
  43. package/astro.config.mjs +45 -0
  44. package/content/guide/api-map.md +89 -0
  45. package/content/guide/camera-and-controls.md +98 -0
  46. package/content/guide/first-scene.md +176 -0
  47. package/content/guide/index.md +72 -0
  48. package/content/guide/installation.md +179 -0
  49. package/content/guide/materials-and-lighting.md +138 -0
  50. package/content/guide/plugins-and-render-pipeline.md +124 -0
  51. package/content/guide/render-targets-and-views.md +147 -0
  52. package/content/guide/scene-graph-and-transforms.md +113 -0
  53. package/content/guide/textures-and-assets.md +120 -0
  54. package/content/guide/troubleshooting.md +49 -0
  55. package/env.d.ts +19 -0
  56. package/examples/addons/rendergraph_gui.js +580 -0
  57. package/examples/camera/orthographic.js +120 -0
  58. package/examples/camera/perspective.js +138 -0
  59. package/examples/lights/directional.js +397 -0
  60. package/examples/lights/multiple_spot_lights.js +304 -0
  61. package/examples/lights/point.js +337 -0
  62. package/examples/lights/spot.js +366 -0
  63. package/examples/loader/gltf_material.js +111 -0
  64. package/examples/loader/gltfloader.js +78 -0
  65. package/examples/loader/objloader.js +95 -0
  66. package/examples/material/cullface.js +111 -0
  67. package/examples/material/materials.js +126 -0
  68. package/examples/material/standard/basic.js +164 -0
  69. package/examples/mesh/circle.js +117 -0
  70. package/examples/mesh/cuboid.js +151 -0
  71. package/examples/mesh/cylinder.js +139 -0
  72. package/examples/mesh/geometries.js +108 -0
  73. package/examples/mesh/meshTopology.js +103 -0
  74. package/examples/mesh/plane.js +117 -0
  75. package/examples/mesh/skinning.js +136 -0
  76. package/examples/mesh/uvsphere.js +113 -0
  77. package/examples/other/rotatingCube.js +93 -0
  78. package/examples/other/rotatingSphere.js +96 -0
  79. package/examples/rendertarget/basic_canvas.js +130 -0
  80. package/examples/rendertarget/depth_texture.js +130 -0
  81. package/examples/rendertarget/image_target.js +140 -0
  82. package/examples/rendertarget/multiple_views.js +158 -0
  83. package/examples/rendertarget/render_masks.js +173 -0
  84. package/examples/rendertarget/split_screen.js +123 -0
  85. package/examples/rendertarget/split_view.js +137 -0
  86. package/examples/skybox/skybox.js +111 -0
  87. package/examples/texture/arrays.js +156 -0
  88. package/examples/texture/textureWrap.js +118 -0
  89. package/examples/transform/propagation.js +92 -0
  90. package/package.json +55 -0
  91. package/rollup.config.js +66 -0
  92. package/scripts/stage-chorama.mjs +29 -0
  93. package/src/caches/cache.js +420 -0
  94. package/src/caches/index.js +2 -0
  95. package/src/caches/uniformbuffers.js +104 -0
  96. package/src/cameracontrols/index.js +258 -0
  97. package/src/constants/index.js +3 -0
  98. package/src/constants/mesh.js +197 -0
  99. package/src/constants/others.js +218 -0
  100. package/src/constants/texture.js +183 -0
  101. package/src/core/constants.js +14 -0
  102. package/src/core/extensions.js +42 -0
  103. package/src/core/index.js +7 -0
  104. package/src/core/layouts/index.js +4 -0
  105. package/src/core/layouts/meshvertex.js +60 -0
  106. package/src/core/layouts/uniform.js +21 -0
  107. package/src/core/layouts/uniformbuffer.js +15 -0
  108. package/src/core/layouts/vertexbuffer.js +43 -0
  109. package/src/core/limits.js +247 -0
  110. package/src/core/resources/blendparams.js +89 -0
  111. package/src/core/resources/framebuffer.js +127 -0
  112. package/src/core/resources/gpubuffer.js +32 -0
  113. package/src/core/resources/gpumesh.js +43 -0
  114. package/src/core/resources/gputexture.js +73 -0
  115. package/src/core/resources/index.js +5 -0
  116. package/src/core/shader.js +62 -0
  117. package/src/core/webgl/bindgroup.js +89 -0
  118. package/src/core/webgl/descriptors.js +104 -0
  119. package/src/core/webgl/index.js +5 -0
  120. package/src/core/webgl/renderpassencoder.js +96 -0
  121. package/src/core/webgl/renderpipeline.js +54 -0
  122. package/src/core/webgl/utils.js +371 -0
  123. package/src/core/webgl/webglrenderdevice.js +235 -0
  124. package/src/function.js +358 -0
  125. package/src/index.js +15 -0
  126. package/src/loader/gltf.js +2172 -0
  127. package/src/loader/index.js +3 -0
  128. package/src/loader/loader.js +174 -0
  129. package/src/loader/obj.js +188 -0
  130. package/src/loader/texture.js +85 -0
  131. package/src/loader/utils.js +16 -0
  132. package/src/material/basic.js +75 -0
  133. package/src/material/depth.js +73 -0
  134. package/src/material/index.js +8 -0
  135. package/src/material/lambert.js +73 -0
  136. package/src/material/material.js +106 -0
  137. package/src/material/normal.js +30 -0
  138. package/src/material/phong.js +86 -0
  139. package/src/material/raw.js +52 -0
  140. package/src/material/standard.js +221 -0
  141. package/src/math/index.js +3 -0
  142. package/src/math/transform.js +38 -0
  143. package/src/mesh/attribute/attribute.js +79 -0
  144. package/src/mesh/attribute/index.js +1 -0
  145. package/src/mesh/attributedata/index.js +1 -0
  146. package/src/mesh/attributedata/separate.js +180 -0
  147. package/src/mesh/builders/base.js +41 -0
  148. package/src/mesh/builders/circle.js +63 -0
  149. package/src/mesh/builders/cuboid.js +135 -0
  150. package/src/mesh/builders/cylinder.js +131 -0
  151. package/src/mesh/builders/index.js +7 -0
  152. package/src/mesh/builders/plane.js +73 -0
  153. package/src/mesh/builders/utils.js +20 -0
  154. package/src/mesh/builders/uvsphere.js +80 -0
  155. package/src/mesh/builders/wireframe.js +62 -0
  156. package/src/mesh/index.js +4 -0
  157. package/src/mesh/mesh.js +149 -0
  158. package/src/objects/bone.js +17 -0
  159. package/src/objects/camera/camera.js +56 -0
  160. package/src/objects/camera/index.js +2 -0
  161. package/src/objects/camera/projection.js +203 -0
  162. package/src/objects/debug/index.js +1 -0
  163. package/src/objects/debug/skeleton.js +28 -0
  164. package/src/objects/index.js +7 -0
  165. package/src/objects/light/ambient.js +20 -0
  166. package/src/objects/light/directional.js +29 -0
  167. package/src/objects/light/index.js +5 -0
  168. package/src/objects/light/point.js +32 -0
  169. package/src/objects/light/shadow/index.js +1 -0
  170. package/src/objects/light/shadow/shadow.js +67 -0
  171. package/src/objects/light/spot.js +56 -0
  172. package/src/objects/mesh.js +141 -0
  173. package/src/objects/object3d.js +167 -0
  174. package/src/objects/skybox.js +38 -0
  175. package/src/plugins/camera/camera.js +19 -0
  176. package/src/plugins/camera/index.js +2 -0
  177. package/src/plugins/camera/nodes/cameraview.js +46 -0
  178. package/src/plugins/camera/nodes/index.js +2 -0
  179. package/src/plugins/camera/nodes/opaquepass.js +79 -0
  180. package/src/plugins/index.js +6 -0
  181. package/src/plugins/light/index.js +2 -0
  182. package/src/plugins/light/light.js +23 -0
  183. package/src/plugins/light/nodes/index.js +1 -0
  184. package/src/plugins/light/nodes/light.js +127 -0
  185. package/src/plugins/meshmaterial/index.js +3 -0
  186. package/src/plugins/meshmaterial/meshmaterial.js +381 -0
  187. package/src/plugins/meshmaterial/nodes/index.js +1 -0
  188. package/src/plugins/meshmaterial/nodes/meshmaterial.js +50 -0
  189. package/src/plugins/meshmaterial/resources/index.js +1 -0
  190. package/src/plugins/meshmaterial/resources/meshmaterialpipelines.js +50 -0
  191. package/src/plugins/shadow/index.js +3 -0
  192. package/src/plugins/shadow/nodes/index.js +3 -0
  193. package/src/plugins/shadow/nodes/shadow.js +272 -0
  194. package/src/plugins/shadow/nodes/shadowOccluder.js +112 -0
  195. package/src/plugins/shadow/nodes/shadowOpaquePass.js +73 -0
  196. package/src/plugins/shadow/resources/ShadowMap.js +99 -0
  197. package/src/plugins/shadow/resources/index.js +2 -0
  198. package/src/plugins/shadow/resources/shadowpipelines.js +25 -0
  199. package/src/plugins/shadow/shadow.js +31 -0
  200. package/src/plugins/skeletonhelper/index.js +1 -0
  201. package/src/plugins/skeletonhelper/skeletonhelper.js +160 -0
  202. package/src/plugins/skybox/index.js +3 -0
  203. package/src/plugins/skybox/nodes/index.js +1 -0
  204. package/src/plugins/skybox/nodes/skybox.js +143 -0
  205. package/src/plugins/skybox/resources/index.js +2 -0
  206. package/src/plugins/skybox/resources/skyboxmesh.js +14 -0
  207. package/src/plugins/skybox/resources/skyboxpipeline.js +6 -0
  208. package/src/plugins/skybox/skybox.js +137 -0
  209. package/src/renderer/core/index.js +179 -0
  210. package/src/renderer/graph/index.js +3 -0
  211. package/src/renderer/graph/nodes.js +34 -0
  212. package/src/renderer/graph/rendergraph.js +182 -0
  213. package/src/renderer/index.js +5 -0
  214. package/src/renderer/plugin.js +36 -0
  215. package/src/renderer/renderer.js +179 -0
  216. package/src/renderer/views.js +28 -0
  217. package/src/rendertarget/canvastarget.js +30 -0
  218. package/src/rendertarget/image.js +132 -0
  219. package/src/rendertarget/index.js +3 -0
  220. package/src/rendertarget/rendertarget.js +89 -0
  221. package/src/shader/basicFragment.glsl +30 -0
  222. package/src/shader/basicVertex.glsl +87 -0
  223. package/src/shader/common/color.glsl +7 -0
  224. package/src/shader/common/common.glsl +25 -0
  225. package/src/shader/common/index.js +4 -0
  226. package/src/shader/common/light.glsl +437 -0
  227. package/src/shader/common/math.glsl +12 -0
  228. package/src/shader/debug/index.js +2 -0
  229. package/src/shader/debug/skeletonFragment.glsl +8 -0
  230. package/src/shader/debug/skeletonVertex.glsl +27 -0
  231. package/src/shader/depthFragment.glsl +37 -0
  232. package/src/shader/index.js +11 -0
  233. package/src/shader/lambertFragment.glsl +126 -0
  234. package/src/shader/normalFragment.glsl +25 -0
  235. package/src/shader/phongFragment.glsl +140 -0
  236. package/src/shader/skyboxFragment.glsl +16 -0
  237. package/src/shader/skyboxVertex.glsl +20 -0
  238. package/src/shader/standardFragment.glsl +274 -0
  239. package/src/texture/index.js +2 -0
  240. package/src/texture/sampler.js +111 -0
  241. package/src/texture/texture.js +234 -0
  242. package/src/utils/index.js +115 -0
  243. package/tsconfig.json +11 -0
  244. package/website/config/index.ts +1 -0
  245. package/website/config/navigation.ts +53 -0
  246. package/website/content.config.ts +92 -0
  247. package/website/layouts/DocLayout.astro +501 -0
  248. package/website/layouts/Example.astro +91 -0
  249. package/website/pages/examples/[...slug].astro +77 -0
  250. package/website/pages/examples/index.astro +98 -0
  251. package/website/pages/examples/samples/[...slug].astro +17 -0
  252. package/website/pages/guide/[slug].astro +30 -0
  253. package/website/pages/guide/index.astro +21 -0
  254. package/website/pages/index.astro +9 -0
  255. package/website/plugins/remark-link-base.js +23 -0
  256. package/website/utils/url.ts +30 -0
@@ -0,0 +1,180 @@
1
+ import { Affine3, Vector3 } from "../../math/index.js"
2
+ import { copyBuffer } from "../../utils/index.js"
3
+ import { Attribute } from "../attribute/index.js"
4
+
5
+ export class SeparateAttributeData {
6
+ /**
7
+ * Internal storage for attribute data.
8
+ * @type {Map<string, DataView>}
9
+ * */
10
+ #data = new Map()
11
+
12
+ /**
13
+ * Tracks if the attribute data has changed since last checked.
14
+ * @type {boolean}
15
+ * */
16
+ #changed = false
17
+
18
+ /**
19
+ * @package
20
+ * @returns {boolean}
21
+ * Indicates if the data has changed since last queried.
22
+ * Automatically resets the flag.
23
+ */
24
+ get changed() {
25
+ const wasChanged = this.#changed
26
+ this.#changed = false
27
+ return wasChanged
28
+ }
29
+
30
+ /**
31
+ * Sets an attribute data entry.
32
+ * @param {string} name
33
+ * @param {DataView<ArrayBufferLike>} data
34
+ * @returns {this}
35
+ */
36
+ set(name, data) {
37
+ this.#data.set(name, data)
38
+ this.#changed = true
39
+ return this
40
+ }
41
+
42
+ /**
43
+ * Retrieves an attribute data entry.
44
+ * @param {string} name
45
+ * @returns {DataView | undefined}
46
+ */
47
+ get(name) {
48
+ return this.#data.get(name)
49
+ }
50
+
51
+ /**
52
+ * Checks if an attribute exists.
53
+ * @param {string} name
54
+ * @returns {boolean}
55
+ */
56
+ has(name) {
57
+ return this.#data.has(name)
58
+ }
59
+
60
+ /**
61
+ * Deletes an attribute by name.
62
+ * @param {string} name
63
+ * @returns {boolean}
64
+ */
65
+ delete(name) {
66
+ const result = this.#data.delete(name)
67
+ if (result) this.#changed = true
68
+ return result
69
+ }
70
+
71
+ /**
72
+ * Clears all attribute data.
73
+ * @returns {this}
74
+ */
75
+ clear() {
76
+ if (this.#data.size > 0) {
77
+ this.#data.clear()
78
+ this.#changed = true
79
+ }
80
+ return this
81
+ }
82
+
83
+ keys(){
84
+ return this.#data.keys()
85
+ }
86
+
87
+ values(){
88
+ return this.#data.values()
89
+ }
90
+
91
+ entries(){
92
+ this.#data.entries()
93
+ }
94
+
95
+ /**
96
+ * Merges this attribute data with another instance.
97
+ * @param {SeparateAttributeData} other
98
+ * @returns {SeparateAttributeData}
99
+ */
100
+ merge(other) {
101
+ const newAttributes = new SeparateAttributeData()
102
+
103
+ for (const [id, data] of this.#data) {
104
+ const otherData = other.get(id)
105
+ if (!otherData) continue
106
+
107
+ const newData = new ArrayBuffer(otherData.byteLength + data.byteLength)
108
+ copyBuffer(data.buffer, newData, 0, data.byteLength)
109
+ copyBuffer(otherData.buffer, newData, data.byteLength, otherData.byteLength)
110
+
111
+ newAttributes.set(id, new DataView(newData))
112
+ }
113
+
114
+ if (newAttributes.#data.size > 0) {
115
+ newAttributes.#changed = true
116
+ }
117
+
118
+ return newAttributes
119
+ }
120
+
121
+ /**
122
+ * Transforms attribute data using an affine transformation.
123
+ * @param {Affine3} affine
124
+ */
125
+ transform(affine) {
126
+ const positions = this.get(Attribute.Position.name)
127
+ const normals = this.get(Attribute.Normal.name)
128
+ const tangents = this.get(Attribute.Tangent.name)
129
+
130
+ if (positions) {
131
+ const trPositions = new Float32Array(positions.buffer, positions.byteOffset, positions.byteLength / Float32Array.BYTES_PER_ELEMENT)
132
+ for (let i = 0; i < trPositions.length; i += 3) {
133
+ const position = new Vector3(
134
+ trPositions[i],
135
+ trPositions[i + 1],
136
+ trPositions[i + 2],
137
+ )
138
+ affine.transform(position)
139
+ trPositions[i] = position.x
140
+ trPositions[i + 1] = position.y
141
+ trPositions[i + 2] = position.z
142
+ }
143
+ this.#changed = true
144
+ }
145
+
146
+ if (normals) {
147
+ const floats = new Float32Array(normals.buffer, normals.byteOffset, normals.byteLength / Float32Array.BYTES_PER_ELEMENT)
148
+ for (let i = 0; i < floats.length; i += 3) {
149
+ const normal = new Vector3(
150
+ floats[i],
151
+ floats[i + 1],
152
+ floats[i + 2],
153
+ )
154
+ affine.transformWithoutTranslation(normal)
155
+ floats[i] = normal.x
156
+ floats[i + 1] = normal.y
157
+ floats[i + 2] = normal.z
158
+ }
159
+ this.#changed = true
160
+ }
161
+
162
+ if (tangents) {
163
+ const floats = new Float32Array(tangents.buffer, tangents.byteOffset, tangents.byteLength / Float32Array.BYTES_PER_ELEMENT)
164
+ for (let i = 0; i < floats.length; i += 3) {
165
+ const tangent = new Vector3(
166
+ floats[i],
167
+ floats[i + 1],
168
+ floats[i + 2],
169
+ )
170
+ affine.transformWithoutTranslation(tangent)
171
+ floats[i] = tangent.x
172
+ floats[i + 1] = tangent.y
173
+ floats[i + 2] = tangent.z
174
+ }
175
+ this.#changed = true
176
+ }
177
+
178
+ return this
179
+ }
180
+ }
@@ -0,0 +1,41 @@
1
+ import { abstractClass, abstractMethod } from "../../utils/index.js"
2
+ import { Mesh } from "../mesh.js"
3
+
4
+ /**
5
+ * @abstract
6
+ */
7
+ export class MeshBuilder {
8
+ attributes = new MeshBuilderVertexAttributes()
9
+
10
+ constructor() {
11
+ abstractClass(this, MeshBuilder)
12
+ }
13
+ /**
14
+ * @returns {Mesh}
15
+ */
16
+ build() {
17
+ abstractMethod(this, MeshBuilder, MeshBuilder.prototype.build.name)
18
+ }
19
+ }
20
+
21
+ export class MeshBuilderVertexAttributes {
22
+ /**
23
+ * @type {boolean}
24
+ */
25
+ position = true
26
+
27
+ /**
28
+ * @type {boolean}
29
+ */
30
+ uvs = true
31
+
32
+ /**
33
+ * @type {boolean}
34
+ */
35
+ normals = true
36
+
37
+ /**
38
+ * @type {boolean}
39
+ */
40
+ tangents = false
41
+ }
@@ -0,0 +1,63 @@
1
+ import { Attribute } from "../attribute/index.js"
2
+ import { SeparateAttributeData } from "../attributedata/index.js"
3
+ import { Mesh } from "../mesh.js"
4
+ import { MeshBuilder } from "./base.js"
5
+
6
+ export class Circle3DMeshBuilder extends MeshBuilder {
7
+ radius = 0.5
8
+ segments = 32
9
+ arcStart = 0
10
+ arcLength = Math.PI * 2
11
+ /**
12
+ * @override
13
+ */
14
+ build() {
15
+ const { radius, arcStart: arcstart, arcLength: arclength, segments} = this
16
+ const vertices = [0, 0, 0]
17
+ const normals = [0, 0, 1]
18
+ const uvs = [0.5, 0.5]
19
+ const indices = []
20
+ const angleIncrement = arclength / segments
21
+ const epilson = Math.pow(2, -31)
22
+
23
+ for (let angle = arcstart; angle < arcstart + arclength + epilson; angle += angleIncrement) {
24
+ const cos = Math.cos(angle)
25
+ const sin = Math.sin(angle)
26
+
27
+ vertices.push(
28
+ radius * cos,
29
+ radius * sin,
30
+ 0
31
+ )
32
+ normals.push(
33
+ 0, 0, 1
34
+ )
35
+ uvs.push(
36
+ (cos + 1) * 0.5, (sin + 1) * 0.5,
37
+ )
38
+ }
39
+ for (let i = 2; i < vertices.length / 3; i++) {
40
+ indices.push(i - 1, i, 0)
41
+ }
42
+
43
+ const attributes = new SeparateAttributeData()
44
+
45
+ attributes
46
+ .set(
47
+ Attribute.Position.name,
48
+ new DataView(new Float32Array(vertices).buffer)
49
+ )
50
+ .set(
51
+ Attribute.Normal.name,
52
+ new DataView(new Float32Array(normals).buffer)
53
+ )
54
+ .set(
55
+ Attribute.UV.name,
56
+ new DataView(new Float32Array(uvs).buffer)
57
+ )
58
+ const mesh = new Mesh(attributes)
59
+ mesh.indices = new Uint16Array(indices)
60
+
61
+ return mesh
62
+ }
63
+ }
@@ -0,0 +1,135 @@
1
+ import { Affine3, Quaternion, Vector3 } from "../../math/index.js"
2
+ import { SeparateAttributeData } from "../attributedata/index.js"
3
+ import { Mesh } from "../mesh.js"
4
+ import { PlaneMeshBuilder } from "./plane.js"
5
+ import { MeshBuilder } from "./base.js"
6
+ import { mergeMeshes } from "./utils.js"
7
+
8
+ export class CuboidMeshBuilder extends MeshBuilder {
9
+ /**
10
+ * @type {number}
11
+ */
12
+ width = 1
13
+ /**
14
+ * @type {number}
15
+ */
16
+ height = 1
17
+ /**
18
+ * @type {number}
19
+ */
20
+ depth = 1
21
+ /**
22
+ * @type {number}
23
+ */
24
+ widthSegments = 1
25
+ /**
26
+ * @type {number}
27
+ */
28
+ heightSegments = 1
29
+ /**
30
+ * @type {number}
31
+ */
32
+ depthSegments = 1
33
+ /**
34
+ * @type {CuboidOpenFaces}
35
+ */
36
+ openFaces = new CuboidOpenFaces()
37
+
38
+ /**
39
+ * @override
40
+ */
41
+ build() {
42
+ const halfWidth = this.width / 2
43
+ const halfHeight = this.height / 2
44
+ const halfDepth = this.depth / 2
45
+
46
+ const sideBuilder = new PlaneMeshBuilder()
47
+ const affine = new Affine3()
48
+ let meshes = []
49
+
50
+ sideBuilder.width = this.width
51
+ sideBuilder.height = this.height
52
+ sideBuilder.widthSegments = this.widthSegments
53
+ sideBuilder.heightSegments = this.heightSegments
54
+
55
+ if (!this.openFaces.front) {
56
+ affine.compose(
57
+ new Vector3(0, 0, halfDepth),
58
+ Quaternion.Identity,
59
+ new Vector3(1, 1, 1)
60
+ )
61
+
62
+ meshes.push(sideBuilder.build().transform(affine))
63
+ }
64
+
65
+ if (!this.openFaces.back) {
66
+ affine.compose(
67
+ new Vector3(0, 0, -halfDepth),
68
+ Quaternion.fromEuler(0, Math.PI, 0),
69
+ new Vector3(1, 1, 1)
70
+ )
71
+
72
+ meshes.push(sideBuilder.build().transform(affine))
73
+ }
74
+
75
+ sideBuilder.width = this.depth
76
+ sideBuilder.height = this.height
77
+ sideBuilder.widthSegments = this.depthSegments
78
+ sideBuilder.heightSegments = this.heightSegments
79
+
80
+ if (!this.openFaces.left) {
81
+ affine.compose(
82
+ new Vector3(-halfWidth, 0, 0),
83
+ Quaternion.fromEuler(0, -Math.PI / 2, 0),
84
+ new Vector3(1, 1, 1)
85
+ )
86
+
87
+ meshes.push(sideBuilder.build().transform(affine))
88
+ }
89
+
90
+ if (!this.openFaces.right) {
91
+ affine.compose(
92
+ new Vector3(halfWidth, 0, 0),
93
+ Quaternion.fromEuler(0, Math.PI / 2, 0),
94
+ new Vector3(1, 1, 1)
95
+ )
96
+
97
+ meshes.push(sideBuilder.build().transform(affine))
98
+ }
99
+
100
+ sideBuilder.width = this.width
101
+ sideBuilder.height = this.depth
102
+ sideBuilder.widthSegments = this.depthSegments
103
+ sideBuilder.heightSegments = this.depthSegments
104
+
105
+ if (!this.openFaces.top) {
106
+ affine.compose(
107
+ new Vector3(0, halfHeight, 0),
108
+ Quaternion.fromEuler(-Math.PI / 2, 0, 0),
109
+ new Vector3(1, 1, 1)
110
+ )
111
+
112
+ meshes.push(sideBuilder.build().transform(affine))
113
+ }
114
+
115
+ if (!this.openFaces.bottom) {
116
+ affine.compose(
117
+ new Vector3(0, -halfHeight, 0),
118
+ Quaternion.fromEuler(Math.PI / 2, 0, 0),
119
+ new Vector3(1, 1, 1)
120
+ )
121
+
122
+ meshes.push(sideBuilder.build().transform(affine))
123
+ }
124
+ return mergeMeshes(meshes) || new Mesh(new SeparateAttributeData())
125
+ }
126
+ }
127
+
128
+ export class CuboidOpenFaces {
129
+ top = false
130
+ bottom = false
131
+ left = false
132
+ right = false
133
+ front = false
134
+ back = false
135
+ }
@@ -0,0 +1,131 @@
1
+ import { Affine3, Quaternion, Vector3 } from "../../math/index.js"
2
+ import { Attribute } from "../attribute/index.js"
3
+ import { SeparateAttributeData } from "../attributedata/index.js"
4
+ import { Mesh } from "../mesh.js"
5
+ import { Circle3DMeshBuilder } from "./circle.js"
6
+ import { mergeMeshes } from "./utils.js"
7
+
8
+ export class CylinderMeshBuilder {
9
+ radiusTop = 0.5
10
+ radiusBottom = 0.5
11
+ height = 1
12
+ radialSegments = 32
13
+ heightSegments = 1
14
+ arcStart = 0
15
+ arcLength = Math.PI * 2
16
+ /**
17
+ * @type {CylinderOpenEnds}
18
+ */
19
+ openEnds = {
20
+ top: false,
21
+ bottom: false
22
+ }
23
+
24
+ build() {
25
+ const halfHeight = this.height / 2
26
+ const capBuilder = new Circle3DMeshBuilder()
27
+ const transform = new Affine3()
28
+ const torso = generateTorso.call(this)
29
+ const meshes = [torso]
30
+
31
+ capBuilder.segments = this.radialSegments
32
+ capBuilder.arcStart = this.arcStart
33
+ capBuilder.arcLength = this.arcLength
34
+
35
+ if (!this.openEnds.top) {
36
+ transform.compose(
37
+ new Vector3(0, halfHeight, 0),
38
+ Quaternion.fromEuler(-Math.PI / 2, 0, -Math.PI * 0.5),
39
+ new Vector3(1, 1, 1)
40
+ )
41
+ capBuilder.radius = this.radiusTop
42
+ meshes.push(capBuilder.build().transform(transform))
43
+ }
44
+ if (!this.openEnds.bottom) {
45
+ transform.compose(
46
+ new Vector3(0, -halfHeight, 0),
47
+ Quaternion.fromEuler(-Math.PI / 2, 0, -Math.PI * 0.5),
48
+ new Vector3(1, 1, 1)
49
+ )
50
+ capBuilder.radius = this.radiusBottom
51
+ meshes.push(capBuilder.build().transform(transform))
52
+ }
53
+ return mergeMeshes(meshes) || torso
54
+ }
55
+ }
56
+
57
+ /**
58
+ * @this {CylinderMeshBuilder}
59
+ * @returns {Mesh}
60
+ */
61
+ function generateTorso() {
62
+ const { radiusTop, radiusBottom, height, radialSegments, heightSegments, arcStart: thetaStart, arcLength: thetaLength } = this
63
+ const indices = [];
64
+ const positions = [];
65
+ const normals = [];
66
+ const uvs = [];
67
+
68
+ const halfHeight = height / 2;
69
+ const attributes = new SeparateAttributeData()
70
+ const mesh = new Mesh(attributes)
71
+ const normal = new Vector3();
72
+ const slope = (radiusBottom - radiusTop) / height;
73
+
74
+ for (let y = 0; y <= heightSegments; y++) {
75
+ const v = y / heightSegments;
76
+ const radius = v * (radiusBottom - radiusTop) + radiusTop;
77
+
78
+ for (let x = 0; x <= radialSegments; x++) {
79
+ const u = x / radialSegments;
80
+ const theta = u * thetaLength + thetaStart;
81
+ const sinTheta = Math.sin(theta);
82
+ const cosTheta = Math.cos(theta);
83
+
84
+ positions.push(
85
+ radius * sinTheta,
86
+ - v * height + halfHeight,
87
+ radius * cosTheta
88
+ );
89
+
90
+ normal.set(sinTheta, slope, cosTheta).normalize();
91
+ normals.push(normal.x, normal.y, normal.z);
92
+
93
+ uvs.push(u, 1 - v);
94
+ }
95
+ }
96
+
97
+ for (let x = 0; x < radialSegments; x++) {
98
+ for (let y = 0; y < heightSegments; y++) {
99
+ const a = y * (radialSegments + 1) + x
100
+ const b = (y + 1) * (radialSegments + 1) + x
101
+ const c = (y + 1) * (radialSegments + 1) + (x + 1)
102
+ const d = (y) * (radialSegments + 1) + (x + 1)
103
+
104
+ indices.push(a, b, d);
105
+ indices.push(b, c, d);
106
+ }
107
+ }
108
+
109
+
110
+ attributes
111
+ .set(
112
+ Attribute.Position.name,
113
+ new DataView(new Float32Array(positions).buffer)
114
+ )
115
+ .set(
116
+ Attribute.Normal.name,
117
+ new DataView(new Float32Array(normals).buffer)
118
+ )
119
+ .set(
120
+ Attribute.UV.name,
121
+ new DataView(new Float32Array(uvs).buffer)
122
+ )
123
+ mesh.indices = new Uint16Array(indices)
124
+ return mesh
125
+ }
126
+
127
+ /**
128
+ * @typedef CylinderOpenEnds
129
+ * @property {boolean} top
130
+ * @property {boolean} bottom
131
+ */
@@ -0,0 +1,7 @@
1
+ export * from './base.js'
2
+ export * from './plane.js'
3
+ export * from './circle.js'
4
+ export * from './cylinder.js'
5
+ export * from './cuboid.js'
6
+ export * from './uvsphere.js'
7
+ export * from './wireframe.js'
@@ -0,0 +1,73 @@
1
+ import { Attribute } from "../attribute/attribute.js";
2
+ import { SeparateAttributeData } from "../attributedata/separate.js";
3
+ import { Mesh } from "../mesh.js";
4
+ import { MeshBuilder } from "./base.js";
5
+
6
+ export class PlaneMeshBuilder extends MeshBuilder {
7
+ width = 1
8
+ height = 1
9
+ widthSegments = 1
10
+ heightSegments = 1
11
+
12
+ /**
13
+ * @override
14
+ */
15
+ build() {
16
+ const positions = []
17
+ const normals = []
18
+ const uvs = []
19
+ const indices = []
20
+
21
+ const widthHalf = this.width / 2;
22
+ const heightHalf = this.height / 2;
23
+ const gridX = this.widthSegments
24
+ const gridY = this.heightSegments
25
+ const gridX1 = gridX + 1;
26
+ const gridY1 = gridY + 1;
27
+ const segmentWidth = this.width / gridX;
28
+ const segmentHeight = this.height / gridY
29
+
30
+ for (let i = 0; i < gridY1; i++) {
31
+ const dy = i * segmentHeight - heightHalf;
32
+ for (let y = 0; y < gridX1; y++) {
33
+ const dx = y * segmentWidth - widthHalf;
34
+
35
+ positions.push(dx, -dy, 0);
36
+ normals.push(0, 0, 1);
37
+ uvs.push(y / gridX, 1 - (i / gridY));
38
+ }
39
+ }
40
+
41
+ for (let x = 0; x < gridY; x++) {
42
+ for (let y = 0; y < gridX; y++) {
43
+ const a = y + gridX1 * x;
44
+ const b = y + gridX1 * (x + 1);
45
+ const c = (y + 1) + gridX1 * (x + 1);
46
+ const d = (y + 1) + gridX1 * x;
47
+
48
+ indices.push(a, b, d);
49
+ indices.push(b, c, d);
50
+ }
51
+ }
52
+
53
+ const attributes = new SeparateAttributeData()
54
+
55
+ attributes
56
+ .set(
57
+ Attribute.Position.name,
58
+ new DataView(new Float32Array(positions).buffer)
59
+ )
60
+ .set(
61
+ Attribute.Normal.name,
62
+ new DataView(new Float32Array(normals).buffer)
63
+ )
64
+ .set(
65
+ Attribute.UV.name,
66
+ new DataView(new Float32Array(uvs).buffer)
67
+ )
68
+ const mesh = new Mesh(attributes)
69
+ mesh.indices = new Uint16Array(indices)
70
+ return mesh
71
+ }
72
+ }
73
+
@@ -0,0 +1,20 @@
1
+ import { Mesh } from "../mesh.js"
2
+
3
+ /**
4
+ * @param {Mesh[]} meshes
5
+ */
6
+ export function mergeMeshes(meshes) {
7
+ let result = meshes[0]
8
+
9
+ if (!result) {
10
+ return
11
+ }
12
+
13
+ for (let i = 1; i < meshes.length; i++) {
14
+ const nextMesh = /**@type {Mesh}*/ (meshes[i])
15
+
16
+ result = result.merge(nextMesh)
17
+ }
18
+
19
+ return result
20
+ }