├── .gitignore
├── README.md
├── assets
├── in_out_test.ai
├── in_out_test.png
├── models
│ ├── binaries
│ │ ├── chthulu.bin
│ │ ├── chthulu.js
│ │ ├── dwarf.bin
│ │ ├── dwarf.js
│ │ ├── plane.bin
│ │ ├── plane.js
│ │ ├── spider.bin
│ │ ├── spider.js
│ │ ├── suzanne.bin
│ │ ├── suzanne.js
│ │ ├── suzanne_invert.bin
│ │ └── suzanne_invert.js
│ └── particles
│ │ ├── dwarf
│ │ ├── dwarf2k.txt
│ │ ├── dwarf32k.txt
│ │ └── dwarf4k.txt
│ │ ├── plane
│ │ └── plane65k.txt
│ │ ├── spider
│ │ └── spider32k.txt
│ │ └── suzanne
│ │ ├── skeleton65k.txt
│ │ └── volume65k.txt
├── normals.png
├── source
│ ├── BK_WIDOW
│ │ ├── BK_WIDOW.3DS
│ │ ├── BK_WIDOW.DXF
│ │ ├── BK_WIDOW.JPG
│ │ ├── BK_WIDOW.LWO
│ │ ├── BK_WIDOW.MTL
│ │ ├── BK_WIDOW.OBJ
│ │ └── BK_WIDOW.TIF
│ ├── chthulu.max
│ ├── convert.py
│ ├── dwarf.obj
│ ├── plane.obj
│ ├── skeleton.max
│ ├── skeleton
│ │ ├── skeleton.3DS
│ │ ├── skeleton.max
│ │ ├── skeleton.mtl
│ │ └── skeleton.obj
│ ├── skeletor.obj
│ ├── skull.max
│ ├── spider.max
│ └── suzanne.max
├── textures
│ ├── matcap
│ │ ├── 00ZBrush_RedWax.png
│ │ ├── BazC_SkinMat.jpg
│ │ ├── JGSpecial_01.png
│ │ ├── JG_Drink01.png
│ │ ├── JG_Gold.png
│ │ ├── JG_Red.png
│ │ ├── chrome_dark.png
│ │ ├── chrome_eye.png
│ │ ├── close_to_50.png
│ │ ├── darker.jpg
│ │ ├── droplet_01.png
│ │ ├── env.png
│ │ ├── generator1.jpg
│ │ ├── generator3.jpg
│ │ ├── generator5.jpg
│ │ ├── generator6.jpg
│ │ ├── generator7.jpg
│ │ ├── generator8.jpg
│ │ ├── generator9.jpg
│ │ ├── genetic.png
│ │ ├── ghost.jpg
│ │ ├── gold.png
│ │ ├── green_gel.png
│ │ ├── grey_reflective.jpg
│ │ ├── index.json
│ │ ├── mashrim.png
│ │ ├── mashrim2.jpg
│ │ ├── matcap.png
│ │ ├── material2.png
│ │ ├── material3.jpg
│ │ ├── material4.png
│ │ ├── mshade3.jpg
│ │ ├── mshade4.jpg
│ │ ├── mshade5.jpg
│ │ ├── normals.jpg
│ │ ├── old_gold.png
│ │ ├── red_bob.jpg
│ │ ├── red_clay.jpg
│ │ ├── right_light.jpg
│ │ ├── scary-light.jpg
│ │ ├── silver.jpg
│ │ ├── skintone.jpg
│ │ ├── softunderlight.png
│ │ ├── strong rim.png
│ │ ├── test_gold.jpg
│ │ ├── test_steel.jpg
│ │ ├── thuggle.jpg
│ │ ├── thuglee-03.jpg
│ │ ├── thuglee-backlight-01.jpg
│ │ ├── thuglee-chrome-02b.jpg
│ │ └── untitled.6.jpg
│ └── particles.png
└── valid.png
├── dwarf.html
├── glsl
├── env_fs.glsl
├── env_vs.glsl
├── line_sem_fs.glsl
├── line_sem_vs.glsl
├── meshline_fs.glsl
├── meshline_vs.glsl
├── particles_fs.glsl
├── particles_vs.glsl
├── sem_fs.glsl
├── sem_vs.glsl
├── texture_particles_fs.glsl
├── texture_particles_vs.glsl
└── tmp
├── img
├── dwarf.jpg
├── plane.jpg
├── spider.jpg
├── suzanne.jpg
└── suzanne_distribution.jpg
├── js
├── common
│ ├── Scatter.js
│ ├── assetsLoader.js
│ └── scene3d.js
├── dwarf.js
├── dwarf_bk.js
├── plane.js
├── spider.js
└── suzanne.js
├── plane.html
├── spider.html
├── sreenshots
├── 4k.png
├── 4k0.png
├── 4k1.png
├── 4k2.png
├── 4k3.png
├── 8k0.png
├── 8k1.png
├── lines0.png
├── lines1.png
└── spider0.png
├── suzanne.html
└── vendor
├── BinaryLoader.js
├── OrbitControls.js
├── THREE.MeshLine.js
└── three.js
/.gitignore:
--------------------------------------------------------------------------------
1 | #ignore thumbnails created by windows
2 | Thumbs.db
3 | /sreenshots/
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # volume distribution
2 | distributing 3D vectors inside a mesh with THREE.js
3 |
4 | 
5 | this post and demos are also [available here](http://barradeau.com/blog/?p=1058)
6 |
7 | the idea is to distribute (scatter) a set of random 3D points inside a volume, preferably an arbitrary mesh.
8 |
9 | distributing random points in geometric volumes is quite straight forward. if you know the formula of a sphere, a cube, a cylinder or any shape, you can create a point inside the said shape. also, and much like Constructive Solid Geometry, it’s fairly easy to use boolean operations (union, subtraction, intersection & XOR) between the shapes and obtain a broad variety of complex shapes.
10 |
11 | if this approach is elegant, probably fast and efficient, it has a big downside ; arbitrary meshes are hard – if not impossible – to model with equations. it is therefore often limited to simple use cases like procedural or fractals shapes.
12 |
13 | being a long time 3DS max user, I often used the “Scatter” modifier to distribute point on or inside a mesh. when I used a non-manifold polyhedron – a “broken” mesh, with holes, no inside or outside – the modifier failed or 3DS crashed. that’s when I decided to try to code something.
14 |
15 | the algorithm goes as follow:
16 |
17 | * pick a random point on the bounding volume of the mesh and a random direction
18 | * shoot a ray at the mesh from that origin, in that direction
19 | * evaluate the result to keep or discard the intersection points
20 | it implies shooting many rays at a mesh so depending on the mesh’s complexity, it can take a lot of time and anyway it’s more suited as a mesh “pre-processor” than as a real time modifier.
21 |
22 | step 1 is trivial, for step 2, THREE.js has a built-in raycaster and for step 3, we’ll mostly need to determine if we’re ‘inside’ or ‘outside’ the mesh.
23 |
24 | to determine if a point is inside or outside a polyhedron, assuming the mesh is a manifold (it has an ‘inside’ and an ‘outside’), we can shoot a ray from that point in any direction and count how many times the ray intersects the polyhedron.
25 |
26 | if the number is even, your point is outside, if it’s odd, it’s inside. a visual explanation:
27 |
28 | 
29 |
30 | I think it also works with actual octopuses but I would recommend not to try.
31 |
32 | essentially, we’ll use the number of times a ray intersects the mesh to determine wether we’re inside or outside. here’s my implementation:
33 |
34 | ```javascript
35 | var raycaster;//THREE.raycaster: used to shoot rays at the mesh
36 | var o;//ray origin
37 | var d;//ray direction
38 | var intersections;//stores the result of the raycasting
39 | var a;//DOM element tag to download the result ( see particlesToString )
40 |
41 | function distribute( mesh, count ) {
42 |
43 | //this will store the results
44 | var coords = [];
45 | var dests = [];
46 | //temporary vars to store the position and destination
47 | var p0, p1;
48 |
49 | //this has an influence as to how the raycasting is performed
50 | var side = mesh.material.side;
51 | mesh.material.side = THREE.DoubleSide;
52 |
53 | //we'll need normals (it's probably done implicitly when we raycast though)
54 | mesh.geometry.computeFaceNormals();
55 |
56 | //this is used to distributte the origins of the rays
57 | mesh.geometry.computeBoundingBox();
58 | var bbox = mesh.geometry.boundingBox;
59 |
60 | // 'inflates' the box by 10% to prevent colinearity
61 | // or coplanarity of the origin with the mesh
62 | bbox.min.multiplyScalar( 1.1 );
63 | bbox.max.multiplyScalar( 1.1 );
64 |
65 | //computes the box' size to compute random points
66 | var size = bbox.max.sub( bbox.min );
67 |
68 | //to perform raycast
69 | raycaster = raycaster || new THREE.Raycaster();
70 | o = o || new THREE.Vector3();
71 | d = d || new THREE.Vector3();
72 |
73 | for( var i = 0; i < count; i++ ){
74 |
75 | // randomize the rays origin
76 | o.x = bbox.min.x + Math.random() * size.x;
77 | o.y = bbox.min.y + Math.random() * size.y;
78 | o.z = bbox.min.z + Math.random() * size.z;
79 |
80 | //randomize the ray's direction
81 | d.x = ( Math.random() - .5 );
82 | d.y = ( Math.random() - .5 );
83 | d.z = ( Math.random() - .5 );
84 | d.normalize();
85 |
86 | //sets the raycaster
87 | raycaster.set( o, d );
88 |
89 | //shoots the ray
90 | intersections = raycaster.intersectObject( mesh, false );
91 |
92 | //no result
93 | if( intersections.length == 0 ){
94 |
95 | //bail out & continue
96 | i--;
97 |
98 | }else{
99 |
100 | //checks if we meet the conditions:
101 | //the origin must be outside
102 | var valid = intersections.length >= 2 && (intersections.length % 2==0);
103 | if (valid) {
104 |
105 | //tests all the intersection pairs
106 | var additions = -1;
107 | for( var j = 0; j < intersections.length; j+= 2 ){
108 |
109 | // make sure that the origin -> direction vector have the same
110 | // direction as the normal of the face they hit
111 |
112 | //test the direction against the outwards' face's normal
113 | var dp0 = d.dot(intersections[ j + 1 ].face.normal) <= 0;
114 |
115 | //flips the direction to make it 'look at' the origin
116 | d.negate();
117 |
118 | //test the direction against the inwards' face's normal
119 | var dp1 = d.dot(intersections[ j ].face.normal) <= 0;
120 |
121 | //flips the direction again for the next test
122 | d.negate();
123 |
124 | // if both vectors pairs head in the same direction
125 | // the point is guarranteed to be inside
126 | if( dp0 || dp1){
127 | continue;
128 | }
129 |
130 | //adds the points
131 | if( coords.length < count * 3 ){
132 | console.log("ok")
133 | p0 = intersections[j].point;
134 | coords.push( p0.x, p0.y, p0.z);
135 | p1 = intersections[j+1].point;
136 | dests.push( p1.x, p1.y, p1.z);
137 | additions++;
138 | }
139 | }
140 | //increments the counter by the number of additions
141 | i += additions;
142 |
143 | }else{
144 | //invalid intersection, try again...
145 | i--;
146 | }
147 | }
148 | }
149 | //resets the material side
150 | mesh.material.side = side;
151 | return {
152 | pos:coords,
153 | dst:dests
154 | };
155 | };
156 | ```
157 | this is rather self-explanatory (hopefully) ; we get the bounding box of the mesh, ‘inflate’ it a bit to avoid some colinearity / coplanarity issues, then randomize the ray’s origin/direction. performa ray casting onto the mesh then classify the result.
158 |
159 | let’s focus on the ‘classify’ bit a minute:
160 |
161 |
162 | ```javascript
163 | //the origin must be outside
164 | var valid = intersections.length >= 2 && ( intersections.length % 2 == 0 );
165 | if (valid) {
166 | [...]
167 | ```
168 | we’re in a valid state if we have: at least 2 intersections and an even number of intersections which means that we hit the mesh at least once and our origin is outside the mesh ( as seen above with that glorious octopus illustration ). we have something like this when valid is true:
169 | valid
170 | 
171 |
172 | the next bit takes all pairs of points and retrieves the associated normals like so:
173 | 
174 | and computes the dot product between the 2 vectors of the same color. if the dot product of 2 vectors is positive, they’re heading in the same direction, if the dot product is negative, they are heading in opposite directions and if it’s 0, they are perpendicular. this dreadful 4 liners will do this for all intersections pairs.
175 |
176 | ```javascript
177 | //test the direction against the outwards' face's normal
178 | var dp0 = d.dot(intersections[ j + 1 ].face.normal) <= 0;
179 |
180 | //flips the direction to make it 'look at' the origin
181 | d.negate();
182 |
183 | //test the direction against the inwards' face's normal
184 | var dp1 = d.dot(intersections[ j ].face.normal) <= 0;
185 |
186 | //flips the direction again for the next test
187 | d.negate();
188 |
189 | // if both vectors pairs head in the same direction
190 | // the point is guarranteed to be inside
191 | if( dp0 || dp1){
192 | continue;
193 | }
194 | ```
195 | this ensures that the “broken polyhedra” work too ; if the 2 faces’ normals head in the same direction, the object is broken ; it has no inside or outside. the code above checks this case and bails out if need be. it can also collect more than 2 points per ray which is nice :)
196 |
197 | you would call it like:
198 |
199 | ```javascript
200 | var model = CHTHULU;//a THREE.Mesh
201 | var count = Math.pow( 2, 12 );// -> 4096 point pairs
202 |
203 | //call the method and strore the result in a prticles object
204 | var inside = distribute( model, count );
205 | ```
206 |
207 | the result of the distribute function is a pair of float32Arrays containing XYZ triplets for the in & out positions respectively. to place an object ‘inside’ the polyhedron, you’d do something like:
208 |
209 | ```javascript
210 | //midpoint of the 2 intersection points
211 | var p = new THREE.Vector3(
212 | ( inside.pos[ id ].x + inside.dst[ id ].x ) * .5,
213 | ( inside.pos[ id ].y + inside.dst[ id ].y ) * .5,
214 | ( inside.pos[ id ].z + inside.dst[ id ].z ) * .5
215 | );
216 | ```
217 |
218 | or more likely, pass inside.dst as an attribute and ask the shader to mix the two:
219 | ```glsl
220 | float t = abs( sin( time ) );
221 | vec3 pos = mix( position, dest, t );
222 | ```
223 |
224 | with a value t between 0 & 1 which guarantees that the position will remain inside the mesh.
225 |
226 | of course we can change the above to ‘carve’ the mesh inside a cloud of points and keep only the “outside”. :)
227 |
228 | HAMMER TIME!
229 | this is a model with 65K particles floating around (click)
230 |
231 | [](http://www.barradeau.com/2017/volume/suzanne.html)
232 |
233 | if you notice some particles floating around, it’s because the distribution mesh is the mother of all non-manifold polyhedra ^^
234 | 
235 |
236 | this is again 65K particles distributed inside a mesh. notice how it retained the fine details (on the legs for instance)
237 |
238 | [](http://www.barradeau.com/2017/volume/spider.html)
239 |
240 | still 65K particles, this time rendered as line segments
241 |
242 | [](http://www.barradeau.com/2017/volume/plane.html)
243 |
244 | finally a splendid rendition of 2K particles as line sets, using the Spite’s MeshLines. my code is ugly as fuck but hey…
245 |
246 | [](http://www.barradeau.com/2017/volume/dwarf.html)
247 |
248 | and that’s it! well, I gues you get the idea ^^
249 | enjoy :)
--------------------------------------------------------------------------------
/assets/in_out_test.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/in_out_test.ai
--------------------------------------------------------------------------------
/assets/in_out_test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/in_out_test.png
--------------------------------------------------------------------------------
/assets/models/binaries/chthulu.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/models/binaries/chthulu.bin
--------------------------------------------------------------------------------
/assets/models/binaries/chthulu.js:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "metadata" :
4 | {
5 | "formatVersion" : 3.1,
6 | "sourceFile" : "chthulu.obj",
7 | "generatedBy" : "OBJConverter",
8 | "vertices" : 1751,
9 | "faces" : 3488,
10 | "normals" : 0,
11 | "uvs" : 0,
12 | "materials" : 0
13 | },
14 |
15 | "materials": [ {
16 | "DbgColor" : 15658734,
17 | "DbgIndex" : 0,
18 | "DbgName" : "default"
19 | }],
20 |
21 | "buffers": "chthulu.bin"
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/assets/models/binaries/dwarf.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/models/binaries/dwarf.bin
--------------------------------------------------------------------------------
/assets/models/binaries/dwarf.js:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "metadata" :
4 | {
5 | "formatVersion" : 3.1,
6 | "sourceFile" : "dwarf.obj",
7 | "generatedBy" : "OBJConverter",
8 | "vertices" : 3083,
9 | "faces" : 6166,
10 | "normals" : 0,
11 | "uvs" : 0,
12 | "materials" : 0
13 | },
14 |
15 | "materials": [ {
16 | "DbgColor" : 15658734,
17 | "DbgIndex" : 0,
18 | "DbgName" : "default"
19 | }],
20 |
21 | "buffers": "dwarf.bin"
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/assets/models/binaries/plane.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/models/binaries/plane.bin
--------------------------------------------------------------------------------
/assets/models/binaries/plane.js:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "metadata" :
4 | {
5 | "formatVersion" : 3.1,
6 | "sourceFile" : "plane.obj",
7 | "generatedBy" : "OBJConverter",
8 | "vertices" : 866,
9 | "faces" : 1607,
10 | "normals" : 0,
11 | "uvs" : 0,
12 | "materials" : 0
13 | },
14 |
15 | "materials": [ {
16 | "DbgColor" : 15658734,
17 | "DbgIndex" : 0,
18 | "DbgName" : "default"
19 | }],
20 |
21 | "buffers": "plane.bin"
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/assets/models/binaries/spider.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/models/binaries/spider.bin
--------------------------------------------------------------------------------
/assets/models/binaries/spider.js:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "metadata" :
4 | {
5 | "formatVersion" : 3.1,
6 | "sourceFile" : "spider.obj",
7 | "generatedBy" : "OBJConverter",
8 | "vertices" : 1393,
9 | "faces" : 2782,
10 | "normals" : 0,
11 | "uvs" : 0,
12 | "materials" : 0
13 | },
14 |
15 | "materials": [ {
16 | "DbgColor" : 15658734,
17 | "DbgIndex" : 0,
18 | "DbgName" : "default"
19 | }],
20 |
21 | "buffers": "spider.bin"
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/assets/models/binaries/suzanne.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/models/binaries/suzanne.bin
--------------------------------------------------------------------------------
/assets/models/binaries/suzanne.js:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "metadata" :
4 | {
5 | "formatVersion" : 3.1,
6 | "sourceFile" : "suzanne_skeleton.obj",
7 | "generatedBy" : "OBJConverter",
8 | "vertices" : 13270,
9 | "faces" : 26832,
10 | "normals" : 13270,
11 | "uvs" : 0,
12 | "materials" : 0
13 | },
14 |
15 | "materials": [ {
16 | "DbgColor" : 15658734,
17 | "DbgIndex" : 0,
18 | "DbgName" : "default"
19 | }],
20 |
21 | "buffers": "suzanne.bin"
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/assets/models/binaries/suzanne_invert.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/models/binaries/suzanne_invert.bin
--------------------------------------------------------------------------------
/assets/models/binaries/suzanne_invert.js:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "metadata" :
4 | {
5 | "formatVersion" : 3.1,
6 | "sourceFile" : "suzanne_invert.obj",
7 | "generatedBy" : "OBJConverter",
8 | "vertices" : 1070,
9 | "faces" : 912,
10 | "normals" : 0,
11 | "uvs" : 0,
12 | "materials" : 0
13 | },
14 |
15 | "materials": [ {
16 | "DbgColor" : 15658734,
17 | "DbgIndex" : 0,
18 | "DbgName" : "default"
19 | }],
20 |
21 | "buffers": "suzanne_invert.bin"
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/assets/normals.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/normals.png
--------------------------------------------------------------------------------
/assets/source/BK_WIDOW/BK_WIDOW.3DS:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/BK_WIDOW/BK_WIDOW.3DS
--------------------------------------------------------------------------------
/assets/source/BK_WIDOW/BK_WIDOW.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/BK_WIDOW/BK_WIDOW.JPG
--------------------------------------------------------------------------------
/assets/source/BK_WIDOW/BK_WIDOW.LWO:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/BK_WIDOW/BK_WIDOW.LWO
--------------------------------------------------------------------------------
/assets/source/BK_WIDOW/BK_WIDOW.MTL:
--------------------------------------------------------------------------------
1 | # Wavefront material library
2 | # Tue Aug 03 08:00:08 1999
3 | # Created with Viewpoint Interchange www.viewpoint.com
4 |
5 | newmtl blkw_body
6 | Ka 0 0 0
7 | Kd 0 0 0
8 | Ks 0 0 0
9 | illum 2
10 | map_Kd images\bk_widow.tif
11 |
--------------------------------------------------------------------------------
/assets/source/BK_WIDOW/BK_WIDOW.TIF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/BK_WIDOW/BK_WIDOW.TIF
--------------------------------------------------------------------------------
/assets/source/chthulu.max:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/chthulu.max
--------------------------------------------------------------------------------
/assets/source/skeleton.max:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/skeleton.max
--------------------------------------------------------------------------------
/assets/source/skeleton/skeleton.3DS:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/skeleton/skeleton.3DS
--------------------------------------------------------------------------------
/assets/source/skeleton/skeleton.max:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/skeleton/skeleton.max
--------------------------------------------------------------------------------
/assets/source/skeleton/skeleton.mtl:
--------------------------------------------------------------------------------
1 | #
2 | # Wavefront material file
3 | # Converted by the DEEP Exploration Deep Exploration 5.5 5.5.3.2642 Release
4 | # Right Hemisphere, LTD
5 | # http://www.righthemisphere.com/
6 | #
7 |
8 | newmtl Bones___Vray
9 | Ka 0 0 0
10 | Kd 0.584314 0.584314 0.584314
11 | Ks 0 0 0
12 | illum 2
13 | Ns 9.84916
14 | map_Kd
15 | map_bump
16 | bump
17 | map_opacity
18 | map_d
19 | refl
20 | map_kS
21 | map_kA
22 | map_Ns
23 |
24 | newmtl White___Vray
25 | Ka 0 0 0
26 | Kd 0.584314 0.584314 0.584314
27 | Ks 0 0 0
28 | illum 2
29 | Ns 9.84916
30 | map_Kd
31 | map_bump
32 | bump
33 | map_opacity
34 | map_d
35 | refl
36 | map_kS
37 | map_kA
38 | map_Ns
39 |
40 | newmtl Brown___Vray
41 | Ka 0 0 0
42 | Kd 0.584314 0.584314 0.584314
43 | Ks 0 0 0
44 | illum 2
45 | Ns 9.84916
46 | map_Kd
47 | map_bump
48 | bump
49 | map_opacity
50 | map_d
51 | refl
52 | map_kS
53 | map_kA
54 | map_Ns
55 |
56 | newmtl Explorer_Default
57 | Ka 0.117647 0.117647 0.117647
58 | Kd 0.752941 0.752941 0.752941
59 | Ks 0.752941 0.752941 0.752941
60 | illum 2
61 | Ns 8
62 | map_Kd
63 | map_bump
64 | bump
65 | map_opacity
66 | map_d
67 | refl
68 | map_kS
69 | map_kA
70 | map_Ns
71 |
--------------------------------------------------------------------------------
/assets/source/skull.max:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/skull.max
--------------------------------------------------------------------------------
/assets/source/spider.max:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/spider.max
--------------------------------------------------------------------------------
/assets/source/suzanne.max:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/source/suzanne.max
--------------------------------------------------------------------------------
/assets/textures/matcap/00ZBrush_RedWax.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/00ZBrush_RedWax.png
--------------------------------------------------------------------------------
/assets/textures/matcap/BazC_SkinMat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/BazC_SkinMat.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/JGSpecial_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/JGSpecial_01.png
--------------------------------------------------------------------------------
/assets/textures/matcap/JG_Drink01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/JG_Drink01.png
--------------------------------------------------------------------------------
/assets/textures/matcap/JG_Gold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/JG_Gold.png
--------------------------------------------------------------------------------
/assets/textures/matcap/JG_Red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/JG_Red.png
--------------------------------------------------------------------------------
/assets/textures/matcap/chrome_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/chrome_dark.png
--------------------------------------------------------------------------------
/assets/textures/matcap/chrome_eye.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/chrome_eye.png
--------------------------------------------------------------------------------
/assets/textures/matcap/close_to_50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/close_to_50.png
--------------------------------------------------------------------------------
/assets/textures/matcap/darker.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/darker.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/droplet_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/droplet_01.png
--------------------------------------------------------------------------------
/assets/textures/matcap/env.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/env.png
--------------------------------------------------------------------------------
/assets/textures/matcap/generator1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/generator1.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/generator3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/generator3.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/generator5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/generator5.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/generator6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/generator6.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/generator7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/generator7.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/generator8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/generator8.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/generator9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/generator9.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/genetic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/genetic.png
--------------------------------------------------------------------------------
/assets/textures/matcap/ghost.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/ghost.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/gold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/gold.png
--------------------------------------------------------------------------------
/assets/textures/matcap/green_gel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/green_gel.png
--------------------------------------------------------------------------------
/assets/textures/matcap/grey_reflective.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/grey_reflective.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/index.json:
--------------------------------------------------------------------------------
1 | [
2 | "00ZBrush_RedWax.png",
3 | "close_to_50.png",
4 | "droplet_01.png",
5 | "green_gel.png",
6 | "JGSpecial_01.png",
7 | "JG_Drink01.png",
8 | "JG_Gold.png",
9 | "JG_Red.png",
10 | "mashrim.png",
11 | "material2.png",
12 | "material4.png",
13 | "softunderlight.png",
14 | "strong rim.png",
15 | "BazC_SkinMat.jpg",
16 | "darker.jpg",
17 | "generator1.jpg",
18 | "generator3.jpg",
19 | "generator5.jpg",
20 | "generator6.jpg",
21 | "generator7.jpg",
22 | "generator8.jpg",
23 | "generator9.jpg",
24 | "ghost.jpg",
25 | "grey_reflective.jpg",
26 | "mashrim2.jpg",
27 | "material3.jpg",
28 | "mshade3.jpg",
29 | "mshade4.jpg",
30 | "mshade5.jpg",
31 | "normals.jpg",
32 | "red_bob.jpg",
33 | "red_clay.jpg",
34 | "right_light.jpg",
35 | "scary-light.jpg",
36 | "silver.jpg",
37 | "skintone.jpg",
38 | "test_gold.jpg",
39 | "test_steel.jpg",
40 | "thuglee-03.jpg",
41 | "thuglee-backlight-01.jpg",
42 | "thuglee-chrome-02b.jpg",
43 | "untitled.6.jpg"
44 | ]
--------------------------------------------------------------------------------
/assets/textures/matcap/mashrim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/mashrim.png
--------------------------------------------------------------------------------
/assets/textures/matcap/mashrim2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/mashrim2.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/matcap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/matcap.png
--------------------------------------------------------------------------------
/assets/textures/matcap/material2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/material2.png
--------------------------------------------------------------------------------
/assets/textures/matcap/material3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/material3.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/material4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/material4.png
--------------------------------------------------------------------------------
/assets/textures/matcap/mshade3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/mshade3.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/mshade4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/mshade4.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/mshade5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/mshade5.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/normals.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/normals.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/old_gold.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/old_gold.png
--------------------------------------------------------------------------------
/assets/textures/matcap/red_bob.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/red_bob.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/red_clay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/red_clay.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/right_light.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/right_light.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/scary-light.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/scary-light.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/silver.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/silver.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/skintone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/skintone.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/softunderlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/softunderlight.png
--------------------------------------------------------------------------------
/assets/textures/matcap/strong rim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/strong rim.png
--------------------------------------------------------------------------------
/assets/textures/matcap/test_gold.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/test_gold.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/test_steel.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/test_steel.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/thuggle.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/thuggle.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/thuglee-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/thuglee-03.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/thuglee-backlight-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/thuglee-backlight-01.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/thuglee-chrome-02b.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/thuglee-chrome-02b.jpg
--------------------------------------------------------------------------------
/assets/textures/matcap/untitled.6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/matcap/untitled.6.jpg
--------------------------------------------------------------------------------
/assets/textures/particles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/textures/particles.png
--------------------------------------------------------------------------------
/assets/valid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/assets/valid.png
--------------------------------------------------------------------------------
/dwarf.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | THREE.MeshLine - Shape example
6 |
7 |
8 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/glsl/env_fs.glsl:
--------------------------------------------------------------------------------
1 |
2 | uniform vec3 bottomColor;
3 | uniform vec3 topColor;
4 | uniform float horizon;
5 | uniform float spread;
6 | varying float vY;
7 | void main()
8 | {
9 |
10 | float val = smoothstep( horizon-spread, horizon+spread, vY );
11 | gl_FragColor = vec4( mix( bottomColor, topColor, val ), 1. );
12 |
13 |
14 | }
--------------------------------------------------------------------------------
/glsl/env_vs.glsl:
--------------------------------------------------------------------------------
1 | varying float vY;
2 | void main() {
3 |
4 | vY = position.y + .5;
5 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
6 |
7 |
8 | }
--------------------------------------------------------------------------------
/glsl/line_sem_fs.glsl:
--------------------------------------------------------------------------------
1 | uniform sampler2D tMatCap;
2 | uniform float alpha;
3 |
4 | varying vec3 e;
5 | varying vec3 n;
6 |
7 | void main() {
8 |
9 | vec3 r = reflect( e, n );
10 | float m = 2. * sqrt( pow( r.x, 2. ) + pow( r.y, 2. ) + pow( r.z + 1., 2. ) );
11 | vec2 vN = r.xy / m + .5;
12 | vec3 base = texture2D( tMatCap, vN ).rgb;
13 | gl_FragColor = vec4( base, alpha );
14 |
15 | }
--------------------------------------------------------------------------------
/glsl/line_sem_vs.glsl:
--------------------------------------------------------------------------------
1 |
2 | float SimplexPerlin3D( vec3 P )
3 | {
4 | // https://github.com/BrianSharpe/Wombat/blob/master/SimplexPerlin3D.glsl
5 |
6 | // simplex math constants
7 | const float SKEWFACTOR = 1.0/3.0;
8 | const float UNSKEWFACTOR = 1.0/6.0;
9 | const float SIMPLEX_CORNER_POS = 0.5;
10 | const float SIMPLEX_TETRAHADRON_HEIGHT = 0.70710678118654752440084436210485; // sqrt( 0.5 )
11 |
12 | // establish our grid cell.
13 | P *= SIMPLEX_TETRAHADRON_HEIGHT; // scale space so we can have an approx feature size of 1.0
14 | vec3 Pi = floor( P + dot( P, vec3( SKEWFACTOR) ) );
15 |
16 | // Find the vectors to the corners of our simplex tetrahedron
17 | vec3 x0 = P - Pi + dot(Pi, vec3( UNSKEWFACTOR ) );
18 | vec3 g = step(x0.yzx, x0.xyz);
19 | vec3 l = 1.0 - g;
20 | vec3 Pi_1 = min( g.xyz, l.zxy );
21 | vec3 Pi_2 = max( g.xyz, l.zxy );
22 | vec3 x1 = x0 - Pi_1 + UNSKEWFACTOR;
23 | vec3 x2 = x0 - Pi_2 + SKEWFACTOR;
24 | vec3 x3 = x0 - SIMPLEX_CORNER_POS;
25 |
26 | // pack them into a parallel-friendly arrangement
27 | vec4 v1234_x = vec4( x0.x, x1.x, x2.x, x3.x );
28 | vec4 v1234_y = vec4( x0.y, x1.y, x2.y, x3.y );
29 | vec4 v1234_z = vec4( x0.z, x1.z, x2.z, x3.z );
30 |
31 | // clamp the domain of our grid cell
32 | Pi.xyz = Pi.xyz - floor(Pi.xyz * ( 1.0 / 69.0 )) * 69.0;
33 | vec3 Pi_inc1 = step( Pi, vec3( 69.0 - 1.5 ) ) * ( Pi + 1.0 );
34 |
35 | // generate the random vectors
36 | vec4 Pt = vec4( Pi.xy, Pi_inc1.xy ) + vec2( 50.0, 161.0 ).xyxy;
37 | Pt *= Pt;
38 | vec4 V1xy_V2xy = mix( Pt.xyxy, Pt.zwzw, vec4( Pi_1.xy, Pi_2.xy ) );
39 | Pt = vec4( Pt.x, V1xy_V2xy.xz, Pt.z ) * vec4( Pt.y, V1xy_V2xy.yw, Pt.w );
40 | const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );
41 | const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );
42 | vec3 lowz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi.zzz * ZINC.xyz ) );
43 | vec3 highz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi_inc1.zzz * ZINC.xyz ) );
44 | Pi_1 = ( Pi_1.z < 0.5 ) ? lowz_mods : highz_mods;
45 | Pi_2 = ( Pi_2.z < 0.5 ) ? lowz_mods : highz_mods;
46 | vec4 hash_0 = fract( Pt * vec4( lowz_mods.x, Pi_1.x, Pi_2.x, highz_mods.x ) ) - 0.49999;
47 | vec4 hash_1 = fract( Pt * vec4( lowz_mods.y, Pi_1.y, Pi_2.y, highz_mods.y ) ) - 0.49999;
48 | vec4 hash_2 = fract( Pt * vec4( lowz_mods.z, Pi_1.z, Pi_2.z, highz_mods.z ) ) - 0.49999;
49 |
50 | // evaluate gradients
51 | vec4 grad_results = inversesqrt( hash_0 * hash_0 + hash_1 * hash_1 + hash_2 * hash_2 ) * ( hash_0 * v1234_x + hash_1 * v1234_y + hash_2 * v1234_z );
52 |
53 | // Normalization factor to scale the final result to a strict 1.0->-1.0 range
54 | // http://briansharpe.wordpress.com/2012/01/13/simplex-noise/#comment-36
55 | const float FINAL_NORMALIZATION = 37.837227241611314102871574478976;
56 |
57 | // evaulate the kernel weights ( use (0.5-x*x)^3 instead of (0.6-x*x)^4 to fix discontinuities )
58 | vec4 kernel_weights = v1234_x * v1234_x + v1234_y * v1234_y + v1234_z * v1234_z;
59 | kernel_weights = max(0.5 - kernel_weights, 0.0);
60 | kernel_weights = kernel_weights*kernel_weights*kernel_weights;
61 |
62 | // sum with the kernel and return
63 | return dot( kernel_weights, grad_results ) * FINAL_NORMALIZATION;
64 | }
65 | uniform float time;
66 | varying vec3 e;
67 | varying vec3 n;
68 |
69 | void main() {
70 |
71 | vec3 t = vec3( 0, cos( time * .1 ), time * .1 );
72 |
73 | e = normalize( vec3( modelViewMatrix * vec4( position, 1.0 ) ) );
74 | n = normalize( ( modelViewMatrix * vec4( position, 1. ) ).xyz );
75 |
76 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1. );
77 |
78 | }
--------------------------------------------------------------------------------
/glsl/meshline_fs.glsl:
--------------------------------------------------------------------------------
1 | #extension GL_OES_standard_derivatives : enable
2 | precision mediump float;
3 |
4 | uniform sampler2D map;
5 | uniform sampler2D alphaMap;
6 | uniform float useMap;
7 | uniform float useAlphaMap;
8 | uniform float useDash;
9 | uniform vec2 dashArray;
10 | uniform vec2 visibility;
11 | uniform vec2 depth;
12 | uniform float alphaTest;
13 | uniform vec2 repeat;
14 |
15 | varying vec2 vUV;
16 | varying vec4 vColor;
17 | varying float vCounters;
18 | varying float vZ;
19 |
20 | void main() {
21 |
22 | vec4 c = vColor;
23 | if( useMap == 1. ) c *= texture2D( map, vUV * repeat );
24 | if( useAlphaMap == 1. ) c.a *= texture2D( alphaMap, vUV * repeat ).a;
25 | if( c.a < alphaTest ) discard;
26 | if( useDash == 1. ){
27 |
28 | }
29 | gl_FragColor = c;
30 |
31 | float alpha = abs( sin( smoothstep(visibility.x, visibility.y, vCounters) * 3.14159 ) );
32 | gl_FragColor.rgb *= pow( alpha,.5 );
33 | gl_FragColor.a *= step(visibility.x, vCounters) * step(vCounters,visibility.y) * alpha;
34 | }
--------------------------------------------------------------------------------
/glsl/meshline_vs.glsl:
--------------------------------------------------------------------------------
1 | precision highp float;
2 |
3 | attribute vec3 position;
4 | attribute vec3 previous;
5 | attribute vec3 next;
6 | attribute float side;
7 | attribute float width;
8 | attribute vec2 uv;
9 | attribute float counters;
10 |
11 | uniform mat4 projectionMatrix;
12 | uniform mat4 modelViewMatrix;
13 | uniform vec2 resolution;
14 | uniform float lineWidth;
15 | uniform vec3 color;
16 | uniform float opacity;
17 | uniform float near;
18 | uniform float far;
19 | uniform float sizeAttenuation;
20 | uniform float time;
21 |
22 | varying vec2 vUV;
23 | varying vec4 vColor;
24 | varying float vCounters;
25 | varying float vZ;
26 |
27 | float SimplexPerlin3D( vec3 P )
28 | {
29 | // https://github.com/BrianSharpe/Wombat/blob/master/SimplexPerlin3D.glsl
30 |
31 | // simplex math constants
32 | const float SKEWFACTOR = 1.0/3.0;
33 | const float UNSKEWFACTOR = 1.0/6.0;
34 | const float SIMPLEX_CORNER_POS = 0.5;
35 | const float SIMPLEX_TETRAHADRON_HEIGHT = 0.70710678118654752440084436210485; // sqrt( 0.5 )
36 |
37 | // establish our grid cell.
38 | P *= SIMPLEX_TETRAHADRON_HEIGHT; // scale space so we can have an approx feature size of 1.0
39 | vec3 Pi = floor( P + dot( P, vec3( SKEWFACTOR) ) );
40 |
41 | // Find the vectors to the corners of our simplex tetrahedron
42 | vec3 x0 = P - Pi + dot(Pi, vec3( UNSKEWFACTOR ) );
43 | vec3 g = step(x0.yzx, x0.xyz);
44 | vec3 l = 1.0 - g;
45 | vec3 Pi_1 = min( g.xyz, l.zxy );
46 | vec3 Pi_2 = max( g.xyz, l.zxy );
47 | vec3 x1 = x0 - Pi_1 + UNSKEWFACTOR;
48 | vec3 x2 = x0 - Pi_2 + SKEWFACTOR;
49 | vec3 x3 = x0 - SIMPLEX_CORNER_POS;
50 |
51 | // pack them into a parallel-friendly arrangement
52 | vec4 v1234_x = vec4( x0.x, x1.x, x2.x, x3.x );
53 | vec4 v1234_y = vec4( x0.y, x1.y, x2.y, x3.y );
54 | vec4 v1234_z = vec4( x0.z, x1.z, x2.z, x3.z );
55 |
56 | // clamp the domain of our grid cell
57 | Pi.xyz = Pi.xyz - floor(Pi.xyz * ( 1.0 / 69.0 )) * 69.0;
58 | vec3 Pi_inc1 = step( Pi, vec3( 69.0 - 1.5 ) ) * ( Pi + 1.0 );
59 |
60 | // generate the random vectors
61 | vec4 Pt = vec4( Pi.xy, Pi_inc1.xy ) + vec2( 50.0, 161.0 ).xyxy;
62 | Pt *= Pt;
63 | vec4 V1xy_V2xy = mix( Pt.xyxy, Pt.zwzw, vec4( Pi_1.xy, Pi_2.xy ) );
64 | Pt = vec4( Pt.x, V1xy_V2xy.xz, Pt.z ) * vec4( Pt.y, V1xy_V2xy.yw, Pt.w );
65 | const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );
66 | const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );
67 | vec3 lowz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi.zzz * ZINC.xyz ) );
68 | vec3 highz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi_inc1.zzz * ZINC.xyz ) );
69 | Pi_1 = ( Pi_1.z < 0.5 ) ? lowz_mods : highz_mods;
70 | Pi_2 = ( Pi_2.z < 0.5 ) ? lowz_mods : highz_mods;
71 | vec4 hash_0 = fract( Pt * vec4( lowz_mods.x, Pi_1.x, Pi_2.x, highz_mods.x ) ) - 0.49999;
72 | vec4 hash_1 = fract( Pt * vec4( lowz_mods.y, Pi_1.y, Pi_2.y, highz_mods.y ) ) - 0.49999;
73 | vec4 hash_2 = fract( Pt * vec4( lowz_mods.z, Pi_1.z, Pi_2.z, highz_mods.z ) ) - 0.49999;
74 |
75 | // evaluate gradients
76 | vec4 grad_results = inversesqrt( hash_0 * hash_0 + hash_1 * hash_1 + hash_2 * hash_2 ) * ( hash_0 * v1234_x + hash_1 * v1234_y + hash_2 * v1234_z );
77 |
78 | // Normalization factor to scale the final result to a strict 1.0->-1.0 range
79 | // http://briansharpe.wordpress.com/2012/01/13/simplex-noise/#comment-36
80 | const float FINAL_NORMALIZATION = 37.837227241611314102871574478976;
81 |
82 | // evaulate the kernel weights ( use (0.5-x*x)^3 instead of (0.6-x*x)^4 to fix discontinuities )
83 | vec4 kernel_weights = v1234_x * v1234_x + v1234_y * v1234_y + v1234_z * v1234_z;
84 | kernel_weights = max(0.5 - kernel_weights, 0.0);
85 | kernel_weights = kernel_weights*kernel_weights*kernel_weights;
86 |
87 | // sum with the kernel and return
88 | return dot( kernel_weights, grad_results ) * FINAL_NORMALIZATION;
89 | }
90 | vec2 fix( vec4 i, float aspect ) {
91 |
92 | vec2 res = i.xy / i.w;
93 | res.x *= aspect;
94 | vCounters = counters;
95 | return res;
96 |
97 | }
98 |
99 | void main() {
100 |
101 | float aspect = resolution.x / resolution.y;
102 | float pixelWidthRatio = 1. / (resolution.x * projectionMatrix[0][0]);
103 |
104 | vColor = vec4( color, opacity );
105 | vUV = uv;
106 |
107 | vec3 t = vec3( 0, cos( time * .1 ), time * .1 );
108 | vec3 pos = position + SimplexPerlin3D( position * 0.01 + t * 5. ) * .5;
109 | vZ = pos.z;
110 |
111 | mat4 m = projectionMatrix * modelViewMatrix;
112 | vec4 finalPosition = m * vec4( pos, 1.0 );
113 | vec4 prevPos = m * vec4( previous, 1.0 );
114 | vec4 nextPos = m * vec4( next, 1.0 );
115 |
116 | vec2 currentP = fix( finalPosition, aspect );
117 | vec2 prevP = fix( prevPos, aspect );
118 | vec2 nextP = fix( nextPos, aspect );
119 |
120 | float pixelWidth = finalPosition.w * pixelWidthRatio;
121 | float w = 1.8 * pixelWidth * lineWidth * width;
122 |
123 | if( sizeAttenuation == 1. ) {
124 | w = 1.8 * lineWidth * width;
125 | }
126 |
127 | vec2 dir;
128 | if( nextP == currentP ) dir = normalize( currentP - prevP );
129 | else if( prevP == currentP ) dir = normalize( nextP - currentP );
130 | else {
131 | vec2 dir1 = normalize( currentP - prevP );
132 | vec2 dir2 = normalize( nextP - currentP );
133 | dir = normalize( dir1 + dir2 );
134 |
135 | vec2 perp = vec2( -dir1.y, dir1.x );
136 | vec2 miter = vec2( -dir.y, dir.x );
137 | //w = clamp( w / dot( miter, perp ), 0., 4. * lineWidth * width );
138 |
139 | }
140 |
141 | //vec2 normal = ( cross( vec3( dir, 0. ), vec3( 0., 0., 1. ) ) ).xy;
142 | vec2 normal = vec2( -dir.y, dir.x );
143 | normal.x /= aspect;
144 | normal *= .5 * w;
145 |
146 | vec4 offset = vec4( normal * side, 0.0, 1.0 );
147 | finalPosition.xy += offset.xy;
148 |
149 | gl_Position = finalPosition;
150 |
151 | }
--------------------------------------------------------------------------------
/glsl/particles_fs.glsl:
--------------------------------------------------------------------------------
1 | uniform vec3 color0;
2 | uniform vec3 color1;
3 | varying float vAlpha;
4 |
5 | void main(){
6 | vec3 color = mix( color0, color1, vAlpha );
7 | gl_FragColor = vec4( color, pow( vAlpha, .5 ) );
8 | }
--------------------------------------------------------------------------------
/glsl/particles_vs.glsl:
--------------------------------------------------------------------------------
1 | attribute vec3 dest;
2 |
3 | uniform vec2 bounds;
4 | uniform float time;
5 | uniform float modBig;
6 | uniform float pointSize;
7 | uniform float alpha;
8 |
9 | vec3 mod289(vec3 x) {
10 | return x - floor(x * (1.0 / 289.0)) * 289.0;
11 | }
12 |
13 | vec2 mod289(vec2 x) {
14 | return x - floor(x * (1.0 / 289.0)) * 289.0;
15 | }
16 |
17 | vec3 permute(vec3 x) {
18 | return mod289(((x*34.0)+1.0)*x);
19 | }
20 |
21 | float noise(vec2 v)
22 | {
23 | const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
24 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
25 | -0.577350269189626, // -1.0 + 2.0 * C.x
26 | 0.024390243902439); // 1.0 / 41.0
27 | // First corner
28 | vec2 i = floor(v + dot(v, C.yy) );
29 | vec2 x0 = v - i + dot(i, C.xx);
30 |
31 | // Other corners
32 | vec2 i1;
33 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
34 | //i1.y = 1.0 - i1.x;
35 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
36 | // x0 = x0 - 0.0 + 0.0 * C.xx ;
37 | // x1 = x0 - i1 + 1.0 * C.xx ;
38 | // x2 = x0 - 1.0 + 2.0 * C.xx ;
39 | vec4 x12 = x0.xyxy + C.xxzz;
40 | x12.xy -= i1;
41 |
42 | // Permutations
43 | i = mod289(i); // Avoid truncation effects in permutation
44 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
45 | + i.x + vec3(0.0, i1.x, 1.0 ));
46 |
47 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
48 | m = m*m ;
49 | m = m*m ;
50 |
51 | // Gradients: 41 points uniformly over a line, mapped onto a diamond.
52 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
53 |
54 | vec3 x = 2.0 * fract(p * C.www) - 1.0;
55 | vec3 h = abs(x) - 0.5;
56 | vec3 ox = floor(x + 0.5);
57 | vec3 a0 = x - ox;
58 |
59 | // Normalise gradients implicitly by scaling m
60 | // Approximation of: m *= inversesqrt( a0*a0 + h*h );
61 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
62 |
63 | // Compute final noise value at P
64 | vec3 g;
65 | g.x = a0.x * x0.x + h.x * x0.y;
66 | g.yz = a0.yz * x12.xz + h.yz * x12.yw;
67 | return 130.0 * dot(m, g);
68 | }
69 |
70 | varying float vAlpha;
71 | void main() {
72 |
73 | float t = time;
74 | float a = alpha;
75 |
76 | a = smoothstep( -1.,1., noise( vec2( position.x * position.y + time * 2. , time * .5 ) * .1 ) );
77 | a = bounds.x + a * bounds.y;
78 | vec3 pos = mix( position, dest, a );
79 |
80 | vAlpha = max( .25, a );
81 |
82 | float N1 = modBig;
83 | float P1 = step(mod( floor( position.x * N1 ), N1 ), 1. );
84 | gl_PointSize = 2. + ( pointSize * P1 );
85 |
86 | gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
87 |
88 |
89 | }
--------------------------------------------------------------------------------
/glsl/sem_fs.glsl:
--------------------------------------------------------------------------------
1 | uniform sampler2D tMatCap;
2 | uniform float alpha;
3 |
4 | varying vec3 e;
5 | varying vec3 n;
6 |
7 | void main() {
8 |
9 | vec3 r = reflect( e, n );
10 | float m = 2. * sqrt( pow( r.x, 2. ) + pow( r.y, 2. ) + pow( r.z + 1., 2. ) );
11 | vec2 vN = r.xy / m + .5;
12 |
13 | vec3 base = texture2D( tMatCap, vN ).rgb;
14 |
15 | gl_FragColor = vec4( base, alpha );
16 |
17 | }
--------------------------------------------------------------------------------
/glsl/sem_vs.glsl:
--------------------------------------------------------------------------------
1 |
2 | float SimplexPerlin3D( vec3 P )
3 | {
4 | // https://github.com/BrianSharpe/Wombat/blob/master/SimplexPerlin3D.glsl
5 |
6 | // simplex math constants
7 | const float SKEWFACTOR = 1.0/3.0;
8 | const float UNSKEWFACTOR = 1.0/6.0;
9 | const float SIMPLEX_CORNER_POS = 0.5;
10 | const float SIMPLEX_TETRAHADRON_HEIGHT = 0.70710678118654752440084436210485; // sqrt( 0.5 )
11 |
12 | // establish our grid cell.
13 | P *= SIMPLEX_TETRAHADRON_HEIGHT; // scale space so we can have an approx feature size of 1.0
14 | vec3 Pi = floor( P + dot( P, vec3( SKEWFACTOR) ) );
15 |
16 | // Find the vectors to the corners of our simplex tetrahedron
17 | vec3 x0 = P - Pi + dot(Pi, vec3( UNSKEWFACTOR ) );
18 | vec3 g = step(x0.yzx, x0.xyz);
19 | vec3 l = 1.0 - g;
20 | vec3 Pi_1 = min( g.xyz, l.zxy );
21 | vec3 Pi_2 = max( g.xyz, l.zxy );
22 | vec3 x1 = x0 - Pi_1 + UNSKEWFACTOR;
23 | vec3 x2 = x0 - Pi_2 + SKEWFACTOR;
24 | vec3 x3 = x0 - SIMPLEX_CORNER_POS;
25 |
26 | // pack them into a parallel-friendly arrangement
27 | vec4 v1234_x = vec4( x0.x, x1.x, x2.x, x3.x );
28 | vec4 v1234_y = vec4( x0.y, x1.y, x2.y, x3.y );
29 | vec4 v1234_z = vec4( x0.z, x1.z, x2.z, x3.z );
30 |
31 | // clamp the domain of our grid cell
32 | Pi.xyz = Pi.xyz - floor(Pi.xyz * ( 1.0 / 69.0 )) * 69.0;
33 | vec3 Pi_inc1 = step( Pi, vec3( 69.0 - 1.5 ) ) * ( Pi + 1.0 );
34 |
35 | // generate the random vectors
36 | vec4 Pt = vec4( Pi.xy, Pi_inc1.xy ) + vec2( 50.0, 161.0 ).xyxy;
37 | Pt *= Pt;
38 | vec4 V1xy_V2xy = mix( Pt.xyxy, Pt.zwzw, vec4( Pi_1.xy, Pi_2.xy ) );
39 | Pt = vec4( Pt.x, V1xy_V2xy.xz, Pt.z ) * vec4( Pt.y, V1xy_V2xy.yw, Pt.w );
40 | const vec3 SOMELARGEFLOATS = vec3( 635.298681, 682.357502, 668.926525 );
41 | const vec3 ZINC = vec3( 48.500388, 65.294118, 63.934599 );
42 | vec3 lowz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi.zzz * ZINC.xyz ) );
43 | vec3 highz_mods = vec3( 1.0 / ( SOMELARGEFLOATS.xyz + Pi_inc1.zzz * ZINC.xyz ) );
44 | Pi_1 = ( Pi_1.z < 0.5 ) ? lowz_mods : highz_mods;
45 | Pi_2 = ( Pi_2.z < 0.5 ) ? lowz_mods : highz_mods;
46 | vec4 hash_0 = fract( Pt * vec4( lowz_mods.x, Pi_1.x, Pi_2.x, highz_mods.x ) ) - 0.49999;
47 | vec4 hash_1 = fract( Pt * vec4( lowz_mods.y, Pi_1.y, Pi_2.y, highz_mods.y ) ) - 0.49999;
48 | vec4 hash_2 = fract( Pt * vec4( lowz_mods.z, Pi_1.z, Pi_2.z, highz_mods.z ) ) - 0.49999;
49 |
50 | // evaluate gradients
51 | vec4 grad_results = inversesqrt( hash_0 * hash_0 + hash_1 * hash_1 + hash_2 * hash_2 ) * ( hash_0 * v1234_x + hash_1 * v1234_y + hash_2 * v1234_z );
52 |
53 | // Normalization factor to scale the final result to a strict 1.0->-1.0 range
54 | // http://briansharpe.wordpress.com/2012/01/13/simplex-noise/#comment-36
55 | const float FINAL_NORMALIZATION = 37.837227241611314102871574478976;
56 |
57 | // evaulate the kernel weights ( use (0.5-x*x)^3 instead of (0.6-x*x)^4 to fix discontinuities )
58 | vec4 kernel_weights = v1234_x * v1234_x + v1234_y * v1234_y + v1234_z * v1234_z;
59 | kernel_weights = max(0.5 - kernel_weights, 0.0);
60 | kernel_weights = kernel_weights*kernel_weights*kernel_weights;
61 |
62 | // sum with the kernel and return
63 | return dot( kernel_weights, grad_results ) * FINAL_NORMALIZATION;
64 | }
65 | varying vec3 e;
66 | varying vec3 n;
67 |
68 | void main() {
69 |
70 | vec3 pos = position;
71 |
72 | e = normalize( vec3( modelViewMatrix * vec4( pos, 1.0 ) ) );
73 | n = normalize( normalMatrix * normal );
74 |
75 | gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1. );
76 |
77 | }
--------------------------------------------------------------------------------
/glsl/texture_particles_fs.glsl:
--------------------------------------------------------------------------------
1 | uniform sampler2D texture;
2 | uniform float time;
3 | varying float vAlpha;
4 | varying vec2 vUv;
5 |
6 | vec4 FAST_32_hash( vec2 gridcell )
7 | {
8 | // gridcell is assumed to be an integer coordinate
9 | const vec2 OFFSET = vec2( 26.0, 161.0 );
10 | const float DOMAIN = 71.0;
11 | const float SOMELARGEFLOAT = 951.135664;
12 | vec4 P = vec4( gridcell.xy, gridcell.xy + vec2( 1.,1.) );
13 | P = P - floor(P * ( 1.0 / DOMAIN )) * DOMAIN; // truncate the domain
14 | P += OFFSET.xyxy; // offset to interesting part of the noise
15 | P *= P; // calculate and return the hash
16 | return fract( P.xzxz * P.yyww * vec4( 1.0 / SOMELARGEFLOAT ) );
17 | }
18 | void main()
19 | {
20 |
21 | // float t = .5 + .5 * (cos( time ) * sin( time ) );
22 | // gl_FragColor = vec4( vec3( 1. ), vAlpha );
23 |
24 | vec2 uvs = vUv + gl_PointCoord.xy * vec2( .25 );
25 | uvs.y = 1. - uvs.y;
26 | gl_FragColor = vec4( 1. ) * texture2D( texture, uvs ) * vAlpha;
27 |
28 |
29 | }
--------------------------------------------------------------------------------
/glsl/texture_particles_vs.glsl:
--------------------------------------------------------------------------------
1 | //attribute float pdistance;
2 | //attribute vec3 pnormal;
3 | attribute vec3 dest;
4 | attribute vec2 uvOffset;
5 |
6 |
7 | uniform float time;
8 | uniform float modBig;
9 | uniform float modSmall;
10 | uniform float pointSize;
11 | uniform float alpha;
12 |
13 | vec3 mod289(vec3 x) {
14 | return x - floor(x * (1.0 / 289.0)) * 289.0;
15 | }
16 |
17 | vec2 mod289(vec2 x) {
18 | return x - floor(x * (1.0 / 289.0)) * 289.0;
19 | }
20 |
21 | vec3 permute(vec3 x) {
22 | return mod289(((x*34.0)+1.0)*x);
23 | }
24 |
25 | float noise(vec2 v)
26 | {
27 | const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0
28 | 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)
29 | -0.577350269189626, // -1.0 + 2.0 * C.x
30 | 0.024390243902439); // 1.0 / 41.0
31 | // First corner
32 | vec2 i = floor(v + dot(v, C.yy) );
33 | vec2 x0 = v - i + dot(i, C.xx);
34 |
35 | // Other corners
36 | vec2 i1;
37 | //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
38 | //i1.y = 1.0 - i1.x;
39 | i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
40 | // x0 = x0 - 0.0 + 0.0 * C.xx ;
41 | // x1 = x0 - i1 + 1.0 * C.xx ;
42 | // x2 = x0 - 1.0 + 2.0 * C.xx ;
43 | vec4 x12 = x0.xyxy + C.xxzz;
44 | x12.xy -= i1;
45 |
46 | // Permutations
47 | i = mod289(i); // Avoid truncation effects in permutation
48 | vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
49 | + i.x + vec3(0.0, i1.x, 1.0 ));
50 |
51 | vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
52 | m = m*m ;
53 | m = m*m ;
54 |
55 | // Gradients: 41 points uniformly over a line, mapped onto a diamond.
56 | // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
57 |
58 | vec3 x = 2.0 * fract(p * C.www) - 1.0;
59 | vec3 h = abs(x) - 0.5;
60 | vec3 ox = floor(x + 0.5);
61 | vec3 a0 = x - ox;
62 |
63 | // Normalise gradients implicitly by scaling m
64 | // Approximation of: m *= inversesqrt( a0*a0 + h*h );
65 | m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
66 |
67 | // Compute final noise value at P
68 | vec3 g;
69 | g.x = a0.x * x0.x + h.x * x0.y;
70 | g.yz = a0.yz * x12.xz + h.yz * x12.yw;
71 | return 130.0 * dot(m, g);
72 | }
73 |
74 | vec4 FAST_32_hash( vec2 gridcell )
75 | {
76 | // gridcell is assumed to be an integer coordinate
77 | const vec2 OFFSET = vec2( 26.0, 161.0 );
78 | const float DOMAIN = 71.0;
79 | const float SOMELARGEFLOAT = 951.135664;
80 | vec4 P = vec4( gridcell.xy, gridcell.xy + vec2( 1.,1.) );
81 | P = P - floor(P * ( 1.0 / DOMAIN )) * DOMAIN; // truncate the domain
82 | P += OFFSET.xyxy; // offset to interesting part of the noise
83 | P *= P; // calculate and return the hash
84 | return fract( P.xzxz * P.yyww * vec4( 1.0 / SOMELARGEFLOAT ) );
85 | }
86 |
87 | varying float vAlpha;
88 | varying vec2 vUv;
89 | void main() {
90 |
91 | float t = time;
92 | float a = alpha;
93 |
94 | a = smoothstep( -1.,1., noise( vec2( position.x * position.y + time * 2. , time * .5 ) * .1 ) );
95 | vec3 pos = mix( position, dest, a );
96 |
97 | vAlpha = max( .25, a );
98 | vUv = uvOffset;
99 |
100 | float N1 = modBig;
101 | float P1 = step(mod( floor( position.x * N1 ), N1 ), 1. );
102 | gl_PointSize = 4. + ( pointSize * P1 );
103 |
104 | gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
105 |
106 |
107 | }
--------------------------------------------------------------------------------
/img/dwarf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/img/dwarf.jpg
--------------------------------------------------------------------------------
/img/plane.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/img/plane.jpg
--------------------------------------------------------------------------------
/img/spider.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/img/spider.jpg
--------------------------------------------------------------------------------
/img/suzanne.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/img/suzanne.jpg
--------------------------------------------------------------------------------
/img/suzanne_distribution.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/img/suzanne_distribution.jpg
--------------------------------------------------------------------------------
/js/common/Scatter.js:
--------------------------------------------------------------------------------
1 | var Scatter = function( scatter ){
2 |
3 | var raycaster;//THREE.raycaster: used to shoot rays at the mesh
4 | var o;//ray origin
5 | var d;//ray direction
6 | var intersections;//stores the result of the raycasting
7 | var a;//DOM element tag to download the result ( see particlesToString )
8 |
9 | scatter.distribute = function( mesh, count ) {
10 |
11 | //this will store the results
12 | var coords = [];
13 | var dests = [];
14 | //temporary vars to store the position and destination
15 | var p0, p1;
16 |
17 | //this has an influence as to how the raycasting is performed
18 | var side = mesh.material.side;
19 | mesh.material.side = THREE.DoubleSide;
20 |
21 | //we'll need this (juste to be sure as it's probably done implicitly when we raycast)
22 | mesh.geometry.computeFaceNormals();
23 |
24 | //this is used to distributte the origins of the rays
25 | mesh.geometry.computeBoundingBox();
26 | var bbox = mesh.geometry.boundingBox;
27 |
28 | // 'inflates' the box by 10% to prevent colinearity
29 | // or coplanarity of the origin with the mesh
30 | bbox.min.multiplyScalar( 1.1 );
31 | bbox.max.multiplyScalar( 1.1 );
32 |
33 | //computes the box' size to compute random points
34 | var size = bbox.max.sub( bbox.min );
35 |
36 | //to perform raycast
37 | raycaster = raycaster || new THREE.Raycaster();
38 | o = o || new THREE.Vector3();
39 | d = d || new THREE.Vector3();
40 |
41 | for( var i = 0; i < count; i++ ){
42 |
43 | // randomize the rays origin
44 | o.x = bbox.min.x + Math.random() * size.x;
45 | o.y = bbox.min.y + Math.random() * size.y;
46 | o.z = bbox.min.z + Math.random() * size.z;
47 |
48 | //randomize the ray's direction
49 | d.x = ( Math.random() - .5 );
50 | d.y = ( Math.random() - .5 );
51 | d.z = ( Math.random() - .5 );
52 | d.normalize();
53 |
54 | //sets the raycaster
55 | raycaster.set( o, d );
56 |
57 | //shoots the ray
58 | intersections = raycaster.intersectObject( mesh, false );
59 |
60 | //no result
61 | if( intersections.length == 0 ){
62 |
63 | //bail out & continue
64 | i--;
65 |
66 | }else{
67 |
68 | //checks if we meet the conditions:
69 | //the origin must be outside
70 | var valid = intersections.length >= 2 && ( intersections.length % 2 == 0 );
71 | if (valid) {
72 |
73 | //tests all the intersection pairs
74 | var additions = -1;
75 | for( var j = 0; j < intersections.length; j+= 2 ){
76 |
77 | // make sure that the origin -> direction vector have the same
78 | // direction as the normal of the face they hit
79 |
80 | //test the direction against the outwards' face's normal
81 | var dp0 = d.dot(intersections[ j + 1 ].face.normal) <= 0;
82 |
83 | //flips the direction to make it 'look at' the origin
84 | d.negate();
85 |
86 | //test the direction against the inwards' face's normal
87 | var dp1 = d.dot(intersections[ j ].face.normal) <= 0;
88 |
89 | //flips the direction again for the next test
90 | d.negate();
91 |
92 | // if both vectors pairs head in the same direction
93 | // the point is guarranteed to be inside
94 | if( dp0 || dp1){
95 | continue;
96 | }
97 |
98 | //adds the points
99 | if( coords.length < count * 3 ){
100 | console.log("ok")
101 | p0 = intersections[j].point;
102 | coords.push( p0.x, p0.y, p0.z);
103 | p1 = intersections[j+1].point;
104 | dests.push( p1.x, p1.y, p1.z);
105 | additions++;
106 | }
107 | }
108 | //increments the counter by the number of additions
109 | i += additions;
110 |
111 | }else{
112 | //invalid intersection, try again...
113 | i--;
114 | }
115 | }
116 | }
117 |
118 | //resets the material side
119 | mesh.material.side = side;
120 | return {
121 | pos:coords,
122 | dst:dests
123 | };
124 |
125 | };
126 |
127 |
128 | /**
129 | * converts the result of the scatter to a text string
130 | * @param particles coordinates of the points/dest
131 | * @param decimalPrecision floating point precision
132 | * @param name optional: name for the file
133 | */
134 | scatter.toString = function( particles, decimalPrecision, name ){
135 |
136 | var precision = decimalPrecision;
137 | if( precision === undefined )precision = 3;
138 | var coords = assetsLoader.particles.pos.map( function( v ){return v.toFixed( precision ); });
139 | var dests = assetsLoader.particles.dst.map( function( v ){return v.toFixed( precision ); });
140 |
141 | var count = ( coords.length / 3 );
142 | var label = ( name || ( "particles_"+ count ) ) +".txt";
143 | var data = coords.join(',') + "|" + dests.join(',') ;
144 |
145 | var txtData = new Blob([data], { type: 'text/csv' });
146 | var txtUrl = window.URL.createObjectURL(txtData);
147 |
148 | a = a || document.createElement( "a" );
149 | a.setAttribute( "href", txtUrl );
150 | a.setAttribute( "download", label );
151 | a.innerHTML = label;
152 |
153 | a.style.position = "absolute";
154 | a.style.padding = a.style.margin = "10px";
155 | a.style.bottom = "0";
156 | a.style.left = "0";
157 | a.style.backgroundColor = "#FFF";
158 |
159 | document.body.appendChild( a );
160 |
161 | };
162 |
163 | return scatter;
164 | }({});
--------------------------------------------------------------------------------
/js/common/assetsLoader.js:
--------------------------------------------------------------------------------
1 | var assetsLoader = function(exports ){
2 |
3 | var xhr, bl, tl, queue, callback;
4 | exports.IMG = 0;
5 | exports.MOD = 1;
6 | exports.TXT = 2;
7 | exports.load = function( list, cb ){
8 |
9 |
10 | queue = list;
11 | callback = cb;
12 |
13 | bl = new THREE.BinaryLoader();
14 | tl = new THREE.TextureLoader();
15 | xhr = new XMLHttpRequest();
16 | xhr.onload = onLoad;
17 |
18 | loadNext();
19 |
20 | };
21 |
22 | function loadNext(){
23 |
24 | if( queue.length == 0 ){
25 | if( callback )callback();
26 | return;
27 | }
28 |
29 | if( queue[0].type == assetsLoader.IMG ){
30 | tl.load( queue[0].url, onLoad );
31 | }
32 |
33 | if( queue[0].type == assetsLoader.MOD ){
34 | bl.load( queue[0].url, onLoad );
35 | }
36 |
37 | if( queue[0].type == assetsLoader.TXT ){
38 | xhr.open( "GET", queue[0].url );
39 | xhr.send();
40 | }
41 |
42 | }
43 |
44 | function onLoad( e ){
45 |
46 | if( queue[0].type == assetsLoader.TXT ){
47 | exports[ queue[0].name ] = e.target.responseText;
48 |
49 | }else{
50 | exports[ queue[0].name ] = e;
51 | }
52 |
53 | if( queue[0].onLoad !== undefined ){
54 | queue[0].onLoad( exports[ queue[0].name ] );
55 | }
56 |
57 | queue.shift();
58 | loadNext();
59 |
60 | }
61 |
62 | return exports;
63 |
64 | }({});
--------------------------------------------------------------------------------
/js/common/scene3d.js:
--------------------------------------------------------------------------------
1 |
2 | var scene, camera, renderer, resolution, controls, materials, startTime, colors;
3 |
4 | function init3D(){
5 |
6 | scene = new THREE.Scene();
7 | camera = new THREE.PerspectiveCamera( 42, window.innerWidth / window.innerHeight, 1, 10000 );
8 |
9 | renderer = new THREE.WebGLRenderer({antialias:true});
10 | renderer.setClearColor( new THREE.Color( 0x101010 ));
11 | renderer.setSize( window.innerWidth, window.innerHeight );
12 | renderer.setPixelRatio( window.devicePixelRatio );
13 | document.body.appendChild( renderer.domElement );
14 |
15 | controls = new THREE.OrbitControls( camera, renderer.domElement );
16 |
17 | materials = {};
18 | startTime = Date.now();
19 |
20 | colors = "264653-2a9d8f-e9c46a-f4a261-e76f51".split('-').map( function( v ){ return parseInt( "0x" + v ); } );
21 | colors = colors.concat( "114b5f-456990-028090-79b473-70a37f".split('-').map( function( v ){ return parseInt( "0x" + v ); } ) );
22 | resolution = new THREE.Vector2( window.innerWidth, window.innerHeight );
23 |
24 | window.addEventListener( 'resize', onResize );
25 | onResize();
26 |
27 | }
28 |
29 | function onResize() {
30 |
31 | var w = window.innerWidth;
32 | var h = window.innerHeight;
33 | camera.aspect = w / h;
34 | camera.updateProjectionMatrix();
35 | renderer.setSize( w, h );
36 | resolution.set( w, h );
37 |
38 | }
39 | //utils
40 | function lerp ( t, a, b ){ return a * (1-t) + b * t; }
41 | // function norm( t, a, b ){return ( t - a ) / ( b - a );}
42 | // function map( t, a0, b0, a1, b1 ){ return lerp( norm( t, a0, b0 ), a1, b1 );}
43 |
44 |
--------------------------------------------------------------------------------
/js/dwarf.js:
--------------------------------------------------------------------------------
1 |
2 | var dwarf, env, particles, lines = [], origin;
3 |
4 | var colors = "264653-2a9d8f-e9c46a-f4a261-e76f51".split('-').map( function( v ){ return parseInt( "0x" + v ); } );
5 | colors = colors.concat( "f2f3ae-edd382-e7a977-e87461-b38cb4".split('-').map( function( v ){ return parseInt( "0x" + v ); } ) );
6 | colors = colors.concat( "114b5f-456990-028090-79b473-70a37f".split('-').map( function( v ){ return parseInt( "0x" + v ); } ) );
7 |
8 |
9 | window.onload = function(){
10 |
11 | var queue = [
12 |
13 | {name: "meshline_vs", url: "./glsl/meshline_vs.glsl", type:assetsLoader.TXT },
14 | {name: "meshline_fs", url: "./glsl/meshline_fs.glsl", type:assetsLoader.TXT },
15 | {name: "sem_vs", url: "./glsl/sem_vs.glsl", type:assetsLoader.TXT },
16 | {name: "sem_fs", url: "./glsl/sem_fs.glsl", type:assetsLoader.TXT },
17 | {name: "env_vs", url: "./glsl/env_vs.glsl", type:assetsLoader.TXT },
18 | {name: "env_fs", url: "./glsl/env_fs.glsl", type:assetsLoader.TXT },
19 |
20 | {
21 | name: "dwarfTexture",
22 | url: "./assets/textures/matcap/env.png",type:assetsLoader.IMG
23 | },
24 | {
25 | name: "dwarf",
26 | url: "./assets/models/binaries/dwarf.js",type:assetsLoader.MOD
27 | },
28 | {
29 | name: "particles",
30 | url:"./assets/models/particles/dwarf/dwarf2k.txt", type:assetsLoader.TXT,
31 | onLoad:function (txt) {
32 | var obj = {};
33 | var res = txt.split( '|' );
34 | obj.pos = res[0].split(',').map( function( v ){return parseFloat( v ); } );
35 | obj.dst = res[1].split(',').map( function( v ){return parseFloat( v ); } );
36 | assetsLoader.particles = obj;
37 | }
38 | }
39 | ];
40 | assetsLoader.load(queue, init);
41 | };
42 |
43 | function init() {
44 |
45 | init3D();
46 |
47 | camera.position.x = -200;
48 | camera.position.y = 90;
49 | camera.position.z = 300;
50 |
51 | createMaterials();
52 | createMeshes();
53 |
54 | render();
55 | }
56 |
57 | function createMaterials(){
58 |
59 | startTime = Date.now();
60 |
61 | materials.dwarf = new THREE.ShaderMaterial({
62 | uniforms:{
63 | tMatCap : {type:"t", value:assetsLoader.dwarfTexture },
64 | time:{type:"f", value:0 },
65 | alpha:{type:"f", value:.5 }
66 | },
67 | vertexShader:assetsLoader.sem_vs,
68 | fragmentShader:assetsLoader.sem_fs,
69 | blending:THREE.MultiplyBlending,
70 | transparent: true,
71 | depthWrite:false
72 | });
73 |
74 | materials.environment = new THREE.ShaderMaterial({
75 | uniforms : {
76 | horizon:{type:"f", value: .45 },
77 | spread:{type:"f", value: .05 },
78 | topColor:{type:"v3", value:new THREE.Color( 0xEEEEEE )},
79 | bottomColor:{type:"v3", value:new THREE.Color( 0xBBBBBB )}
80 | },
81 | vertexShader: assetsLoader.env_vs,
82 | fragmentShader: assetsLoader.env_fs,
83 | side:THREE.BackSide,
84 | depthWrite:false
85 | });
86 |
87 | }
88 |
89 | function createMeshes() {
90 |
91 | assetsLoader.dwarf.computeVertexNormals();
92 | dwarf = new THREE.Mesh(assetsLoader.dwarf, materials.dwarf );
93 | scene.add(dwarf);
94 |
95 | env = new THREE.Mesh(new THREE.CylinderBufferGeometry(.5, .5, 1, 64), materials.environment);
96 | env.scale.multiplyScalar(1000);
97 | scene.add(env);
98 |
99 | if( assetsLoader.particles === undefined ){
100 |
101 | var model = dwarf;
102 | var count = Math.pow( 2, 11 );//->2048
103 |
104 | assetsLoader.particles = Scatter.distribute( model, count );
105 | Scatter.toString( assetsLoader.particles, 3, "dwarf"+~~(count/1000)+"k" );
106 |
107 | }
108 |
109 | //create line sets
110 | // colllect vector3 from particle positions
111 | var nodes = [];
112 | var pos = assetsLoader.particles.pos;
113 | var dst = assetsLoader.particles.dst;
114 | for( var i = 0; i< pos.length; i+=3 ){
115 |
116 | nodes.push( new THREE.Vector3(
117 | (pos[ i ]+dst[i])* .5,
118 | (pos[ i+1 ]+dst[i+1])* .5,
119 | (pos[ i+2 ]+dst[i+2])* .5 )
120 | )
121 | }
122 |
123 | //extremely brutal way of doing this but hey...
124 | var group = new THREE.Group();
125 | for( i = 0; i < 100; i++ ){
126 |
127 | var vectors = [];
128 | origin = nodes.splice( parseInt( Math.random() * nodes.length ), 1 )[0];
129 | vectors.push( origin );
130 | for( var j = 0; j < 16; j++ ){
131 |
132 |
133 | nodes.sort( function( a, b ){
134 | return a.distanceToSquared( origin ) - b.distanceToSquared( origin );
135 | });
136 |
137 | var n = nodes.splice(~~(Math.random() * 10 ),1)[0];
138 | vectors.push( n );
139 | origin = n;
140 | }
141 |
142 | var material = new MeshLineMaterial( {
143 | useMap: false,
144 | color: new THREE.Color( colors[ parseInt( Math.random() * colors.length ) ] ),//0xFFFFFF ),
145 | opacity: 1,
146 | resolution: resolution,
147 | sizeAttenuation: true,
148 | lineWidth: 1 + ( ( Math.random() > .35 ? 1 : 0 )*~~(Math.random() * 3 ) ),
149 | near: camera.near,
150 | far: camera.far,
151 | depthWrite: false,
152 | transparent: true
153 | },
154 | assetsLoader.meshline_vs,
155 | assetsLoader.meshline_fs);
156 |
157 |
158 | var spl = new THREE.CatmullRomCurve3( vectors );
159 | var res = spl.getPoints( vectors.length * 5 );
160 | var path = [];
161 | res.forEach(function( p, i, a ){
162 | path.push( p.x, p.y, p.z );
163 | });
164 |
165 | var l = new MeshLine();
166 | l.setGeometry( path, function( p ) { return 1; } );
167 |
168 | var line = new THREE.Mesh( l.geometry, material );
169 | line.startTime = Math.random() * 3 * 1000;
170 | line.lineLength = .25;
171 | line.speed = .0001;
172 | lines.push( line );
173 | group.add( line );
174 |
175 | }
176 |
177 | scene.add( group );
178 |
179 | }
180 |
181 | function render() {
182 |
183 | requestAnimationFrame( render );
184 | controls.update();
185 |
186 | lines.forEach( function(l){
187 |
188 | var t = ( ( Date.now() - l.startTime ) * l.speed ) % ( 1 + l.lineLength );
189 | l.material.uniforms.visibility.value.x = t - l.lineLength;
190 | l.material.uniforms.visibility.value.y = t;
191 |
192 | });
193 | renderer.render( scene, camera );
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/js/dwarf_bk.js:
--------------------------------------------------------------------------------
1 |
2 | var dwarf, env, particles;
3 | window.onload = function(){
4 |
5 | var queue = [
6 |
7 | {name: "particles_vs", url: "./glsl/line_sem_vs.glsl", type:assetsLoader.TXT },
8 | {name: "particles_fs", url: "./glsl/line_sem_fs.glsl", type:assetsLoader.TXT },
9 | {name: "sem_vs", url: "./glsl/sem_vs.glsl", type:assetsLoader.TXT },
10 | {name: "sem_fs", url: "./glsl/sem_fs.glsl", type:assetsLoader.TXT },
11 | {name: "env_vs", url: "./glsl/env_vs.glsl", type:assetsLoader.TXT },
12 | {name: "env_fs", url: "./glsl/env_fs.glsl", type:assetsLoader.TXT },
13 |
14 | {
15 | name: "dwarfTexture",
16 | url: "./assets/textures/matcap/thuglee-03.jpg",type:assetsLoader.IMG
17 | },
18 | {
19 | name: "dwarf",
20 | url: "./assets/models/binaries/dwarf.js",type:assetsLoader.MOD
21 | },
22 | {
23 | name: "particles",
24 | url:"./assets/models/particles/dwarf/dwarf2k.txt", type:assetsLoader.TXT,
25 | onLoad:function (txt) {
26 | var obj = {};
27 | var res = txt.split( '|' );
28 | obj.pos = res[0].split(',').map( function( v ){return parseFloat( v ); } );
29 | obj.dst = res[1].split(',').map( function( v ){return parseFloat( v ); } );
30 | assetsLoader.particles = obj;
31 | }
32 | }
33 |
34 | ];
35 |
36 | assetsLoader.load(queue, init);
37 | };
38 |
39 | function init() {
40 |
41 | init3D();
42 |
43 | camera.position.x = 100;
44 | camera.position.y = -45;
45 | camera.position.z = 350;
46 |
47 | createMaterials();
48 | createMeshes();
49 | createParticles();
50 |
51 | scene.add(env);
52 | scene.add( particles );
53 | scene.add(dwarf);
54 |
55 | render();
56 | }
57 |
58 | function createMaterials(){
59 |
60 | startTime = Date.now();
61 |
62 | materials.dwarf = new THREE.ShaderMaterial({
63 | uniforms:{
64 | tMatCap : {type:"t", value:assetsLoader.dwarfTexture },
65 | time:{type:"f", value:0 },
66 | alpha:{type:"f", value:.35 }
67 | },
68 | vertexShader:assetsLoader.sem_vs,
69 | fragmentShader:assetsLoader.sem_fs,
70 | blending:THREE.MultiplyBlending,
71 | transparent: true,
72 | side:THREE.FrontSide,
73 | depthWrite:false
74 | });
75 |
76 | materials.particles = new THREE.LineBasicMaterial({
77 | color:0x000000,
78 | transparent:true,
79 | opacity: .25
80 | });
81 |
82 | materials.environment = new THREE.ShaderMaterial({
83 | uniforms : {
84 | horizon:{type:"f", value: .45 },
85 | spread:{type:"f", value: .05 },
86 | topColor:{type:"v3", value:new THREE.Color( 0xEEEEEE )},
87 | bottomColor:{type:"v3", value:new THREE.Color( 0xBBBBBB )}
88 | },
89 | vertexShader: assetsLoader.env_vs,
90 | fragmentShader: assetsLoader.env_fs,
91 | side:THREE.BackSide
92 | });
93 |
94 | }
95 |
96 | function createMeshes() {
97 |
98 | assetsLoader.dwarf.computeVertexNormals();
99 | dwarf = new THREE.Mesh(assetsLoader.dwarf, materials.dwarf );
100 |
101 | env = new THREE.Mesh(new THREE.CylinderBufferGeometry(.5, .5, 1, 64), materials.environment);
102 | env.scale.multiplyScalar(1000);
103 |
104 | }
105 |
106 |
107 | function createParticles(){
108 |
109 | if( assetsLoader.particles === undefined ){
110 |
111 | var model = dwarf;
112 | var count = Math.pow( 2, 11 );//->2048
113 |
114 | assetsLoader.particles = Scatter.distribute( model, count );
115 | Scatter.toString( assetsLoader.particles, 3, "dwarf"+~~(count/1000)+"k" );
116 |
117 | }
118 |
119 | var pos = assetsLoader.particles.pos;
120 | var dst = assetsLoader.particles.dst;
121 | var buffer = new Float32Array( pos.length * 2 );
122 | for( var i = 0; i< pos.length; i+=3 ){
123 |
124 | var id = i * 2;
125 | buffer[ id++ ] = pos[ i ];
126 | buffer[ id++ ] = pos[ i + 1 ];
127 | buffer[ id++ ] = pos[ i + 2 ];
128 |
129 | buffer[ id++ ] = dst[ i ];
130 | buffer[ id++ ] = dst[ i + 1 ];
131 | buffer[ id++ ] = dst[ i + 2 ];
132 |
133 | }
134 |
135 | var g = new THREE.BufferGeometry();
136 | g.addAttribute( "position", new THREE.BufferAttribute( buffer, 3 ));
137 | g.computeVertexNormals();
138 |
139 | particles = new THREE.LineSegments(g,materials.particles );
140 |
141 | }
142 |
143 |
144 | function render() {
145 |
146 | requestAnimationFrame( render );
147 | controls.update();
148 |
149 | var time = ( Date.now() - startTime ) * 0.001;
150 | for( var k in materials ){
151 |
152 | if( materials[ k ].uniforms !== undefined && materials[ k ].uniforms.time !== undefined ){
153 |
154 | materials[ k ].uniforms.time.value = time;
155 |
156 | }
157 | }
158 |
159 | renderer.render( scene, camera );
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/js/plane.js:
--------------------------------------------------------------------------------
1 |
2 | var plane, env, particles;
3 | window.onload = function(){
4 |
5 | var queue = [
6 |
7 | {name: "particles_vs", url: "./glsl/line_sem_vs.glsl", type:assetsLoader.TXT },
8 | {name: "particles_fs", url: "./glsl/line_sem_fs.glsl", type:assetsLoader.TXT },
9 | {name: "sem_vs", url: "./glsl/sem_vs.glsl", type:assetsLoader.TXT },
10 | {name: "sem_fs", url: "./glsl/sem_fs.glsl", type:assetsLoader.TXT },
11 | {name: "env_vs", url: "./glsl/env_vs.glsl", type:assetsLoader.TXT },
12 | {name: "env_fs", url: "./glsl/env_fs.glsl", type:assetsLoader.TXT },
13 |
14 | {
15 | name: "planeTexture",
16 | // url: "./assets/textures/matcap/untitled.6.jpg",type:assetsLoader.IMG
17 | url: "./assets/textures/matcap/thuglee-03.jpg",type:assetsLoader.IMG
18 | },
19 | {
20 | name: "plane",
21 | url: "./assets/models/binaries/plane.js",type:assetsLoader.MOD
22 | },
23 | {
24 | name: "particles",
25 | url:"./assets/models/particles/plane/plane65k.txt", type:assetsLoader.TXT,
26 | onLoad:function (txt) {
27 | var obj = {};
28 | var res = txt.split( '|' );
29 | obj.pos = res[0].split(',').map( function( v ){return parseFloat( v ); } );
30 | obj.dst = res[1].split(',').map( function( v ){return parseFloat( v ); } );
31 | assetsLoader.particles = obj;
32 | }
33 | }
34 | ];
35 |
36 | assetsLoader.load(queue, init);
37 | };
38 |
39 | function init() {
40 |
41 | init3D();
42 |
43 | camera.position.x = -200;
44 | camera.position.y = 250;
45 | camera.position.z = 180;
46 |
47 | controls.target.set( 16, 22, -13);
48 |
49 | createMaterials();
50 | createMeshes();
51 | createParticles();
52 |
53 | scene.add(env);
54 | scene.add( plane );
55 | scene.add( particles );
56 |
57 | render();
58 | }
59 |
60 | function createMaterials(){
61 |
62 | startTime = Date.now();
63 |
64 | materials.plane = new THREE.ShaderMaterial({
65 | uniforms:{
66 | tMatCap : {type:"t", value:assetsLoader.planeTexture },
67 | time:{type:"f", value:0 },
68 | alpha:{type:"f", value:.85 }
69 | },
70 | vertexShader:assetsLoader.sem_vs,
71 | fragmentShader:assetsLoader.sem_fs,
72 | blending:THREE.MultiplyBlending,
73 | transparent: true,
74 | side:THREE.FrontSide,
75 | depthWrite:false
76 | });
77 |
78 | materials.particles = new THREE.LineBasicMaterial({
79 | color:0x000000,
80 | transparent:true,
81 | opacity: .2
82 | });
83 |
84 | materials.environment = new THREE.ShaderMaterial({
85 | uniforms : {
86 | horizon:{type:"f", value: .45 },
87 | spread:{type:"f", value: .05 },
88 | topColor:{type:"v3", value:new THREE.Color( 0xEEEEEE )},
89 | bottomColor:{type:"v3", value:new THREE.Color( 0xBBBBBB )}
90 | },
91 | vertexShader: assetsLoader.env_vs,
92 | fragmentShader: assetsLoader.env_fs,
93 | side:THREE.BackSide
94 | });
95 |
96 | }
97 |
98 | function createMeshes() {
99 |
100 | assetsLoader.plane.computeVertexNormals();
101 | plane = new THREE.Mesh(assetsLoader.plane, materials.plane );
102 |
103 | env = new THREE.Mesh(new THREE.CylinderBufferGeometry(.5, .5, 1, 64), materials.environment);
104 | env.scale.multiplyScalar(1000);
105 |
106 | }
107 |
108 |
109 | function createParticles(){
110 |
111 | if( assetsLoader.particles === undefined ){
112 |
113 | var model = plane;
114 | var count = Math.pow( 2, 16 );//->65536
115 |
116 | assetsLoader.particles = Scatter.distribute( model, count );
117 | Scatter.toString( assetsLoader.particles, 3, "plane"+~~(count/1000)+"k" );
118 |
119 | }
120 |
121 | var pos = assetsLoader.particles.pos;
122 | var dst = assetsLoader.particles.dst;
123 | var buffer = new Float32Array( pos.length * 2 );
124 | for( var i = 0; i< pos.length; i+=3 ){
125 |
126 | var id = i * 2;
127 | buffer[ id++ ] = pos[ i ];
128 | buffer[ id++ ] = pos[ i + 1 ];
129 | buffer[ id++ ] = pos[ i + 2 ];
130 |
131 | buffer[ id++ ] = dst[ i ];
132 | buffer[ id++ ] = dst[ i + 1 ];
133 | buffer[ id++ ] = dst[ i + 2 ];
134 |
135 | }
136 |
137 | var g = new THREE.BufferGeometry();
138 | g.addAttribute( "position", new THREE.BufferAttribute( buffer, 3 ));
139 | g.computeVertexNormals();
140 |
141 | particles = new THREE.LineSegments(g,materials.particles );
142 |
143 | }
144 |
145 |
146 | function render() {
147 |
148 | requestAnimationFrame( render );
149 | controls.update();
150 |
151 | var time = ( Date.now() - startTime ) * 0.001;
152 | for( var k in materials ){
153 |
154 | if( materials[ k ].uniforms !== undefined && materials[ k ].uniforms.time !== undefined ){
155 |
156 | materials[ k ].uniforms.time.value = time;
157 |
158 | }
159 | }
160 |
161 | renderer.render( scene, camera );
162 |
163 | }
164 |
--------------------------------------------------------------------------------
/js/spider.js:
--------------------------------------------------------------------------------
1 |
2 | var spider, env, particles;
3 | window.onload = function(){
4 |
5 | var queue = [
6 |
7 | {name: "particles_vs", url: "./glsl/particles_vs.glsl", type:assetsLoader.TXT },
8 | {name: "particles_fs", url: "./glsl/particles_fs.glsl", type:assetsLoader.TXT },
9 | {name: "sem_vs", url: "./glsl/sem_vs.glsl", type:assetsLoader.TXT },
10 | {name: "sem_fs", url: "./glsl/sem_fs.glsl", type:assetsLoader.TXT },
11 | {name: "env_vs", url: "./glsl/env_vs.glsl", type:assetsLoader.TXT },
12 | {name: "env_fs", url: "./glsl/env_fs.glsl", type:assetsLoader.TXT },
13 |
14 | {
15 | name: "spiderTexture",
16 | // url: "./assets/textures/matcap/chrome_eye.png",type:assetsLoader.IMG
17 | url: "./assets/textures/matcap/droplet_01.png",type:assetsLoader.IMG
18 | },
19 | {
20 | name: "particlesTexture",
21 | url: "./assets/textures/particles.png",type:assetsLoader.IMG
22 | },
23 | {
24 | name: "spider",
25 | url: "./assets/models/binaries/spider.js",type:assetsLoader.MOD
26 | },
27 |
28 | {
29 | name: "particles",
30 | url:"./assets/models/particles/spider/spider32k.txt", type:assetsLoader.TXT,
31 | onLoad:function (txt) {
32 | var obj = {};
33 | var res = txt.split( '|' );
34 | obj.pos = res[0].split(',').map( function( v ){return parseFloat( v ); } );
35 | obj.dst = res[1].split(',').map( function( v ){return parseFloat( v ); } );
36 | assetsLoader.particles = obj;
37 | }
38 | }
39 |
40 | ];
41 |
42 | assetsLoader.load(queue, init);
43 | };
44 |
45 | function init() {
46 |
47 | init3D();
48 |
49 | camera.position.x = -70;
50 | camera.position.y = 140;
51 | camera.position.z = 60;
52 |
53 | createMaterials();
54 | createMeshes();
55 | createParticles();
56 |
57 | scene.add( particles );
58 | scene.add(spider);
59 | scene.add(env);
60 |
61 |
62 | render();
63 |
64 | }
65 |
66 | function createMaterials(){
67 |
68 | startTime = Date.now();
69 |
70 | materials.spiderTexture = new THREE.ShaderMaterial({
71 | uniforms:{
72 | tMatCap : {type:"t", value:assetsLoader.spiderTexture },
73 | time:{type:"f", value:0 },
74 | alpha:{type:"f", value:.75 }
75 | },
76 | vertexShader:assetsLoader.sem_vs,
77 | fragmentShader:assetsLoader.sem_fs,
78 | blending:THREE.AdditiveBlending,
79 | // side:THREE.DoubleSide,
80 | depthWrite:false,
81 | transparent: true
82 | });
83 |
84 | materials.particles = new THREE.ShaderMaterial({
85 | uniforms : {
86 | color0:{type:"v3", value:new THREE.Color( 0x00CCFF )},
87 | color1:{type:"v3", value:new THREE.Color( 0xFFCC00 )},
88 | bounds:{type:"v2", value:new THREE.Vector2( .25, .5 )},//start / length
89 | time:{type:"f", value:0},
90 | modBig:{type:"f", value:100},
91 | pointSize:{type:"f", value:2},
92 | alpha:{type:"f", value:1}
93 | },
94 | vertexShader: assetsLoader.particles_vs,
95 | fragmentShader: assetsLoader.particles_fs,
96 | transparent: true
97 | });
98 |
99 | materials.environment = new THREE.ShaderMaterial({
100 | uniforms : {
101 | horizon:{type:"f", value: .45 },
102 | spread:{type:"f", value: .05 },
103 | topColor:{type:"v3", value:new THREE.Color( 0x303030 )},
104 | bottomColor:{type:"v3", value:new THREE.Color( 0x101010 )}
105 | },
106 | vertexShader: assetsLoader.env_vs,
107 | fragmentShader: assetsLoader.env_fs,
108 | side:THREE.BackSide,
109 | depthWrite:false
110 | });
111 |
112 | }
113 |
114 | function createMeshes() {
115 |
116 | assetsLoader.spider.computeVertexNormals();
117 | spider = new THREE.Mesh(assetsLoader.spider, materials.spiderTexture );
118 |
119 | env = new THREE.Mesh(new THREE.CylinderBufferGeometry(.5, .5, 1, 64), materials.environment);
120 | env.scale.multiplyScalar(1000);
121 |
122 | }
123 |
124 |
125 | function createParticles(){
126 |
127 | if( assetsLoader.particles === undefined ){
128 |
129 | var model = spider;
130 | var count = Math.pow( 2, 15 );
131 |
132 | assetsLoader.particles = Scatter.distribute( model, count );
133 | Scatter.toString( assetsLoader.particles, 3, "spider32k" );
134 |
135 | }
136 |
137 | var g = new THREE.BufferGeometry();
138 | g.addAttribute( "position", new THREE.BufferAttribute( new Float32Array( assetsLoader.particles.pos ), 3 ));
139 | g.addAttribute( "dest", new THREE.BufferAttribute( new Float32Array( assetsLoader.particles.dst ), 3 ));
140 | particles = new THREE.Points(g,materials.particles);
141 | }
142 |
143 |
144 | function render() {
145 |
146 | requestAnimationFrame( render );
147 | controls.update();
148 |
149 | var time = ( Date.now() - startTime ) * 0.001;
150 | for( var k in materials ){
151 |
152 | if( materials[ k ].uniforms.time !== undefined ){
153 |
154 | materials[ k ].uniforms.time.value = time;
155 |
156 | }
157 | }
158 |
159 | renderer.render( scene, camera );
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/js/suzanne.js:
--------------------------------------------------------------------------------
1 |
2 | var skeleton, invertSkeleton, env, particles;
3 |
4 | window.onload = function(){
5 |
6 | var queue = [
7 |
8 | {name: "particles_vs", url: "./glsl/texture_particles_vs.glsl", type:assetsLoader.TXT },
9 | {name: "particles_fs", url: "./glsl/texture_particles_fs.glsl", type:assetsLoader.TXT },
10 | {name: "sem_vs", url: "./glsl/sem_vs.glsl", type:assetsLoader.TXT },
11 | {name: "sem_fs", url: "./glsl/sem_fs.glsl", type:assetsLoader.TXT },
12 | {name: "env_vs", url: "./glsl/env_vs.glsl", type:assetsLoader.TXT },
13 | {name: "env_fs", url: "./glsl/env_fs.glsl", type:assetsLoader.TXT },
14 |
15 | {
16 | name: "silver",
17 | url: "./assets/textures/matcap/test_steel.jpg",type:assetsLoader.IMG
18 | },
19 | {
20 | name: "blue",
21 | url: "./assets/textures/matcap/JG_Drink01.png",type:assetsLoader.IMG
22 | },
23 | {
24 | name: "particlesTexture",
25 | url: "./assets/textures/particles.png",type:assetsLoader.IMG
26 | },
27 |
28 | {
29 | name: "skeleton",
30 | url: "./assets/models/binaries/suzanne.js",type:assetsLoader.MOD
31 | },
32 | {
33 | name: "invert",
34 | url: "./assets/models/binaries/suzanne_invert.js",type:assetsLoader.MOD
35 | },
36 | {
37 | name: "particles",
38 | url:"./assets/models/particles/suzanne/volume65k.txt", type:assetsLoader.TXT,
39 | onLoad:function (txt) {
40 | var obj = {};
41 | var res = txt.split( '|' );
42 | obj.pos = res[0].split(',').map( function( v ){return parseFloat( v ); } );
43 | obj.dst = res[1].split(',').map( function( v ){return parseFloat( v ); } );
44 | assetsLoader.particles = obj;
45 | }
46 | }
47 |
48 | ];
49 | assetsLoader.load(queue, init);
50 | };
51 |
52 | function init() {
53 |
54 | init3D();
55 | camera.position.x = 0;
56 | camera.position.y = 7;
57 | camera.position.z = 20;
58 |
59 | createMaterials();
60 |
61 | createMeshes();
62 | createParticles();
63 |
64 | scene.add(skeleton);
65 | scene.add(invertSkeleton);
66 | scene.add(env);
67 | scene.add( particles );
68 |
69 |
70 | render();
71 |
72 | }
73 |
74 | function createMaterials(){
75 |
76 | startTime = Date.now();
77 |
78 | materials.silver = new THREE.ShaderMaterial({
79 | uniforms:{
80 | tMatCap : {type:"t", value:assetsLoader.silver },
81 | time:{type:"f", value:0 },
82 | alpha:{type:"f", value:0 }
83 | },
84 | vertexShader:assetsLoader.sem_vs,
85 | fragmentShader:assetsLoader.sem_fs
86 | });
87 |
88 | materials.blue = new THREE.ShaderMaterial({
89 | uniforms:{
90 | tMatCap : {type:"t", value:assetsLoader.blue },
91 | time:{type:"f", value:0 },
92 | alpha:{type:"f", value:0.45 }
93 | },
94 | vertexShader:assetsLoader.sem_vs,
95 | fragmentShader:assetsLoader.sem_fs,
96 | transparent: true,
97 | side:THREE.DoubleSide,
98 | depthWrite:false
99 | });
100 |
101 | materials.particles = new THREE.ShaderMaterial({
102 | uniforms : {
103 | texture:{type:"t", value:assetsLoader.particlesTexture},
104 | time:{type:"f", value:0},
105 | modBig:{type:"f", value:25},
106 | pointSize:{type:"f", value:4},
107 | alpha:{type:"f", value:1}
108 | },
109 | vertexShader: assetsLoader.particles_vs,
110 | fragmentShader: assetsLoader.particles_fs,
111 | transparent: true
112 | });
113 |
114 | materials.environment = new THREE.ShaderMaterial({
115 | uniforms : {
116 | horizon:{type:"f", value: .45 },
117 | spread:{type:"f", value: .05 },
118 | topColor:{type:"v3", value:new THREE.Color( 0x505050 )},
119 | bottomColor:{type:"v3", value:new THREE.Color( 0x101010 )}
120 | },
121 | vertexShader: assetsLoader.env_vs,
122 | fragmentShader: assetsLoader.env_fs,
123 | side:THREE.BackSide,
124 | depthWrite:false
125 | });
126 |
127 | }
128 |
129 | function createMeshes() {
130 |
131 | skeleton = new THREE.Mesh(assetsLoader.skeleton, materials.silver);
132 |
133 | invertSkeleton = new THREE.Mesh(assetsLoader.invert, materials.blue);
134 |
135 | env = new THREE.Mesh(new THREE.CylinderBufferGeometry(.5, .5, 1, 64), materials.environment);
136 | env.scale.multiplyScalar(1000);
137 |
138 | }
139 |
140 |
141 | function createParticles(){
142 |
143 | if( assetsLoader.particles === undefined ){
144 |
145 | var model = invertSkeleton;
146 | var count = Math.pow( 2, 16 );
147 |
148 | assetsLoader.particles = Scatter.distribute( model, count );
149 | Scatter.toString( assetsLoader.particles, 3, "surface65k" );
150 |
151 | }
152 |
153 | var g = new THREE.BufferGeometry();
154 | g.addAttribute( "position", new THREE.BufferAttribute( new Float32Array( assetsLoader.particles.pos ), 3 ));
155 | g.addAttribute( "dest", new THREE.BufferAttribute( new Float32Array( assetsLoader.particles.dst ), 3 ));
156 |
157 | //adds uvs to the particles (the texture is a 4*4 spritesheet
158 | var uvCount = ( g.getAttribute("position").array.length / 3 ) * 2;
159 | var uvOffset = new Float32Array( uvCount );
160 | var i = 0;
161 | while( i < uvCount ){
162 | uvOffset[ i++ ] = Math.floor( Math.random() * 4 ) / 4;
163 | }
164 | g.addAttribute( "uvOffset", new THREE.BufferAttribute( uvOffset, 2 ));
165 | particles = new THREE.Points(g,materials.particles);
166 |
167 | }
168 |
169 |
170 | function render() {
171 |
172 | requestAnimationFrame( render );
173 | controls.update();
174 |
175 | var time = ( Date.now() - startTime ) * 0.001;
176 | for( var k in materials ){
177 |
178 | if( materials[ k ].uniforms.time !== undefined ){
179 |
180 | materials[ k ].uniforms.time.value = time;
181 |
182 | }
183 | }
184 |
185 | renderer.render( scene, camera );
186 |
187 | }
188 |
--------------------------------------------------------------------------------
/plane.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | THREE.MeshLine - Shape example
6 |
7 |
8 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/spider.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | THREE.MeshLine - Shape example
6 |
7 |
8 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/sreenshots/4k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/4k.png
--------------------------------------------------------------------------------
/sreenshots/4k0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/4k0.png
--------------------------------------------------------------------------------
/sreenshots/4k1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/4k1.png
--------------------------------------------------------------------------------
/sreenshots/4k2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/4k2.png
--------------------------------------------------------------------------------
/sreenshots/4k3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/4k3.png
--------------------------------------------------------------------------------
/sreenshots/8k0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/8k0.png
--------------------------------------------------------------------------------
/sreenshots/8k1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/8k1.png
--------------------------------------------------------------------------------
/sreenshots/lines0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/lines0.png
--------------------------------------------------------------------------------
/sreenshots/lines1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/lines1.png
--------------------------------------------------------------------------------
/sreenshots/spider0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/volume_distribution/2554d9d96a278a3cd24b2b3b39bb5554c89b98fc/sreenshots/spider0.png
--------------------------------------------------------------------------------
/suzanne.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | THREE.MeshLine - Shape example
6 |
7 |
8 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/vendor/BinaryLoader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.BinaryLoader = function ( manager ) {
6 |
7 | if ( typeof manager === 'boolean' ) {
8 |
9 | console.warn( 'THREE.BinaryLoader: showStatus parameter has been removed from constructor.' );
10 | manager = undefined;
11 |
12 | }
13 |
14 | this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
15 |
16 | };
17 |
18 | THREE.BinaryLoader.prototype = {
19 |
20 | constructor: THREE.BinaryLoader,
21 |
22 | // Load models generated by slim OBJ converter with BINARY option (converter_obj_three_slim.py -t binary)
23 | // - binary models consist of two files: JS and BIN
24 | // - parameters
25 | // - url (required)
26 | // - callback (required)
27 | // - texturePath (optional: if not specified, textures will be assumed to be in the same folder as JS model file)
28 | // - binaryPath (optional: if not specified, binary file will be assumed to be in the same folder as JS model file)
29 | load: function ( url, onLoad, onProgress, onError ) {
30 |
31 | // todo: unify load API to for easier SceneLoader use
32 |
33 | var texturePath = this.texturePath || THREE.Loader.prototype.extractUrlBase( url );
34 | var binaryPath = this.binaryPath || THREE.Loader.prototype.extractUrlBase( url );
35 |
36 | // #1 load JS part via web worker
37 |
38 | var scope = this;
39 |
40 | var jsonloader = new THREE.FileLoader( this.manager );
41 | jsonloader.load( url, function ( data ) {
42 |
43 | var json = JSON.parse( data );
44 |
45 | var bufferUrl = binaryPath + json.buffers;
46 |
47 | var bufferLoader = new THREE.FileLoader( scope.manager );
48 | bufferLoader.setResponseType( 'arraybuffer' );
49 | bufferLoader.load( bufferUrl, function ( bufData ) {
50 |
51 | // IEWEBGL needs this ???
52 | //buffer = ( new Uint8Array( xhr.responseBody ) ).buffer;
53 |
54 | //// iOS and other XMLHttpRequest level 1 ???
55 |
56 | scope.parse( bufData, onLoad, texturePath, json.materials );
57 |
58 | }, onProgress, onError );
59 |
60 | }, onProgress, onError );
61 |
62 | },
63 |
64 | setBinaryPath: function ( value ) {
65 |
66 | this.binaryPath = value;
67 |
68 | },
69 |
70 | setCrossOrigin: function ( value ) {
71 |
72 | this.crossOrigin = value;
73 |
74 | },
75 |
76 | setTexturePath: function ( value ) {
77 |
78 | this.texturePath = value;
79 |
80 | },
81 |
82 | parse: function ( data, callback, texturePath, jsonMaterials ) {
83 |
84 | var Model = function ( texturePath ) {
85 |
86 | var scope = this,
87 | currentOffset = 0,
88 | md,
89 | normals = [],
90 | uvs = [],
91 | start_tri_flat, start_tri_smooth, start_tri_flat_uv, start_tri_smooth_uv,
92 | start_quad_flat, start_quad_smooth, start_quad_flat_uv, start_quad_smooth_uv,
93 | tri_size, quad_size,
94 | len_tri_flat, len_tri_smooth, len_tri_flat_uv, len_tri_smooth_uv,
95 | len_quad_flat, len_quad_smooth, len_quad_flat_uv, len_quad_smooth_uv;
96 |
97 |
98 | THREE.Geometry.call( this );
99 |
100 | md = parseMetaData( data, currentOffset );
101 |
102 | currentOffset += md.header_bytes;
103 | /*
104 | md.vertex_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
105 | md.material_index_bytes = Uint16Array.BYTES_PER_ELEMENT;
106 | md.normal_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
107 | md.uv_index_bytes = Uint32Array.BYTES_PER_ELEMENT;
108 | */
109 | // buffers sizes
110 |
111 | tri_size = md.vertex_index_bytes * 3 + md.material_index_bytes;
112 | quad_size = md.vertex_index_bytes * 4 + md.material_index_bytes;
113 |
114 | len_tri_flat = md.ntri_flat * ( tri_size );
115 | len_tri_smooth = md.ntri_smooth * ( tri_size + md.normal_index_bytes * 3 );
116 | len_tri_flat_uv = md.ntri_flat_uv * ( tri_size + md.uv_index_bytes * 3 );
117 | len_tri_smooth_uv = md.ntri_smooth_uv * ( tri_size + md.normal_index_bytes * 3 + md.uv_index_bytes * 3 );
118 |
119 | len_quad_flat = md.nquad_flat * ( quad_size );
120 | len_quad_smooth = md.nquad_smooth * ( quad_size + md.normal_index_bytes * 4 );
121 | len_quad_flat_uv = md.nquad_flat_uv * ( quad_size + md.uv_index_bytes * 4 );
122 | len_quad_smooth_uv = md.nquad_smooth_uv * ( quad_size + md.normal_index_bytes * 4 + md.uv_index_bytes * 4 );
123 |
124 | // read buffers
125 |
126 | currentOffset += init_vertices( currentOffset );
127 |
128 | currentOffset += init_normals( currentOffset );
129 | currentOffset += handlePadding( md.nnormals * 3 );
130 |
131 | currentOffset += init_uvs( currentOffset );
132 |
133 | start_tri_flat = currentOffset;
134 | start_tri_smooth = start_tri_flat + len_tri_flat + handlePadding( md.ntri_flat * 2 );
135 | start_tri_flat_uv = start_tri_smooth + len_tri_smooth + handlePadding( md.ntri_smooth * 2 );
136 | start_tri_smooth_uv = start_tri_flat_uv + len_tri_flat_uv + handlePadding( md.ntri_flat_uv * 2 );
137 |
138 | start_quad_flat = start_tri_smooth_uv + len_tri_smooth_uv + handlePadding( md.ntri_smooth_uv * 2 );
139 | start_quad_smooth = start_quad_flat + len_quad_flat + handlePadding( md.nquad_flat * 2 );
140 | start_quad_flat_uv = start_quad_smooth + len_quad_smooth + handlePadding( md.nquad_smooth * 2 );
141 | start_quad_smooth_uv = start_quad_flat_uv + len_quad_flat_uv + handlePadding( md.nquad_flat_uv * 2 );
142 |
143 | // have to first process faces with uvs
144 | // so that face and uv indices match
145 |
146 | init_triangles_flat_uv( start_tri_flat_uv );
147 | init_triangles_smooth_uv( start_tri_smooth_uv );
148 |
149 | init_quads_flat_uv( start_quad_flat_uv );
150 | init_quads_smooth_uv( start_quad_smooth_uv );
151 |
152 | // now we can process untextured faces
153 |
154 | init_triangles_flat( start_tri_flat );
155 | init_triangles_smooth( start_tri_smooth );
156 |
157 | init_quads_flat( start_quad_flat );
158 | init_quads_smooth( start_quad_smooth );
159 |
160 | this.computeFaceNormals();
161 |
162 | function handlePadding( n ) {
163 |
164 | return ( n % 4 ) ? ( 4 - n % 4 ) : 0;
165 |
166 | }
167 |
168 | function parseMetaData( data, offset ) {
169 |
170 | var metaData = {
171 |
172 | 'signature' : parseString( data, offset, 12 ),
173 | 'header_bytes' : parseUChar8( data, offset + 12 ),
174 |
175 | 'vertex_coordinate_bytes' : parseUChar8( data, offset + 13 ),
176 | 'normal_coordinate_bytes' : parseUChar8( data, offset + 14 ),
177 | 'uv_coordinate_bytes' : parseUChar8( data, offset + 15 ),
178 |
179 | 'vertex_index_bytes' : parseUChar8( data, offset + 16 ),
180 | 'normal_index_bytes' : parseUChar8( data, offset + 17 ),
181 | 'uv_index_bytes' : parseUChar8( data, offset + 18 ),
182 | 'material_index_bytes' : parseUChar8( data, offset + 19 ),
183 |
184 | 'nvertices' : parseUInt32( data, offset + 20 ),
185 | 'nnormals' : parseUInt32( data, offset + 20 + 4 * 1 ),
186 | 'nuvs' : parseUInt32( data, offset + 20 + 4 * 2 ),
187 |
188 | 'ntri_flat' : parseUInt32( data, offset + 20 + 4 * 3 ),
189 | 'ntri_smooth' : parseUInt32( data, offset + 20 + 4 * 4 ),
190 | 'ntri_flat_uv' : parseUInt32( data, offset + 20 + 4 * 5 ),
191 | 'ntri_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 6 ),
192 |
193 | 'nquad_flat' : parseUInt32( data, offset + 20 + 4 * 7 ),
194 | 'nquad_smooth' : parseUInt32( data, offset + 20 + 4 * 8 ),
195 | 'nquad_flat_uv' : parseUInt32( data, offset + 20 + 4 * 9 ),
196 | 'nquad_smooth_uv' : parseUInt32( data, offset + 20 + 4 * 10 )
197 |
198 | };
199 | /*
200 | console.log( "signature: " + metaData.signature );
201 |
202 | console.log( "header_bytes: " + metaData.header_bytes );
203 | console.log( "vertex_coordinate_bytes: " + metaData.vertex_coordinate_bytes );
204 | console.log( "normal_coordinate_bytes: " + metaData.normal_coordinate_bytes );
205 | console.log( "uv_coordinate_bytes: " + metaData.uv_coordinate_bytes );
206 |
207 | console.log( "vertex_index_bytes: " + metaData.vertex_index_bytes );
208 | console.log( "normal_index_bytes: " + metaData.normal_index_bytes );
209 | console.log( "uv_index_bytes: " + metaData.uv_index_bytes );
210 | console.log( "material_index_bytes: " + metaData.material_index_bytes );
211 |
212 | console.log( "nvertices: " + metaData.nvertices );
213 | console.log( "nnormals: " + metaData.nnormals );
214 | console.log( "nuvs: " + metaData.nuvs );
215 |
216 | console.log( "ntri_flat: " + metaData.ntri_flat );
217 | console.log( "ntri_smooth: " + metaData.ntri_smooth );
218 | console.log( "ntri_flat_uv: " + metaData.ntri_flat_uv );
219 | console.log( "ntri_smooth_uv: " + metaData.ntri_smooth_uv );
220 |
221 | console.log( "nquad_flat: " + metaData.nquad_flat );
222 | console.log( "nquad_smooth: " + metaData.nquad_smooth );
223 | console.log( "nquad_flat_uv: " + metaData.nquad_flat_uv );
224 | console.log( "nquad_smooth_uv: " + metaData.nquad_smooth_uv );
225 |
226 | var total = metaData.header_bytes
227 | + metaData.nvertices * metaData.vertex_coordinate_bytes * 3
228 | + metaData.nnormals * metaData.normal_coordinate_bytes * 3
229 | + metaData.nuvs * metaData.uv_coordinate_bytes * 2
230 | + metaData.ntri_flat * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes )
231 | + metaData.ntri_smooth * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 )
232 | + metaData.ntri_flat_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.uv_index_bytes*3 )
233 | + metaData.ntri_smooth_uv * ( metaData.vertex_index_bytes*3 + metaData.material_index_bytes + metaData.normal_index_bytes*3 + metaData.uv_index_bytes*3 )
234 | + metaData.nquad_flat * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes )
235 | + metaData.nquad_smooth * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 )
236 | + metaData.nquad_flat_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.uv_index_bytes*4 )
237 | + metaData.nquad_smooth_uv * ( metaData.vertex_index_bytes*4 + metaData.material_index_bytes + metaData.normal_index_bytes*4 + metaData.uv_index_bytes*4 );
238 | console.log( "total bytes: " + total );
239 | */
240 |
241 | return metaData;
242 |
243 | }
244 |
245 | function parseString( data, offset, length ) {
246 |
247 | var charArray = new Uint8Array( data, offset, length );
248 |
249 | var text = "";
250 |
251 | for ( var i = 0; i < length; i ++ ) {
252 |
253 | text += String.fromCharCode( charArray[ offset + i ] );
254 |
255 | }
256 |
257 | return text;
258 |
259 | }
260 |
261 | function parseUChar8( data, offset ) {
262 |
263 | var charArray = new Uint8Array( data, offset, 1 );
264 |
265 | return charArray[ 0 ];
266 |
267 | }
268 |
269 | function parseUInt32( data, offset ) {
270 |
271 | var intArray = new Uint32Array( data, offset, 1 );
272 |
273 | return intArray[ 0 ];
274 |
275 | }
276 |
277 | function init_vertices( start ) {
278 |
279 | var nElements = md.nvertices;
280 |
281 | var coordArray = new Float32Array( data, start, nElements * 3 );
282 |
283 | var i, x, y, z;
284 |
285 | for ( i = 0; i < nElements; i ++ ) {
286 |
287 | x = coordArray[ i * 3 ];
288 | y = coordArray[ i * 3 + 1 ];
289 | z = coordArray[ i * 3 + 2 ];
290 |
291 | scope.vertices.push( new THREE.Vector3( x, y, z ) );
292 |
293 | }
294 |
295 | return nElements * 3 * Float32Array.BYTES_PER_ELEMENT;
296 |
297 | }
298 |
299 | function init_normals( start ) {
300 |
301 | var nElements = md.nnormals;
302 |
303 | if ( nElements ) {
304 |
305 | var normalArray = new Int8Array( data, start, nElements * 3 );
306 |
307 | var i, x, y, z;
308 |
309 | for ( i = 0; i < nElements; i ++ ) {
310 |
311 | x = normalArray[ i * 3 ];
312 | y = normalArray[ i * 3 + 1 ];
313 | z = normalArray[ i * 3 + 2 ];
314 |
315 | normals.push( x / 127, y / 127, z / 127 );
316 |
317 | }
318 |
319 | }
320 |
321 | return nElements * 3 * Int8Array.BYTES_PER_ELEMENT;
322 |
323 | }
324 |
325 | function init_uvs( start ) {
326 |
327 | var nElements = md.nuvs;
328 |
329 | if ( nElements ) {
330 |
331 | var uvArray = new Float32Array( data, start, nElements * 2 );
332 |
333 | var i, u, v;
334 |
335 | for ( i = 0; i < nElements; i ++ ) {
336 |
337 | u = uvArray[ i * 2 ];
338 | v = uvArray[ i * 2 + 1 ];
339 |
340 | uvs.push( u, v );
341 |
342 | }
343 |
344 | }
345 |
346 | return nElements * 2 * Float32Array.BYTES_PER_ELEMENT;
347 |
348 | }
349 |
350 | function init_uvs3( nElements, offset ) {
351 |
352 | var i, uva, uvb, uvc, u1, u2, u3, v1, v2, v3;
353 |
354 | var uvIndexBuffer = new Uint32Array( data, offset, 3 * nElements );
355 |
356 | for ( i = 0; i < nElements; i ++ ) {
357 |
358 | uva = uvIndexBuffer[ i * 3 ];
359 | uvb = uvIndexBuffer[ i * 3 + 1 ];
360 | uvc = uvIndexBuffer[ i * 3 + 2 ];
361 |
362 | u1 = uvs[ uva * 2 ];
363 | v1 = uvs[ uva * 2 + 1 ];
364 |
365 | u2 = uvs[ uvb * 2 ];
366 | v2 = uvs[ uvb * 2 + 1 ];
367 |
368 | u3 = uvs[ uvc * 2 ];
369 | v3 = uvs[ uvc * 2 + 1 ];
370 |
371 | scope.faceVertexUvs[ 0 ].push( [
372 | new THREE.Vector2( u1, v1 ),
373 | new THREE.Vector2( u2, v2 ),
374 | new THREE.Vector2( u3, v3 )
375 | ] );
376 |
377 | }
378 |
379 | }
380 |
381 | function init_uvs4( nElements, offset ) {
382 |
383 | var i, uva, uvb, uvc, uvd, u1, u2, u3, u4, v1, v2, v3, v4;
384 |
385 | var uvIndexBuffer = new Uint32Array( data, offset, 4 * nElements );
386 |
387 | for ( i = 0; i < nElements; i ++ ) {
388 |
389 | uva = uvIndexBuffer[ i * 4 ];
390 | uvb = uvIndexBuffer[ i * 4 + 1 ];
391 | uvc = uvIndexBuffer[ i * 4 + 2 ];
392 | uvd = uvIndexBuffer[ i * 4 + 3 ];
393 |
394 | u1 = uvs[ uva * 2 ];
395 | v1 = uvs[ uva * 2 + 1 ];
396 |
397 | u2 = uvs[ uvb * 2 ];
398 | v2 = uvs[ uvb * 2 + 1 ];
399 |
400 | u3 = uvs[ uvc * 2 ];
401 | v3 = uvs[ uvc * 2 + 1 ];
402 |
403 | u4 = uvs[ uvd * 2 ];
404 | v4 = uvs[ uvd * 2 + 1 ];
405 |
406 | scope.faceVertexUvs[ 0 ].push( [
407 | new THREE.Vector2( u1, v1 ),
408 | new THREE.Vector2( u2, v2 ),
409 | new THREE.Vector2( u4, v4 )
410 | ] );
411 |
412 | scope.faceVertexUvs[ 0 ].push( [
413 | new THREE.Vector2( u2, v2 ),
414 | new THREE.Vector2( u3, v3 ),
415 | new THREE.Vector2( u4, v4 )
416 | ] );
417 |
418 | }
419 |
420 | }
421 |
422 | function init_faces3_flat( nElements, offsetVertices, offsetMaterials ) {
423 |
424 | var i, a, b, c, m;
425 |
426 | var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
427 | var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
428 |
429 | for ( i = 0; i < nElements; i ++ ) {
430 |
431 | a = vertexIndexBuffer[ i * 3 ];
432 | b = vertexIndexBuffer[ i * 3 + 1 ];
433 | c = vertexIndexBuffer[ i * 3 + 2 ];
434 |
435 | m = materialIndexBuffer[ i ];
436 |
437 | scope.faces.push( new THREE.Face3( a, b, c, null, null, m ) );
438 |
439 | }
440 |
441 | }
442 |
443 | function init_faces4_flat( nElements, offsetVertices, offsetMaterials ) {
444 |
445 | var i, a, b, c, d, m;
446 |
447 | var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
448 | var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
449 |
450 | for ( i = 0; i < nElements; i ++ ) {
451 |
452 | a = vertexIndexBuffer[ i * 4 ];
453 | b = vertexIndexBuffer[ i * 4 + 1 ];
454 | c = vertexIndexBuffer[ i * 4 + 2 ];
455 | d = vertexIndexBuffer[ i * 4 + 3 ];
456 |
457 | m = materialIndexBuffer[ i ];
458 |
459 | scope.faces.push( new THREE.Face3( a, b, d, null, null, m ) );
460 | scope.faces.push( new THREE.Face3( b, c, d, null, null, m ) );
461 |
462 | }
463 |
464 | }
465 |
466 | function init_faces3_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
467 |
468 | var i, a, b, c, m;
469 | var na, nb, nc;
470 |
471 | var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 3 * nElements );
472 | var normalIndexBuffer = new Uint32Array( data, offsetNormals, 3 * nElements );
473 | var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
474 |
475 | for ( i = 0; i < nElements; i ++ ) {
476 |
477 | a = vertexIndexBuffer[ i * 3 ];
478 | b = vertexIndexBuffer[ i * 3 + 1 ];
479 | c = vertexIndexBuffer[ i * 3 + 2 ];
480 |
481 | na = normalIndexBuffer[ i * 3 ];
482 | nb = normalIndexBuffer[ i * 3 + 1 ];
483 | nc = normalIndexBuffer[ i * 3 + 2 ];
484 |
485 | m = materialIndexBuffer[ i ];
486 |
487 | var nax = normals[ na * 3 ],
488 | nay = normals[ na * 3 + 1 ],
489 | naz = normals[ na * 3 + 2 ],
490 |
491 | nbx = normals[ nb * 3 ],
492 | nby = normals[ nb * 3 + 1 ],
493 | nbz = normals[ nb * 3 + 2 ],
494 |
495 | ncx = normals[ nc * 3 ],
496 | ncy = normals[ nc * 3 + 1 ],
497 | ncz = normals[ nc * 3 + 2 ];
498 |
499 | scope.faces.push( new THREE.Face3( a, b, c, [
500 | new THREE.Vector3( nax, nay, naz ),
501 | new THREE.Vector3( nbx, nby, nbz ),
502 | new THREE.Vector3( ncx, ncy, ncz )
503 | ], null, m ) );
504 |
505 | }
506 |
507 | }
508 |
509 | function init_faces4_smooth( nElements, offsetVertices, offsetNormals, offsetMaterials ) {
510 |
511 | var i, a, b, c, d, m;
512 | var na, nb, nc, nd;
513 |
514 | var vertexIndexBuffer = new Uint32Array( data, offsetVertices, 4 * nElements );
515 | var normalIndexBuffer = new Uint32Array( data, offsetNormals, 4 * nElements );
516 | var materialIndexBuffer = new Uint16Array( data, offsetMaterials, nElements );
517 |
518 | for ( i = 0; i < nElements; i ++ ) {
519 |
520 | a = vertexIndexBuffer[ i * 4 ];
521 | b = vertexIndexBuffer[ i * 4 + 1 ];
522 | c = vertexIndexBuffer[ i * 4 + 2 ];
523 | d = vertexIndexBuffer[ i * 4 + 3 ];
524 |
525 | na = normalIndexBuffer[ i * 4 ];
526 | nb = normalIndexBuffer[ i * 4 + 1 ];
527 | nc = normalIndexBuffer[ i * 4 + 2 ];
528 | nd = normalIndexBuffer[ i * 4 + 3 ];
529 |
530 | m = materialIndexBuffer[ i ];
531 |
532 | var nax = normals[ na * 3 ],
533 | nay = normals[ na * 3 + 1 ],
534 | naz = normals[ na * 3 + 2 ],
535 |
536 | nbx = normals[ nb * 3 ],
537 | nby = normals[ nb * 3 + 1 ],
538 | nbz = normals[ nb * 3 + 2 ],
539 |
540 | ncx = normals[ nc * 3 ],
541 | ncy = normals[ nc * 3 + 1 ],
542 | ncz = normals[ nc * 3 + 2 ],
543 |
544 | ndx = normals[ nd * 3 ],
545 | ndy = normals[ nd * 3 + 1 ],
546 | ndz = normals[ nd * 3 + 2 ];
547 |
548 | scope.faces.push( new THREE.Face3( a, b, d, [
549 | new THREE.Vector3( nax, nay, naz ),
550 | new THREE.Vector3( nbx, nby, nbz ),
551 | new THREE.Vector3( ndx, ndy, ndz )
552 | ], null, m ) );
553 |
554 | scope.faces.push( new THREE.Face3( b, c, d, [
555 | new THREE.Vector3( nbx, nby, nbz ),
556 | new THREE.Vector3( ncx, ncy, ncz ),
557 | new THREE.Vector3( ndx, ndy, ndz )
558 | ], null, m ) );
559 |
560 | }
561 |
562 | }
563 |
564 | function init_triangles_flat( start ) {
565 |
566 | var nElements = md.ntri_flat;
567 |
568 | if ( nElements ) {
569 |
570 | var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
571 | init_faces3_flat( nElements, start, offsetMaterials );
572 |
573 | }
574 |
575 | }
576 |
577 | function init_triangles_flat_uv( start ) {
578 |
579 | var nElements = md.ntri_flat_uv;
580 |
581 | if ( nElements ) {
582 |
583 | var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
584 | var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
585 |
586 | init_faces3_flat( nElements, start, offsetMaterials );
587 | init_uvs3( nElements, offsetUvs );
588 |
589 | }
590 |
591 | }
592 |
593 | function init_triangles_smooth( start ) {
594 |
595 | var nElements = md.ntri_smooth;
596 |
597 | if ( nElements ) {
598 |
599 | var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
600 | var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
601 |
602 | init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
603 |
604 | }
605 |
606 | }
607 |
608 | function init_triangles_smooth_uv( start ) {
609 |
610 | var nElements = md.ntri_smooth_uv;
611 |
612 | if ( nElements ) {
613 |
614 | var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
615 | var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
616 | var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 3;
617 |
618 | init_faces3_smooth( nElements, start, offsetNormals, offsetMaterials );
619 | init_uvs3( nElements, offsetUvs );
620 |
621 | }
622 |
623 | }
624 |
625 | function init_quads_flat( start ) {
626 |
627 | var nElements = md.nquad_flat;
628 |
629 | if ( nElements ) {
630 |
631 | var offsetMaterials = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
632 | init_faces4_flat( nElements, start, offsetMaterials );
633 |
634 | }
635 |
636 | }
637 |
638 | function init_quads_flat_uv( start ) {
639 |
640 | var nElements = md.nquad_flat_uv;
641 |
642 | if ( nElements ) {
643 |
644 | var offsetUvs = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
645 | var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
646 |
647 | init_faces4_flat( nElements, start, offsetMaterials );
648 | init_uvs4( nElements, offsetUvs );
649 |
650 | }
651 |
652 | }
653 |
654 | function init_quads_smooth( start ) {
655 |
656 | var nElements = md.nquad_smooth;
657 |
658 | if ( nElements ) {
659 |
660 | var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
661 | var offsetMaterials = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
662 |
663 | init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
664 |
665 | }
666 |
667 | }
668 |
669 | function init_quads_smooth_uv( start ) {
670 |
671 | var nElements = md.nquad_smooth_uv;
672 |
673 | if ( nElements ) {
674 |
675 | var offsetNormals = start + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
676 | var offsetUvs = offsetNormals + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
677 | var offsetMaterials = offsetUvs + nElements * Uint32Array.BYTES_PER_ELEMENT * 4;
678 |
679 | init_faces4_smooth( nElements, start, offsetNormals, offsetMaterials );
680 | init_uvs4( nElements, offsetUvs );
681 |
682 | }
683 |
684 | }
685 |
686 | };
687 |
688 | Model.prototype = Object.create( THREE.Geometry.prototype );
689 | Model.prototype.constructor = Model;
690 |
691 | var geometry = new Model( texturePath );
692 | var materials = THREE.Loader.prototype.initMaterials( jsonMaterials, texturePath, this.crossOrigin );
693 |
694 | callback( geometry, materials );
695 |
696 | }
697 |
698 | };
699 |
--------------------------------------------------------------------------------
/vendor/OrbitControls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author qiao / https://github.com/qiao
3 | * @author mrdoob / http://mrdoob.com
4 | * @author alteredq / http://alteredqualia.com/
5 | * @author WestLangley / http://github.com/WestLangley
6 | * @author erich666 / http://erichaines.com
7 | */
8 |
9 | // This set of controls performs orbiting, dollying (zooming), and panning.
10 | // Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
11 | //
12 | // Orbit - left mouse / touch: one finger move
13 | // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
14 | // Pan - right mouse, or arrow keys / touch: three finger swipe
15 |
16 | THREE.OrbitControls = function ( object, domElement ) {
17 |
18 | this.object = object;
19 |
20 | this.domElement = ( domElement !== undefined ) ? domElement : document;
21 |
22 | // Set to false to disable this control
23 | this.enabled = true;
24 |
25 | // "target" sets the location of focus, where the object orbits around
26 | this.target = new THREE.Vector3();
27 |
28 | // How far you can dolly in and out ( PerspectiveCamera only )
29 | this.minDistance = 0;
30 | this.maxDistance = Infinity;
31 |
32 | // How far you can zoom in and out ( OrthographicCamera only )
33 | this.minZoom = 0;
34 | this.maxZoom = Infinity;
35 |
36 | // How far you can orbit vertically, upper and lower limits.
37 | // Range is 0 to Math.PI radians.
38 | this.minPolarAngle = 0; // radians
39 | this.maxPolarAngle = Math.PI; // radians
40 |
41 | // How far you can orbit horizontally, upper and lower limits.
42 | // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
43 | this.minAzimuthAngle = - Infinity; // radians
44 | this.maxAzimuthAngle = Infinity; // radians
45 |
46 | // Set to true to enable damping (inertia)
47 | // If damping is enabled, you must call controls.update() in your animation loop
48 | this.enableDamping = false;
49 | this.dampingFactor = 0.25;
50 |
51 | // This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
52 | // Set to false to disable zooming
53 | this.enableZoom = true;
54 | this.zoomSpeed = 1.0;
55 |
56 | // Set to false to disable rotating
57 | this.enableRotate = true;
58 | this.rotateSpeed = 1.0;
59 |
60 | // Set to false to disable panning
61 | this.enablePan = true;
62 | this.keyPanSpeed = 7.0; // pixels moved per arrow key push
63 |
64 | // Set to true to automatically rotate around the target
65 | // If auto-rotate is enabled, you must call controls.update() in your animation loop
66 | this.autoRotate = false;
67 | this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
68 |
69 | // Set to false to disable use of the keys
70 | this.enableKeys = true;
71 |
72 | // The four arrow keys
73 | this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
74 |
75 | // Mouse buttons
76 | this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };
77 |
78 | // for reset
79 | this.target0 = this.target.clone();
80 | this.position0 = this.object.position.clone();
81 | this.zoom0 = this.object.zoom;
82 |
83 | //
84 | // public methods
85 | //
86 |
87 | this.getPolarAngle = function () {
88 |
89 | return spherical.phi;
90 |
91 | };
92 |
93 | this.getAzimuthalAngle = function () {
94 |
95 | return spherical.theta;
96 |
97 | };
98 |
99 | this.saveState = function () {
100 |
101 | scope.target0.copy( scope.target );
102 | scope.position0.copy( scope.object.position );
103 | scope.zoom0 = scope.object.zoom;
104 |
105 | };
106 |
107 | this.reset = function () {
108 |
109 | scope.target.copy( scope.target0 );
110 | scope.object.position.copy( scope.position0 );
111 | scope.object.zoom = scope.zoom0;
112 |
113 | scope.object.updateProjectionMatrix();
114 | scope.dispatchEvent( changeEvent );
115 |
116 | scope.update();
117 |
118 | state = STATE.NONE;
119 |
120 | };
121 |
122 | // this method is exposed, but perhaps it would be better if we can make it private...
123 | this.update = function () {
124 |
125 | var offset = new THREE.Vector3();
126 |
127 | // so camera.up is the orbit axis
128 | var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
129 | var quatInverse = quat.clone().inverse();
130 |
131 | var lastPosition = new THREE.Vector3();
132 | var lastQuaternion = new THREE.Quaternion();
133 |
134 | return function update() {
135 |
136 | var position = scope.object.position;
137 |
138 | offset.copy( position ).sub( scope.target );
139 |
140 | // rotate offset to "y-axis-is-up" space
141 | offset.applyQuaternion( quat );
142 |
143 | // angle from z-axis around y-axis
144 | spherical.setFromVector3( offset );
145 |
146 | if ( scope.autoRotate && state === STATE.NONE ) {
147 |
148 | rotateLeft( getAutoRotationAngle() );
149 |
150 | }
151 |
152 | spherical.theta += sphericalDelta.theta;
153 | spherical.phi += sphericalDelta.phi;
154 |
155 | // restrict theta to be between desired limits
156 | spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
157 |
158 | // restrict phi to be between desired limits
159 | spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
160 |
161 | spherical.makeSafe();
162 |
163 |
164 | spherical.radius *= scale;
165 |
166 | // restrict radius to be between desired limits
167 | spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
168 |
169 | // move target to panned location
170 | scope.target.add( panOffset );
171 |
172 | offset.setFromSpherical( spherical );
173 |
174 | // rotate offset back to "camera-up-vector-is-up" space
175 | offset.applyQuaternion( quatInverse );
176 |
177 | position.copy( scope.target ).add( offset );
178 |
179 | scope.object.lookAt( scope.target );
180 |
181 | if ( scope.enableDamping === true ) {
182 |
183 | sphericalDelta.theta *= ( 1 - scope.dampingFactor );
184 | sphericalDelta.phi *= ( 1 - scope.dampingFactor );
185 |
186 | } else {
187 |
188 | sphericalDelta.set( 0, 0, 0 );
189 |
190 | }
191 |
192 | scale = 1;
193 | panOffset.set( 0, 0, 0 );
194 |
195 | // update condition is:
196 | // min(camera displacement, camera rotation in radians)^2 > EPS
197 | // using small-angle approximation cos(x/2) = 1 - x^2 / 8
198 |
199 | if ( zoomChanged ||
200 | lastPosition.distanceToSquared( scope.object.position ) > EPS ||
201 | 8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
202 |
203 | scope.dispatchEvent( changeEvent );
204 |
205 | lastPosition.copy( scope.object.position );
206 | lastQuaternion.copy( scope.object.quaternion );
207 | zoomChanged = false;
208 |
209 | return true;
210 |
211 | }
212 |
213 | return false;
214 |
215 | };
216 |
217 | }();
218 |
219 | this.dispose = function () {
220 |
221 | scope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );
222 | scope.domElement.removeEventListener( 'mousedown', onMouseDown, false );
223 | scope.domElement.removeEventListener( 'wheel', onMouseWheel, false );
224 |
225 | scope.domElement.removeEventListener( 'touchstart', onTouchStart, false );
226 | scope.domElement.removeEventListener( 'touchend', onTouchEnd, false );
227 | scope.domElement.removeEventListener( 'touchmove', onTouchMove, false );
228 |
229 | document.removeEventListener( 'mousemove', onMouseMove, false );
230 | document.removeEventListener( 'mouseup', onMouseUp, false );
231 |
232 | window.removeEventListener( 'keydown', onKeyDown, false );
233 |
234 | //scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
235 |
236 | };
237 |
238 | //
239 | // internals
240 | //
241 |
242 | var scope = this;
243 |
244 | var changeEvent = { type: 'change' };
245 | var startEvent = { type: 'start' };
246 | var endEvent = { type: 'end' };
247 |
248 | var STATE = { NONE: - 1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };
249 |
250 | var state = STATE.NONE;
251 |
252 | var EPS = 0.000001;
253 |
254 | // current position in spherical coordinates
255 | var spherical = new THREE.Spherical();
256 | var sphericalDelta = new THREE.Spherical();
257 |
258 | var scale = 1;
259 | var panOffset = new THREE.Vector3();
260 | var zoomChanged = false;
261 |
262 | var rotateStart = new THREE.Vector2();
263 | var rotateEnd = new THREE.Vector2();
264 | var rotateDelta = new THREE.Vector2();
265 |
266 | var panStart = new THREE.Vector2();
267 | var panEnd = new THREE.Vector2();
268 | var panDelta = new THREE.Vector2();
269 |
270 | var dollyStart = new THREE.Vector2();
271 | var dollyEnd = new THREE.Vector2();
272 | var dollyDelta = new THREE.Vector2();
273 |
274 | function getAutoRotationAngle() {
275 |
276 | return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
277 |
278 | }
279 |
280 | function getZoomScale() {
281 |
282 | return Math.pow( 0.95, scope.zoomSpeed );
283 |
284 | }
285 |
286 | function rotateLeft( angle ) {
287 |
288 | sphericalDelta.theta -= angle;
289 |
290 | }
291 |
292 | function rotateUp( angle ) {
293 |
294 | sphericalDelta.phi -= angle;
295 |
296 | }
297 |
298 | var panLeft = function () {
299 |
300 | var v = new THREE.Vector3();
301 |
302 | return function panLeft( distance, objectMatrix ) {
303 |
304 | v.setFromMatrixColumn( objectMatrix, 0 ); // get X column of objectMatrix
305 | v.multiplyScalar( - distance );
306 |
307 | panOffset.add( v );
308 |
309 | };
310 |
311 | }();
312 |
313 | var panUp = function () {
314 |
315 | var v = new THREE.Vector3();
316 |
317 | return function panUp( distance, objectMatrix ) {
318 |
319 | v.setFromMatrixColumn( objectMatrix, 1 ); // get Y column of objectMatrix
320 | v.multiplyScalar( distance );
321 |
322 | panOffset.add( v );
323 |
324 | };
325 |
326 | }();
327 |
328 | // deltaX and deltaY are in pixels; right and down are positive
329 | var pan = function () {
330 |
331 | var offset = new THREE.Vector3();
332 |
333 | return function pan( deltaX, deltaY ) {
334 |
335 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
336 |
337 | if ( scope.object instanceof THREE.PerspectiveCamera ) {
338 |
339 | // perspective
340 | var position = scope.object.position;
341 | offset.copy( position ).sub( scope.target );
342 | var targetDistance = offset.length();
343 |
344 | // half of the fov is center to top of screen
345 | targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
346 |
347 | // we actually don't use screenWidth, since perspective camera is fixed to screen height
348 | panLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );
349 | panUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );
350 |
351 | } else if ( scope.object instanceof THREE.OrthographicCamera ) {
352 |
353 | // orthographic
354 | panLeft( deltaX * ( scope.object.right - scope.object.left ) / scope.object.zoom / element.clientWidth, scope.object.matrix );
355 | panUp( deltaY * ( scope.object.top - scope.object.bottom ) / scope.object.zoom / element.clientHeight, scope.object.matrix );
356 |
357 | } else {
358 |
359 | // camera neither orthographic nor perspective
360 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
361 | scope.enablePan = false;
362 |
363 | }
364 |
365 | };
366 |
367 | }();
368 |
369 | function dollyIn( dollyScale ) {
370 |
371 | if ( scope.object instanceof THREE.PerspectiveCamera ) {
372 |
373 | scale /= dollyScale;
374 |
375 | } else if ( scope.object instanceof THREE.OrthographicCamera ) {
376 |
377 | scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );
378 | scope.object.updateProjectionMatrix();
379 | zoomChanged = true;
380 |
381 | } else {
382 |
383 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
384 | scope.enableZoom = false;
385 |
386 | }
387 |
388 | }
389 |
390 | function dollyOut( dollyScale ) {
391 |
392 | if ( scope.object instanceof THREE.PerspectiveCamera ) {
393 |
394 | scale *= dollyScale;
395 |
396 | } else if ( scope.object instanceof THREE.OrthographicCamera ) {
397 |
398 | scope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );
399 | scope.object.updateProjectionMatrix();
400 | zoomChanged = true;
401 |
402 | } else {
403 |
404 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );
405 | scope.enableZoom = false;
406 |
407 | }
408 |
409 | }
410 |
411 | //
412 | // event callbacks - update the object state
413 | //
414 |
415 | function handleMouseDownRotate( event ) {
416 |
417 | //console.log( 'handleMouseDownRotate' );
418 |
419 | rotateStart.set( event.clientX, event.clientY );
420 |
421 | }
422 |
423 | function handleMouseDownDolly( event ) {
424 |
425 | //console.log( 'handleMouseDownDolly' );
426 |
427 | dollyStart.set( event.clientX, event.clientY );
428 |
429 | }
430 |
431 | function handleMouseDownPan( event ) {
432 |
433 | //console.log( 'handleMouseDownPan' );
434 |
435 | panStart.set( event.clientX, event.clientY );
436 |
437 | }
438 |
439 | function handleMouseMoveRotate( event ) {
440 |
441 | //console.log( 'handleMouseMoveRotate' );
442 |
443 | rotateEnd.set( event.clientX, event.clientY );
444 | rotateDelta.subVectors( rotateEnd, rotateStart );
445 |
446 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
447 |
448 | // rotating across whole screen goes 360 degrees around
449 | rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
450 |
451 | // rotating up and down along whole screen attempts to go 360, but limited to 180
452 | rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
453 |
454 | rotateStart.copy( rotateEnd );
455 |
456 | scope.update();
457 |
458 | }
459 |
460 | function handleMouseMoveDolly( event ) {
461 |
462 | //console.log( 'handleMouseMoveDolly' );
463 |
464 | dollyEnd.set( event.clientX, event.clientY );
465 |
466 | dollyDelta.subVectors( dollyEnd, dollyStart );
467 |
468 | if ( dollyDelta.y > 0 ) {
469 |
470 | dollyIn( getZoomScale() );
471 |
472 | } else if ( dollyDelta.y < 0 ) {
473 |
474 | dollyOut( getZoomScale() );
475 |
476 | }
477 |
478 | dollyStart.copy( dollyEnd );
479 |
480 | scope.update();
481 |
482 | }
483 |
484 | function handleMouseMovePan( event ) {
485 |
486 | //console.log( 'handleMouseMovePan' );
487 |
488 | panEnd.set( event.clientX, event.clientY );
489 |
490 | panDelta.subVectors( panEnd, panStart );
491 |
492 | pan( panDelta.x, panDelta.y );
493 |
494 | panStart.copy( panEnd );
495 |
496 | scope.update();
497 |
498 | }
499 |
500 | function handleMouseUp( event ) {
501 |
502 | // console.log( 'handleMouseUp' );
503 |
504 | }
505 |
506 | function handleMouseWheel( event ) {
507 |
508 | // console.log( 'handleMouseWheel' );
509 |
510 | if ( event.deltaY < 0 ) {
511 |
512 | dollyOut( getZoomScale() );
513 |
514 | } else if ( event.deltaY > 0 ) {
515 |
516 | dollyIn( getZoomScale() );
517 |
518 | }
519 |
520 | scope.update();
521 |
522 | }
523 |
524 | function handleKeyDown( event ) {
525 |
526 | //console.log( 'handleKeyDown' );
527 |
528 | switch ( event.keyCode ) {
529 |
530 | case scope.keys.UP:
531 | pan( 0, scope.keyPanSpeed );
532 | scope.update();
533 | break;
534 |
535 | case scope.keys.BOTTOM:
536 | pan( 0, - scope.keyPanSpeed );
537 | scope.update();
538 | break;
539 |
540 | case scope.keys.LEFT:
541 | pan( scope.keyPanSpeed, 0 );
542 | scope.update();
543 | break;
544 |
545 | case scope.keys.RIGHT:
546 | pan( - scope.keyPanSpeed, 0 );
547 | scope.update();
548 | break;
549 |
550 | }
551 |
552 | }
553 |
554 | function handleTouchStartRotate( event ) {
555 |
556 | //console.log( 'handleTouchStartRotate' );
557 |
558 | rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
559 |
560 | }
561 |
562 | function handleTouchStartDolly( event ) {
563 |
564 | //console.log( 'handleTouchStartDolly' );
565 |
566 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
567 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
568 |
569 | var distance = Math.sqrt( dx * dx + dy * dy );
570 |
571 | dollyStart.set( 0, distance );
572 |
573 | }
574 |
575 | function handleTouchStartPan( event ) {
576 |
577 | //console.log( 'handleTouchStartPan' );
578 |
579 | panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
580 |
581 | }
582 |
583 | function handleTouchMoveRotate( event ) {
584 |
585 | //console.log( 'handleTouchMoveRotate' );
586 |
587 | rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
588 | rotateDelta.subVectors( rotateEnd, rotateStart );
589 |
590 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
591 |
592 | // rotating across whole screen goes 360 degrees around
593 | rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
594 |
595 | // rotating up and down along whole screen attempts to go 360, but limited to 180
596 | rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
597 |
598 | rotateStart.copy( rotateEnd );
599 |
600 | scope.update();
601 |
602 | }
603 |
604 | function handleTouchMoveDolly( event ) {
605 |
606 | //console.log( 'handleTouchMoveDolly' );
607 |
608 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
609 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
610 |
611 | var distance = Math.sqrt( dx * dx + dy * dy );
612 |
613 | dollyEnd.set( 0, distance );
614 |
615 | dollyDelta.subVectors( dollyEnd, dollyStart );
616 |
617 | if ( dollyDelta.y > 0 ) {
618 |
619 | dollyOut( getZoomScale() );
620 |
621 | } else if ( dollyDelta.y < 0 ) {
622 |
623 | dollyIn( getZoomScale() );
624 |
625 | }
626 |
627 | dollyStart.copy( dollyEnd );
628 |
629 | scope.update();
630 |
631 | }
632 |
633 | function handleTouchMovePan( event ) {
634 |
635 | //console.log( 'handleTouchMovePan' );
636 |
637 | panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
638 |
639 | panDelta.subVectors( panEnd, panStart );
640 |
641 | pan( panDelta.x, panDelta.y );
642 |
643 | panStart.copy( panEnd );
644 |
645 | scope.update();
646 |
647 | }
648 |
649 | function handleTouchEnd( event ) {
650 |
651 | //console.log( 'handleTouchEnd' );
652 |
653 | }
654 |
655 | //
656 | // event handlers - FSM: listen for events and reset state
657 | //
658 |
659 | function onMouseDown( event ) {
660 |
661 | if ( scope.enabled === false ) return;
662 |
663 | event.preventDefault();
664 |
665 | if ( event.button === scope.mouseButtons.ORBIT ) {
666 |
667 | if ( scope.enableRotate === false ) return;
668 |
669 | handleMouseDownRotate( event );
670 |
671 | state = STATE.ROTATE;
672 |
673 | } else if ( event.button === scope.mouseButtons.ZOOM ) {
674 |
675 | if ( scope.enableZoom === false ) return;
676 |
677 | handleMouseDownDolly( event );
678 |
679 | state = STATE.DOLLY;
680 |
681 | } else if ( event.button === scope.mouseButtons.PAN ) {
682 |
683 | if ( scope.enablePan === false ) return;
684 |
685 | handleMouseDownPan( event );
686 |
687 | state = STATE.PAN;
688 |
689 | }
690 |
691 | if ( state !== STATE.NONE ) {
692 |
693 | document.addEventListener( 'mousemove', onMouseMove, false );
694 | document.addEventListener( 'mouseup', onMouseUp, false );
695 |
696 | scope.dispatchEvent( startEvent );
697 |
698 | }
699 |
700 | }
701 |
702 | function onMouseMove( event ) {
703 |
704 | if ( scope.enabled === false ) return;
705 |
706 | event.preventDefault();
707 |
708 | if ( state === STATE.ROTATE ) {
709 |
710 | if ( scope.enableRotate === false ) return;
711 |
712 | handleMouseMoveRotate( event );
713 |
714 | } else if ( state === STATE.DOLLY ) {
715 |
716 | if ( scope.enableZoom === false ) return;
717 |
718 | handleMouseMoveDolly( event );
719 |
720 | } else if ( state === STATE.PAN ) {
721 |
722 | if ( scope.enablePan === false ) return;
723 |
724 | handleMouseMovePan( event );
725 |
726 | }
727 |
728 | }
729 |
730 | function onMouseUp( event ) {
731 |
732 | if ( scope.enabled === false ) return;
733 |
734 | handleMouseUp( event );
735 |
736 | document.removeEventListener( 'mousemove', onMouseMove, false );
737 | document.removeEventListener( 'mouseup', onMouseUp, false );
738 |
739 | scope.dispatchEvent( endEvent );
740 |
741 | state = STATE.NONE;
742 |
743 | }
744 |
745 | function onMouseWheel( event ) {
746 |
747 | if ( scope.enabled === false || scope.enableZoom === false || ( state !== STATE.NONE && state !== STATE.ROTATE ) ) return;
748 |
749 | event.preventDefault();
750 | event.stopPropagation();
751 |
752 | handleMouseWheel( event );
753 |
754 | scope.dispatchEvent( startEvent ); // not sure why these are here...
755 | scope.dispatchEvent( endEvent );
756 |
757 | }
758 |
759 | function onKeyDown( event ) {
760 |
761 | if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;
762 |
763 | handleKeyDown( event );
764 |
765 | }
766 |
767 | function onTouchStart( event ) {
768 |
769 | if ( scope.enabled === false ) return;
770 |
771 | switch ( event.touches.length ) {
772 |
773 | case 1: // one-fingered touch: rotate
774 |
775 | if ( scope.enableRotate === false ) return;
776 |
777 | handleTouchStartRotate( event );
778 |
779 | state = STATE.TOUCH_ROTATE;
780 |
781 | break;
782 |
783 | case 2: // two-fingered touch: dolly
784 |
785 | if ( scope.enableZoom === false ) return;
786 |
787 | handleTouchStartDolly( event );
788 |
789 | state = STATE.TOUCH_DOLLY;
790 |
791 | break;
792 |
793 | case 3: // three-fingered touch: pan
794 |
795 | if ( scope.enablePan === false ) return;
796 |
797 | handleTouchStartPan( event );
798 |
799 | state = STATE.TOUCH_PAN;
800 |
801 | break;
802 |
803 | default:
804 |
805 | state = STATE.NONE;
806 |
807 | }
808 |
809 | if ( state !== STATE.NONE ) {
810 |
811 | scope.dispatchEvent( startEvent );
812 |
813 | }
814 |
815 | }
816 |
817 | function onTouchMove( event ) {
818 |
819 | if ( scope.enabled === false ) return;
820 |
821 | event.preventDefault();
822 | event.stopPropagation();
823 |
824 | switch ( event.touches.length ) {
825 |
826 | case 1: // one-fingered touch: rotate
827 |
828 | if ( scope.enableRotate === false ) return;
829 | if ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...
830 |
831 | handleTouchMoveRotate( event );
832 |
833 | break;
834 |
835 | case 2: // two-fingered touch: dolly
836 |
837 | if ( scope.enableZoom === false ) return;
838 | if ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...
839 |
840 | handleTouchMoveDolly( event );
841 |
842 | break;
843 |
844 | case 3: // three-fingered touch: pan
845 |
846 | if ( scope.enablePan === false ) return;
847 | if ( state !== STATE.TOUCH_PAN ) return; // is this needed?...
848 |
849 | handleTouchMovePan( event );
850 |
851 | break;
852 |
853 | default:
854 |
855 | state = STATE.NONE;
856 |
857 | }
858 |
859 | }
860 |
861 | function onTouchEnd( event ) {
862 |
863 | if ( scope.enabled === false ) return;
864 |
865 | handleTouchEnd( event );
866 |
867 | scope.dispatchEvent( endEvent );
868 |
869 | state = STATE.NONE;
870 |
871 | }
872 |
873 | function onContextMenu( event ) {
874 |
875 | event.preventDefault();
876 |
877 | }
878 |
879 | //
880 |
881 | scope.domElement.addEventListener( 'contextmenu', onContextMenu, false );
882 |
883 | scope.domElement.addEventListener( 'mousedown', onMouseDown, false );
884 | scope.domElement.addEventListener( 'wheel', onMouseWheel, false );
885 |
886 | scope.domElement.addEventListener( 'touchstart', onTouchStart, false );
887 | scope.domElement.addEventListener( 'touchend', onTouchEnd, false );
888 | scope.domElement.addEventListener( 'touchmove', onTouchMove, false );
889 |
890 | window.addEventListener( 'keydown', onKeyDown, false );
891 |
892 | // force an update at start
893 |
894 | this.update();
895 |
896 | };
897 |
898 | THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
899 | THREE.OrbitControls.prototype.constructor = THREE.OrbitControls;
900 |
901 | Object.defineProperties( THREE.OrbitControls.prototype, {
902 |
903 | center: {
904 |
905 | get: function () {
906 |
907 | console.warn( 'THREE.OrbitControls: .center has been renamed to .target' );
908 | return this.target;
909 |
910 | }
911 |
912 | },
913 |
914 | // backward compatibility
915 |
916 | noZoom: {
917 |
918 | get: function () {
919 |
920 | console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
921 | return ! this.enableZoom;
922 |
923 | },
924 |
925 | set: function ( value ) {
926 |
927 | console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );
928 | this.enableZoom = ! value;
929 |
930 | }
931 |
932 | },
933 |
934 | noRotate: {
935 |
936 | get: function () {
937 |
938 | console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
939 | return ! this.enableRotate;
940 |
941 | },
942 |
943 | set: function ( value ) {
944 |
945 | console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );
946 | this.enableRotate = ! value;
947 |
948 | }
949 |
950 | },
951 |
952 | noPan: {
953 |
954 | get: function () {
955 |
956 | console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
957 | return ! this.enablePan;
958 |
959 | },
960 |
961 | set: function ( value ) {
962 |
963 | console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );
964 | this.enablePan = ! value;
965 |
966 | }
967 |
968 | },
969 |
970 | noKeys: {
971 |
972 | get: function () {
973 |
974 | console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
975 | return ! this.enableKeys;
976 |
977 | },
978 |
979 | set: function ( value ) {
980 |
981 | console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );
982 | this.enableKeys = ! value;
983 |
984 | }
985 |
986 | },
987 |
988 | staticMoving: {
989 |
990 | get: function () {
991 |
992 | console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
993 | return ! this.enableDamping;
994 |
995 | },
996 |
997 | set: function ( value ) {
998 |
999 | console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );
1000 | this.enableDamping = ! value;
1001 |
1002 | }
1003 |
1004 | },
1005 |
1006 | dynamicDampingFactor: {
1007 |
1008 | get: function () {
1009 |
1010 | console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1011 | return this.dampingFactor;
1012 |
1013 | },
1014 |
1015 | set: function ( value ) {
1016 |
1017 | console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );
1018 | this.dampingFactor = value;
1019 |
1020 | }
1021 |
1022 | }
1023 |
1024 | } );
1025 |
--------------------------------------------------------------------------------
/vendor/THREE.MeshLine.js:
--------------------------------------------------------------------------------
1 | ;(function() {
2 |
3 | "use strict";
4 |
5 | var root = this
6 |
7 | var has_require = typeof require !== 'undefined'
8 |
9 | var THREE = root.THREE || has_require && require('three')
10 | if( !THREE )
11 | throw new Error( 'MeshLine requires three.js' )
12 |
13 | function MeshLine() {
14 |
15 | this.positions = [];
16 |
17 | this.previous = [];
18 | this.next = [];
19 | this.side = [];
20 | this.width = [];
21 | this.indices_array = [];
22 | this.uvs = [];
23 | this.counters = [];
24 | this.geometry = new THREE.BufferGeometry();
25 |
26 | this.widthCallback = null;
27 |
28 | }
29 |
30 | MeshLine.prototype.setGeometry = function( g, c ) {
31 |
32 | this.widthCallback = c;
33 |
34 | this.positions = [];
35 | this.counters = [];
36 |
37 | if( g instanceof THREE.Geometry ) {
38 | for( var j = 0; j < g.vertices.length; j++ ) {
39 | var v = g.vertices[ j ];
40 | var c = j/g.vertices.length;
41 | this.positions.push( v.x, v.y, v.z );
42 | this.positions.push( v.x, v.y, v.z );
43 | this.counters.push(c);
44 | this.counters.push(c);
45 | }
46 | }
47 |
48 | if( g instanceof THREE.BufferGeometry ) {
49 | // read attribute positions ?
50 | }
51 |
52 | if( g instanceof Float32Array || g instanceof Array ) {
53 | for( var j = 0; j < g.length; j += 3 ) {
54 | var c = j/g.length;
55 | this.positions.push( g[ j ], g[ j + 1 ], g[ j + 2 ] );
56 | this.positions.push( g[ j ], g[ j + 1 ], g[ j + 2 ] );
57 | this.counters.push(c);
58 | this.counters.push(c);
59 | }
60 | }
61 |
62 | this.process();
63 |
64 | }
65 |
66 | MeshLine.prototype.compareV3 = function( a, b ) {
67 |
68 | var aa = a * 6;
69 | var ab = b * 6;
70 | return ( this.positions[ aa ] === this.positions[ ab ] ) && ( this.positions[ aa + 1 ] === this.positions[ ab + 1 ] ) && ( this.positions[ aa + 2 ] === this.positions[ ab + 2 ] );
71 |
72 | }
73 |
74 | MeshLine.prototype.copyV3 = function( a ) {
75 |
76 | var aa = a * 6;
77 | return [ this.positions[ aa ], this.positions[ aa + 1 ], this.positions[ aa + 2 ] ];
78 |
79 | }
80 |
81 | MeshLine.prototype.process = function() {
82 |
83 | var l = this.positions.length / 6;
84 |
85 | this.previous = [];
86 | this.next = [];
87 | this.side = [];
88 | this.width = [];
89 | this.indices_array = [];
90 | this.uvs = [];
91 |
92 | for( var j = 0; j < l; j++ ) {
93 | this.side.push( 1 );
94 | this.side.push( -1 );
95 | }
96 |
97 | var w;
98 | for( var j = 0; j < l; j++ ) {
99 | if( this.widthCallback ) w = this.widthCallback( j / ( l -1 ) );
100 | else w = 1;
101 | this.width.push( w );
102 | this.width.push( w );
103 | }
104 |
105 | for( var j = 0; j < l; j++ ) {
106 | this.uvs.push( j / ( l - 1 ), 0 );
107 | this.uvs.push( j / ( l - 1 ), 1 );
108 | }
109 |
110 | var v;
111 |
112 | if( this.compareV3( 0, l - 1 ) ){
113 | v = this.copyV3( l - 2 );
114 | } else {
115 | v = this.copyV3( 0 );
116 | }
117 | this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
118 | this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
119 | for( var j = 0; j < l - 1; j++ ) {
120 | v = this.copyV3( j );
121 | this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
122 | this.previous.push( v[ 0 ], v[ 1 ], v[ 2 ] );
123 | }
124 |
125 | for( var j = 1; j < l; j++ ) {
126 | v = this.copyV3( j );
127 | this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
128 | this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
129 | }
130 |
131 | if( this.compareV3( l - 1, 0 ) ){
132 | v = this.copyV3( 1 );
133 | } else {
134 | v = this.copyV3( l - 1 );
135 | }
136 | this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
137 | this.next.push( v[ 0 ], v[ 1 ], v[ 2 ] );
138 |
139 | for( var j = 0; j < l - 1; j++ ) {
140 | var n = j * 2;
141 | this.indices_array.push( n, n + 1, n + 2 );
142 | this.indices_array.push( n + 2, n + 1, n + 3 );
143 | }
144 |
145 | if (!this.attributes) {
146 | this.attributes = {
147 | position: new THREE.BufferAttribute( new Float32Array( this.positions ), 3 ),
148 | previous: new THREE.BufferAttribute( new Float32Array( this.previous ), 3 ),
149 | next: new THREE.BufferAttribute( new Float32Array( this.next ), 3 ),
150 | side: new THREE.BufferAttribute( new Float32Array( this.side ), 1 ),
151 | width: new THREE.BufferAttribute( new Float32Array( this.width ), 1 ),
152 | uv: new THREE.BufferAttribute( new Float32Array( this.uvs ), 2 ),
153 | index: new THREE.BufferAttribute( new Uint16Array( this.indices_array ), 1 ),
154 | counters: new THREE.BufferAttribute( new Float32Array( this.counters ), 1 )
155 | }
156 | } else {
157 | this.attributes.position.copyArray(new Float32Array(this.positions));
158 | this.attributes.position.needsUpdate = true;
159 | this.attributes.previous.copyArray(new Float32Array(this.previous));
160 | this.attributes.previous.needsUpdate = true;
161 | this.attributes.next.copyArray(new Float32Array(this.next));
162 | this.attributes.next.needsUpdate = true;
163 | this.attributes.side.copyArray(new Float32Array(this.side));
164 | this.attributes.side.needsUpdate = true;
165 | this.attributes.width.copyArray(new Float32Array(this.width));
166 | this.attributes.width.needsUpdate = true;
167 | this.attributes.uv.copyArray(new Float32Array(this.uvs));
168 | this.attributes.uv.needsUpdate = true;
169 | this.attributes.index.copyArray(new Uint16Array(this.indices_array));
170 | this.attributes.index.needsUpdate = true;
171 | }
172 |
173 | this.geometry.addAttribute( 'position', this.attributes.position );
174 | this.geometry.addAttribute( 'previous', this.attributes.previous );
175 | this.geometry.addAttribute( 'next', this.attributes.next );
176 | this.geometry.addAttribute( 'side', this.attributes.side );
177 | this.geometry.addAttribute( 'width', this.attributes.width );
178 | this.geometry.addAttribute( 'uv', this.attributes.uv );
179 | this.geometry.addAttribute( 'counters', this.attributes.counters );
180 |
181 | this.geometry.setIndex( this.attributes.index );
182 |
183 | }
184 |
185 | function memcpy (src, srcOffset, dst, dstOffset, length) {
186 | var i
187 |
188 | src = src.subarray || src.slice ? src : src.buffer
189 | dst = dst.subarray || dst.slice ? dst : dst.buffer
190 |
191 | src = srcOffset ? src.subarray ?
192 | src.subarray(srcOffset, length && srcOffset + length) :
193 | src.slice(srcOffset, length && srcOffset + length) : src
194 |
195 | if (dst.set) {
196 | dst.set(src, dstOffset)
197 | } else {
198 | for (i=0; i