scenejs_on_rails 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/app/controllers/scenejs_controller.rb +53 -0
- data/app/views/scenejs/get_scenejs_data.html.erb +3 -0
- data/lib/scenejs_on_rails.rb +1 -1
- data/lib/scenejs_on_rails/rails.rb +5 -0
- data/lib/scenejs_on_rails/version.rb +1 -1
- data/vendor/assets/javascripts/scenejs.js +17307 -0
- data/vendor/assets/javascripts/scenejs_extras/gui.js +478 -0
- data/vendor/assets/javascripts/scenejs_extras/gui/README.md +4 -0
- data/vendor/assets/javascripts/scenejs_extras/gui/dat.gui.min.js +94 -0
- data/vendor/assets/javascripts/scenejs_extras/gui/gui.js +385 -0
- data/vendor/assets/javascripts/scenejs_lib/cityBuilder.js +457 -0
- data/vendor/assets/javascripts/scenejs_lib/dat.gui.min.js +94 -0
- data/vendor/assets/javascripts/scenejs_lib/gl-matrix-min.js +28 -0
- data/vendor/assets/javascripts/scenejs_lib/gl-matrix.js +4078 -0
- data/vendor/assets/javascripts/scenejs_lib/require.js +36 -0
- data/vendor/assets/javascripts/scenejs_lib/requireConfig.js +18 -0
- data/vendor/assets/javascripts/scenejs_lib/requireWrapperEnd.js +1 -0
- data/vendor/assets/javascripts/scenejs_lib/requireWrapperStart.js +2 -0
- data/vendor/assets/javascripts/scenejs_lib/stats.min.js +6 -0
- data/vendor/assets/javascripts/scenejs_lib/sylvester.js +1 -0
- data/vendor/assets/javascripts/scenejs_lib/webgl-debug-utils.js +839 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/boundary.js +59 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/box.js +72 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/plane.js +126 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/quad.js +37 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/skybox.js +86 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/sphere.js +82 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/teapot.js +5853 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/torus.js +139 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/vectorText.js +1499 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/wobblyBox.js +44 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/canvas2image.js +198 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullEngine.js +810 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullSystem.js +185 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullSystemPool.js +174 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullWorker.js +142 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/gl-matrix-min.js +28 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/jquery-1.8.3.min.js +2 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/k3d.js +1029 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/physics/jiglib.all.min.js +3 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/physics/physics.js +223 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/physics/worker.js +330 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/alpha/orbitTracking.js +295 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/alpha/orbitTrackingTarget.js +43 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/backgrounds/gradient.js +148 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/cameras/orbit.js +172 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/cameras/pickFlyOrbit.js +409 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/canvas/capture.js +107 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/demos/color.js +30 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/demos/redTeapot.js +52 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/demos/spinningTeapot.js +43 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/crt.js +36 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/fog.js +159 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/snowyPeaks.js +50 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/wobble.js +42 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/xray.js +126 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/frustum/body.js +112 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/frustum/cull.js +42 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/frustum/lod.js +125 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/heightmaps/custom.js +185 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/import/3ds.js +91 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/import/md2.js +139 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/import/obj.js +100 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building.js +352 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/HighRiseGlass.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/HighRiseGlassSpecular.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/highrise-windows.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/pixelcity_windows7.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/city.js +26 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/plants/ghostTree.js +387 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth.js +168 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth-lights.gif +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth-specular.gif +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth-specular.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earthbump.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earthclouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/toys/drinkingBird.js +632 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/vehicles/tank.js +77670 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/vehicles/tank.js~ +77636 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/body.js +85 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/box.js +30 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/material.js +35 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/plane.js +47 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/sphere.js +32 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/system.js +44 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/teapot.js +29 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/boundary.js +73 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/box.js +87 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/cylinder.js +186 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/grid.js +47 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/plane.js +137 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/quad.js +43 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/sphere.js +107 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/teapot.js +5846 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/torus.js +149 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/vectorText.js +1508 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/clouds.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/cloudySea.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/custom.js +150 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/grimmNight.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/interstellarClouds.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/miramarClouds.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/stormyDays.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/clouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/cloudySea.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/grimmNight.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/interstellarClouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/miramarClouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/stormyDays.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/violentDays.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/violentDays.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/texture/image.js +67 -0
- data/vendor/assets/javascripts/scenejs_plugins/texture/video.js +105 -0
- metadata +113 -1
@@ -0,0 +1,185 @@
|
|
1
|
+
(function () {
|
2
|
+
|
3
|
+
SceneJS.Types.addType("heightmaps/custom", {
|
4
|
+
|
5
|
+
construct:function (params) {
|
6
|
+
|
7
|
+
if (!params.src) {
|
8
|
+
throw "heightmap param expected: src";
|
9
|
+
}
|
10
|
+
|
11
|
+
params.xSize = params.xSize || 1.0;
|
12
|
+
params.ySize = params.ySize || 1.0;
|
13
|
+
params.zSize = params.zSize || 1.0;
|
14
|
+
|
15
|
+
params.xSegments = params.xSegments || 1;
|
16
|
+
params.zSegments = params.zSegments || 1;
|
17
|
+
|
18
|
+
var self = this;
|
19
|
+
|
20
|
+
// Notify SceneJS so it can support loading/busy indicators etc
|
21
|
+
this._taskId = this.taskStarted("Loading heightmap");
|
22
|
+
|
23
|
+
var image = new Image();
|
24
|
+
|
25
|
+
image.onload = function (e) {
|
26
|
+
|
27
|
+
var element = window.document.createElement('canvas');
|
28
|
+
element.width = image.width;
|
29
|
+
element.height = image.height;
|
30
|
+
|
31
|
+
var c = element.getContext("2d");
|
32
|
+
|
33
|
+
c.drawImage(image, 0, 0);
|
34
|
+
|
35
|
+
var imageData = c.getImageData(0, 0, image.width, image.height).data;
|
36
|
+
|
37
|
+
var mesh = createMeshData(params, image, imageData);
|
38
|
+
|
39
|
+
var wire = params.wire;
|
40
|
+
|
41
|
+
if (self._taskId) {
|
42
|
+
|
43
|
+
self._taskId = self.taskFinished(self._taskId);
|
44
|
+
|
45
|
+
// Create geometry node
|
46
|
+
self.addNode({
|
47
|
+
type:"rotate",
|
48
|
+
x:1,
|
49
|
+
angle:90,
|
50
|
+
nodes:[
|
51
|
+
{
|
52
|
+
type:"geometry",
|
53
|
+
primitive:wire ? "lines" : "triangles",
|
54
|
+
positions:mesh.positions,
|
55
|
+
normals:!wire ? "auto" : null, // Get SceneJS to compute the normals
|
56
|
+
uv:!wire ? mesh.uv : null,
|
57
|
+
indices:mesh.indices,
|
58
|
+
coreId:"heightmap_" + (wire == true ? "wire_" : "") + params.zSize + "_" + params.xSize + "_" + params.xSegments + "_" + params.zSegments
|
59
|
+
}
|
60
|
+
]
|
61
|
+
});
|
62
|
+
}
|
63
|
+
};
|
64
|
+
|
65
|
+
image.onerror = function () {
|
66
|
+
self._taskId = self.taskFailed(self._taskId);
|
67
|
+
};
|
68
|
+
|
69
|
+
image.src = params.src;
|
70
|
+
},
|
71
|
+
|
72
|
+
destruct:function () {
|
73
|
+
this._taskId = self.taskFinished(this._taskId);
|
74
|
+
}
|
75
|
+
});
|
76
|
+
|
77
|
+
function createMeshData(params, image, imageData) {
|
78
|
+
|
79
|
+
var imageWidth = image.width;
|
80
|
+
var imageHeight = image.height;
|
81
|
+
|
82
|
+
var positions = [];
|
83
|
+
var uvs = [];
|
84
|
+
var indices = [];
|
85
|
+
|
86
|
+
var width = params.xSize;
|
87
|
+
var height = params.zSize;
|
88
|
+
|
89
|
+
var xSegments = params.xSegments;
|
90
|
+
var zSegments = params.zSegments;
|
91
|
+
|
92
|
+
var halfWidth = width / 2;
|
93
|
+
var halfHeight = height / 2;
|
94
|
+
|
95
|
+
var gridX = xSegments;
|
96
|
+
var gridZ = zSegments;
|
97
|
+
|
98
|
+
var gridX1 = gridX + 1;
|
99
|
+
var gridZ1 = gridZ + 1;
|
100
|
+
|
101
|
+
var segWidth = width / gridX;
|
102
|
+
var segHeight = height / gridZ;
|
103
|
+
|
104
|
+
var imgX;
|
105
|
+
var imgY;
|
106
|
+
|
107
|
+
var x;
|
108
|
+
var y;
|
109
|
+
var z;
|
110
|
+
|
111
|
+
for (var px = 0; px <= gridZ; px++) {
|
112
|
+
for (var py = 0; py <= gridX; py++) {
|
113
|
+
|
114
|
+
x = px * segWidth;
|
115
|
+
y = py * segHeight;
|
116
|
+
|
117
|
+
imgX = Math.round((x / width) * imageWidth);
|
118
|
+
imgY = Math.round((y / height) * imageHeight);
|
119
|
+
|
120
|
+
z = (imageData[(imageWidth * imgY + imgX) * 4]) / 255 * params.ySize;
|
121
|
+
|
122
|
+
if (z == undefined) {
|
123
|
+
z = 0;
|
124
|
+
}
|
125
|
+
|
126
|
+
positions.push(x - halfWidth);
|
127
|
+
positions.push(-y + halfHeight);
|
128
|
+
positions.push(-z);
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
var a;
|
133
|
+
var b;
|
134
|
+
var c;
|
135
|
+
var d;
|
136
|
+
|
137
|
+
for (var iz = 0; iz < gridZ; iz++) {
|
138
|
+
for (var ix = 0; ix < gridX; ix++) {
|
139
|
+
|
140
|
+
a = ix + gridX1 * iz;
|
141
|
+
b = ix + gridX1 * ( iz + 1 );
|
142
|
+
c = ( ix + 1 ) + gridX1 * ( iz + 1 );
|
143
|
+
d = ( ix + 1 ) + gridX1 * iz;
|
144
|
+
|
145
|
+
indices.push(a);
|
146
|
+
indices.push(b);
|
147
|
+
indices.push(c);
|
148
|
+
|
149
|
+
indices.push(c);
|
150
|
+
indices.push(d);
|
151
|
+
indices.push(a);
|
152
|
+
|
153
|
+
// a
|
154
|
+
uvs.push(ix / gridX);
|
155
|
+
uvs.push(1 - iz / gridZ);
|
156
|
+
|
157
|
+
//b
|
158
|
+
uvs.push(ix / gridX);
|
159
|
+
uvs.push(1 - ( iz + 1 ) / gridZ);
|
160
|
+
|
161
|
+
//c
|
162
|
+
uvs.push(( ix + 1 ) / gridX);
|
163
|
+
uvs.push(1 - ( iz + 1 ) / gridZ);
|
164
|
+
|
165
|
+
//c
|
166
|
+
uvs.push(( ix + 1 ) / gridX);
|
167
|
+
uvs.push(1 - ( iz + 1 ) / gridZ);
|
168
|
+
|
169
|
+
//d
|
170
|
+
uvs.push(( ix + 1 ) / gridX, 1 - iz / gridZ);
|
171
|
+
uvs.push(1 - iz / gridZ);
|
172
|
+
|
173
|
+
//a
|
174
|
+
uvs.push(ix / gridX);
|
175
|
+
uvs.push(1 - iz / gridZ);
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
return {
|
180
|
+
positions:positions,
|
181
|
+
uv:uvs,
|
182
|
+
indices:indices
|
183
|
+
};
|
184
|
+
}
|
185
|
+
})();
|
@@ -0,0 +1,91 @@
|
|
1
|
+
/**
|
2
|
+
* 3DS importer plugin
|
3
|
+
*
|
4
|
+
* Uses the K3D library to parse 3DS
|
5
|
+
* © 2012 Ivan Kuckir
|
6
|
+
* http://k3d.ivank.net/
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
require([
|
10
|
+
|
11
|
+
// This prefix routes to the 3rd-party libs directory containing resources used by plugins
|
12
|
+
"scenejsPluginDeps/k3d"
|
13
|
+
],
|
14
|
+
function () {
|
15
|
+
|
16
|
+
SceneJS.Types.addType("import/3ds", {
|
17
|
+
|
18
|
+
construct:function (params) {
|
19
|
+
|
20
|
+
if (!params.src) {
|
21
|
+
this.log("error", "Attribute expected: src");
|
22
|
+
}
|
23
|
+
|
24
|
+
// Notify SceneJS so it can support loading/busy indicators etc
|
25
|
+
this._taskId = this.taskStarted("Loading .3DS");
|
26
|
+
|
27
|
+
var self = this;
|
28
|
+
|
29
|
+
load(params.src,
|
30
|
+
function (data) {
|
31
|
+
|
32
|
+
var m = K3D.parse.from3DS(data);
|
33
|
+
|
34
|
+
console.log(m);
|
35
|
+
|
36
|
+
var mesh = m.edit.objects[0].mesh;
|
37
|
+
|
38
|
+
// Need to flip the UV coordinates on Y-axis for SceneJS geometry
|
39
|
+
for (var i = 1, len = mesh.uvt.length; i < len; i += 2) {
|
40
|
+
mesh.uvt[i] *= -1.0;
|
41
|
+
}
|
42
|
+
|
43
|
+
self.addNode({
|
44
|
+
type:"geometry",
|
45
|
+
primitive:"triangles",
|
46
|
+
positions:mesh.vertices,
|
47
|
+
uv:mesh.uvt,
|
48
|
+
//normals:"auto",
|
49
|
+
indices:mesh.indices
|
50
|
+
});
|
51
|
+
|
52
|
+
self._taskId = self.taskFinished(self._taskId);
|
53
|
+
},
|
54
|
+
|
55
|
+
function (err) {
|
56
|
+
self.log("error", "Failed to load file: " + err);
|
57
|
+
self._taskId = self.taskFailed(self._taskId);
|
58
|
+
});
|
59
|
+
|
60
|
+
},
|
61
|
+
|
62
|
+
destruct:function () {
|
63
|
+
this._taskId = this.taskFinished(this._taskId);
|
64
|
+
}
|
65
|
+
});
|
66
|
+
|
67
|
+
|
68
|
+
function load(url, ok, error) {
|
69
|
+
var xhr = new XMLHttpRequest();
|
70
|
+
xhr.responseType = "arraybuffer";
|
71
|
+
// xhr.addEventListener('progress',
|
72
|
+
// function (event) {
|
73
|
+
// // TODO: Update the task? { type:'progress', loaded:event.loaded, total:event.total }
|
74
|
+
// }, false);
|
75
|
+
xhr.addEventListener('load',
|
76
|
+
function (event) {
|
77
|
+
if (event.target.response) {
|
78
|
+
ok(event.target.response);
|
79
|
+
} else {
|
80
|
+
error('Invalid file [' + url + ']');
|
81
|
+
}
|
82
|
+
}, false);
|
83
|
+
xhr.addEventListener('error',
|
84
|
+
function () {
|
85
|
+
error('Couldn\'t load URL [' + url + ']');
|
86
|
+
}, false);
|
87
|
+
xhr.open('GET', url, true);
|
88
|
+
xhr.send(null);
|
89
|
+
}
|
90
|
+
|
91
|
+
})();
|
@@ -0,0 +1,139 @@
|
|
1
|
+
/**
|
2
|
+
* MD2 importer
|
3
|
+
*
|
4
|
+
* Uses the K3D library to parse .MD2
|
5
|
+
* © 2012 Ivan Kuckir
|
6
|
+
* http://k3d.ivank.net/
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
require([
|
10
|
+
|
11
|
+
// This prefix routes to the 3rd-party libs directory containing resources used by plugins
|
12
|
+
"scenejsPluginDeps/k3d"
|
13
|
+
],
|
14
|
+
function () {
|
15
|
+
|
16
|
+
SceneJS.Types.addType("import/md2", {
|
17
|
+
|
18
|
+
construct:function (params) {
|
19
|
+
|
20
|
+
if (!params.src) {
|
21
|
+
this.log("error", "Attribute expected: src");
|
22
|
+
}
|
23
|
+
|
24
|
+
// Notify SceneJS so it can support loading/busy indicators etc
|
25
|
+
this._taskId = this.taskStarted("Loading .MD2");
|
26
|
+
|
27
|
+
var self = this;
|
28
|
+
|
29
|
+
load(params.src,
|
30
|
+
function (data) {
|
31
|
+
|
32
|
+
var m = K3D.parse.fromMD2(data);
|
33
|
+
|
34
|
+
// Build morph targets
|
35
|
+
var keys = [];
|
36
|
+
var morphTargets = [];
|
37
|
+
for (var i = 0, len = m.frames.length - 3; i < len; i++) { // TODO: why do I need to skip the last three frames?
|
38
|
+
var f = m.frames[i];
|
39
|
+
keys.push((1.0 / len) * i);
|
40
|
+
|
41
|
+
// Target
|
42
|
+
var verts = K3D.edit.unwrap(m.i_verts, f.verts, 3);
|
43
|
+
|
44
|
+
// In my model, Y and Z are swapped
|
45
|
+
K3D.edit.transform(verts, K3D.mat.rotateDeg(90, 0, 0));
|
46
|
+
morphTargets.push({
|
47
|
+
positions:verts
|
48
|
+
})
|
49
|
+
}
|
50
|
+
|
51
|
+
// Build UVs
|
52
|
+
var uv = K3D.edit.unwrap(m.i_uvt, m.c_uvt, 2);
|
53
|
+
for (var i = 1, len = uv.length; i < len; i += 2) { // Flip UVs on Y-axis for SceneJS
|
54
|
+
uv[i] *= -1.0;
|
55
|
+
}
|
56
|
+
|
57
|
+
// Build indices
|
58
|
+
var indices = [];
|
59
|
+
for (var i = 0; i < m.i_verts.length; i++) {
|
60
|
+
indices.push(i);
|
61
|
+
}
|
62
|
+
|
63
|
+
// Create morph wrapping geometry
|
64
|
+
// Morph has positions in targets, geometry has UVs and indices
|
65
|
+
var morph = self.addNode({
|
66
|
+
type:"morphGeometry",
|
67
|
+
factor:0,
|
68
|
+
keys:keys,
|
69
|
+
targets:morphTargets,
|
70
|
+
nodes:[
|
71
|
+
{
|
72
|
+
type:"geometry",
|
73
|
+
primitive:"triangles",
|
74
|
+
uv:uv,
|
75
|
+
indices:indices
|
76
|
+
}
|
77
|
+
]
|
78
|
+
});
|
79
|
+
|
80
|
+
// If rate param is given, then
|
81
|
+
// automatically play the morph
|
82
|
+
|
83
|
+
if (params.rate) {
|
84
|
+
|
85
|
+
var factor = 0;
|
86
|
+
var lastKey = (keys.length > 0) ? keys[keys.length - 1] : 0;
|
87
|
+
var rate = params.rate;
|
88
|
+
|
89
|
+
// Start morphing
|
90
|
+
this._tick = self.getScene().on("tick",
|
91
|
+
function () {
|
92
|
+
morph.setFactor(factor);
|
93
|
+
factor += rate;
|
94
|
+
if (factor > lastKey) {
|
95
|
+
factor = factor % lastKey;
|
96
|
+
}
|
97
|
+
});
|
98
|
+
}
|
99
|
+
|
100
|
+
// Done
|
101
|
+
self._taskId = self.taskFinished(self._taskId);
|
102
|
+
},
|
103
|
+
|
104
|
+
function (err) {
|
105
|
+
self.log("error", "Failed to load file: " + err);
|
106
|
+
self._taskId = self.taskFailed(self._taskId);
|
107
|
+
});
|
108
|
+
|
109
|
+
},
|
110
|
+
|
111
|
+
destruct:function () {
|
112
|
+
if (this._tick) {
|
113
|
+
this.getScene().off(this._tick); // Stop morphing
|
114
|
+
}
|
115
|
+
this._taskId = this.taskFinished(this._taskId); // Just in case
|
116
|
+
}
|
117
|
+
});
|
118
|
+
|
119
|
+
|
120
|
+
function load(url, ok, error) {
|
121
|
+
var xhr = new XMLHttpRequest();
|
122
|
+
xhr.responseType = "arraybuffer";
|
123
|
+
xhr.addEventListener('load',
|
124
|
+
function (event) {
|
125
|
+
if (event.target.response) {
|
126
|
+
ok(event.target.response);
|
127
|
+
} else {
|
128
|
+
error('Invalid file [' + url + ']');
|
129
|
+
}
|
130
|
+
}, false);
|
131
|
+
xhr.addEventListener('error',
|
132
|
+
function () {
|
133
|
+
error('Couldn\'t load URL [' + url + ']');
|
134
|
+
}, false);
|
135
|
+
xhr.open('GET', url, true);
|
136
|
+
xhr.send(null);
|
137
|
+
}
|
138
|
+
|
139
|
+
})();
|
@@ -0,0 +1,100 @@
|
|
1
|
+
/**
|
2
|
+
* WaveFront OBJ mesh importer
|
3
|
+
*
|
4
|
+
* Uses the K3D library to parse OBJ
|
5
|
+
* © 2012 Ivan Kuckir
|
6
|
+
* http://k3d.ivank.net/
|
7
|
+
*
|
8
|
+
*/
|
9
|
+
require([
|
10
|
+
|
11
|
+
// This prefix routes to the 3rd-party libs directory containing resources used by plugins
|
12
|
+
"scenejsPluginDeps/k3d"
|
13
|
+
],
|
14
|
+
function () {
|
15
|
+
|
16
|
+
SceneJS.Types.addType("import/obj", {
|
17
|
+
|
18
|
+
construct:function (params) {
|
19
|
+
|
20
|
+
if (!params.src) {
|
21
|
+
this.log("error", "Attribute expected: src");
|
22
|
+
}
|
23
|
+
|
24
|
+
// Notify SceneJS so it can support loading/busy indicators etc
|
25
|
+
this._taskId = this.taskStarted("Loading .OBJ");
|
26
|
+
|
27
|
+
var self = this;
|
28
|
+
|
29
|
+
load(params.src,
|
30
|
+
function (data) {
|
31
|
+
|
32
|
+
var m = K3D.parse.fromOBJ(data); // done !
|
33
|
+
|
34
|
+
// unwrap simply duplicates some values, so they can be indexed with indices [0,1,2,3 ... ]
|
35
|
+
// In some rendering engines, you can have only one index value for vertices, UVs, normals ...,
|
36
|
+
// so "unwrapping" is a simple solution.
|
37
|
+
|
38
|
+
var positions = K3D.edit.unwrap(m.i_verts, m.c_verts, 3);
|
39
|
+
var normals = K3D.edit.unwrap(m.i_norms, m.c_norms, 3);
|
40
|
+
var uv = K3D.edit.unwrap(m.i_uvt, m.c_uvt, 2);
|
41
|
+
|
42
|
+
var indices = [];
|
43
|
+
for (var i = 0; i < m.i_verts.length; i++) {
|
44
|
+
indices.push(i);
|
45
|
+
}
|
46
|
+
|
47
|
+
// Need to flip the UV coordinates on Y-axis for SceneJS geometry
|
48
|
+
for (var i = 1, len = uv.length; i < len; i += 2) {
|
49
|
+
uv[i] *= -1.0;
|
50
|
+
}
|
51
|
+
|
52
|
+
self.addNode({
|
53
|
+
type:"geometry",
|
54
|
+
primitive:"triangles",
|
55
|
+
positions:positions,
|
56
|
+
uv:uv.length > 0 ? uv : undefined,
|
57
|
+
normals:normals.length > 0 ? normals : undefined,
|
58
|
+
indices:indices
|
59
|
+
});
|
60
|
+
|
61
|
+
self._taskId = self.taskFinished(self._taskId);
|
62
|
+
},
|
63
|
+
|
64
|
+
function (err) {
|
65
|
+
self.log("error", "Failed to load file: " + err);
|
66
|
+
self._taskId = self.taskFailed(self._taskId);
|
67
|
+
});
|
68
|
+
|
69
|
+
},
|
70
|
+
|
71
|
+
destruct:function () {
|
72
|
+
this._taskId = this.taskFinished(this._taskId);
|
73
|
+
}
|
74
|
+
});
|
75
|
+
|
76
|
+
|
77
|
+
function load(url, ok, error) {
|
78
|
+
var xhr = new XMLHttpRequest();
|
79
|
+
xhr.responseType = "arraybuffer";
|
80
|
+
// xhr.addEventListener('progress',
|
81
|
+
// function (event) {
|
82
|
+
// // TODO: Update the task? { type:'progress', loaded:event.loaded, total:event.total }
|
83
|
+
// }, false);
|
84
|
+
xhr.addEventListener('load',
|
85
|
+
function (event) {
|
86
|
+
if (event.target.response) {
|
87
|
+
ok(event.target.response);
|
88
|
+
} else {
|
89
|
+
error('Invalid file [' + url + ']');
|
90
|
+
}
|
91
|
+
}, false);
|
92
|
+
xhr.addEventListener('error',
|
93
|
+
function () {
|
94
|
+
error('Couldn\'t load URL [' + url + ']');
|
95
|
+
}, false);
|
96
|
+
xhr.open('GET', url, true);
|
97
|
+
xhr.send(null);
|
98
|
+
}
|
99
|
+
|
100
|
+
})();
|