Skip to content

Commit 34160a9

Browse files
committed
low poly starting
1 parent 2e79971 commit 34160a9

File tree

7 files changed

+272
-2
lines changed

7 files changed

+272
-2
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
# aframe-low-poly
2-
low poly add-ons for aframe virtual reality
1+
# A-Frame Low Poly
2+
3+
Low poly add-ons for a-frame virtual reality models.

dist/aframe-low-poly.min.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.js

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
class LowPoly {
2+
3+
static addMappings(name, mapping) {
4+
return Object.assign({}, mapping, {
5+
amplitude: name + '.amplitude',
6+
'amplitude-variance': name + '.amplitudeVariance',
7+
seed: name + '.seed',
8+
});
9+
}
10+
11+
static addSchema(schema) {
12+
return Object.assign({}, schema, {
13+
// Randomness amplitude and variance.
14+
amplitude: {default: 0.05},
15+
amplitudeVariance: {default: 0.001},
16+
17+
// Material.
18+
flatShading: {default: true},
19+
20+
// Randomness
21+
seed: {default: 0},
22+
});
23+
}
24+
25+
static play(that, geometry) {
26+
const data = that.data,
27+
el = that.el;
28+
29+
let material = el.components.material;
30+
geometry.mergeVertices();
31+
LowPoly.randomizeVertices(data, geometry.vertices);
32+
33+
if (!material) {
34+
material = {};
35+
material.material = new THREE.MeshPhongMaterial();
36+
}
37+
38+
if (data.flatShading) {
39+
material.material.setValues({
40+
flatShading: true,
41+
});
42+
}
43+
44+
that.mesh = new THREE.Mesh(geometry, material.material);
45+
el.setObject3D('mesh', that.mesh);
46+
}
47+
48+
static randomizeVertices(data, vertices) {
49+
Random.seed(data.seed);
50+
for (let v, i = 0, l = vertices.length; i < l; i++) {
51+
v = vertices[i];
52+
53+
LowPoly.randomizeVertexDimension(v, 'x', data.amplitude, data.amplitudeVariance);
54+
LowPoly.randomizeVertexDimension(v, 'y', data.amplitude, data.amplitudeVariance);
55+
LowPoly.randomizeVertexDimension(v, 'z', data.amplitude, data.amplitudeVariance);
56+
}
57+
}
58+
59+
static randomizeVertexDimension(vertex, dimension, amplitude, amplitudeVariance) {
60+
let ang = Random.random() * Math.PI * 2,
61+
amp = amplitude + Random.random() * amplitudeVariance;
62+
vertex[dimension] += Math.sin(ang) * amp;
63+
}
64+
}
65+
66+
class Random {
67+
// https://stackoverflow.com/a/47593316/4855984
68+
69+
static seed(seed) {
70+
// Create a xfnv1a state:
71+
var seed = Random.xfnv1a(seed.toString());
72+
73+
// output one 32-bit hash to produce the seed for mulberry32.
74+
this.random = Random.mulberry32(seed());
75+
}
76+
77+
static xfnv1a(k) {
78+
for(var i = 0, h = 2166136261 >>> 0; i < k.length; i++)
79+
h = Math.imul(h ^ k.charCodeAt(i), 16777619);
80+
return function() {
81+
h += h << 13; h ^= h >>> 7;
82+
h += h << 3; h ^= h >>> 17;
83+
return (h += h << 5) >>> 0;
84+
}
85+
}
86+
87+
static mulberry32(a) {
88+
return function() {
89+
var t = a += 0x6D2B79F5;
90+
t = Math.imul(t ^ t >>> 15, t | 1);
91+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
92+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
93+
}
94+
}
95+
96+
static random() {
97+
return this.random();
98+
}
99+
}

src/primitives/circle.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
var extendDeep = AFRAME.utils.extendDeep;
2+
3+
// The mesh mixin provides common material properties for creating mesh-based primitives.
4+
// This makes the material component a default component and maps all the base material properties.
5+
var meshMixin = AFRAME.primitives.getMeshMixin();
6+
7+
AFRAME.registerPrimitive('lp-circle', extendDeep({}, meshMixin, {
8+
// Preset default components. These components and component properties will be attached to the entity out-of-the-box.
9+
defaultComponents: {
10+
'low-poly-circle': {},
11+
},
12+
mappings: LowPoly.addMappings('low-poly-circle', {
13+
'radius': 'low-poly-circle.radius',
14+
'segments': 'low-poly-circle.segments',
15+
})
16+
}));
17+
18+
AFRAME.registerComponent('low-poly-circle', {
19+
schema: LowPoly.addSchema({
20+
// Geometry
21+
radius: {default: 1},
22+
segments: {default: 10},
23+
}),
24+
25+
/**
26+
* Use play() instead of init(), because component mappings – unavailable as dependencies – are
27+
* not guaranteed to have parsed when this component is initialized.
28+
*/
29+
play: function() {
30+
const data = this.data;
31+
const geometry = new THREE.CircleGeometry(data.radius, data.segments);
32+
LowPoly.play(this, geometry);
33+
},
34+
35+
remove: function () {
36+
this.el.removeObject3D('mesh');
37+
},
38+
39+
});

src/primitives/cone.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
var extendDeep = AFRAME.utils.extendDeep;
2+
3+
// The mesh mixin provides common material properties for creating mesh-based primitives.
4+
// This makes the material component a default component and maps all the base material properties.
5+
var meshMixin = AFRAME.primitives.getMeshMixin();
6+
7+
AFRAME.registerPrimitive('lp-cone', extendDeep({}, meshMixin, {
8+
// Preset default components. These components and component properties will be attached to the entity out-of-the-box.
9+
defaultComponents: {
10+
'low-poly-cone': {},
11+
},
12+
mappings: LowPoly.addMappings('low-poly-cone', {
13+
'radius-top': 'low-poly-cone.topRadius',
14+
'radius-bottom': 'low-poly-cone.bottomRadius',
15+
height: 'low-poly-cone.height',
16+
'segments-radial': 'low-poly-cone.radialSegments',
17+
'segments-height': 'low-poly-cone.heightSegments',
18+
})
19+
}));
20+
21+
AFRAME.registerComponent('low-poly-cone', {
22+
schema: LowPoly.addSchema({
23+
// Geometry
24+
topRadius: {default: 1},
25+
bottomRadius: {default: 1},
26+
height: {default: 1},
27+
radialSegments: {default: 10},
28+
heightSegments: {default: 10},
29+
}),
30+
31+
/**
32+
* Use play() instead of init(), because component mappings – unavailable as dependencies – are
33+
* not guaranteed to have parsed when this component is initialized.
34+
*/
35+
play: function() {
36+
const data = this.data;
37+
const geometry = new THREE.CylinderGeometry(
38+
data.topRadius, data.bottomRadius, data.height, data.radialSegments, data.heightSegments);
39+
LowPoly.play(this, geometry);
40+
},
41+
42+
remove: function () {
43+
this.el.removeObject3D('mesh');
44+
},
45+
46+
});

src/primitives/plane.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
var extendDeep = AFRAME.utils.extendDeep;
2+
3+
// The mesh mixin provides common material properties for creating mesh-based primitives.
4+
// This makes the material component a default component and maps all the base material properties.
5+
var meshMixin = AFRAME.primitives.getMeshMixin();
6+
7+
AFRAME.registerPrimitive('lp-plane', extendDeep({}, meshMixin, {
8+
// Preset default components. These components and component properties will be attached to the entity out-of-the-box.
9+
defaultComponents: {
10+
'low-poly-plane': {},
11+
},
12+
mappings: LowPoly.addMappings('low-poly-plane', {
13+
'width': 'low-poly-plane.width',
14+
'height': 'low-poly-plane.height',
15+
'segments-width': 'low-poly-plane.widthSegments',
16+
'segments-height': 'low-poly-plane.heightSegments',
17+
})
18+
}));
19+
20+
AFRAME.registerComponent('low-poly-plane', {
21+
schema: LowPoly.addSchema({
22+
// Geometry
23+
width: {default: 1},
24+
height: {default: 1},
25+
widthSegments: {default: 10},
26+
heightSegments: {default: 10},
27+
}),
28+
29+
/**
30+
* Use play() instead of init(), because component mappings – unavailable as dependencies – are
31+
* not guaranteed to have parsed when this component is initialized.
32+
*/
33+
play: function() {
34+
const data = this.data;
35+
const geometry = new THREE.PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);
36+
LowPoly.play(this, geometry);
37+
},
38+
39+
remove: function () {
40+
this.el.removeObject3D('mesh');
41+
},
42+
43+
});

src/primitives/sphere.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
var extendDeep = AFRAME.utils.extendDeep;
2+
3+
// The mesh mixin provides common material properties for creating mesh-based primitives.
4+
// This makes the material component a default component and maps all the base material properties.
5+
var meshMixin = AFRAME.primitives.getMeshMixin();
6+
7+
AFRAME.registerPrimitive('lp-sphere', extendDeep({}, meshMixin, {
8+
// Preset default components. These components and component properties will be attached to the entity out-of-the-box.
9+
defaultComponents: {
10+
'low-poly-sphere': {},
11+
},
12+
mappings: LowPoly.addMappings('low-poly-sphere', {
13+
'radius': 'low-poly-sphere.radius',
14+
'segments-height': 'low-poly-sphere.heightSegments',
15+
'segments-width': 'low-poly-sphere.widthSegments',
16+
})
17+
}));
18+
19+
AFRAME.registerComponent('low-poly-sphere', {
20+
schema: LowPoly.addSchema({
21+
// Geometry
22+
radius: {default: 1},
23+
heightSegments: {default: 5},
24+
widthSegments: {default: 5}
25+
}),
26+
27+
/**
28+
* Use play() instead of init(), because component mappings – unavailable as dependencies – are
29+
* not guaranteed to have parsed when this component is initialized.
30+
*/
31+
play: function() {
32+
const data = this.data;
33+
const geometry = new THREE.SphereGeometry(data.radius, data.widthSegments, data.heightSegments);
34+
LowPoly.play(this, geometry);
35+
},
36+
37+
remove: function () {
38+
this.el.removeObject3D('mesh');
39+
},
40+
41+
});

0 commit comments

Comments
 (0)