├── .gitignore ├── CONTRIBUTORS ├── ColladaExport.py ├── LICENSE ├── MergeSkins.py ├── README ├── audio └── space-opera.ogg ├── dae ├── anim-idle.dae ├── anim-turn.dae ├── anim-walk.dae ├── character.dae ├── space-station.dae └── walkable-area.dae ├── demo.html ├── images.css ├── images └── viewer-icons.png ├── js ├── Animation.js ├── ArcBall.js ├── Area.js ├── Camera.js ├── Collada.js ├── DebugDraw.js ├── Demo.js ├── GlobalMaterialProperties.js ├── Joint.js ├── Light.js ├── Loader.js ├── Material.js ├── MaterialCache.js ├── Mesh.js ├── Node.js ├── PreProcess.js ├── Scene.js ├── TextureCache.js └── VectorMath.js ├── json ├── anim-idle.json ├── anim-idle_anim.json ├── anim-turn.json ├── anim-turn_anim.json ├── anim-walk.json ├── anim-walk_anim.json ├── char_no_scale.json ├── character.json ├── character │ ├── blinn2-fx.json │ └── merged.json ├── index.json ├── space-station.json ├── space-station │ ├── Glass-fx.json │ ├── LightsPlatform_geoShape.json │ ├── LightsWalkway_geoShape.json │ ├── MainSection_geoShape.json │ ├── Walls_geoShape.json │ ├── blinn1-fx.json │ ├── blinn12-fx.json │ ├── blinn4-fx.json │ ├── blinn5-fx.json │ ├── blinn6-fx.json │ ├── blinn7-fx.json │ ├── blinn8-fx.json │ ├── blinn9-fx.json │ ├── customPillar-fx.json │ ├── glass_geoShape.json │ ├── lambert3-fx.json │ ├── lambert4-fx.json │ ├── lambert5-fx.json │ ├── matte_geoShape.json │ ├── monitors_geoShape.json │ ├── particleBeam_l_geoShape.json │ ├── particleBeam_r_geoShape.json │ └── phong1-fx.json ├── space-station_anim.json ├── walkable-area.json └── walkable-area │ └── WalkableArea_geoShape-mesh.json ├── mobile ├── OperaMobile.png ├── backdrop.jpg ├── backdrop.png ├── fullscreen.png ├── idle.png ├── index.html ├── json │ ├── anim-idle_anim.json │ ├── anim-turn_anim.json │ ├── anim-walk_anim.json │ ├── character.json │ ├── character │ │ ├── blinn2-fx.json │ │ └── merged.json │ └── mobile-a.json ├── shaders │ ├── standard_fragment.txt │ └── standard_vertex.txt ├── textures │ ├── Color_512.jpg │ ├── SI 512.jpg │ └── S_512.jpg └── walk.png ├── preprocess-test.html ├── py ├── ColladaAnim.py ├── ColladaBone.py ├── ColladaCamera.py ├── ColladaLight.py ├── ColladaMaterial.py ├── ColladaMesh.py ├── ColladaNode.py └── ColladaScene.py ├── shaders ├── Pillar-fx_fragment.txt ├── Pillar-fx_vertex.txt ├── standard_fragment.txt └── standard_vertex.txt ├── textures ├── Color_1024.png ├── Color_2048.png ├── ConcreteTile.png ├── ConcreteTile2.png ├── ConcreteTile2_S.png ├── ConcreteTile3B.png ├── ConcreteTile3B_S.png ├── ConcreteTile_S.png ├── MechWall2.png ├── MechWall_S.png ├── MetalTile2.png ├── MetalTile2_S.png ├── N_1024.png ├── N_2048.png ├── Ridges1.png ├── Ridges1_S.png ├── SI 512.png ├── S_1024.png ├── S_2048.png ├── checker.jpeg ├── circle_pad.png ├── circle_pad_S.png ├── glass.png ├── glass_Color.png ├── keyboard.png ├── keyboard_S.png ├── main_lightmap.png ├── main_lightmap_2k.png ├── mattePainting_pow2.png ├── monitorDisplay2.png ├── monitorDisplay3.png ├── plasma.png ├── red_light.png └── walls_lightmap.png ├── viewer.css └── viewer.html /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Contributors in order of appearance. 2 | 3 | Programming by: 4 | "Erik Moller" @erikjmoller 5 | "Tim Johansson" 6 | "Marcus Geelnard" @m_bitsnbites 7 | 8 | Music by Magnus Ringblom 9 | Meshes and textures by Henk Venter 10 | Animations and matte painting by Jan Almqvist -------------------------------------------------------------------------------- /ColladaExport.py: -------------------------------------------------------------------------------- 1 | import xml.dom.minidom 2 | import sys 3 | sys.path.append('py') 4 | import ColladaScene 5 | import ColladaAnim 6 | import os 7 | import shutil 8 | import re 9 | 10 | #matchThis = '.' 11 | matchThis = 'space-station' 12 | 13 | outFolder = './json/' 14 | #if os.path.exists(outFolder[:-1]): 15 | # shutil.rmtree(outFolder[:-1]) 16 | #os.makedirs(outFolder[:-1]) 17 | 18 | fileHandle = open(outFolder + 'index.json', 'w') 19 | fileHandle.write('{\n "scenes" : [\n') 20 | 21 | numWritten = 0 22 | dirList = os.listdir('./dae'); 23 | for dae in dirList: 24 | if dae[0] == '.' or re.search(matchThis, dae) == None: 25 | continue 26 | print('Reading file ' + dae) 27 | doc = xml.dom.minidom.parse('./dae/' + dae) 28 | 29 | scenes = doc.getElementsByTagName('scene'); 30 | if len(scenes) != 1: 31 | print('Multiple scenes, skipping.') 32 | continue 33 | 34 | sceneInstances = scenes[0].getElementsByTagName('instance_visual_scene'); 35 | if len(sceneInstances) != 1: 36 | print('Multiple scene instances, skipping.') 37 | continue 38 | 39 | visualSceneURL = sceneInstances[0].getAttribute('url') 40 | if visualSceneURL[0] != '#': 41 | print('Scene URL pointing outside of this document, skipping.') 42 | continue 43 | 44 | visualScene = None 45 | for vs in doc.getElementsByTagName('visual_scene'): 46 | if vs.getAttribute('id') == visualSceneURL[1:]: 47 | visualScene = vs 48 | break 49 | 50 | if visualScene == None: 51 | print("Couldn't find visual scene with id '" + visualSceneURL + "', skipping.") 52 | continue 53 | 54 | outFileName = dae.split('.')[0] 55 | outFilePath = outFolder + outFileName + '.json' 56 | 57 | cScene = ColladaScene.Scene(doc, visualScene, outFolder) 58 | cScene.Write(outFolder, outFileName); 59 | numWritten = numWritten + 1 60 | 61 | animList = '' 62 | for libAnims in doc.getElementsByTagName('library_animations'): 63 | anim = ColladaAnim.Anim(libAnims) 64 | anim.Write(outFolder + outFileName + '_anim.json') 65 | if len(animList): 66 | animList = animList + ', ' 67 | animList = animList + '"' + outFolder + outFileName + '_anim.json"' 68 | 69 | 70 | if numWritten != 1: 71 | fileHandle.write(',\n') 72 | fileHandle.write(' { "name" : "' + outFilePath + '", "anims" : [' + animList + '] }') 73 | 74 | fileHandle.write('\n ]\n}\n') 75 | fileHandle.close() 76 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Opera Software ASA 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the 14 | distribution. 15 | 16 | 3. Neither the name of Opera Software ASA nor the names of its 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPERA SOFTWARE 24 | ASA BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /MergeSkins.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | import os 4 | import re 5 | 6 | folder = './json/character' 7 | jsons = [] 8 | 9 | # Read and parse the json files, storing them in a list. 10 | dirList = os.listdir(folder); 11 | for dae in dirList: 12 | if dae[0] == '.' or re.search('-fx', dae) != None: 13 | continue 14 | print('Reading file ' + dae) 15 | f = open(folder + '/' + dae, 'r') 16 | s = f.read(); 17 | f.close() 18 | jsons.append(json.loads(s)) 19 | 20 | # For each of the jsons 21 | for j in jsons: 22 | # except the first one which we'll merge into. 23 | if j == jsons[0]: 24 | continue 25 | # Append the indices, but increase them with the number of vertices in the merged one. 26 | l = len(jsons[0]['vertexPositions'][0]) / 3 27 | for i in j['indices']: 28 | jsons[0]['indices'].append(i + l) 29 | 30 | # Build a joint remap table. 31 | jointRemap = [] 32 | ji = 0 33 | for joint in j['jointNames']: 34 | found = False 35 | index = 0 36 | for jn in jsons[0]['jointNames']: 37 | if jn == joint: 38 | found = True 39 | jointRemap.append(index) 40 | # This just assumes all skins have the same inverse bind transform for the bone in question. 41 | break 42 | index = index + 1 43 | if found: 44 | break 45 | if not found: 46 | jointRemap.append(len(jsons[0]['jointNames'])) 47 | jsons[0]['jointNames'].append(joint) 48 | for x in range(ji * 16, (ji + 1) * 16): 49 | jsons[0]['invBindMatrices'].append(j['invBindMatrices'][x]) 50 | ji = ji + 1 51 | 52 | # Append all the joint indices, but use the remap table. 53 | for i in j['jointIndices']: 54 | jsons[0]['jointIndices'].append(jointRemap[i]) 55 | 56 | # Append all the data that isn't affected by the merge. 57 | jsons[0]['vertexWeights'] = jsons[0]['vertexWeights'] + j['vertexWeights'] 58 | jsons[0]['vertexNormals'][0] = jsons[0]['vertexNormals'][0] + j['vertexNormals'][0] 59 | jsons[0]['vertexTextureCoords'][0] = jsons[0]['vertexTextureCoords'][0] + j['vertexTextureCoords'][0] 60 | jsons[0]['vertexPositions'][0] = jsons[0]['vertexPositions'][0] + j['vertexPositions'][0] 61 | 62 | # Write out the merged json. 63 | f = open('./json/character/merged.json', 'w') 64 | f.write(json.dumps(jsons[0])) 65 | f.close() 66 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Odin is a demo created to showcase what you can do with WebGL and hopefully inspire people to create great content for the web. 2 | It uses collada as a source format and aims to be able to read both COLLADA directly as well as a run-time format created from COLLADA suitable for releases. 3 | 4 | The demo, the viewer and the COLLADA pipeline is still a work in progress. 5 | 6 | Check out the live demo at http://operasoftware.github.com/Odin/ -------------------------------------------------------------------------------- /audio/space-opera.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/audio/space-opera.ogg -------------------------------------------------------------------------------- /dae/walkable-area.dae: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mage 6 | Blender 2.60.0 r41098 7 | 8 | 2011-10-28T14:38:26 9 | 2011-10-28T14:38:26 10 | 11 | Y_UP 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -0.3904955 -0.2 2.941502 -0.3871012 -0.2 20.92238 0.3725318 -0.2 20.91103 0.3695374 -0.2 2.9354 0.4134358 -0.2 2.120568 1.326089 -0.2 1.635458 1.810754 -0.2 0.9595599 2.014973 -0.2 0.1240248 1.660438 -0.2 -0.6446204 0.827382 -0.2 -0.7678409 0.4102145 -0.2 -1.043106 -0.3976236 -0.2 -1.043107 -0.816115 -0.2 -0.7678418 -1.651396 -0.2 -0.7037807 -2.007732 -0.2 0.1240239 -1.819566 -0.2 0.9792788 -1.356303 -0.2 1.609164 -0.4286587 -0.2 2.118621 -5.80177e-4 -0.2000001 0.4722952 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 0 0 -1 -1.25827e-7 0 -1 0 0 -1 0 0 -1 -1.20294e-7 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |

0 0 2 0 1 0 0 1 3 1 2 1 3 2 0 2 17 2 17 3 4 3 3 3 17 4 18 4 4 4 5 5 4 5 18 5 11 6 18 6 12 6 16 7 18 7 17 7 18 8 6 8 5 8 10 9 9 9 18 9 10 10 18 10 11 10 15 11 18 11 16 11 14 12 18 12 15 12 18 13 7 13 6 13 13 14 12 14 18 14 18 15 14 15 13 15 8 16 7 16 18 16 18 17 9 17 8 17

48 |
49 |
50 | 1 51 |
52 |
53 | 54 | 55 | 56 | 0 0.4286164 0 57 | 0 0 1 0 58 | 0 1 0 0 59 | 1 0 0 0 60 | 1 1 1 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
69 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | Opera WebGL demo 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 35 | 36 | 37 | 40 |
41 | 42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /images.css: -------------------------------------------------------------------------------- 1 | div.zoom-selected 2 | { 3 | position: relative; 4 | width: 64px; 5 | height: 64px; 6 | background: url('images/viewer-icons.png') 0px -64px no-repeat; 7 | background-clip: content-box; 8 | } 9 | 10 | div.zoom 11 | { 12 | position: relative; 13 | width: 64px; 14 | height: 64px; 15 | background: url('images/viewer-icons.png') 0px -128px no-repeat; 16 | background-clip: content-box; 17 | } 18 | 19 | div.pan-selected 20 | { 21 | position: relative; 22 | width: 64px; 23 | height: 64px; 24 | background: url('images/viewer-icons.png') -64px -64px no-repeat; 25 | background-clip: content-box; 26 | } 27 | 28 | div.pan 29 | { 30 | position: relative; 31 | width: 64px; 32 | height: 64px; 33 | background: url('images/viewer-icons.png') -64px -128px no-repeat; 34 | background-clip: content-box; 35 | } 36 | 37 | div.track-selected 38 | { 39 | position: relative; 40 | width: 64px; 41 | height: 64px; 42 | background: url('images/viewer-icons.png') -128px -64px no-repeat; 43 | background-clip: content-box; 44 | } 45 | 46 | div.track 47 | { 48 | position: relative; 49 | width: 64px; 50 | height: 64px; 51 | background: url('images/viewer-icons.png') -128px -128px no-repeat; 52 | background-clip: content-box; 53 | } 54 | 55 | div.camera-selected 56 | { 57 | position: relative; 58 | width: 32px; 59 | height: 32px; 60 | background: url('images/viewer-icons.png') 0px 0px no-repeat; 61 | background-clip: content-box; 62 | } 63 | 64 | div.camera 65 | { 66 | position: relative; 67 | width: 32px; 68 | height: 32px; 69 | background: url('images/viewer-icons.png') 0px -32px no-repeat; 70 | background-clip: content-box; 71 | } -------------------------------------------------------------------------------- /images/viewer-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/images/viewer-icons.png -------------------------------------------------------------------------------- /js/Animation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function evaluateAttribute(attr, component, t) { 4 | var p0,p1,p2,p3,c0,c1,t0,t1,sc,sc2,sc3,s2,s3; 5 | var v = 0; 6 | 7 | var comp = attr[component]; 8 | 9 | if (attr.time.length > 1) { 10 | 11 | // Use constant post and pre infinity. 12 | if (t <= attr.time[0]) { 13 | return comp.pos[0]; 14 | } else if (t >= attr.time[attr.time.length - 1]) { 15 | return comp.pos[attr.time.length - 1]; 16 | } 17 | 18 | // Find the start of the segment to interpolate. 19 | var from = 0; 20 | while (from < attr.time.length - 1 && t > attr.time[from + 1]) { 21 | from++; 22 | } 23 | 24 | // If it's a step curve we don't need to interpolate. 25 | if (attr.type === 'STEP') { 26 | v = comp.pos[from]; 27 | } else { 28 | // Calculate s [0..1] the interpolation value for the segment. 29 | var s = (t - attr.time[from]) / (attr.time[from + 1] - attr.time[from]); 30 | // This isn't entirely true. If the tangents have different magnitudes along the t axis we should do a 31 | // De-casteljau approximation to find s, but in favor of speed we ignore that as it's not that common. 32 | 33 | if (attr.type === 'BEZIER') { 34 | p0 = comp.pos[from]; 35 | p1 = comp.pos[from + 1]; 36 | c0 = comp.outtan[from * 2 + 1]; 37 | c1 = comp.intan[(from + 1) * 2 + 1]; 38 | sc = 1 - s; 39 | sc2 = sc * sc; 40 | sc3 = sc2 * sc; 41 | s2 = s * s; 42 | s3 = s2 * s; 43 | v = p0 * sc3 + 3 * c0 * s * sc2 + 3 * c1 * s2 * sc + p1 * s3; 44 | } else if (attr.type === 'HERMITE') { 45 | p0 = comp.pos[from]; 46 | p1 = comp.pos[from + 1]; 47 | t0 = comp.outtan[from * 2 + 1]; 48 | t1 = comp.intan[(from + 1) * 2 + 1]; 49 | s2 = s * s; 50 | s3 = s2 * s; 51 | v = p0 * (2 * s3 - 3 * s2 + 1) + 52 | t0 * (s3 - 2 * s2 + s) + 53 | p1 * (-2 * s3 + 3 * s2) + 54 | t1 * (s3 - s2); 55 | } else if (attr.type === 'BSPLINE') { 56 | if (from != 0) { 57 | p0 = comp.pos[from-1]; 58 | } else { 59 | p0 = 2 * comp.pos[0] - comp.pos[1]; 60 | } 61 | p1 = comp.pos[from]; 62 | p2 = comp.pos[from + 1]; 63 | if (from == attr.time.length - 2) { 64 | p3 = 2 * comp.pos[from + 2] - comp.pos[from + 1]; 65 | } else { 66 | p3 = comp.pos[from + 2]; 67 | } 68 | s2 = s * s; 69 | s3 = s2 * s; 70 | v = p0 * (s3 + 3 * s2 - 3 * s + 1) + 71 | p1 * (3 * s2 + 4) + 72 | p2 * (-3 * s3 + 3 * s2 + 3 * s + 1) + 73 | p3 * s3; 74 | } else if (attr.type === 'CARDINAL') { 75 | throw 'CARDINAL not handled.' 76 | } else if ('LINEAR') { 77 | v = comp.pos[from] + (comp.pos[from + 1] - comp.pos[from]) * s; 78 | } 79 | } 80 | } else { 81 | v = comp.pos[0]; 82 | } 83 | return v; 84 | } 85 | 86 | function getMaxTime(obj) { 87 | var maxT = obj.time ? obj.time[obj.time.length - 1] : 0; 88 | for (var x in obj) { 89 | if (typeof obj[x] === 'object' && !(obj[x] instanceof Array)) { 90 | maxT = Math.max(maxT, getMaxTime(obj[x])); 91 | } 92 | } 93 | return maxT; 94 | } 95 | -------------------------------------------------------------------------------- /js/ArcBall.js: -------------------------------------------------------------------------------- 1 | 2 | function ArcBall(w, h) { 3 | this.setBounds(w, h); 4 | }; 5 | 6 | ArcBall.prototype = { 7 | setBounds : function(w, h) { 8 | this.adjustWidth = 1 / ((w - 1) * 0.5); 9 | this.adjustHeight = 1 / ((h - 1) * 0.5); 10 | }, 11 | 12 | click : function(x, y) { 13 | this.startVec = this.mapToSphere(x, y); 14 | }, 15 | 16 | drag : function(x, y) { 17 | var endVec = this.mapToSphere(x, y); 18 | var perp = this.startVec.copy().cross(endVec); 19 | if (perp.magnitudeSquared() > 0.0000001) 20 | { 21 | // Create the quaternion. 22 | var q = { x : perp.x, y : perp.y, z : perp.z, w : this.startVec.dot(endVec) }; 23 | 24 | // Build a 4x3 matrix from the quaternion. 25 | var n = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w; 26 | var s = n > 0 ? 2 / n : 0; 27 | 28 | var xs = q.x * s; 29 | var ys = q.y * s; 30 | var zs = q.z * s; 31 | var wx = q.w * xs; 32 | var wy = q.w * ys; 33 | var wz = q.w * zs; 34 | var xx = q.x * xs; 35 | var xy = q.x * ys; 36 | var xz = q.x * zs; 37 | var yy = q.y * ys; 38 | var yz = q.y * zs; 39 | var zz = q.z * zs; 40 | 41 | return M4x3().make(1 - (yy + zz), xy + wz, xz - wy, xy - wz, 1 - (xx + zz), yz + wx, xz + wy, yz - wx, 1 - (xx + yy), 0, 0, 0); 42 | } 43 | else 44 | { 45 | // The start and end vectors are equal so don't rotate. 46 | return I4x3(); 47 | } 48 | }, 49 | 50 | mapToSphere : function(x, y) { 51 | // Scale down to [-1 ... 1] 52 | var temp = Vec3().make(x * this.adjustWidth - 1, 1 - y * this.adjustHeight, 0); 53 | var length = temp.magnitude(); 54 | // If the point is outside the sphere, normalize it. 55 | if (length > 1) { 56 | temp.normalize(); 57 | } else { 58 | // Map it to the sphere. 59 | temp.z = Math.sqrt(1 - length); 60 | } 61 | return temp; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /js/Area.js: -------------------------------------------------------------------------------- 1 | function Area(node) { 2 | // Extract all the triangles from the geometry 3 | // FIXME: Perhaps a bit nicer... (let the Node object do this, include 4 | // transformations etc?) 5 | this.mTris = []; 6 | var json = node.children[0].json; 7 | var indices = json.indices; 8 | var verts = json.vertexPositions[0]; 9 | var s = 1 / 0.117; // HACK to compensate for the scaling of the character 10 | for (var i = 0; i < indices.length / 3; ++i) { 11 | var idx1 = indices[i*3]*3; 12 | var idx2 = indices[i*3+1]*3; 13 | var idx3 = indices[i*3+2]*3; 14 | this.mTris.push([ 15 | [s*verts[idx1], s*verts[idx1+1], s*verts[idx1+2]], 16 | [s*verts[idx2], s*verts[idx2+1], s*verts[idx2+2]], 17 | [s*verts[idx3], s*verts[idx3+1], s*verts[idx3+2]] 18 | ]); 19 | } 20 | }; 21 | 22 | Area.prototype = new (function AreaPrototype() { 23 | "use strict"; 24 | 25 | this.pointInside = function(point) { 26 | var tri, dot00, dot01, dot02, dot11, dot12, u, v, inv, dist; 27 | var v0 = [0, 0], v1 = [0, 0], v2 = [0, 0]; 28 | 29 | // Check against all triangles. Achtung! O(n) 30 | for (var i = 0; i < this.mTris.length; ++i) { 31 | tri = this.mTris[i]; 32 | 33 | // Compute vectors 34 | v0[0] = tri[2][0] - tri[0][0], v0[1] = tri[2][2] - tri[0][2]; // C - A 35 | v1[0] = tri[1][0] - tri[0][0], v1[1] = tri[1][2] - tri[0][2]; // B - A 36 | v2[0] = point[0] - tri[0][0], v2[1] = point[2] - tri[0][2]; // P - A 37 | 38 | // Compute dot products 39 | dot00 = v0[0]*v0[0] + v0[1]*v0[1]; // dot(v0, v0) 40 | dot01 = v0[0]*v1[0] + v0[1]*v1[1]; // dot(v0, v1) 41 | dot02 = v0[0]*v2[0] + v0[1]*v2[1]; // dot(v0, v2) 42 | dot11 = v1[0]*v1[0] + v1[1]*v1[1]; // dot(v1, v1) 43 | dot12 = v1[0]*v2[0] + v1[1]*v2[1]; // dot(v1, v2) 44 | 45 | // Compute barycentric coordinates 46 | inv = 1 / (dot00 * dot11 - dot01 * dot01); 47 | u = (dot11 * dot02 - dot01 * dot12) * inv; 48 | v = (dot00 * dot12 - dot01 * dot02) * inv; 49 | 50 | // Check if point is in triangle 51 | if ((u >= 0) && (v >= 0) && (u + v <= 1)) 52 | return true; 53 | } 54 | 55 | return false; 56 | } 57 | 58 | this.confinePoint = function(oldPoint, newPoint) { 59 | var dir = [newPoint[0]-oldPoint[0], newPoint[1]-oldPoint[1], newPoint[2]-oldPoint[2]]; 60 | 61 | var tri, v12 = [0, 0], v23 = [0, 0], v31 = [0, 0], v = [0, 0], inv, 62 | n1 = [0, 0], n2 = [0, 0], n3 = [0, 0], d1, d2, d3, 63 | dist1, dist2, dist3, outside1, outside2, outside3, 64 | point = [0, 0, 0], dist; 65 | 66 | // How far should we move (squared), at most? 67 | var maxDist = dir[0]*dir[0] + dir[2]*dir[2]; 68 | 69 | // Check against all triangles. Achtung! O(n) 70 | var bestPoint = [oldPoint[0], oldPoint[1], oldPoint[2]], 71 | bestDist = 0; 72 | for (var i = 0; i < this.mTris.length; ++i) { 73 | tri = this.mTris[i]; 74 | 75 | point[0] = newPoint[0]; 76 | point[1] = newPoint[1]; 77 | point[2] = newPoint[2]; 78 | 79 | v12[0] = tri[1][0] - tri[0][0], v12[1] = tri[1][2] - tri[0][2]; // Edge 1: B - A 80 | v23[0] = tri[2][0] - tri[1][0], v23[1] = tri[2][2] - tri[1][2]; // Edge 2: C - B 81 | v31[0] = tri[0][0] - tri[2][0], v31[1] = tri[0][2] - tri[2][2]; // Edge 3: A - C 82 | 83 | // Check edge 1 84 | inv = 1 / Math.sqrt(v12[0]*v12[0] + v12[1]*v12[1]); 85 | n1 = [v12[1] * inv, -v12[0] * inv]; 86 | d1 = -n1[0] * tri[0][0] - n1[1] * tri[0][2]; 87 | dist1 = point[0] * n1[0] + point[2] * n1[1] + d1; 88 | outside1 = dist1 > 0; 89 | 90 | // Check edge 2 91 | inv = 1 / Math.sqrt(v23[0]*v23[0] + v23[1]*v23[1]); 92 | n2 = [v23[1] * inv, -v23[0] * inv]; 93 | d2 = -n2[0] * tri[1][0] - n2[1] * tri[1][2]; 94 | dist2 = point[0] * n2[0] + point[2] * n2[1] + d2; 95 | outside2 = dist2 > 0; 96 | 97 | // Check edge 3 98 | inv = 1 / Math.sqrt(v31[0]*v31[0] + v31[1]*v31[1]); 99 | n3 = [v31[1] * inv, -v31[0] * inv]; 100 | d3 = -n3[0] * tri[2][0] - n3[1] * tri[2][2]; 101 | dist3 = point[0] * n3[0] + point[2] * n3[1] + d3; 102 | outside3 = dist3 > 0; 103 | 104 | if (outside1 && outside2) { 105 | point[0] = tri[1][0]; 106 | point[2] = tri[1][2]; 107 | } 108 | else if (outside2 && outside3) { 109 | point[0] = tri[2][0]; 110 | point[2] = tri[2][2]; 111 | } 112 | else if (outside3 && outside1) { 113 | point[0] = tri[0][0]; 114 | point[2] = tri[0][2]; 115 | } 116 | else if (outside1) { 117 | point[0] -= dist1 * n1[0]; 118 | point[2] -= dist1 * n1[1]; 119 | } 120 | else if (outside2) { 121 | point[0] -= dist2 * n2[0]; 122 | point[2] -= dist2 * n2[1]; 123 | } 124 | else if (outside3) { 125 | point[0] -= dist3 * n3[0]; 126 | point[2] -= dist3 * n3[1]; 127 | } 128 | 129 | // Did we get any further with this triangle? 130 | v[0] = point[0] - oldPoint[0]; 131 | v[1] = point[2] - oldPoint[2]; 132 | if ((v[0]*dir[0] + v[1]*dir[2]) > 0) { 133 | dist = v[0]*v[0] + v[1]*v[1]; 134 | if ((dist > bestDist) && (dist < maxDist)) { 135 | bestDist = dist; 136 | bestPoint[0] = point[0]; 137 | bestPoint[1] = point[1]; 138 | bestPoint[2] = point[2]; 139 | } 140 | } 141 | } 142 | 143 | // Return the best point 144 | newPoint[0] = bestPoint[0]; 145 | newPoint[1] = bestPoint[1]; 146 | newPoint[2] = bestPoint[2]; 147 | } 148 | 149 | this.moveInsideArea = function(oldPoint, dir) { 150 | // Calculate nominal (unconstrained) movement 151 | var newPoint = [oldPoint[0] + dir[0], oldPoint[1], oldPoint[2] + dir[2]]; 152 | 153 | // Confine the point to the area 154 | if (!this.pointInside(newPoint)) { 155 | this.confinePoint(oldPoint, newPoint); 156 | } 157 | 158 | return newPoint; 159 | } 160 | })(); -------------------------------------------------------------------------------- /js/Camera.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function Camera(scene, template) { 4 | this.type = template.type; 5 | this.subtype = template.subtype; 6 | this.xfov = template.xfov; 7 | this.yfov = template.yfov; 8 | this.znear = template.znear; 9 | this.zfar = template.zfar; 10 | this.xmag = template.xmag; 11 | this.ymag = template.ymag; 12 | this.xoff = 0; 13 | this.yoff = 0; 14 | this.aspect = scene.aspect; 15 | if (!this.xfov) { 16 | this.xfov = this.aspect * this.yfov; 17 | } 18 | if (!this.xmag) { 19 | this.xmag = this.aspect * this.ymag; 20 | } 21 | if (!this.ymag) { 22 | this.ymag = this.xmag / this.aspect; 23 | } 24 | }; 25 | 26 | function CameraPrototype() { 27 | this.setMatrices = function() { 28 | viewMatrix().make(this.getAccumulatedTransform()).invertRigidBody(); 29 | if (this.subtype == 'perspective') { 30 | projectionMatrix().makePerspective(this.yfov, this.aspect, this.znear, this.zfar); 31 | } else if (this.subtype == 'orthographic') { 32 | projectionMatrix().makeOrtho(this.xoff-this.xmag, this.xoff+this.xmag, this.yoff-this.ymag, this.yoff+this.ymag, this.znear, this.zfar); 33 | } 34 | } 35 | 36 | this.drawSkeleton = function(dbgDraw, frames) { 37 | /*var alen = 0.3 38 | dbgDraw.drawLine(0,0,-alen, -alen,-alen,alen, dbgDraw.RED,frames, 1); 39 | dbgDraw.drawLine(0,0,-alen, -alen, alen,alen, dbgDraw.RED,frames, 1); 40 | dbgDraw.drawLine(0,0,-alen, alen,-alen,alen, dbgDraw.RED,frames, 1); 41 | dbgDraw.drawLine(0,0,-alen, alen, alen,alen, dbgDraw.RED,frames, 1);*/ 42 | } 43 | 44 | this.pan = function(h,v) { 45 | if (this.subtype == 'perspective') { 46 | var acc = this.getAccumulatedTransform(); 47 | var x = acc.getX(); 48 | var y = acc.getY(); 49 | var m = M4x3().makeTranslate(x.x*h+y.x*v, x.y*h+y.y*v, x.z*h+y.z*v); 50 | this.parent.local = m.multiply(this.parent.local); 51 | } else { 52 | this.xoff += h; 53 | this.yoff += v; 54 | } 55 | } 56 | 57 | this.zoom = function(h,v) { 58 | if (this.subtype == 'perspective') { 59 | var acc = this.getAccumulatedTransform(); 60 | var z = acc.getZ(); 61 | this.parent.local = M4x3().makeTranslate(z.x * h, z.y * h, z.z * h).multiply(this.parent.local); 62 | } else { 63 | this.xmag *= (1 + h / 10); 64 | this.ymag *= (1 + h / 10); 65 | } 66 | } 67 | 68 | this.startTrack = function(x,y,arcball) { 69 | if (this.subtype == 'perspective') { 70 | arcball.click(x,y); 71 | this.trackTfrm = this.getAccumulatedTransform(); 72 | } 73 | } 74 | 75 | this.track = function(x,y,arcball) { 76 | if (this.subtype == 'perspective') { 77 | // For now we always track around origin. 78 | var m = arcball.drag(x,y); 79 | m = m.invertRigidBody(); 80 | this.parent.local = m.multiply(this.trackTfrm); 81 | } 82 | } 83 | }; 84 | 85 | CameraPrototype.prototype = Node.prototype; 86 | Camera.prototype = new CameraPrototype(); 87 | -------------------------------------------------------------------------------- /js/Collada.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | NOTE: this is work in progress and is not yet functional. 4 | 5 | */ 6 | 7 | 8 | function getChildNodeByAttrib(node, attr, val) { 9 | var child = node.firstChild; 10 | while (child) { 11 | if (child.nodeType == child.ELEMENT_NODE) { 12 | if (child.attributes[attr] && child.attributes[attr].nodeValue == val) { 13 | return child; 14 | } 15 | } 16 | child = child.nextSibling; 17 | } 18 | return null; 19 | } 20 | 21 | function getChildNodesByNodeName(node, name) { 22 | var children = []; 23 | var child = node.firstChild; 24 | while (child) { 25 | if (child.nodeType == child.ELEMENT_NODE) { 26 | if (child.nodeName == name) { 27 | children.push(child); 28 | } 29 | } 30 | child = child.nextSibling; 31 | } 32 | return children; 33 | } 34 | 35 | function getTransformation(node, sid) { 36 | var child = getChildNodeByAttrib(node, 'sid', sid); 37 | if (child) { 38 | return child.firstChild.nodeValue.trim().split(' '); 39 | } 40 | return undefined; 41 | } 42 | 43 | function ColladaNode() { 44 | 45 | this.parse = function(xmlDoc, node) { 46 | this.type = 'node'; 47 | this.name = node.attributes['name'].nodeValue; 48 | this.translate = getTransformation(node, 'translate'); 49 | var rotateZ = getTransformation(node, 'rotateZ'); 50 | var rotateY = getTransformation(node, 'rotateY'); 51 | var rotateX = getTransformation(node, 'rotateX'); 52 | this.scale = getTransformation(node, 'scale'); 53 | this.rotatePivot = getTransformation(node, 'rotatePivot'); 54 | this.scalePivot = getTransformation(node, 'scalePivot'); 55 | this.rotate = [0, 0, 0]; 56 | if (rotateX) 57 | this.rotate[0] = rotateX[3]; 58 | if (rotateY) 59 | this.rotate[1] = rotateY[3]; 60 | if (rotateZ) 61 | this.rotate[2] = rotateZ[3]; 62 | 63 | this.children = []; 64 | for (var x = 0; x < node.childNodes.length; ++x) { 65 | var child = node.childNodes[x]; 66 | if (child.nodeType == child.ELEMENT_NODE) { 67 | var newNode = createColladaNode(child); 68 | if (newNode) { 69 | newNode.parse(xmlDoc, child); 70 | this.children.push(newNode); 71 | } 72 | } 73 | } 74 | } 75 | 76 | this.print = function() { 77 | var str = '{ "type" : "' + this.type + '", "name" : "' + this.name + '", "translate" : [' + this.translate + '], "rotate" : [' + this.rotate + '], "scale" : [' + this.scale + '], "children" : ['; 78 | for (var i = 0; i < this.children.length; ++i) { 79 | if (i != 0) { 80 | str += ', '; 81 | } 82 | str += this.children[i].print(); 83 | } 84 | return str + '] }'; 85 | } 86 | } 87 | 88 | function trim(str) { 89 | return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); 90 | } 91 | 92 | function makeArray(str, stride) { 93 | str = trim(str); 94 | var arr = str.split(' '); 95 | var res = []; 96 | for (var x = 0; x < arr.length; x = x + stride) 97 | res.push(arr.slice(x, x + stride)); 98 | return res; 99 | } 100 | 101 | function validateFragmentURI(uri) { 102 | if (uri.length == 0 || uri[0] != '#') { 103 | alert(uri + ' is not a fragment URI.'); 104 | } 105 | return uri.slice(1); 106 | } 107 | 108 | function getSource(node) { 109 | var source = { 'id' : node.attributes['id'].nodeValue }; 110 | var techniqueCommonArray = getChildNodesByNodeName(node, 'technique_common'); 111 | if (techniqueCommonArray.length == 0) 112 | alert('No technique_common... dunno what to do!'); 113 | var techniqueCommon = techniqueCommonArray[0]; 114 | var accessorsArray = getChildNodesByNodeName(techniqueCommon, 'accessor'); 115 | for (var a = 0; a < accessorsArray.length; ++a) { 116 | var sourceURI = validateFragmentURI(accessorsArray[a].attributes['source'].nodeValue); 117 | var sourceCount = accessorsArray[a].attributes['count'].nodeValue; 118 | var sourceStride = accessorsArray[a].attributes['stride'].nodeValue; 119 | var dataArray = getChildNodeByAttrib(node, 'id', sourceURI); 120 | var dataCount = dataArray.attributes['count'].nodeValue; 121 | if (dataCount != sourceCount * sourceStride) 122 | alert('Ooops params may be repeating!'); 123 | source.data = makeArray(dataArray.firstChild.nodeValue, sourceStride); 124 | break; // TODO: what do we do if there are more accessors? 125 | } 126 | return source; 127 | } 128 | 129 | function ColladaMesh() { 130 | this.parse = function(xmlDoc, node) { 131 | var instanceGeometryURI = validateFragmentURI(node.attributes['url'].nodeValue); 132 | this.file = ''; 133 | var collada = xmlDoc.documentElement; 134 | var libraryGeometriesArray = collada.getElementsByTagName('library_geometries'); 135 | if (libraryGeometriesArray.length == 0) 136 | return; 137 | var libraryGeometries = libraryGeometriesArray[0]; 138 | for (var x = 0; x < libraryGeometries.childNodes.length; ++x) { 139 | var node = libraryGeometries.childNodes[x]; 140 | if (node.nodeType == node.ELEMENT_NODE && node.nodeName == 'geometry' && node.attributes['id'].nodeValue == instanceGeometryURI) { 141 | var meshArray = getChildNodesByNodeName(node, 'mesh'); 142 | if (meshArray.length == 0) 143 | alert('Geometry containing spline or convex_mesh is unsupported.') 144 | var mesh = meshArray[0]; 145 | 146 | var sources = []; 147 | var triangles = []; 148 | var child = mesh.firstChild; 149 | while (child) { 150 | if (child.nodeType == child.ELEMENT_NODE) { 151 | switch (child.nodeName) { 152 | case 'source': 153 | sources.push(getSource(child)); 154 | break; 155 | case 'triangles': 156 | triangles.push(child); 157 | break; 158 | case 'lines': 159 | case 'linestrips': 160 | case 'polygons': 161 | case 'polylists': 162 | case 'trifans': 163 | case 'tristrips': 164 | alert('Unsupported mesh primitive ' + child.nodeName); 165 | break; 166 | default: 167 | break; 168 | } 169 | } 170 | child = child.nextSibling; 171 | } 172 | 173 | var inputList = []; 174 | for (var t = 0; t < triangles.length; ++t) { 175 | var material = triangles[t].attributes['material'].nodeValue; 176 | var count = triangles[t].attributes['count'].nodeValue; 177 | var inputArray = getChildNodesByNodeName(triangles[t], 'input'); 178 | for (var i = 0; i < inputArray.length; ++i) { 179 | var semantic = inputArray[i].attributes['semantic'].nodeValue; 180 | var sourceURI = validateFragmentURI(inputArray[i].attributes['source'].nodeValue); 181 | var offset = inputArray[i].attributes['offset'].nodeValue; 182 | var set = inputArray[i].attributes['set'] ? inputArray[i].attributes['set'].nodeValue : 0; 183 | 184 | if (semantic == 'VERTEX') { 185 | var vert = getChildNodeByAttrib(mesh, 'id', sourceURI); 186 | var vertInputArray = getChildNodesByNodeName(vert, 'input'); 187 | for (var j = 0; j < vertInputArray.length; ++j) { 188 | var semantic = vertInputArray[j].attributes['semantic'].nodeValue; 189 | var sourceURI = validateFragmentURI(vertInputArray[j].attributes['source'].nodeValue); 190 | inputList.push({ 'semantic' : semantic, 'source' : sourceURI, 'offset' : offset, 'set' : set }); 191 | } 192 | } else { 193 | inputList.push({ 'semantic' : semantic, 'source' : sourceURI, 'offset' : offset, 'set' : set }); 194 | } 195 | } 196 | // KEEP GOING 197 | var pArray = getChildNodesByNodeName(triangles[t], 'p'); 198 | var p = pArray[0]; 199 | } 200 | } 201 | } 202 | 203 | this.file = './json/space-station/matte_geoShape.json'; 204 | } 205 | 206 | this.print = function() { 207 | return '{ "type" : "mesh", "file" : "' + this.file + '" }'; 208 | } 209 | } 210 | 211 | function ColladaLight() { 212 | this.parse = function(xmlDoc, node) { 213 | } 214 | 215 | this.print = function() { 216 | return '{ "type" : "light", "subtype" : "spot", "color" : [1, 1, 1], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0, "falloff_angle" : 40.0, "falloff_exponent" : 1.0 }'; 217 | } 218 | } 219 | 220 | function ColladaCamera() { 221 | this.parse = function(xmlDoc, node) { 222 | } 223 | 224 | this.print = function() { 225 | return '{ "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 }'; 226 | } 227 | } 228 | 229 | function createColladaNode(node) { 230 | if (node.nodeName == 'instance_controller' || node.nodeName == 'instance_geometry') { 231 | return new ColladaMesh(); 232 | } else if (node.nodeName == 'instance_light') { 233 | return new ColladaLight(); 234 | } else if (node.nodeName == 'instance_camera') { 235 | return new ColladaCamera(); 236 | } else if (node.nodeName == 'node' && node.attributes['type'].nodeValue == 'JOINT') { 237 | alert('joint'); 238 | } else if (node.nodeName == 'node') { 239 | return new ColladaNode(); 240 | } 241 | return null; 242 | } 243 | 244 | function ColladaScene() { 245 | 246 | this.parse = function(xmlDoc, visualScene) { 247 | this.nodes = []; 248 | 249 | for (var x = 0; x < visualScene.childNodes.length; ++x) { 250 | var node = visualScene.childNodes[x]; 251 | if (node.nodeType == node.ELEMENT_NODE) { 252 | var newNode = createColladaNode(node); 253 | newNode.parse(xmlDoc, node); 254 | this.nodes.push(newNode); 255 | } 256 | } 257 | } 258 | 259 | this.print = function() { 260 | var str = '{ "nodes" : [ '; 261 | for (var i = 0; i < this.nodes.length; ++i) { 262 | if (i != 0) 263 | str += ', '; 264 | str += this.nodes[i].print(); 265 | } 266 | str += ' ] }'; 267 | return str; 268 | } 269 | } 270 | 271 | function collada2JSON(xmlDoc) { 272 | var emptyScene = '{ "nodes" : [ ] }'; 273 | var collada = xmlDoc.documentElement; 274 | 275 | if (!collada) 276 | return emptyScene; 277 | 278 | var sceneArray = collada.getElementsByTagName('scene'); 279 | if (sceneArray.length == 0) 280 | return emptyScene; 281 | 282 | // There can be zero or one scenes in a collada element. 283 | var scene = sceneArray[0]; 284 | 285 | var ivSceneList = scene.getElementsByTagName('instance_visual_scene'); 286 | if (ivSceneList.length == 0) 287 | return emptyScene; 288 | 289 | // There can be zero or one instance_visual_scene in a scene element. 290 | var instance_visual_scene = ivSceneList[0]; 291 | var visualSceneURI = validateFragmentURI(instance_visual_scene.attributes['url'].nodeValue); 292 | 293 | var libraryVisualScenesArray = collada.getElementsByTagName('library_visual_scenes'); 294 | if (libraryVisualScenesArray.length == 0) 295 | return emptyScene; 296 | 297 | // There can be zero or one library_visual_scenes in a collada element. 298 | var libraryVisualScenes = libraryVisualScenesArray[0]; 299 | for (var x = 0; x < libraryVisualScenes.childNodes.length; ++x) { 300 | var node = libraryVisualScenes.childNodes[x]; 301 | if (node.nodeType == node.ELEMENT_NODE && node.nodeName == 'visual_scene' && node.attributes['id'].nodeValue == visualSceneURI) { 302 | var scene = new ColladaScene(); 303 | scene.parse(xmlDoc, node); 304 | var jsonString = scene.print(); 305 | return jsonString; 306 | } 307 | } 308 | return emptyScene; 309 | } -------------------------------------------------------------------------------- /js/DebugDraw.js: -------------------------------------------------------------------------------- 1 | /* 2 | DebugDraw: 3 | 4 | draw() 5 | Draws the queued up debug info and decrement life of all primitives with 1. 6 | 7 | drawLine(ax,ay,az,bx,by,bz,col,life) 8 | Draw a line from (ax,ay,az) to (bx,by,bz). A life of 0 means forever. 9 | */ 10 | function DebugDraw() { 11 | this.mVertexPositionBuffer = gl.createBuffer(); 12 | this.lines = new Array(); 13 | this.initialize(); 14 | } 15 | 16 | DebugDraw.prototype = new (function DebugDrawPrototype(callback) { 17 | Object.defineProperty(this, 'RED', { value : 0 }); 18 | Object.defineProperty(this, 'GREEN', { value : 1 }); 19 | Object.defineProperty(this, 'BLUE', { value : 2 }); 20 | Object.defineProperty(this, 'WHITE', { value : 3 }); 21 | Object.defineProperty(this, 'BLACK', { value : 4 }); 22 | Object.defineProperty(this, 'cols', { value : [[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, 1], [1, 1, 1, 1], [0, 0, 0, 1]] }); 23 | this.outstandingRequests = 0; 24 | this.initialized = false; 25 | 26 | this.handleMaterialLoaded = function (mat) { 27 | this.outstandingRequests--; 28 | } 29 | 30 | this.draw = function () { 31 | if (!this.initialized || this.outstandingRequests != 0) { 32 | return; 33 | } 34 | 35 | modelMatrix().makeIdentity(); 36 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 37 | 38 | gl.bindBuffer(gl.ARRAY_BUFFER, this.mVertexPositionBuffer); 39 | var arr = new Array(); 40 | for (var c in this.lines) { 41 | arr = arr.concat(this.lines[c].verts); 42 | } 43 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(arr), gl.DYNAMIC_DRAW); 44 | 45 | for (var c in this.lines) { 46 | var line = this.lines[c]; 47 | var mat = this.materials[line.col]; 48 | pushModelMatrix(line.mmat); 49 | gl.vertexAttribPointer(mat.shaderProgram.vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); 50 | mat.enable(); 51 | gl.drawArrays(gl.LINES, c * 2, 2); 52 | mat.disable(); 53 | popModelMatrix(); 54 | } 55 | 56 | for (var c = 0; c < this.lines.length;) { 57 | if (this.lines[c].life > 0) { 58 | this.lines[c].life -= 1; 59 | if (this.lines[c].life == 0) { 60 | this.lines.splice(c, 1); 61 | continue; 62 | } 63 | } 64 | ++c; 65 | } 66 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 67 | } 68 | 69 | this.drawLine = function(ax, ay, az, bx, by, bz, col, life) { 70 | this.lines.push({ 'verts' : [ax, ay, az, bx, by, bz], 'col' : col, 'life' : life, 'mmat' : modelMatrix().copy() }); 71 | } 72 | 73 | this.initialize = function() { 74 | if (!this.initialized) { 75 | this.initialized = true; 76 | this.materials = new Array(); 77 | 78 | var thisObj = this; 79 | var tempMat = { 'name': 'debugmaterial', 'diffuse': [1, 1, 1, 1], 'type' : 'matte' }; 80 | for (var c in this.cols) { 81 | tempMat.diffuse = this.cols[c]; 82 | this.outstandingRequests++; 83 | this.materials.push(new Material(tempMat, function(mat) { thisObj.handleMaterialLoaded(mat); })); 84 | } 85 | } 86 | } 87 | })(); 88 | 89 | -------------------------------------------------------------------------------- /js/GlobalMaterialProperties.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | window.globalMaterialProperties = { 4 | // ambient, 0-1 minimum ambient light that should be used 5 | }; 6 | -------------------------------------------------------------------------------- /js/Joint.js: -------------------------------------------------------------------------------- 1 | 2 | function JointPrototype() { 3 | 4 | this.calculateLocalTransform = function(translation, rotation, scale, inverseParentScale, visibility) { 5 | var degToRad = Math.PI / 180.0; 6 | this.local = M4x3().make(inverseParentScale[0],0,0,0,inverseParentScale[1],0,0,0,inverseParentScale[2],translation[0],translation[1],translation[2]); 7 | this.local.multiply(M4x3().makeRotateZ(this.jointOrient[2] * degToRad)); 8 | this.local.multiply(M4x3().makeRotateY(this.jointOrient[1] * degToRad)); 9 | this.local.multiply(M4x3().makeRotateX(this.jointOrient[0] * degToRad)); 10 | this.local.multiply(M4x3().makeRotateZ(rotation[2] * degToRad)); 11 | this.local.multiply(M4x3().makeRotateY(rotation[1] * degToRad)); 12 | this.local.multiply(M4x3().makeRotateX(rotation[0] * degToRad)); 13 | if (this.postRotate) { 14 | this.local.multiply(M4x3().makeRotateZ(this.postRotate[2] * degToRad)); 15 | this.local.multiply(M4x3().makeRotateY(this.postRotate[1] * degToRad)); 16 | this.local.multiply(M4x3().makeRotateX(this.postRotate[0] * degToRad)); 17 | } 18 | this.local.multiply(M4x3().make(scale[0],0,0,0,scale[1],0,0,0,scale[2],0,0,0)); 19 | this.visible = visibility; 20 | } 21 | 22 | this.drawSkeleton = function(dbgDraw, frames) { 23 | 24 | var lt = this.getLocalTransform(); 25 | 26 | if (this.parent && this.parent.type == 'joint') { 27 | dbgDraw.drawLine(0, 0, 0, lt.t0, lt.t1, lt.t2, dbgDraw.WHITE, frames); 28 | } 29 | 30 | pushModelMatrix(); 31 | modelMatrix().multiply(lt); 32 | 33 | var alen = 0.5 34 | dbgDraw.drawLine(0,0,0, alen,0,0, dbgDraw.RED,frames); 35 | dbgDraw.drawLine(0,0,0, 0,alen,0, dbgDraw.GREEN,frames); 36 | dbgDraw.drawLine(0,0,0, 0,0,alen, dbgDraw.BLUE,frames); 37 | 38 | if (this.children) { 39 | for (var i = 0; i < this.children.length; ++i) { 40 | this.children[i].drawSkeleton(dbgDraw, frames); 41 | } 42 | } 43 | 44 | popModelMatrix(); 45 | } 46 | 47 | this.cacheAccumulatedTfrm = function(scene, accumulated) { 48 | scene.jointMatrices[this.name] = accumulated; 49 | } 50 | 51 | this.setupLODJoints = function(scene) { 52 | if (this.lod) { 53 | if (!scene.hasOwnProperty('lod')) { 54 | scene.lod = []; 55 | for (var k = 0; k < this.lod.length; ++k) { 56 | scene.lod[k] = {}; 57 | } 58 | } 59 | for (var j = 0; j < this.lod.length; ++j) { 60 | if (this.lod[j] == 'x') { 61 | scene.lod[j][this.name] = this.name; 62 | } else { 63 | var jnt = this.parent; 64 | while (jnt && jnt.lod[j] != 'x') { 65 | jnt = jnt.parent; 66 | } 67 | if (!jnt) { alert('Could not find parent!'); } 68 | scene.lod[j][this.name] = jnt.name; 69 | } 70 | } 71 | if (this.children) { 72 | for (var i = 0; i < this.children.length; ++i) { 73 | this.children[i].setupLODJoints(scene); 74 | } 75 | } 76 | } 77 | } 78 | 79 | 80 | }; 81 | 82 | function Joint(scene, template) { 83 | Node.call(this, scene, template); 84 | Object.defineProperty(this, 'bindTranslation', { value : template.bindTranslation }); 85 | Object.defineProperty(this, 'bindRotation', { value : template.bindRotation }); 86 | Object.defineProperty(this, 'jointOrient', { value : template.jointOrient }); 87 | Object.defineProperty(this, 'postRotate', { value : template.postRotate }); 88 | Object.defineProperty(this, 'lod', { value : template.lod }); 89 | this.local = I4x3(); 90 | }; 91 | 92 | JointPrototype.prototype = Node.prototype; 93 | Joint.prototype = new JointPrototype(); 94 | -------------------------------------------------------------------------------- /js/Light.js: -------------------------------------------------------------------------------- 1 | function Light(scene, template) { 2 | this.lastUpdateFrame = 0; 3 | this.castsShadows = false; 4 | 5 | this.type = template.type; 6 | this.subtype = template.subtype; 7 | this.falloff_angle = template.falloff_angle; 8 | this.falloff_exponent = template.falloff_exponent; 9 | this.color = template.color; 10 | this.constant_attenuation = template.constant_attenuation; 11 | this.linear_attenuation = template.linear_attenuation; 12 | this.quadratic_attenuation = template.quadratic_attenuation; 13 | 14 | // this.radius = 100; // TODO: Use attenuation values? 15 | this.radius = this.linear_attenuation * 10; 16 | if (this.subtype == 'spot') { 17 | this.projectionMatrix = M4x4().makePerspective(this.falloff_angle, 1.0, 0.1, this.radius); 18 | } else if (this.subtype == 'point') { 19 | this.projectionMatrix = I4x4(); 20 | } else { 21 | // FIXME: the coordinates here is the size in ws units which the shadowmap covers. Should be calculated using som sort of bbox not using the fallof angle 22 | this.projectionMatrix = M4x4().makeOrtho(-this.falloff_angle, this.falloff_angle, -this.falloff_angle, this.falloff_angle, 0, this.radius); 23 | } 24 | 25 | this.shadowmapSize = 1024; 26 | this.shadowTexture = gl.createTexture(); 27 | gl.bindTexture(gl.TEXTURE_2D, this.shadowTexture); 28 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 29 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 30 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 31 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 32 | if (this.subtype != 'point') { 33 | // Create a texture and FBO for shadowmapping 34 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.shadowmapSize, this.shadowmapSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 35 | 36 | this.shadowDepth = gl.createRenderbuffer(); 37 | gl.bindRenderbuffer(gl.RENDERBUFFER, this.shadowDepth); 38 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.shadowmapSize, this.shadowmapSize); 39 | this.shadowFBO = gl.createFramebuffer(); 40 | gl.bindFramebuffer(gl.FRAMEBUFFER, this.shadowFBO); 41 | gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.shadowTexture, 0); 42 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.shadowDepth); 43 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 44 | } else { 45 | // point light does not have shadows. Set the distance to max to achieve that effect 46 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255,255,255,255])); 47 | } 48 | } 49 | 50 | function LightPrototype() { 51 | this.beginShadowmapRendering = function() { 52 | if (this.subtype == 'point') { 53 | return false; 54 | } 55 | // bind the shadowmap FBO 56 | gl.bindFramebuffer(gl.FRAMEBUFFER, this.shadowFBO); 57 | gl.viewport(0,0,this.shadowmapSize,this.shadowmapSize); 58 | gl.clearColor(1,1,1,1); 59 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 60 | gl.clearColor(0.75, 0.75, 0.75, 1.0); 61 | 62 | this.backupProjection = projectionMatrix().copy(); 63 | this.backupView = viewMatrix().copy(); 64 | 65 | projectionMatrix().make(this.projectionMatrix); 66 | viewMatrix().make(this.getAccumulatedTransform()).invertRigidBody(); 67 | return true; 68 | } 69 | 70 | this.endShadowmapRendering = function() { 71 | projectionMatrix().make(this.backupProjection); 72 | viewMatrix().make(this.backupView); 73 | } 74 | 75 | this.viewProjectionMatrix = function() { 76 | var view = M4x3().make(this.getAccumulatedTransform()).invertRigidBody(); 77 | return this.projectionMatrix.copy().multiply(view); 78 | } 79 | 80 | this.getType = function() { 81 | // 0 = point, 1 = spot, 2 = directional 82 | if (this.subtype == 'spot') { 83 | return 1; 84 | } else if (this.subtype == 'directional') { 85 | return 2; 86 | } else { 87 | return 0; 88 | } 89 | } 90 | 91 | this.drawSkeleton = function(dbgDraw, frames) { 92 | if (this.subtype == 'point') { 93 | var alen = 0.3 94 | dbgDraw.drawLine(-alen,0,0, alen,0,0, dbgDraw.RED,frames, 1); 95 | dbgDraw.drawLine(0,-alen,0, 0,alen,0, dbgDraw.RED,frames, 1); 96 | dbgDraw.drawLine(0,0,-alen, 0,0,alen, dbgDraw.RED,frames, 1); 97 | } 98 | } 99 | } 100 | 101 | LightPrototype.prototype = Node.prototype; 102 | Light.prototype = new LightPrototype(); 103 | 104 | -------------------------------------------------------------------------------- /js/Loader.js: -------------------------------------------------------------------------------- 1 | function Loader(doneCallback) { 2 | this.outstandingRequests = 0; 3 | this.loadingDone = [doneCallback]; 4 | }; 5 | 6 | Loader.prototype = new (function LoaderPrototype() { 7 | 8 | this.load = function(file, callback) { 9 | this.outstandingRequests++; 10 | var request = new XMLHttpRequest(); 11 | var thisObj = this; 12 | request.onreadystatechange = function() { 13 | if (request.readyState == 1) { 14 | request.overrideMimeType('application/json'); 15 | request.send(); 16 | } 17 | 18 | if (request.readyState == 4) { 19 | if (request.status == 404) { 20 | alert('file does not exist'); 21 | } else { 22 | callback(request.responseText); 23 | } 24 | thisObj.decOutstandingRequests(); 25 | } 26 | } 27 | request.open('GET', file, true); 28 | //request.open('GET', file + '?' + (new Date()).getTime(), true); // Debug, don't cache anything! 29 | } 30 | 31 | this.addRequest = function() { 32 | this.outstandingRequests++; 33 | } 34 | 35 | this.decOutstandingRequests = function() { 36 | this.outstandingRequests--; 37 | if (this.outstandingRequests == 0) { 38 | for (var j = 0; j < this.loadingDone.length; ++j) { 39 | this.loadingDone[j](); 40 | } 41 | } 42 | } 43 | 44 | this.fullyLoaded = function() { 45 | return this.outstandingRequests == 0; 46 | } 47 | 48 | this.addCallback = function(cb) { 49 | this.loadingDone.push(cb); 50 | } 51 | })(); 52 | -------------------------------------------------------------------------------- /js/MaterialCache.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | window.materialCache = { 4 | loadedMaterials : [], 5 | 6 | newMaterialLoaded : function (filename) { 7 | var mat = this.loadedMaterials[filename]; 8 | InfoMessage('New material ' + filename + ' is loaded.'); 9 | for(var l in mat.listeners) { 10 | mat.listeners[l](mat.material); 11 | } 12 | mat.listeners = []; 13 | }, 14 | 15 | loadMaterial : function (filename, callback, shadowReceiver) { 16 | if (this.loadedMaterials[filename]) { 17 | if (this.loadedMaterials[filename].material.outstandingRequests) { 18 | this.loadedMaterials[filename].listeners.push(callback); 19 | } else { 20 | callback(filename); 21 | } 22 | } else { 23 | var that = this; 24 | var json = undefined; 25 | if (filename === 'shadowgen') { 26 | json = { 'name': 'shadowgen', 'diffuse': [0, 0, 0, 1], 'type': 'shadowmap' }; 27 | } else if (filename === 'shadowgenskinned') { 28 | json = { 'name': 'shadowgenskinned', 'diffuse': [0, 0, 0, 1], 'type': 'shadowmap', 'skinned': true }; 29 | } 30 | this.loadedMaterials[filename] = {'material' : new Material(json ? json : filename, function() { that.newMaterialLoaded(filename); }, shadowReceiver), 'listeners' : [callback]}; 31 | } 32 | return this.loadedMaterials[filename].material; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /js/Node.js: -------------------------------------------------------------------------------- 1 | 2 | function NodePrototype() { 3 | 4 | this.deinit = function() { 5 | if (this.children) 6 | for (var i = 0; i < this.children.length; ++i) 7 | this.children[i].deinit(); 8 | } 9 | 10 | this.resetToBindPose = function(scene, acc) { 11 | 12 | this.translate = this.getBindTranslation(); 13 | this.rotate = this.getBindRotation(); 14 | this.scale = this.getBindScale(); 15 | this.calculateLocalTransform(this.translate, this.rotate, this.scale, [1.0 / acc.getX().magnitude(), 1.0 / acc.getY().magnitude(), 1.0 / acc.getZ().magnitude()], true); 16 | 17 | var accumulated = acc.copy().multiply(this.getLocalTransform()); 18 | this.cacheAccumulatedTfrm(scene, accumulated); 19 | 20 | if (this.children) 21 | for (var i = 0; i < this.children.length; ++i) 22 | this.children[i].resetToBindPose(scene, accumulated); 23 | } 24 | 25 | this.getBindTranslation = function() { 26 | return this.bindTranslation ? Copy3V(this.bindTranslation) : [0,0,0]; 27 | } 28 | 29 | this.getBindRotation = function() { 30 | return this.bindRotation ? Copy3V(this.bindRotation) : [0,0,0]; 31 | } 32 | 33 | this.getBindScale = function() { 34 | return this.bindScale ? Copy3V(this.bindScale) : [1,1,1]; 35 | } 36 | 37 | this.applyToDAG = function(f) { 38 | pushModelMatrix(); 39 | modelMatrix().multiply(this.getLocalTransform()); 40 | 41 | if (this.children) 42 | for (var i = 0; i < this.children.length; ++i) 43 | f.call(this.children[i]); 44 | 45 | popModelMatrix(); 46 | } 47 | 48 | this.drawSkeleton = function(dbgDraw, frames) { 49 | this.applyToDAG(function() { this.drawSkeleton(dbgDraw, frames); }); 50 | } 51 | 52 | this.drawShadow = function(jointMatrices, light) { 53 | this.applyToDAG(function() { this.drawShadow(jointMatrices, light); }); 54 | } 55 | 56 | this.draw = function(jointMatrices, lights) { 57 | if (this.visible) 58 | this.applyToDAG(function() { this.draw(jointMatrices, lights); }); 59 | } 60 | 61 | this.calculateLocalTransform = function(tr, ro, sc, psi, vis) { 62 | this.local = M4x3().makeTranslate(tr[0], tr[1], tr[2]); 63 | 64 | if (ro != [0,0,0]) { 65 | if (this.rotatePivot) 66 | this.local.multiply(M4x3().makeTranslate(this.rotatePivot[0], this.rotatePivot[1], this.rotatePivot[2])); 67 | this.local.multiply(M4x3().makeRotateZ(ro[2] * Math.PI / 180.0)); 68 | this.local.multiply(M4x3().makeRotateY(ro[1] * Math.PI / 180.0)); 69 | this.local.multiply(M4x3().makeRotateX(ro[0] * Math.PI / 180.0)); 70 | if (this.rotatePivot) 71 | this.local.multiply(M4x3().makeTranslate(-this.rotatePivot[0], -this.rotatePivot[1], -this.rotatePivot[2])); 72 | } 73 | 74 | if (sc != [1,1,1]) { 75 | if (this.scalePivot) 76 | this.local.multiply(M4x3().makeTranslate(this.scalePivot[0], this.scalePivot[1], this.scalePivot[2])); 77 | this.local.multiply(M4x3().make(sc[0],0,0,0,sc[1],0,0,0,sc[2],0,0,0)); 78 | if (this.scalePivot) 79 | this.local.multiply(M4x3().makeTranslate(-this.scalePivot[0], -this.scalePivot[1],- this.scalePivot[2])); 80 | } 81 | 82 | this.visible = vis; 83 | } 84 | 85 | this.getAnimatedTransformation = function(animation) { 86 | var translation = Copy3V(this.translate); 87 | var scale = Copy3V(this.scale); 88 | var rotation = Copy3V(this.rotate); 89 | var visibility = true; 90 | var animNode = animation ? animation[this.name] : null; 91 | if (animNode) { 92 | var t = animation.time; 93 | 94 | var attrNode = animNode['translate']; 95 | if (attrNode) { 96 | if (attrNode['X']) 97 | translation[0] = evaluateAttribute(attrNode, 'X', t); 98 | if (attrNode['Y']) 99 | translation[1] = evaluateAttribute(attrNode, 'Y', t); 100 | if (attrNode['Z']) 101 | translation[2] = evaluateAttribute(attrNode, 'Z', t); 102 | } 103 | 104 | attrNode = animNode['rotateX']; 105 | if (attrNode) 106 | rotation[0] = evaluateAttribute(attrNode, 'ANGLE', t); 107 | 108 | attrNode = animNode['rotateY']; 109 | if (attrNode) 110 | rotation[1] = evaluateAttribute(attrNode, 'ANGLE', t); 111 | 112 | attrNode = animNode['rotateZ']; 113 | if (attrNode) 114 | rotation[2] = evaluateAttribute(attrNode, 'ANGLE', t); 115 | 116 | var attrNode = animNode['scale']; 117 | if (attrNode) { 118 | if (attrNode['X']) 119 | scale[0] = evaluateAttribute(attrNode, 'X', t); 120 | if (attrNode['Y']) 121 | scale[1] = evaluateAttribute(attrNode, 'Y', t); 122 | if (attrNode['Z']) 123 | scale[2] = evaluateAttribute(attrNode, 'Z', t); 124 | } 125 | 126 | attrNode = animNode['visibility']; 127 | if (attrNode) 128 | visibility = evaluateAttribute(attrNode, 'VALUE', t); 129 | } 130 | return { 131 | translation: translation, 132 | scale: scale, 133 | rotation: rotation, 134 | visibility: visibility 135 | }; 136 | } 137 | 138 | this.update = function(scene, acc) { 139 | // Current animation 140 | var t1 = this.getAnimatedTransformation(scene.animation); 141 | 142 | if (scene.animation.fadeTime < scene.animation.fadeMax && scene.animation.fadeAnim) { 143 | // Weight factors for the fade in/out animations 144 | var fadeAnim = scene.animation.fadeAnim; 145 | var w1 = scene.animation.fadeTime / scene.animation.fadeMax; 146 | var w2 = 1.0 - w1; 147 | 148 | // Old animation 149 | var t2 = this.getAnimatedTransformation(fadeAnim); 150 | 151 | // Blend animations 152 | var translation = [w1 * t1.translation[0] + w2 * t2.translation[0], 153 | w1 * t1.translation[1] + w2 * t2.translation[1], 154 | w1 * t1.translation[2] + w2 * t2.translation[2]]; 155 | var rotation = [w1 * t1.rotation[0] + w2 * t2.rotation[0], 156 | w1 * t1.rotation[1] + w2 * t2.rotation[1], 157 | w1 * t1.rotation[2] + w2 * t2.rotation[2]]; 158 | var scale = [w1 * t1.scale[0] + w2 * t2.scale[0], 159 | w1 * t1.scale[1] + w2 * t2.scale[1], 160 | w1 * t1.scale[2] + w2 * t2.scale[2]]; 161 | var visibility = t1.visibility || t2.visibility; 162 | this.calculateLocalTransform(translation, rotation, scale, [1.0 / acc.getX().magnitude(), 1.0 / acc.getY().magnitude(), 1.0 / acc.getZ().magnitude()], visibility); 163 | } else { 164 | this.calculateLocalTransform(t1.translation, t1.rotation, t1.scale, [1.0 / acc.getX().magnitude(), 1.0 / acc.getY().magnitude(), 1.0 / acc.getZ().magnitude()], t1.visibility); 165 | } 166 | 167 | var accumulated = acc.copy().multiply(this.getLocalTransform()); 168 | 169 | this.cacheAccumulatedTfrm(scene, accumulated); 170 | 171 | if (this.children) 172 | for (var i = 0; i < this.children.length; ++i) 173 | this.children[i].update(scene, accumulated); 174 | } 175 | 176 | this.cacheAccumulatedTfrm = function(scene, accumulated) { 177 | } 178 | 179 | this.setParentPointers = function(parent) { 180 | this.parent = parent; 181 | if (this.children) 182 | for (var i = 0; i < this.children.length; ++i) 183 | this.children[i].setParentPointers(this); 184 | } 185 | 186 | this.setupLODJoints = function(scene) { 187 | if (this.children) 188 | for (var i = 0; i < this.children.length; ++i) 189 | this.children[i].setupLODJoints(scene); 190 | } 191 | 192 | this.setupLODMeshes = function(lod) { 193 | if (this.children) 194 | for (var i = 0; i < this.children.length; ++i) 195 | this.children[i].setupLODMeshes(lod); 196 | } 197 | 198 | this.getLocalTransform = function() { 199 | return this.local.copy(); 200 | } 201 | 202 | this.getAccumulatedTransform = function() { 203 | var parentTfrm = this.parent ? this.parent.getAccumulatedTransform() : I4x3(); 204 | return parentTfrm.multiply(this.getLocalTransform()); 205 | } 206 | 207 | this.findNode = function(name) { 208 | if (this.name == name) 209 | return this; 210 | if (this.children) 211 | for (var i = 0; i < this.children.length; ++i) { 212 | var n = this.children[i].findNode(name); 213 | if (n) 214 | return n; 215 | } 216 | return null; 217 | } 218 | 219 | this.findNodesByType = function(nodes, type, returnParents, parent) { 220 | if (this.type == type) 221 | if (returnParents) 222 | nodes.push(parent); 223 | else 224 | nodes.push(this); 225 | if (this.children) 226 | for (var i = 0; i < this.children.length; ++i) 227 | this.children[i].findNodesByType(nodes, type, returnParents, this); 228 | } 229 | 230 | this.getCoordinatePlaneIntersection = function() { 231 | var acc = this.getAccumulatedTransform(); 232 | var P0 = acc.getT().scale(-1); 233 | var u = acc.getZ().scale(-1); 234 | var x = Vec3().make(1,0,0); 235 | var y = Vec3().make(0,1,0); 236 | var z = Vec3().make(0,0,1); 237 | var xz = u.y == 0 ? -1 : y.dot(P0) / y.dot(u); 238 | var xy = u.z == 0 ? -1 : z.dot(P0) / z.dot(u); 239 | var yz = u.x == 0 ? -1 : x.dot(P0) / x.dot(u); 240 | var s = -1; 241 | if (xz > 0 && (xz < s || s == -1)) 242 | s = xz; 243 | if (xy > 0 && (xy < s || s == -1)) 244 | s = xy; 245 | if (yz > 0 && (yz < s || s == -1)) 246 | s = yz; 247 | if (s < 0) 248 | s = 10; 249 | return acc.getT().add(u.scale(s)); 250 | } 251 | 252 | }; 253 | 254 | function Node(scene, template) { 255 | Object.defineProperty(this, 'name', { value : template.name }); 256 | Object.defineProperty(this, 'type', { value : template.type }); 257 | this.bindTranslation = template.translate; 258 | this.bindRotation = template.rotate; 259 | Object.defineProperty(this, 'bindScale', { value : template.scale}); 260 | Object.defineProperty(this, 'rotatePivot', { value : template.rotatePivot}); 261 | Object.defineProperty(this, 'scalePivot', { value : template.scalePivot}); 262 | this.visible = true; 263 | this.children = template.children; 264 | this.local = I4x3(); 265 | }; 266 | 267 | Node.prototype = new NodePrototype(); 268 | 269 | -------------------------------------------------------------------------------- /js/PreProcess.js: -------------------------------------------------------------------------------- 1 | function buildBoolExpr(expr) { 2 | var identifier = /([A-Za-z_][A-Za-z_0-9]*)/g; 3 | var boolExpr = /[ \t]*\(?(([ \t]*[A-Za-z_][A-Za-z_0-9]*[ \t]*(((\|\|)|(&&))[ \t]*\(?)?)\)?)+[ \t]*\)?[ \t]*/; 4 | // Sanitize the input. It doesn't mean it's avalid boolean expression, but at least it's harmless. 5 | var valid = boolExpr.exec(expr); 6 | if (!valid || valid[0].length != expr.length) 7 | return ''; 8 | var res = valid[0]; 9 | // Add scope. to all the identifiers so we don't have to pollute the global namespace. 10 | res = res.replace(identifier, 'scope.$1'); 11 | return res; 12 | } 13 | 14 | function doPreprocess(txt, defined) { 15 | // Do line based preprocessing. 16 | lines = txt.split('\n'); 17 | 18 | // RegExps to match preprocessor currentDirectives. 19 | var ifdef = /^[ \t]*#ifdef[ \t]+(.*)/; 20 | var ifndef = /^[ \t]*#ifndef[ \t]+(.*)/; 21 | var helse = /^[ \t]*#else/; 22 | var endif = /^[ \t]*#endif/; 23 | var preprocessor = /^[ \t]*#(#(ifdef|ifndef|endif|else|define).*)/; 24 | 25 | // Build a list of currentDirectives containing the preprocessor currentDirective and it's start and end line. 26 | var currentDirectives = []; 27 | for (var i = 0; i < lines.length; ++i) { 28 | // If it's a pass-through currentDirective, strip one # and write it to the line. 29 | var res = preprocessor.exec(lines[i]); 30 | if (res) { 31 | lines[i] = res[1]; 32 | continue; 33 | } 34 | // If it's an #ifdef. 35 | res = ifdef.exec(lines[i]); 36 | if (res) { 37 | // Sanitize the expression and add it to the currentDirectives list. 38 | var expr = buildBoolExpr(res[1]); 39 | if (expr.length == 0) { 40 | alert('Preprocess, invalid boolean expression ' + res[1]); 41 | return; 42 | } 43 | // Set the line to the directive it corresponds to. 44 | lines[i] = currentDirectives.length; 45 | currentDirectives.push({'type' : 'ifdef', 'label' : expr, 'start' : i, 'helse' : -1, 'end' : -1}); 46 | continue; 47 | } 48 | 49 | // If it's an #ifndef. 50 | res = ifndef.exec(lines[i]); 51 | if (res) { 52 | // Sanitize the expression and add it to the currentDirectives list. 53 | var expr = buildBoolExpr(res[1]); 54 | if (expr.length == 0) { 55 | alert('Preprocess, invalid boolean expression ' + res[1]); 56 | return; 57 | } 58 | // Set the line to the directive it corresponds to. 59 | lines[i] = currentDirectives.length; 60 | currentDirectives.push({'type' : 'ifndef', 'label' : expr, 'start' : i, 'helse' : -1, 'end' : -1}); 61 | continue; 62 | } 63 | 64 | // If it's an #else. 65 | res = helse.test(lines[i]); 66 | if (res) { 67 | // Find the matching directive and set its else line. 68 | var match = false; 69 | for (var j = currentDirectives.length - 1; j >= 0; --j) { 70 | if (currentDirectives[j].end == -1 && currentDirectives[j].helse == -1) { 71 | currentDirectives[j].helse = i; 72 | lines[i] = j; 73 | match = true; 74 | break; 75 | } 76 | } 77 | if (!match) { 78 | alert("Preprocess, couldn't find matching #ifdef/#ifndef to #else."); 79 | return; 80 | } 81 | continue; 82 | } 83 | 84 | // If it's an #endif. 85 | res = endif.test(lines[i]); 86 | if (res) { 87 | // Find the matching directive and set its end line. 88 | var match = false; 89 | for (var j = currentDirectives.length - 1; j >= 0; --j) { 90 | if (currentDirectives[j].end == -1) { 91 | currentDirectives[j].end = i; 92 | lines[i] = j; 93 | match = true; 94 | break; 95 | } 96 | } 97 | if (!match) { 98 | alert("Preprocess, couldn't find matching #ifdef/#ifndef to #endif."); 99 | return; 100 | } 101 | continue; 102 | } 103 | } 104 | // Check that all the currentDirectives had a matching endif. 105 | for (var j = 0; j < currentDirectives.length; ++j) { 106 | if (currentDirectives[j].end == -1) { 107 | alert("Preprocess, couldn't find matching #endif for " + currentDirectives[j].type + " " + currentDirectives[j].label); 108 | return; 109 | } 110 | } 111 | // Build the outdata by iterating over the lines. 112 | var res = ''; 113 | var currentDir = 0; 114 | for (var j = 0; j < lines.length; ++j) { 115 | // Update the current currentDirective. 116 | if ((typeof lines[j]) == 'number') { 117 | currentDir = lines[j]; 118 | } 119 | // If we're on a directive line. 120 | var atElse = currentDir < currentDirectives.length && j == currentDirectives[currentDir].helse; 121 | var atIf = currentDir < currentDirectives.length && j == currentDirectives[currentDir].start; 122 | 123 | if (atIf || atElse) { 124 | // Create a scope object and add all the defines to it.. 125 | var scope = {}; 126 | for (var k = 0; k < defined.length; ++k) { 127 | scope[defined[k].key] = defined[k].value; 128 | } 129 | // Calculate the boolean expression. 130 | eval('var isDefined = ' + currentDirectives[currentDir].label + ';'); 131 | 132 | var atIfNot = currentDirectives[currentDir].type == 'ifndef'; 133 | 134 | // Check if we should jump to the end of this directive. 135 | if (atIf && !(atIfNot ^ isDefined) || atElse) { 136 | j = atIf && currentDirectives[currentDir].helse != -1 ? currentDirectives[currentDir].helse : currentDirectives[currentDir].end; 137 | continue; 138 | } 139 | } 140 | // Anything that's not a directive line should be added to the result. 141 | if ((typeof lines[j]) != 'number') { 142 | res += lines[j] + '\n'; 143 | } 144 | } 145 | 146 | var preproc = ''; 147 | for (var k = 0; k < defined.length; ++k) { 148 | preproc += '#define ' + defined[k].key + ' ' + defined[k].value + '\n'; 149 | } 150 | 151 | return preproc + res; 152 | } -------------------------------------------------------------------------------- /js/TextureCache.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | window.textureCache = { 4 | loadedTextures : [], 5 | 6 | newTextureLoaded : function (filename) { 7 | var tex = this.loadedTextures[filename]; 8 | gl.bindTexture(gl.TEXTURE_2D, tex.texture); 9 | gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); 10 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex.image); 11 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 12 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR); 13 | gl.generateMipmap(gl.TEXTURE_2D); 14 | gl.bindTexture(gl.TEXTURE_2D, null); 15 | InfoMessage('New texture ' + filename + ' is loaded.'); 16 | for(var l in tex.listeners) { 17 | tex.listeners[l](tex.texture); 18 | } 19 | tex.listeners = []; 20 | }, 21 | 22 | loadTexture : function (filename, callback) { 23 | if (this.loadedTextures[filename]) { 24 | if (this.loadedTextures[filename].texture.outstandingRequests) { 25 | this.loadedTextures[filename].listeners.push(callback); 26 | } else { 27 | callback(filename); 28 | } 29 | } else { 30 | var that = this; 31 | var tex = gl.createTexture(); 32 | var image = new Image(); 33 | image.onload = function () { 34 | that.newTextureLoaded(filename); 35 | } 36 | this.loadedTextures[filename] = {'texture' : tex, 'image' : image, 'listeners' : [callback]}; 37 | image.src = filename; 38 | } 39 | return this.loadedTextures[filename].texture; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /js/VectorMath.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/js/VectorMath.js -------------------------------------------------------------------------------- /json/anim-idle.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "RIG_solo", "translate" : [0, 0, 0], "rotate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 5 | { "type" : "node", "name" : "RIG_joints_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 6 | { "type" : "joint", "name" : "bj_root", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [0.013951, 0, 0], "postRotate" : [0.7803711, 0, 0], "children" : [ 7 | { "type" : "joint", "name" : "bj_COG", "bindTranslation" :[0.9041184, 10.6207, -1.179358], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.7618697, 0, 0], "postRotate" : [0.7618697, 0, 0], "children" : [ 8 | { "type" : "joint", "name" : "bj_spineRoot", "bindTranslation" :[0, 0, 0], "bindRotation" : [-2.963601, -8.691995, -2.910036], "jointOrient" : [-179.1666, 0, 180], "postRotate" : [-3.750809, 0, 0], "children" : [ 9 | { "type" : "joint", "name" : "bj_chest", "bindTranslation" :[0, 1.710774, 0.1100414], "bindRotation" : [-3.408639, -8.016404, -4.652469], "jointOrient" : [3.681163, 0, 0], "postRotate" : [-8.20581, 0, 0], "children" : [ 10 | { "type" : "joint", "name" : "bj_neckRoot", "bindTranslation" :[0, 2.872519, -0.2603679], "bindRotation" : [11.07234, 5.602363, 1.149489], "jointOrient" : [25.42642, 0, 0], "postRotate" : [-27.22967, 0, 0], "children" : [ 11 | { "type" : "joint", "name" : "bj_head", "bindTranslation" :[0, 0.8412964, 0.5454057], "bindRotation" : [1.603523, 8.589031, 2.909886], "jointOrient" : [9.970071, 0, 0], "postRotate" : [0, 0, 0]} 12 | ]}, 13 | { "type" : "joint", "name" : "bj_L_clavicle", "bindTranslation" :[0.3181662, 2.147406, 0.03433269], "bindRotation" : [-4.166288, -0.07296783, -1.808549], "jointOrient" : [0.057488, 8.032577, -89.48751], "postRotate" : [178.5763, -88.61498, 179.7818], "children" : [ 14 | { "type" : "joint", "name" : "bj_L_shoulder", "bindTranslation" :[-0.3487489, 1.85798, -0.2393546], "bindRotation" : [-19.49003, 5.670183, -18.07758], "jointOrient" : [-93.73047, 45.64685, -92.62478], "postRotate" : [0, 0, 0], "children" : [ 15 | { "type" : "joint", "name" : "bj_L_elbow", "bindTranslation" :[0.05880454, 2.747025, 0.05386012], "bindRotation" : [-1.356114, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, -37.22785, 0], "children" : [ 16 | { "type" : "joint", "name" : "bj_L_wrist", "bindTranslation" :[-0.1778838, 2.371249, -0.2293983], "bindRotation" : [0, 0, 0], "jointOrient" : [-7.693209, 39.00606, -2.240701], "postRotate" : [9.006295, -39.32423, -3.586556]} 17 | ]} 18 | ]} 19 | ]}, 20 | { "type" : "joint", "name" : "bj_R_clavicle", "bindTranslation" :[-0.318166, 2.147453, 0.0343399], "bindRotation" : [5.236345, -2.169193, -1.917371], "jointOrient" : [-179.9425, -8.032577, 89.48751], "postRotate" : [0, 0, 0], "children" : [ 21 | { "type" : "joint", "name" : "bj_R_shoulder", "bindTranslation" :[-0.3008852, -1.850326, 0.3417481], "bindRotation" : [-21.71049, 10.40771, -26.72171], "jointOrient" : [-0.8608915, 0.8678666, -45.9416], "postRotate" : [0, 0, 0], "children" : [ 22 | { "type" : "joint", "name" : "bj_R_elbow", "bindTranslation" :[-0.0588076, -2.747023, -0.05386006], "bindRotation" : [-9.769515, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, 0, 0], "children" : [ 23 | { "type" : "joint", "name" : "bj_R_wrist", "bindTranslation" :[0.00285297, -2.371255, 0.2902752], "bindRotation" : [0, 0, 0], "jointOrient" : [-6.337167, 1.798823, -1.741885], "postRotate" : [0, 0, 0]} 24 | ]} 25 | ]} 26 | ]}, 27 | { "type" : "joint", "name" : "bj_harness_main", "bindTranslation" :[0, 2.784781, 0.188085], "bindRotation" : [0, 0, 0], "jointOrient" : [171.7636, 0, 180], "postRotate" : [0, 0, 0], "children" : [ 28 | { "type" : "joint", "name" : "bj_harness_padBig", "bindTranslation" :[-1.6953, 0.141024, 0.2607302], "bindRotation" : [0, 0, 0], "jointOrient" : [1.975576, 6.676362, 106.5253], "postRotate" : [6.961252, 0, -106.4101]}, 29 | { "type" : "joint", "name" : "bj_harness_padSmall", "bindTranslation" :[1.641814, 0.141024, 0.3744311], "bindRotation" : [0, 0, 0], "jointOrient" : [2.037478, -6.657809, -107.0585], "postRotate" : [6.961252, 0, 106.94]} 30 | ]} 31 | ]} 32 | ]}, 33 | { "type" : "joint", "name" : "bj_pelvis", "bindTranslation" :[0, 0, 0], "bindRotation" : [-8.403936, 22.38631, -4.245747], "jointOrient" : [179.0654, 0, 0], "postRotate" : [1.728904, 0, 0], "children" : [ 34 | { "type" : "joint", "name" : "bj_L_hip", "bindTranslation" :[-1.093311, 1.517099, -0.03888182], "bindRotation" : [15.71557, -35.28881, 17.05604], "jointOrient" : [-1.671761, 0, 0], "postRotate" : [3.99778, 0, 0], "children" : [ 35 | { "type" : "joint", "name" : "bj_L_knee", "bindTranslation" :[0, 4.464725, -0.3169275], "bindRotation" : [-15.17341, 7.71267e-4, -0.01167107], "jointOrient" : [-13.69354, 0.04425968, -0.001797784], "postRotate" : [0.2320798, 0, 180], "children" : [ 36 | { "type" : "joint", "name" : "bj_L_ankle", "bindTranslation" :[-6.08286e-4, -4.110774, 0.04058781], "bindRotation" : [-1.60148, -13.19133, -6.44529], "jointOrient" : [77.73943, -0.0433915, 179.9911], "postRotate" : [0, 0, 0], "children" : [ 37 | { "type" : "joint", "name" : "bj_L_toe", "bindTranslation" :[0, 1.741616, -0.1062748], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 38 | { "type" : "joint", "name" : "bj_L_toeTip", "bindTranslation" :[0, 0.7852713, -0.02177926], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 39 | ]} 40 | ]} 41 | ]} 42 | ]}, 43 | { "type" : "joint", "name" : "bj_R_hip", "bindTranslation" :[1.09331, 1.517104, -0.03888154], "bindRotation" : [6.112601, -21.22754, 1.754857], "jointOrient" : [178.3282, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 44 | { "type" : "joint", "name" : "bj_R_knee", "bindTranslation" :[0, -4.475952, 0.00488591], "bindRotation" : [-13.57756, 8.36007e-4, -0.01043904], "jointOrient" : [-9.695761, 0.04427732, 0.001292279], "postRotate" : [0, 0, 0], "children" : [ 45 | { "type" : "joint", "name" : "bj_R_ankle", "bindTranslation" :[-6.08285e-4, -4.110905, -0.02393664], "bindRotation" : [11.84254, -7.188511, -3.33449], "jointOrient" : [77.50735, -0.04342722, -0.008730851], "postRotate" : [0, 0, 0], "children" : [ 46 | { "type" : "joint", "name" : "bj_R_toe", "bindTranslation" :[0, -1.741618, 0.1062741], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 47 | { "type" : "joint", "name" : "bj_R_toeTip", "bindTranslation" :[0, -0.785268, 0.02177917], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 48 | ]} 49 | ]} 50 | ]} 51 | ]}, 52 | { "type" : "joint", "name" : "bj_hipPlate", "bindTranslation" :[1.606056, 0.3496374, 0.548943], "bindRotation" : [0, 0, -8.941091], "jointOrient" : [-4.313083, -25.6316, -11.85807], "postRotate" : [10.22947, 23.99762, 15.01932]} 53 | ]} 54 | ]} 55 | ]} 56 | ]} 57 | ]} 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /json/anim-turn.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "RIG_solo", "translate" : [0, 0, 0], "rotate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 5 | { "type" : "node", "name" : "RIG_joints_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 6 | { "type" : "joint", "name" : "bj_root", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [0.013951, 0, 0], "postRotate" : [0.7803711, 0, 0], "children" : [ 7 | { "type" : "joint", "name" : "bj_COG", "bindTranslation" :[0.9399333, 10.65329, -1.203763], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.7618697, 0, 0], "postRotate" : [0.7618697, 0, 0], "children" : [ 8 | { "type" : "joint", "name" : "bj_spineRoot", "bindTranslation" :[0, 0, 0], "bindRotation" : [-3.825912, -9.884205, -2.414273], "jointOrient" : [-179.1666, 0, 180], "postRotate" : [-3.750809, 0, 0], "children" : [ 9 | { "type" : "joint", "name" : "bj_chest", "bindTranslation" :[0, 1.710774, 0.1100414], "bindRotation" : [-4.640172, -9.205235, -3.85364], "jointOrient" : [3.681163, 0, 0], "postRotate" : [-8.20581, 0, 0], "children" : [ 10 | { "type" : "joint", "name" : "bj_neckRoot", "bindTranslation" :[0, 2.872519, -0.2603679], "bindRotation" : [11.35413, 5.013032, 1.373343], "jointOrient" : [25.42642, 0, 0], "postRotate" : [-27.22967, 0, 0], "children" : [ 11 | { "type" : "joint", "name" : "bj_head", "bindTranslation" :[0, 0.8412964, 0.5454057], "bindRotation" : [2.257989, 8.478669, 2.849196], "jointOrient" : [9.970071, 0, 0], "postRotate" : [0, 0, 0]} 12 | ]}, 13 | { "type" : "joint", "name" : "bj_L_clavicle", "bindTranslation" :[0.3181662, 2.147406, 0.03433269], "bindRotation" : [-4.166288, -0.07296783, -1.808549], "jointOrient" : [0.057488, 8.032577, -89.48751], "postRotate" : [178.5763, -88.61498, 179.7818], "children" : [ 14 | { "type" : "joint", "name" : "bj_L_shoulder", "bindTranslation" :[-0.3487489, 1.85798, -0.2393546], "bindRotation" : [-17.55881, 9.889025, -16.41926], "jointOrient" : [-93.73047, 45.64685, -92.62478], "postRotate" : [0, 0, 0], "children" : [ 15 | { "type" : "joint", "name" : "bj_L_elbow", "bindTranslation" :[0.05880454, 2.747025, 0.05386012], "bindRotation" : [0, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, -37.22785, 0], "children" : [ 16 | { "type" : "joint", "name" : "bj_L_wrist", "bindTranslation" :[-0.1778838, 2.371249, -0.2293983], "bindRotation" : [0, 0, 0], "jointOrient" : [-7.693209, 39.00606, -2.240701], "postRotate" : [9.006295, -39.32423, -3.586556]} 17 | ]} 18 | ]} 19 | ]}, 20 | { "type" : "joint", "name" : "bj_R_clavicle", "bindTranslation" :[-0.318166, 2.147453, 0.0343399], "bindRotation" : [5.236345, -2.169193, -1.917371], "jointOrient" : [-179.9425, -8.032577, 89.48751], "postRotate" : [0, 0, 0], "children" : [ 21 | { "type" : "joint", "name" : "bj_R_shoulder", "bindTranslation" :[-0.3008852, -1.850326, 0.3417481], "bindRotation" : [-19.40069, 15.88588, -22.88657], "jointOrient" : [-0.8608915, 0.8678666, -45.9416], "postRotate" : [0, 0, 0], "children" : [ 22 | { "type" : "joint", "name" : "bj_R_elbow", "bindTranslation" :[-0.0588076, -2.747023, -0.05386006], "bindRotation" : [-9.307612, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, 0, 0], "children" : [ 23 | { "type" : "joint", "name" : "bj_R_wrist", "bindTranslation" :[0.00285297, -2.371255, 0.2902752], "bindRotation" : [0, 0, 0], "jointOrient" : [-6.337167, 1.798823, -1.741885], "postRotate" : [0, 0, 0]} 24 | ]} 25 | ]} 26 | ]}, 27 | { "type" : "joint", "name" : "bj_harness_main", "bindTranslation" :[0, 2.784781, 0.188085], "bindRotation" : [0, 0, 0], "jointOrient" : [171.7636, 0, 180], "postRotate" : [0, 0, 0], "children" : [ 28 | { "type" : "joint", "name" : "bj_harness_padBig", "bindTranslation" :[-1.6953, 0.141024, 0.2607302], "bindRotation" : [0, 0, 0], "jointOrient" : [1.975576, 6.676362, 106.5253], "postRotate" : [6.961252, 0, -106.4101]}, 29 | { "type" : "joint", "name" : "bj_harness_padSmall", "bindTranslation" :[1.641814, 0.141024, 0.3744311], "bindRotation" : [0, 0, 0], "jointOrient" : [2.037478, -6.657809, -107.0585], "postRotate" : [6.961252, 0, 106.94]} 30 | ]} 31 | ]} 32 | ]}, 33 | { "type" : "joint", "name" : "bj_pelvis", "bindTranslation" :[0, 0, 0], "bindRotation" : [-8.063894, 22.84842, -3.381755], "jointOrient" : [179.0654, 0, 0], "postRotate" : [1.728904, 0, 0], "children" : [ 34 | { "type" : "joint", "name" : "bj_L_hip", "bindTranslation" :[-1.093311, 1.517099, -0.03888182], "bindRotation" : [13.69268, -35.54758, 16.38906], "jointOrient" : [-1.671761, 0, 0], "postRotate" : [3.99778, 0, 0], "children" : [ 35 | { "type" : "joint", "name" : "bj_L_knee", "bindTranslation" :[0, 4.464725, -0.3169275], "bindRotation" : [-11.94188, 8.6673e-4, -0.009174889], "jointOrient" : [-13.69354, 0.04425968, -0.001797784], "postRotate" : [0.2320798, 0, 180], "children" : [ 36 | { "type" : "joint", "name" : "bj_L_ankle", "bindTranslation" :[-6.08286e-4, -4.110774, 0.04058781], "bindRotation" : [-3.023765, -13.45412, -6.086591], "jointOrient" : [77.73943, -0.0433915, 179.9911], "postRotate" : [0, 0, 0], "children" : [ 37 | { "type" : "joint", "name" : "bj_L_toe", "bindTranslation" :[0, 1.741616, -0.1062748], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 38 | { "type" : "joint", "name" : "bj_L_toeTip", "bindTranslation" :[0, 0.7852713, -0.02177926], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 39 | ]} 40 | ]} 41 | ]} 42 | ]}, 43 | { "type" : "joint", "name" : "bj_R_hip", "bindTranslation" :[1.09331, 1.517104, -0.03888154], "bindRotation" : [5.24327, -20.85807, 2.645707], "jointOrient" : [178.3282, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 44 | { "type" : "joint", "name" : "bj_R_knee", "bindTranslation" :[0, -4.475952, 0.00488591], "bindRotation" : [-12.10939, 8.65243e-4, -0.009304386], "jointOrient" : [-9.695761, 0.04427732, 0.001292279], "postRotate" : [0, 0, 0], "children" : [ 45 | { "type" : "joint", "name" : "bj_R_ankle", "bindTranslation" :[-6.08285e-4, -4.110905, -0.02393664], "bindRotation" : [11.23463, -7.266505, -3.253104], "jointOrient" : [77.50735, -0.04342722, -0.008730851], "postRotate" : [0, 0, 0], "children" : [ 46 | { "type" : "joint", "name" : "bj_R_toe", "bindTranslation" :[0, -1.741618, 0.1062741], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 47 | { "type" : "joint", "name" : "bj_R_toeTip", "bindTranslation" :[0, -0.785268, 0.02177917], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 48 | ]} 49 | ]} 50 | ]} 51 | ]}, 52 | { "type" : "joint", "name" : "bj_hipPlate", "bindTranslation" :[1.606056, 0.3496374, 0.548943], "bindRotation" : [0, 0, -8.941091], "jointOrient" : [-4.313083, -25.6316, -11.85807], "postRotate" : [10.22947, 23.99762, 15.01932]} 53 | ]} 54 | ]} 55 | ]} 56 | ]} 57 | ]} 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /json/anim-walk.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "RIG_solo", "translate" : [0, 0, 0], "rotate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 5 | { "type" : "node", "name" : "RIG_joints_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 6 | { "type" : "joint", "name" : "bj_root", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [0.013951, 0, 0], "postRotate" : [0.7803711, 0, 0], "children" : [ 7 | { "type" : "joint", "name" : "bj_COG", "bindTranslation" :[0.2280533, 10.97254, -0.7596083], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.7618697, 0, 0], "postRotate" : [0.7618697, 0, 0], "children" : [ 8 | { "type" : "joint", "name" : "bj_spineRoot", "bindTranslation" :[0, 0, 0], "bindRotation" : [8.341335, 2.311583, -0.7121736], "jointOrient" : [-179.1666, 0, 180], "postRotate" : [-3.750809, 0, 0], "children" : [ 9 | { "type" : "joint", "name" : "bj_chest", "bindTranslation" :[0, 1.710774, 0.1100414], "bindRotation" : [-2.636477, 6.541734, -3.01], "jointOrient" : [3.681163, 0, 0], "postRotate" : [-8.20581, 0, 0], "children" : [ 10 | { "type" : "joint", "name" : "bj_neckRoot", "bindTranslation" :[0, 2.872519, -0.2603679], "bindRotation" : [-3.124, 0, 0], "jointOrient" : [25.42642, 0, 0], "postRotate" : [-27.22967, 0, 0], "children" : [ 11 | { "type" : "joint", "name" : "bj_head", "bindTranslation" :[0, 0.8412964, 0.5454057], "bindRotation" : [2.045911, -6.053025, 1.191411], "jointOrient" : [9.970071, 0, 0], "postRotate" : [0, 0, 0]} 12 | ]}, 13 | { "type" : "joint", "name" : "bj_L_clavicle", "bindTranslation" :[0.3181662, 2.147406, 0.03433269], "bindRotation" : [-4.218463, 0, -1.133287], "jointOrient" : [0.057488, 8.032577, -89.48751], "postRotate" : [178.5763, -88.61498, 179.7818], "children" : [ 14 | { "type" : "joint", "name" : "bj_L_shoulder", "bindTranslation" :[-0.3487489, 1.85798, -0.2393546], "bindRotation" : [-7.467192, 3.634225, -25.27533], "jointOrient" : [-93.73047, 45.64685, -92.62478], "postRotate" : [0, 0, 0], "children" : [ 15 | { "type" : "joint", "name" : "bj_L_elbow", "bindTranslation" :[0.05880454, 2.747025, 0.05386012], "bindRotation" : [-32.15654, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, -37.22785, 0], "children" : [ 16 | { "type" : "joint", "name" : "bj_L_wrist", "bindTranslation" :[-0.1778838, 2.371249, -0.2293983], "bindRotation" : [0.7229207, 3.694019, -4.60699], "jointOrient" : [-7.693209, 39.00606, -2.240701], "postRotate" : [9.006295, -39.32423, -3.586556]} 17 | ]} 18 | ]} 19 | ]}, 20 | { "type" : "joint", "name" : "bj_R_clavicle", "bindTranslation" :[-0.318166, 2.147453, 0.0343399], "bindRotation" : [2.072967, 0, 0.8576726], "jointOrient" : [-179.9425, -8.032577, 89.48751], "postRotate" : [0, 0, 0], "children" : [ 21 | { "type" : "joint", "name" : "bj_R_shoulder", "bindTranslation" :[-0.3008852, -1.850326, 0.3417481], "bindRotation" : [10.4219, 2.484322, -32.23386], "jointOrient" : [-0.8608915, 0.8678666, -45.9416], "postRotate" : [0, 0, 0], "children" : [ 22 | { "type" : "joint", "name" : "bj_R_elbow", "bindTranslation" :[-0.0588076, -2.747023, -0.05386006], "bindRotation" : [-15.20077, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, 0, 0], "children" : [ 23 | { "type" : "joint", "name" : "bj_R_wrist", "bindTranslation" :[0.00285297, -2.371255, 0.2902752], "bindRotation" : [-1.712589, 30.1959, -6.440643], "jointOrient" : [-6.337167, 1.798823, -1.741885], "postRotate" : [0, 0, 0]} 24 | ]} 25 | ]} 26 | ]}, 27 | { "type" : "joint", "name" : "bj_harness_main", "bindTranslation" :[0, 2.784781, 0.188085], "bindRotation" : [0, 0, 0], "jointOrient" : [171.7636, 0, 180], "postRotate" : [0, 0, 0], "children" : [ 28 | { "type" : "joint", "name" : "bj_harness_padBig", "bindTranslation" :[-1.6953, 0.141024, 0.2607302], "bindRotation" : [0, 0, 0], "jointOrient" : [1.975576, 6.676362, 106.5253], "postRotate" : [6.961252, 0, -106.4101]}, 29 | { "type" : "joint", "name" : "bj_harness_padSmall", "bindTranslation" :[1.641814, 0.141024, 0.3744311], "bindRotation" : [0, 0, 0], "jointOrient" : [2.037478, -6.657809, -107.0585], "postRotate" : [6.961252, 0, 106.94]} 30 | ]} 31 | ]} 32 | ]}, 33 | { "type" : "joint", "name" : "bj_pelvis", "bindTranslation" :[0, 0, 0], "bindRotation" : [-2.764754, 6.832295, -0.05965222], "jointOrient" : [179.0654, 0, 0], "postRotate" : [1.728904, 0, 0], "children" : [ 34 | { "type" : "joint", "name" : "bj_L_hip", "bindTranslation" :[-1.093311, 1.517099, -0.03888182], "bindRotation" : [22.34091, -21.39418, -3.0507], "jointOrient" : [-1.671761, 0, 0], "postRotate" : [3.99778, 0, 0], "children" : [ 35 | { "type" : "joint", "name" : "bj_L_knee", "bindTranslation" :[0, 4.464725, -0.3169275], "bindRotation" : [2.451084, -4.13119e-4, 0.00184924], "jointOrient" : [-13.69354, 0.04425968, -0.001797784], "postRotate" : [0.2320798, 0, 180], "children" : [ 36 | { "type" : "joint", "name" : "bj_L_ankle", "bindTranslation" :[-6.08286e-4, -4.110774, 0.04058781], "bindRotation" : [-7.071533, 1.860115, 0.5475299], "jointOrient" : [77.73943, -0.0433915, 179.9911], "postRotate" : [0, 0, 0], "children" : [ 37 | { "type" : "joint", "name" : "bj_L_toe", "bindTranslation" :[0, 1.741616, -0.1062748], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 38 | { "type" : "joint", "name" : "bj_L_toeTip", "bindTranslation" :[0, 0.7852713, -0.02177926], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 39 | ]} 40 | ]} 41 | ]} 42 | ]}, 43 | { "type" : "joint", "name" : "bj_R_hip", "bindTranslation" :[1.09331, 1.517104, -0.03888154], "bindRotation" : [-26.5712, -4.378678, 7.36078], "jointOrient" : [178.3282, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 44 | { "type" : "joint", "name" : "bj_R_knee", "bindTranslation" :[0, -4.475952, 0.00488591], "bindRotation" : [9.299605, -0.001981651, 0.006902959], "jointOrient" : [-9.695761, 0.04427732, 0.001292279], "postRotate" : [0, 0, 0], "children" : [ 45 | { "type" : "joint", "name" : "bj_R_ankle", "bindTranslation" :[-6.08285e-4, -4.110905, -0.02393664], "bindRotation" : [-24.04984, -8.4472, -1.886986], "jointOrient" : [77.50735, -0.04342722, -0.008730851], "postRotate" : [0, 0, 0], "children" : [ 46 | { "type" : "joint", "name" : "bj_R_toe", "bindTranslation" :[0, -1.741618, 0.1062741], "bindRotation" : [31.64839, -0.02939696, -0.05636886], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 47 | { "type" : "joint", "name" : "bj_R_toeTip", "bindTranslation" :[0, -0.785268, 0.02177917], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 48 | ]} 49 | ]} 50 | ]} 51 | ]}, 52 | { "type" : "joint", "name" : "bj_hipPlate", "bindTranslation" :[1.606056, 0.3496374, 0.548943], "bindRotation" : [0, 0, 0], "jointOrient" : [-4.313083, -25.6316, -11.85807], "postRotate" : [10.22947, 23.99762, 15.01932]} 53 | ]} 54 | ]} 55 | ]} 56 | ]} 57 | ]} 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /json/char_no_scale.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "persp", "translate" : [18.29561, 21.46406, -36.40822], "rotate" : [-15.33843, 10591.8, 0], "scale" : [1, 1, 1], "rotatePivot" : [0, 0, 0], "children" : [ 5 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 6 | ]}, 7 | { "type" : "node", "name" : "top", "translate" : [0, 100.1053, 0], "rotate" : [-90, 0, 0], "scale" : [1, 1, 1], "children" : [ 8 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 25.60255, "znear" : 0.1, "zfar" : 10000.0 } 9 | ]}, 10 | { "type" : "node", "name" : "front", "translate" : [-0.4470711, 8.269901, 100.1161], "scale" : [1, 1, 1], "children" : [ 11 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 3.622956, "znear" : 0.1, "zfar" : 10000.0 } 12 | ]}, 13 | { "type" : "node", "name" : "side", "translate" : [100.5196, 9.145576, -0.6957142], "rotate" : [0, 90, 0], "scale" : [1, 1, 1], "children" : [ 14 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 15.77639, "znear" : 0.1, "zfar" : 10000.0 } 15 | ]}, 16 | { "type" : "node", "name" : "RIG_solo", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 17 | { "type" : "node", "name" : "RIG_noScale_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 18 | { "type" : "mesh", "file" : "./json/character/merged.json" } 19 | ]}, 20 | { "type" : "node", "name" : "RIG_joints_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 21 | { "type" : "joint", "name" : "bj_root", "lod" : "xx", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [0.013951, 0, 0], "postRotate" : [0.7803711, 0, 0], "children" : [ 22 | { "type" : "joint", "name" : "bj_COG", "lod" : "xx", "bindTranslation" :[0, 11.01706, -0.7044944], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.7618697, 0, 0], "postRotate" : [0.7618697, 0, 0], "children" : [ 23 | { "type" : "joint", "name" : "bj_spineRoot", "lod" : "x_", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [-179.1666, 0, 180], "postRotate" : [-3.750809, 0, 0], "children" : [ 24 | { "type" : "joint", "name" : "bj_chest", "lod" : "xx", "bindTranslation" :[0, 1.710774, 0.1100414], "bindRotation" : [0, 0, 0], "jointOrient" : [3.681163, 0, 0], "postRotate" : [-8.20581, 0, 0], "children" : [ 25 | { "type" : "joint", "name" : "bj_neckRoot", "lod" : "x_", "bindTranslation" :[0, 2.872519, -0.2603679], "bindRotation" : [0, 0, 0], "jointOrient" : [25.42642, 0, 0], "postRotate" : [-27.22967, 0, 0], "children" : [ 26 | { "type" : "joint", "name" : "bj_head", "lod" : "x_", "bindTranslation" :[0, 0.8412964, 0.5454057], "bindRotation" : [0, 0, 0], "jointOrient" : [9.970071, 0, 0], "postRotate" : [0, 0, 0]} 27 | ]}, 28 | { "type" : "joint", "name" : "bj_L_clavicle", "lod" : "x_", "bindTranslation" :[0.3181662, 2.147406, 0.03433269], "bindRotation" : [0, 0, 0], "jointOrient" : [0.057488, 8.032577, -89.48751], "postRotate" : [178.5763, -88.61498, 179.7818], "children" : [ 29 | { "type" : "joint", "name" : "bj_L_shoulder", "lod" : "xx", "bindTranslation" :[-0.3487489, 1.85798, -0.2393546], "bindRotation" : [0, 0, 0], "jointOrient" : [-93.73047, 45.64685, -92.62478], "postRotate" : [0, 0, 0], "children" : [ 30 | { "type" : "joint", "name" : "bj_L_elbow", "lod" : "x_", "bindTranslation" :[0.05880454, 2.747025, 0.05386012], "bindRotation" : [0, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, -37.22785, 0], "children" : [ 31 | { "type" : "joint", "name" : "bj_L_wrist", "lod" : "__", "bindTranslation" :[-0.1778838, 2.371249, -0.2293983], "bindRotation" : [0, 0, 0], "jointOrient" : [-7.693209, 39.00606, -2.240701], "postRotate" : [9.006295, -39.32423, -3.586556]} 32 | ]} 33 | ]} 34 | ]}, 35 | { "type" : "joint", "name" : "bj_R_clavicle", "lod" : "x_", "bindTranslation" :[-0.318166, 2.147453, 0.0343399], "bindRotation" : [0, 0, 0], "jointOrient" : [-179.9425, -8.032577, 89.48751], "postRotate" : [0, 0, 0], "children" : [ 36 | { "type" : "joint", "name" : "bj_R_shoulder", "lod" : "xx", "bindTranslation" :[-0.3008852, -1.850326, 0.3417481], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.8608915, 0.8678666, -45.9416], "postRotate" : [0, 0, 0], "children" : [ 37 | { "type" : "joint", "name" : "bj_R_elbow", "lod" : "x_", "bindTranslation" :[-0.0588076, -2.747023, -0.05386006], "bindRotation" : [0, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, 0, 0], "children" : [ 38 | { "type" : "joint", "name" : "bj_R_wrist", "lod" : "__", "bindTranslation" :[0.00285297, -2.371255, 0.2902752], "bindRotation" : [0, 0, 0], "jointOrient" : [-6.337167, 1.798823, -1.741885], "postRotate" : [0, 0, 0]} 39 | ]} 40 | ]} 41 | ]}, 42 | { "type" : "joint", "name" : "bj_harness_main", "lod" : "x_", "bindTranslation" :[0, 2.784781, 0.188085], "bindRotation" : [0, 0, 0], "jointOrient" : [171.7636, 0, 180], "postRotate" : [0, 0, 0], "children" : [ 43 | { "type" : "joint", "name" : "bj_harness_padBig", "lod" : "__", "bindTranslation" :[-1.6953, 0.141024, 0.2607302], "bindRotation" : [0, 0, 0], "jointOrient" : [1.975576, 6.676362, 106.5253], "postRotate" : [6.961252, 0, -106.4101]}, 44 | { "type" : "joint", "name" : "bj_harness_padSmall", "lod" : "__", "bindTranslation" :[1.641814, 0.141024, 0.3744311], "bindRotation" : [0, 0, 0], "jointOrient" : [2.037478, -6.657809, -107.0585], "postRotate" : [6.961252, 0, 106.94]} 45 | ]} 46 | ]} 47 | ]}, 48 | { "type" : "joint", "name" : "bj_pelvis", "lod" : "xx", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [179.0654, 0, 0], "postRotate" : [1.728904, 0, 0], "children" : [ 49 | { "type" : "joint", "name" : "bj_L_hip", "lod" : "xx", "bindTranslation" :[-1.093311, 1.517099, -0.03888182], "bindRotation" : [0, 0, 0], "jointOrient" : [-1.671761, 0, 0], "postRotate" : [3.99778, 0, 0], "children" : [ 50 | { "type" : "joint", "name" : "bj_L_knee", "lod" : "xx", "bindTranslation" :[0, 4.464725, -0.3169275], "bindRotation" : [0, 0, 0], "jointOrient" : [-13.69354, 0.04425968, -0.001797784], "postRotate" : [0.2320798, 0, 180], "children" : [ 51 | { "type" : "joint", "name" : "bj_L_ankle", "lod" : "__", "bindTranslation" :[-6.08286e-4, -4.110774, 0.04058781], "bindRotation" : [0, 0, 0], "jointOrient" : [77.73943, -0.0433915, 179.9911], "postRotate" : [0, 0, 0], "children" : [ 52 | { "type" : "joint", "name" : "bj_L_toe", "lod" : "__", "bindTranslation" :[0, 1.741616, -0.1062748], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 53 | { "type" : "joint", "name" : "bj_L_toeTip", "lod" : "__", "bindTranslation" :[0, 0.7852713, -0.02177926], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 54 | ]} 55 | ]} 56 | ]} 57 | ]}, 58 | { "type" : "joint", "name" : "bj_R_hip", "lod" : "xx", "bindTranslation" :[1.09331, 1.517104, -0.03888154], "bindRotation" : [0, 0, 0], "jointOrient" : [178.3282, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 59 | { "type" : "joint", "name" : "bj_R_knee", "lod" : "xx", "bindTranslation" :[0, -4.475952, 0.00488591], "bindRotation" : [0, 0, 0], "jointOrient" : [-9.695761, 0.04427732, 0.001292279], "postRotate" : [0, 0, 0], "children" : [ 60 | { "type" : "joint", "name" : "bj_R_ankle", "lod" : "__", "bindTranslation" :[-6.08285e-4, -4.110905, -0.02393664], "bindRotation" : [0, 0, 0], "jointOrient" : [77.50735, -0.04342722, -0.008730851], "postRotate" : [0, 0, 0], "children" : [ 61 | { "type" : "joint", "name" : "bj_R_toe", "lod" : "__", "bindTranslation" :[0, -1.741618, 0.1062741], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 62 | { "type" : "joint", "name" : "bj_R_toeTip", "lod" : "__", "bindTranslation" :[0, -0.785268, 0.02177917], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 63 | ]} 64 | ]} 65 | ]} 66 | ]}, 67 | { "type" : "joint", "name" : "bj_hipPlate", "lod" : "__", "bindTranslation" :[1.606056, 0.3496374, 0.548943], "bindRotation" : [0, 0, 0], "jointOrient" : [-4.313083, -25.6316, -11.85807], "postRotate" : [10.22947, 23.99762, 15.01932]} 68 | ]} 69 | ]} 70 | ]} 71 | ]} 72 | ]} 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /json/character.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "persp", "translate" : [18.29561, 21.46406, -36.40822], "rotate" : [-15.33843, 10591.8, 0], "scale" : [1, 1, 1], "rotatePivot" : [0, 0, 0], "children" : [ 5 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 6 | ]}, 7 | { "type" : "node", "name" : "top", "translate" : [0, 100.1053, 0], "rotate" : [-90, 0, 0], "scale" : [1, 1, 1], "children" : [ 8 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 25.60255, "znear" : 0.1, "zfar" : 10000.0 } 9 | ]}, 10 | { "type" : "node", "name" : "front", "translate" : [-0.4470711, 8.269901, 100.1161], "scale" : [1, 1, 1], "children" : [ 11 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 3.622956, "znear" : 0.1, "zfar" : 10000.0 } 12 | ]}, 13 | { "type" : "node", "name" : "side", "translate" : [100.5196, 9.145576, -0.6957142], "rotate" : [0, 90, 0], "scale" : [1, 1, 1], "children" : [ 14 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 15.77639, "znear" : 0.1, "zfar" : 10000.0 } 15 | ]}, 16 | { "type" : "node", "name" : "RIG_solo", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 17 | { "type" : "node", "name" : "RIG_noScale_grp", "translate" : [0, 0, 0], "scale" : [0.117, 0.117, 0.117], "children" : [ 18 | { "type" : "mesh", "file" : "./json/character/merged.json" } 19 | ]}, 20 | { "type" : "node", "name" : "RIG_joints_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 21 | { "type" : "joint", "name" : "bj_root", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [0.013951, 0, 0], "postRotate" : [0.7803711, 0, 0], "children" : [ 22 | { "type" : "joint", "name" : "bj_COG", "bindTranslation" :[0, 11.01706, -0.7044944], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.7618697, 0, 0], "postRotate" : [0.7618697, 0, 0], "children" : [ 23 | { "type" : "joint", "name" : "bj_spineRoot", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [-179.1666, 0, 180], "postRotate" : [-3.750809, 0, 0], "children" : [ 24 | { "type" : "joint", "name" : "bj_chest", "bindTranslation" :[0, 1.710774, 0.1100414], "bindRotation" : [0, 0, 0], "jointOrient" : [3.681163, 0, 0], "postRotate" : [-8.20581, 0, 0], "children" : [ 25 | { "type" : "joint", "name" : "bj_neckRoot", "bindTranslation" :[0, 2.872519, -0.2603679], "bindRotation" : [0, 0, 0], "jointOrient" : [25.42642, 0, 0], "postRotate" : [-27.22967, 0, 0], "children" : [ 26 | { "type" : "joint", "name" : "bj_head", "bindTranslation" :[0, 0.8412964, 0.5454057], "bindRotation" : [0, 0, 0], "jointOrient" : [9.970071, 0, 0], "postRotate" : [0, 0, 0]} 27 | ]}, 28 | { "type" : "joint", "name" : "bj_L_clavicle", "bindTranslation" :[0.3181662, 2.147406, 0.03433269], "bindRotation" : [0, 0, 0], "jointOrient" : [0.057488, 8.032577, -89.48751], "postRotate" : [178.5763, -88.61498, 179.7818], "children" : [ 29 | { "type" : "joint", "name" : "bj_L_shoulder", "bindTranslation" :[-0.3487489, 1.85798, -0.2393546], "bindRotation" : [0, 0, 0], "jointOrient" : [-93.73047, 45.64685, -92.62478], "postRotate" : [0, 0, 0], "children" : [ 30 | { "type" : "joint", "name" : "bj_L_elbow", "bindTranslation" :[0.05880454, 2.747025, 0.05386012], "bindRotation" : [0, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, -37.22785, 0], "children" : [ 31 | { "type" : "joint", "name" : "bj_L_wrist", "bindTranslation" :[-0.1778838, 2.371249, -0.2293983], "bindRotation" : [0, 0, 0], "jointOrient" : [-7.693209, 39.00606, -2.240701], "postRotate" : [9.006295, -39.32423, -3.586556]} 32 | ]} 33 | ]} 34 | ]}, 35 | { "type" : "joint", "name" : "bj_R_clavicle", "bindTranslation" :[-0.318166, 2.147453, 0.0343399], "bindRotation" : [0, 0, 0], "jointOrient" : [-179.9425, -8.032577, 89.48751], "postRotate" : [0, 0, 0], "children" : [ 36 | { "type" : "joint", "name" : "bj_R_shoulder", "bindTranslation" :[-0.3008852, -1.850326, 0.3417481], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.8608915, 0.8678666, -45.9416], "postRotate" : [0, 0, 0], "children" : [ 37 | { "type" : "joint", "name" : "bj_R_elbow", "bindTranslation" :[-0.0588076, -2.747023, -0.05386006], "bindRotation" : [0, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, 0, 0], "children" : [ 38 | { "type" : "joint", "name" : "bj_R_wrist", "bindTranslation" :[0.00285297, -2.371255, 0.2902752], "bindRotation" : [0, 0, 0], "jointOrient" : [-6.337167, 1.798823, -1.741885], "postRotate" : [0, 0, 0]} 39 | ]} 40 | ]} 41 | ]}, 42 | { "type" : "joint", "name" : "bj_harness_main", "bindTranslation" :[0, 2.784781, 0.188085], "bindRotation" : [0, 0, 0], "jointOrient" : [171.7636, 0, 180], "postRotate" : [0, 0, 0], "children" : [ 43 | { "type" : "joint", "name" : "bj_harness_padBig", "bindTranslation" :[-1.6953, 0.141024, 0.2607302], "bindRotation" : [0, 0, 0], "jointOrient" : [1.975576, 6.676362, 106.5253], "postRotate" : [6.961252, 0, -106.4101]}, 44 | { "type" : "joint", "name" : "bj_harness_padSmall", "bindTranslation" :[1.641814, 0.141024, 0.3744311], "bindRotation" : [0, 0, 0], "jointOrient" : [2.037478, -6.657809, -107.0585], "postRotate" : [6.961252, 0, 106.94]} 45 | ]} 46 | ]} 47 | ]}, 48 | { "type" : "joint", "name" : "bj_pelvis", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [179.0654, 0, 0], "postRotate" : [1.728904, 0, 0], "children" : [ 49 | { "type" : "joint", "name" : "bj_L_hip", "bindTranslation" :[-1.093311, 1.517099, -0.03888182], "bindRotation" : [0, 0, 0], "jointOrient" : [-1.671761, 0, 0], "postRotate" : [3.99778, 0, 0], "children" : [ 50 | { "type" : "joint", "name" : "bj_L_knee", "bindTranslation" :[0, 4.464725, -0.3169275], "bindRotation" : [0, 0, 0], "jointOrient" : [-13.69354, 0.04425968, -0.001797784], "postRotate" : [0.2320798, 0, 180], "children" : [ 51 | { "type" : "joint", "name" : "bj_L_ankle", "bindTranslation" :[-6.08286e-4, -4.110774, 0.04058781], "bindRotation" : [0, 0, 0], "jointOrient" : [77.73943, -0.0433915, 179.9911], "postRotate" : [0, 0, 0], "children" : [ 52 | { "type" : "joint", "name" : "bj_L_toe", "bindTranslation" :[0, 1.741616, -0.1062748], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 53 | { "type" : "joint", "name" : "bj_L_toeTip", "bindTranslation" :[0, 0.7852713, -0.02177926], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 54 | ]} 55 | ]} 56 | ]} 57 | ]}, 58 | { "type" : "joint", "name" : "bj_R_hip", "bindTranslation" :[1.09331, 1.517104, -0.03888154], "bindRotation" : [0, 0, 0], "jointOrient" : [178.3282, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 59 | { "type" : "joint", "name" : "bj_R_knee", "bindTranslation" :[0, -4.475952, 0.00488591], "bindRotation" : [0, 0, 0], "jointOrient" : [-9.695761, 0.04427732, 0.001292279], "postRotate" : [0, 0, 0], "children" : [ 60 | { "type" : "joint", "name" : "bj_R_ankle", "bindTranslation" :[-6.08285e-4, -4.110905, -0.02393664], "bindRotation" : [0, 0, 0], "jointOrient" : [77.50735, -0.04342722, -0.008730851], "postRotate" : [0, 0, 0], "children" : [ 61 | { "type" : "joint", "name" : "bj_R_toe", "bindTranslation" :[0, -1.741618, 0.1062741], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 62 | { "type" : "joint", "name" : "bj_R_toeTip", "bindTranslation" :[0, -0.785268, 0.02177917], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 63 | ]} 64 | ]} 65 | ]} 66 | ]}, 67 | { "type" : "joint", "name" : "bj_hipPlate", "bindTranslation" :[1.606056, 0.3496374, 0.548943], "bindRotation" : [0, 0, 0], "jointOrient" : [-4.313083, -25.6316, -11.85807], "postRotate" : [10.22947, 23.99762, 15.01932]} 68 | ]} 69 | ]} 70 | ]} 71 | ]} 72 | ]} 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /json/character/blinn2-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn2-fx", 3 | "skinned" : true, 4 | "type" : "phong", 5 | "ambient" : [0.0,0.0,0.0,1], 6 | "bump" : "textures/N_1024.png", 7 | "bump_uv" : 2, 8 | "diffuse" : "textures/Color_1024.png", 9 | "diffuse_uv" : 1, 10 | "emission" : "textures/SI%20512.png", 11 | "emission_uv" : 0, 12 | "shininess" : [10], 13 | "specular" : "textures/S_1024.png", 14 | "specular_uv" : 3 15 | } -------------------------------------------------------------------------------- /json/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "scenes" : [ 3 | { "name" : "./json/space-station.json", "anims" : [] }, 4 | { "name" : "./json/char_no_scale.json", "anims" : [ "./json/anim-idle_anim.json", "./json/anim-turn_anim.json", "./json/anim-walk_anim.json"] } 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /json/space-station.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "persp", "translate" : [-2.813762, 1.180501, 11.68475], "rotate" : [-0.3383408, 6469, 0], "scale" : [1, 1, 1], "rotatePivot" : [0, 0, 0], "children" : [ 5 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 6 | ]}, 7 | { "type" : "node", "name" : "top", "translate" : [-0.4607509, 30, 2.713311], "rotate" : [-90, 0, 0], "scale" : [1, 1, 1], "children" : [ 8 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 13.64334, "znear" : 0.1, "zfar" : 10000.0 } 9 | ]}, 10 | { "type" : "node", "name" : "front", "translate" : [-0.1991616, 1.006371, 100.1], "scale" : [1, 1, 1], "children" : [ 11 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 5.764667, "znear" : 0.1, "zfar" : 10000.0 } 12 | ]}, 13 | { "type" : "node", "name" : "side", "translate" : [100.1, 1.192381, 1.620239], "rotate" : [0, 90, 0], "scale" : [1, 1, 1], "children" : [ 14 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 5.370502, "znear" : 0.1, "zfar" : 10000.0 } 15 | ]}, 16 | { "type" : "node", "name" : "matte_grp", "translate" : [0, 0, 0], "scale" : [0.87, 0.87, 0.87], "children" : [ 17 | { "type" : "node", "name" : "matte_geo", "translate" : [0, 8.055238, -161.3018], "rotate" : [90, 0, 0], "scale" : [0.04673177, 0.04673177, 0.04673177], "children" : [ 18 | { "type" : "mesh", "file" : "./json/space-station/matte_geoShape.json" } 19 | ]} 20 | ]}, 21 | { "type" : "node", "name" : "Space_Station_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 22 | { "type" : "node", "name" : "Walls_geo", "translate" : [-2.33, 4.151841, -1.904052], "scale" : [1, 1, 1], "rotatePivot" : [2.287803, -24.08894, 5.844801], "scalePivot" : [2.287803, -24.08894, 5.844801], "children" : [ 23 | { "type" : "mesh", "file" : "./json/space-station/Walls_geoShape.json" } 24 | ]}, 25 | { "type" : "node", "name" : "MainSection_geo", "translate" : [-2.293179, 4.151841, -1.912069], "scale" : [1, 1, 1], "rotatePivot" : [2.286323, 3.44986, 1.904691], "scalePivot" : [2.286323, 3.44986, 1.904691], "children" : [ 26 | { "type" : "mesh", "file" : "./json/space-station/MainSection_geoShape.json" } 27 | ]}, 28 | { "type" : "node", "name" : "glass_geo", "translate" : [-2.293179, 4.151841, -1.912069], "scale" : [1, 1, 1], "rotatePivot" : [2.287702, -1.80906, -4.717457], "scalePivot" : [2.287702, -1.80906, -4.717457], "children" : [ 29 | { "type" : "mesh", "file" : "./json/space-station/glass_geoShape.json" } 30 | ]}, 31 | { "type" : "node", "name" : "Self_Illuminated_surfaces_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 32 | { "type" : "node", "name" : "particlePillars_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 33 | { "type" : "node", "name" : "particleBeam_r_geo", "translate" : [-2.293179, 4.151841, -1.912069], "scale" : [1, 1, 1], "rotatePivot" : [2.287702, -1.80906, -4.717457], "scalePivot" : [2.287702, -1.80906, -4.717457], "children" : [ 34 | { "type" : "mesh", "file" : "./json/space-station/particleBeam_r_geoShape.json" } 35 | ]}, 36 | { "type" : "node", "name" : "particleBeam_l_geo", "translate" : [-2.293179, 4.151841, -1.912069], "scale" : [1, 1, 1], "rotatePivot" : [-0.7122977, -2.473878, 1.908223], "scalePivot" : [-0.7122977, -2.473878, 1.908223], "children" : [ 37 | { "type" : "mesh", "file" : "./json/space-station/particleBeam_l_geoShape.json" } 38 | ]} 39 | ]}, 40 | { "type" : "node", "name" : "monitors_geo", "translate" : [-2.293179, 4.151841, -1.912069], "scale" : [1, 1, 1], "rotatePivot" : [2.281099, -3.014077, 0.2091175], "scalePivot" : [2.281099, -3.014077, 0.2091175], "children" : [ 41 | { "type" : "mesh", "file" : "./json/space-station/monitors_geoShape.json" } 42 | ]}, 43 | { "type" : "node", "name" : "LightsWalkway_geo", "translate" : [-2.293179, 4.151841, -1.912069], "scale" : [1, 1, 1], "rotatePivot" : [1.460896, -4.147133, 16.63245], "scalePivot" : [1.460896, -4.147133, 16.63245], "children" : [ 44 | { "type" : "mesh", "file" : "./json/space-station/LightsWalkway_geoShape.json" } 45 | ]}, 46 | { "type" : "node", "name" : "LightsPlatform_geo", "translate" : [-2.293179, 4.151841, -1.912069], "scale" : [1, 1, 1], "rotatePivot" : [2.282358, -4.318928, 1.764573], "scalePivot" : [2.282358, -4.318928, 1.764573], "children" : [ 47 | { "type" : "mesh", "file" : "./json/space-station/LightsPlatform_geoShape.json" } 48 | ]} 49 | ]} 50 | ]}, 51 | { "type" : "node", "name" : "lights", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 52 | { "type" : "node", "name" : "leftPillarPointLight", "translate" : [-2.983903, 1.658036, 0], "scale" : [1, 1, 1], "children" : [ 53 | { "type" : "light", "subtype" : "point", "color" : [0.6055363, 0.699341, 0.8823529], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0 } 54 | ]}, 55 | { "type" : "node", "name" : "rightPillarPointLight", "translate" : [3.025235, 1.658036, 0], "scale" : [1, 1, 1], "children" : [ 56 | { "type" : "light", "subtype" : "point", "color" : [0.6282199, 0.7024043, 0.8431373], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0 } 57 | ]}, 58 | { "type" : "node", "name" : "bottomPointLight", "translate" : [0, -7.648225, 0], "scale" : [1, 1, 1], "children" : [ 59 | { "type" : "light", "subtype" : "point", "color" : [1, 0.3845068, 0], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0 } 60 | ]}, 61 | { "type" : "node", "name" : "spotLight1", "translate" : [0, 6.520953, 2.022932], "rotate" : [-797.4999, 0, 0], "scale" : [1, 1, 1], "children" : [ 62 | { "type" : "light", "subtype" : "spot", "color" : [1, 1, 1], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0, "falloff_angle" : 40.0, "falloff_exponent" : 1.0 } 63 | ]}, 64 | { "type" : "node", "name" : "spotLight2", "translate" : [0, 6.326943, 8.058494], "rotate" : [-1516.961, 0, 0], "scale" : [1, 1, 1], "children" : [ 65 | { "type" : "light", "subtype" : "spot", "color" : [1, 1, 1], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0, "falloff_angle" : 40.0, "falloff_exponent" : 1.0 } 66 | ]}, 67 | { "type" : "node", "name" : "spotLight3", "translate" : [0, 5.615519, 11.27815], "rotate" : [-85.44196, 0, 0], "scale" : [1, 1, 1], "children" : [ 68 | { "type" : "light", "subtype" : "spot", "color" : [1, 1, 1], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0, "falloff_angle" : 40.0, "falloff_exponent" : 1.0 } 69 | ]} 70 | ]}, 71 | { "type" : "node", "name" : "cameras", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 72 | { "type" : "node", "name" : "camera1", "translate" : [-0.02355225, 1.527128, 2.110149], "rotate" : [-4.538353, 360.6, 0], "scale" : [1, 1, 1], "children" : [ 73 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 74 | ]}, 75 | { "type" : "node", "name" : "camera2", "translate" : [0.0599757, 4.442483, -6.183795], "rotate" : [-31.53835, 180.6, 0], "scale" : [1, 1, 1], "children" : [ 76 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 77 | ]}, 78 | { "type" : "node", "name" : "camera3", "translate" : [-0.2942395, 1.268122, 20.5544], "rotate" : [-4.538353, 1.8, 0], "scale" : [1, 1, 1], "children" : [ 79 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 80 | ]}, 81 | { "type" : "node", "name" : "camera4", "translate" : [-3.214108, 1.586023, 13.62035], "rotate" : [-10.53835, -58.2, 0], "scale" : [1, 1, 1], "children" : [ 82 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 83 | ]} 84 | ]} 85 | ] 86 | } 87 | -------------------------------------------------------------------------------- /json/space-station/Glass-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "Glass-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/glass.png", 7 | "diffuse_uv" : 0, 8 | "emission" : [0,0,0,1], 9 | "shininess" : [10], 10 | "specular" : [0,0.2603494,0.2603494,1] 11 | } -------------------------------------------------------------------------------- /json/space-station/blinn1-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn1-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/circle_pad.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/main_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/circle_pad_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/blinn12-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn12-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/keyboard.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/main_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/keyboard_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/blinn4-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn4-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/MechWall2.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/walls_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/MechWall_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/blinn5-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn5-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/ConcreteTile.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/walls_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/ConcreteTile_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/blinn6-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn6-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/MetalTile2.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/main_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/MetalTile2_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/blinn7-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn7-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/ConcreteTile2.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/main_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/ConcreteTile2_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/blinn8-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn8-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/ConcreteTile3B.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/main_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/ConcreteTile3B_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/blinn9-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn9-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/Ridges1.png", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/main_lightmap.png", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/Ridges1_S.png", 12 | "specular_uv" : 2 13 | } -------------------------------------------------------------------------------- /json/space-station/customPillar-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "customPillar-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : "textures/plasma.png", 7 | "diffuse_uv" : 0, 8 | "emission" : [0.451,0.451,0.451,1], 9 | "shininess" : [10], 10 | "specular" : [1,1,1,1] 11 | } -------------------------------------------------------------------------------- /json/space-station/glass_geoShape.json: -------------------------------------------------------------------------------- 1 | { 2 | "materials" : 3 | [ 4 | { "file" : "./json/space-station/Glass-fx.json", "start" : 0 } 5 | ], 6 | "indices" : [0, 1, 2, 2, 1, 3], 7 | "vertexPositions" : [[-2.384508, -3.71098, -4.717457, 6.959912, -3.71098, -4.717457, -2.384508, 0.0928607, -4.717457, 6.959912, 0.0928607, -4.717457]], 8 | "vertexNormals" : [[0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]], 9 | "vertexTextureCoords" : [[0.8945675, 0.09695004, 0.9826846, 0.09695004, 0.8945675, 0.1328199, 0.9826846, 0.1328199]] 10 | } -------------------------------------------------------------------------------- /json/space-station/lambert3-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "lambert3-fx", 3 | "skinned" : false, 4 | "type" : "lambert", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : [0,0,0,1], 7 | "emission" : "textures/monitorDisplay3.png", 8 | "emission_uv" : 0, 9 | "shininess" : [10] 10 | } 11 | -------------------------------------------------------------------------------- /json/space-station/lambert4-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "lambert4-fx", 3 | "skinned" : false, 4 | "type" : "lambert", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : [0,0,0,1], 7 | "emission" : "textures/monitorDisplay2.png", 8 | "emission_uv" : 0, 9 | "shininess" : [10] 10 | } 11 | -------------------------------------------------------------------------------- /json/space-station/lambert5-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "lambert5-fx", 3 | "skinned" : false, 4 | "type" : "lambert", 5 | "ambient" : [1,1,1,1], 6 | "diffuse" : "textures/red_light.png", 7 | "diffuse_uv" : 0, 8 | "emission" : [0,0,0,1], 9 | "shininess" : [10] 10 | } -------------------------------------------------------------------------------- /json/space-station/matte_geoShape.json: -------------------------------------------------------------------------------- 1 | { 2 | "materials" : 3 | [ 4 | { "file" : "./json/space-station/phong1-fx.json", "start" : 0 } 5 | ], 6 | "indices" : [0, 1, 2, 2, 1, 3, 1, 4, 3, 3, 4, 5, 4, 6, 5, 5, 6, 7, 6, 8, 7, 7, 8, 9, 8, 10, 9, 9, 10, 11, 10, 12, 11, 11, 12, 13, 12, 14, 13, 13, 14, 15, 14, 16, 15, 15, 16, 17, 16, 18, 17, 17, 18, 19, 18, 20, 19, 19, 20, 21, 2, 3, 22, 22, 3, 23, 3, 5, 23, 23, 5, 24, 5, 7, 24, 24, 7, 25, 7, 9, 25, 25, 9, 26, 9, 11, 26, 26, 11, 27, 11, 13, 27, 27, 13, 28, 13, 15, 28, 28, 15, 29, 15, 17, 29, 29, 17, 30, 17, 19, 30, 30, 19, 31, 19, 21, 31, 31, 21, 32, 22, 23, 33, 33, 23, 34, 23, 24, 34, 34, 24, 35, 24, 25, 35, 35, 25, 36, 25, 26, 36, 36, 26, 37, 26, 27, 37, 37, 27, 38, 27, 28, 38, 38, 28, 39, 28, 29, 39, 39, 29, 40, 29, 30, 40, 40, 30, 41, 30, 31, 41, 41, 31, 42, 31, 32, 42, 42, 32, 43, 33, 34, 44, 44, 34, 45, 34, 35, 45, 45, 35, 46, 35, 36, 46, 46, 36, 47, 36, 37, 47, 47, 37, 48, 37, 38, 48, 48, 38, 49, 38, 39, 49, 49, 39, 50, 39, 40, 50, 50, 40, 51, 40, 41, 51, 51, 41, 52, 41, 42, 52, 52, 42, 53, 42, 43, 53, 53, 43, 54, 44, 45, 55, 55, 45, 56, 45, 46, 56, 56, 46, 57, 46, 47, 57, 57, 47, 58, 47, 48, 58, 58, 48, 59, 48, 49, 59, 59, 49, 60, 49, 50, 60, 60, 50, 61, 50, 51, 61, 61, 51, 62, 51, 52, 62, 62, 52, 63, 52, 53, 63, 63, 53, 64, 53, 54, 64, 64, 54, 65], 7 | "vertexPositions" : [[-2000, 0, 500, -1600, 0, 500, -2000, 0, 300, -1600, 0, 300, -1200, 0, 500, -1200, 0, 300, -800, 0, 500, -800, 0, 300, -400, 0, 500, -400, 0, 300, 0, 0, 500, 0, 0, 300, 400, 0, 500, 400, 0, 300, 800, 0, 500, 800, 0, 300, 1200, 0, 500, 1200, 0, 300, 1600, 0, 500, 1600, 0, 300, 2000, 0, 500, 2000, 0, 300, -2000, 0, 100, -1600, 0, 100, -1200, 0, 100, -800, 0, 100, -400, 0, 100, 0, 0, 100, 400, 0, 100, 800, 0, 100, 1200, 0, 100, 1600, 0, 100, 2000, 0, 100, -2000, 0, -100, -1600, 0, -100, -1200, 0, -100, -800, 0, -100, -400, 0, -100, 0, 0, -100, 400, 0, -100, 800, 0, -100, 1200, 0, -100, 1600, 0, -100, 2000, 0, -100, -2000, 0, -300, -1600, 0, -300, -1200, 0, -300, -800, 0, -300, -400, 0, -300, 0, 0, -300, 400, 0, -300, 800, 0, -300, 1200, 0, -300, 1600, 0, -300, 2000, 0, -300, -2000, 0, -909.6, -1600, 0, -909.6, -1200, 0, -909.6, -800, 0, -909.6, -400, 0, -909.6, 0, 0, -909.6, 400, 0, -909.6, 800, 0, -909.6, 1200, 0, -909.6, 1600, 0, -909.6, 2000, 0, -909.6]], 8 | "vertexNormals" : [[0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0]], 9 | "vertexTextureCoords" : [[0, 0, 0.09999999, 0, 0, 0.2, 0.09999999, 0.2, 0.2, 0, 0.2, 0.2, 0.3, 0, 0.3, 0.2, 0.4, 0, 0.4, 0.2, 0.5, 0, 0.5, 0.2, 0.6, 0, 0.6, 0.2, 0.7, 0, 0.7, 0.2, 0.8, 0, 0.8, 0.2, 0.9, 0, 0.9, 0.2, 1, 0, 1, 0.2, 0, 0.4, 0.09999999, 0.4, 0.2, 0.4, 0.3, 0.4, 0.4, 0.4, 0.5, 0.4, 0.6, 0.4, 0.7, 0.4, 0.8, 0.4, 0.9, 0.4, 1, 0.4, 0, 0.6, 0.09999999, 0.6, 0.2, 0.6, 0.3, 0.6, 0.4, 0.6, 0.5, 0.6, 0.6, 0.6, 0.7, 0.6, 0.8, 0.6, 0.9, 0.6, 1, 0.6, 0, 0.8, 0.09999999, 0.8, 0.2, 0.8, 0.3, 0.8, 0.4, 0.8, 0.5, 0.8, 0.6, 0.8, 0.7, 0.8, 0.8, 0.8, 0.9, 0.8, 1, 0.8, 0, 1, 0.09999999, 1, 0.2, 1, 0.3, 1, 0.4, 1, 0.5, 1, 0.6, 1, 0.7, 1, 0.8, 1, 0.9, 1, 1, 1]] 10 | } -------------------------------------------------------------------------------- /json/space-station/monitors_geoShape.json: -------------------------------------------------------------------------------- 1 | { 2 | "materials" : 3 | [ 4 | { "file" : "./json/space-station/lambert3-fx.json", "start" : 0 }, 5 | { "file" : "./json/space-station/lambert4-fx.json", "start" : 18 } 6 | ], 7 | "indices" : [0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7, 8, 9, 10, 10, 9, 11, 12, 13, 14, 14, 13, 15, 16, 17, 18, 18, 17, 19, 20, 21, 22, 22, 21, 23, 24, 25, 26, 26, 25, 27, 28, 29, 30, 30, 29, 31, 32, 33, 34, 34, 33, 35], 8 | "vertexPositions" : [[1.906814, -3.187415, 0.1506599, 2.671925, -3.187415, 0.1467893, 1.905063, -2.840739, -0.1960027, 2.670162, -2.840739, -0.1998782, 1.906814, -3.187415, 0.1506599, 1.905063, -2.840739, -0.1960027, 1.897122, -3.180584, 0.1438818, 1.895433, -2.847569, -0.1891298, 2.670162, -2.840739, -0.1998782, 2.671925, -3.187415, 0.1467893, 2.67986, -2.847569, -0.1931038, 2.681548, -3.180584, 0.139909, 2.931151, -3.187415, 0.2289732, 3.589922, -3.187415, 0.6181132, 3.107468, -2.840739, -0.06950688, 3.766232, -2.840739, 0.3196231, 2.931151, -3.187415, 0.2289732, 3.107468, -2.840739, -0.06950688, 2.926308, -3.180584, 0.2181832, 3.095676, -2.847569, -0.06854689, 3.766232, -2.840739, 0.3196231, 3.589922, -3.187415, 0.6181132, 3.771082, -2.847569, 0.3304131, 3.601712, -3.180584, 0.6171432, 0.9665956, -3.187415, 0.6133391, 1.632879, -3.187415, 0.2372069, 0.7961769, -2.840739, 0.3114526, 1.462448, -2.840739, -0.06467855, 0.9665956, -3.187415, 0.6133391, 0.7961769, -2.840739, 0.3114526, 0.9548293, -3.180584, 0.6121416, 0.7911153, -2.847569, 0.3221462, 1.462448, -2.840739, -0.06467855, 1.632879, -3.187415, 0.2372069, 1.474218, -2.847569, -0.06348705, 1.637931, -3.180584, 0.22651]], 9 | "vertexNormals" : [[0.003579446, 0.7071003, 0.7071043, 0.003579446, 0.7071003, 0.7071043, 0.003579446, 0.7071003, 0.7071043, 0.003579446, 0.7071003, 0.7071043, 0.00349437, 0.7070951, 0.7071099, 0.00349437, 0.7070951, 0.7071099, 0.00349437, 0.7070951, 0.7071099, 0.00349437, 0.7070951, 0.7071099, 0.003847745, 0.7071114, 0.7070917, 0.003847745, 0.7071114, 0.7070917, 0.003847745, 0.7071114, 0.7070917, 0.003847745, 0.7071114, 0.7070917, -0.3596357, 0.7071, 0.6088282, -0.3596357, 0.7071, 0.6088282, -0.3596357, 0.7071, 0.6088282, -0.3596357, 0.7071, 0.6088282, -0.359713, 0.7071022, 0.60878, -0.359713, 0.7071022, 0.60878, -0.359713, 0.7071022, 0.60878, -0.359713, 0.7071022, 0.60878, -0.3594113, 0.7071025, 0.6089578, -0.3594113, 0.7071025, 0.6089578, -0.3594113, 0.7071025, 0.6089578, -0.3594113, 0.7071025, 0.6089578, 0.3476182, 0.7071, 0.6157688, 0.3476182, 0.7071, 0.6157688, 0.3476182, 0.7071, 0.6157688, 0.3476182, 0.7071, 0.6157688, 0.3475367, 0.7071053, 0.6158088, 0.3475367, 0.7071053, 0.6158088, 0.3475367, 0.7071053, 0.6158088, 0.3475367, 0.7071053, 0.6158088, 0.34785, 0.7071066, 0.6156303, 0.34785, 0.7071066, 0.6156303, 0.34785, 0.7071066, 0.6156303, 0.34785, 0.7071066, 0.6156303]], 10 | "vertexTextureCoords" : [[0.1056781, 0.002170593, 0.9005729, 0.002176166, 0.1056762, 0.9964889, 0.900573, 0.9964888, 0.1056781, 0.002170593, 0.1056762, 0.9964889, 0.09563959, 0.02176693, 0.09563959, 0.9768965, 0.900573, 0.9964888, 0.9005729, 0.002176166, 0.9106193, 0.9768965, 0.9106154, 0.02176327, 0.1056781, 0.002170593, 0.9005729, 0.002176166, 0.1056762, 0.9964889, 0.900573, 0.9964888, 0.1056781, 0.002170593, 0.1056762, 0.9964889, 0.09563959, 0.02176693, 0.09563959, 0.9768965, 0.900573, 0.9964888, 0.9005729, 0.002176166, 0.9106193, 0.9768965, 0.9106154, 0.02176327, 0.1056781, 0.002170593, 0.9005729, 0.002176166, 0.1056762, 0.9964889, 0.900573, 0.9964888, 0.1056781, 0.002170593, 0.1056762, 0.9964889, 0.09563959, 0.02176693, 0.09563959, 0.9768965, 0.900573, 0.9964888, 0.9005729, 0.002176166, 0.9106193, 0.9768965, 0.9106154, 0.02176327]] 11 | } -------------------------------------------------------------------------------- /json/space-station/particleBeam_l_geoShape.json: -------------------------------------------------------------------------------- 1 | { 2 | "materials" : 3 | [ 4 | { "file" : "./json/space-station/customPillar-fx.json", "start" : 0 } 5 | ], 6 | "indices" : [0, 1, 2, 2, 1, 3, 4, 5, 0, 0, 5, 1, 6, 7, 4, 4, 7, 5, 8, 9, 6, 6, 9, 7, 10, 11, 8, 8, 11, 9, 12, 13, 10, 10, 13, 11, 14, 15, 12, 12, 15, 13, 16, 17, 14, 14, 17, 15, 18, 19, 16, 16, 19, 17, 20, 21, 18, 18, 21, 19, 22, 23, 20, 20, 23, 21, 24, 25, 22, 22, 25, 23, 26, 27, 24, 24, 27, 25, 28, 29, 30, 30, 29, 31, 32, 33, 28, 28, 33, 29, 2, 3, 32, 32, 3, 33], 7 | "vertexPositions" : [[-0.4462376, -1.639709, 1.798019, -0.4462376, -3.308047, 1.798019, -0.5086677, -1.639709, 1.704592, -0.5086677, -3.308047, 1.704592, -0.4243176, -1.639709, 1.908223, -0.4243176, -3.308047, 1.908223, -0.4462376, -1.639709, 2.018428, -0.4462376, -3.308047, 2.018428, -0.5086677, -1.639709, 2.111854, -0.5086677, -3.308047, 2.111854, -0.6020977, -1.639709, 2.17428, -0.6020977, -3.308047, 2.17428, -0.7122977, -1.639709, 2.196201, -0.7122977, -3.308047, 2.196201, -0.8225076, -1.639709, 2.17428, -0.8225076, -3.308047, 2.17428, -0.9159276, -1.639709, 2.111854, -0.9159276, -3.308047, 2.111854, -0.9783578, -1.639709, 2.018427, -0.9783578, -3.308047, 2.018427, -1.000278, -1.639709, 1.908223, -1.000278, -3.308047, 1.908223, -0.9783578, -1.639709, 1.798019, -0.9783578, -3.308047, 1.798019, -0.9159276, -1.639709, 1.704592, -0.9159276, -3.308047, 1.704592, -0.8224976, -1.639709, 1.642166, -0.8224976, -3.308047, 1.642166, -0.7122977, -1.639709, 1.620245, -0.7122977, -3.308047, 1.620245, -0.8224976, -1.639709, 1.642166, -0.8224976, -3.308047, 1.642166, -0.6020977, -1.639709, 1.642166, -0.6020977, -3.308047, 1.642166]], 8 | "vertexNormals" : [[0.9238752, 0, -0.3826939, 0.9238752, 0, -0.3826939, 0.7070907, 0, -0.7071229, 0.7070907, 0, -0.7071229, 1, 0, 0, 1, 0, 0, 0.9238746, 0, 0.3826954, 0.9238746, 0, 0.3826954, 0.7070889, 0, 0.7071247, 0.7070889, 0, 0.7071247, 0.3826799, 0, 0.9238809, 0.3826799, 0, 0.9238809, 0, 0, 1, 0, 0, 1, -0.3826948, 0, 0.9238749, -0.3826948, 0, 0.9238749, -0.7071082, 0, 0.7071054, -0.7071082, 0, 0.7071054, -0.9238752, 0, 0.3826939, -0.9238752, 0, 0.3826939, -1, 0, 0, -1, 0, 0, -0.9238752, 0, -0.3826939, -0.9238752, 0, -0.3826939, -0.7070907, 0, -0.7071229, -0.7070907, 0, -0.7071229, -0.3826799, 0, -0.9238809, -0.3826799, 0, -0.9238809, 0, 0, -1, 0, 0, -1, -0.3826799, 0, -0.9238809, -0.3826799, 0, -0.9238809, 0.3826799, 0, -0.9238809, 0.3826799, 0, -0.9238809]], 9 | "vertexTextureCoords" : [[0.9796766, 0.05880089, 0.923061, 0.0588016, 0.9796793, 0.06261572, 0.923063, 0.06261338, 0.9796783, 0.0549894, 0.9230621, 0.05498862, 0.9796804, 0.05117643, 0.923063, 0.05117643, 0.9796773, 0.04736217, 0.9230633, 0.0473626, 0.979679, 0.04355054, 0.9230635, 0.04355054, 0.9796767, 0.03973649, 0.9230621, 0.03973649, 0.9796779, 0.03592337, 0.923063, 0.03592408, 0.979677, 0.03211004, 0.9230649, 0.03210947, 0.979679, 0.02829727, 0.9230638, 0.02829656, 0.979677, 0.02448421, 0.923062, 0.02448492, 0.979679, 0.02067138, 0.9230641, 0.02067138, 0.979679, 0.01685825, 0.9230621, 0.01685825, 0.979676, 0.01304499, 0.9230641, 0.01304577, 0.979679, 0.07024211, 0.9230641, 0.07024175, 0.9796797, 0.07405431, 0.923062, 0.07405466, 0.9796783, 0.06642728, 0.9230633, 0.06642763]] 10 | } -------------------------------------------------------------------------------- /json/space-station/particleBeam_r_geoShape.json: -------------------------------------------------------------------------------- 1 | { 2 | "materials" : 3 | [ 4 | { "file" : "./json/space-station/customPillar-fx.json", "start" : 0 } 5 | ], 6 | "indices" : [0, 1, 2, 2, 1, 3, 4, 0, 5, 5, 0, 2, 6, 4, 7, 7, 4, 5, 8, 6, 9, 9, 6, 7, 10, 8, 11, 11, 8, 9, 12, 10, 13, 13, 10, 11, 14, 12, 15, 15, 12, 13, 16, 14, 17, 17, 14, 15, 18, 16, 19, 19, 16, 17, 20, 18, 21, 21, 18, 19, 22, 20, 23, 23, 20, 21, 24, 22, 25, 25, 22, 23, 26, 24, 27, 27, 24, 25, 28, 29, 30, 30, 29, 31, 32, 28, 33, 33, 28, 30, 1, 32, 3, 3, 32, 33], 7 | "vertexPositions" : [[5.021642, -1.639709, 1.798019, 5.084072, -1.639709, 1.704592, 5.021642, -3.308047, 1.798019, 5.084072, -3.308047, 1.704592, 4.999722, -1.639709, 1.908223, 4.999722, -3.308047, 1.908223, 5.021642, -1.639709, 2.018428, 5.021642, -3.308047, 2.018428, 5.084072, -1.639709, 2.111854, 5.084072, -3.308047, 2.111854, 5.177503, -1.639709, 2.17428, 5.177503, -3.308047, 2.17428, 5.287703, -1.639709, 2.196201, 5.287703, -3.308047, 2.196201, 5.397912, -1.639709, 2.17428, 5.397912, -3.308047, 2.17428, 5.491332, -1.639709, 2.111854, 5.491332, -3.308047, 2.111854, 5.553762, -1.639709, 2.018427, 5.553762, -3.308047, 2.018427, 5.575683, -1.639709, 1.908223, 5.575683, -3.308047, 1.908223, 5.553762, -1.639709, 1.798019, 5.553762, -3.308047, 1.798019, 5.491332, -1.639709, 1.704592, 5.491332, -3.308047, 1.704592, 5.397902, -1.639709, 1.642166, 5.397902, -3.308047, 1.642166, 5.287703, -1.639709, 1.620245, 5.397902, -1.639709, 1.642166, 5.287703, -3.308047, 1.620245, 5.397902, -3.308047, 1.642166, 5.177503, -1.639709, 1.642166, 5.177503, -3.308047, 1.642166]], 8 | "vertexNormals" : [[-0.923876, 0, -0.3826922, -0.7070904, 0, -0.707123, -0.923876, 0, -0.3826922, -0.7070904, 0, -0.707123, -1, 0, 0, -1, 0, 0, -0.9238753, 0, 0.3826936, -0.9238753, 0, 0.3826936, -0.7070887, 0, 0.7071249, -0.7070887, 0, 0.7071249, -0.3826789, 0, 0.9238814, -0.3826789, 0, 0.9238814, 0, 0, 1, 0, 0, 1, 0.3826952, 0, 0.9238747, 0.3826952, 0, 0.9238747, 0.7071075, 0, 0.707106, 0.7071075, 0, 0.707106, 0.9238744, 0, 0.3826957, 0.9238744, 0, 0.3826957, 1, 0, 0, 1, 0, 0, 0.9238744, 0, -0.3826957, 0.9238744, 0, -0.3826957, 0.7070909, 0, -0.7071227, 0.7070909, 0, -0.7071227, 0.3826811, 0, -0.9238805, 0.3826811, 0, -0.9238805, 0, 0, -1, 0.3826811, 0, -0.9238805, 0, 0, -1, 0.3826811, 0, -0.9238805, -0.3826789, 0, -0.9238814, -0.3826789, 0, -0.9238814]], 9 | "vertexTextureCoords" : [[0.9796766, 0.05880089, 0.9796793, 0.06261572, 0.923061, 0.0588016, 0.923063, 0.06261338, 0.9796783, 0.0549894, 0.9230621, 0.05498862, 0.9796804, 0.05117643, 0.923063, 0.05117643, 0.9796773, 0.04736217, 0.9230633, 0.0473626, 0.979679, 0.04355054, 0.9230635, 0.04355054, 0.9796767, 0.03973649, 0.9230621, 0.03973649, 0.9796779, 0.03592337, 0.923063, 0.03592408, 0.979677, 0.03211004, 0.9230649, 0.03210947, 0.979679, 0.02829727, 0.9230638, 0.02829656, 0.979677, 0.02448421, 0.923062, 0.02448492, 0.979679, 0.02067138, 0.9230641, 0.02067138, 0.979679, 0.01685825, 0.9230621, 0.01685825, 0.979676, 0.01304499, 0.9230641, 0.01304577, 0.979679, 0.07024211, 0.9796797, 0.07405431, 0.9230641, 0.07024175, 0.923062, 0.07405466, 0.9796783, 0.06642728, 0.9230633, 0.06642763]] 10 | } -------------------------------------------------------------------------------- /json/space-station/phong1-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "phong1-fx", 3 | "skinned" : false, 4 | "type" : "phong", 5 | "ambient" : [0,0,0,1], 6 | "diffuse" : [0,0,0,1], 7 | "emission" : "textures/mattePainting_pow2.png", 8 | "emission_uv" : 0, 9 | "shininess" : [10], 10 | "specular" : [0.5,0.5,0.5,1] 11 | } -------------------------------------------------------------------------------- /json/space-station_anim.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "camera1" : 4 | { 5 | "rotateX": 6 | { 7 | "type" : "BEZIER", 8 | "time" : [0, 0.2083333, 0.4166666], 9 | "ANGLE": 10 | { 11 | "pos" : [1.619975, -0.1437631, -1.136701], 12 | "intan" : [-0.3333333, 1.619975, 0.1388888, 0.9819269, 0.3472222, -1.136701], 13 | "outtan" : [0.06944441, 1.619975, 0.2777777, -1.269453, 0.75, -1.136701] 14 | } 15 | }, 16 | "translate": 17 | { 18 | "type" : "BEZIER", 19 | "time" : [0, 0.2083333, 0.4166666], 20 | "Y": 21 | { 22 | "pos" : [0.7805179, 1.5, 1.5], 23 | "intan" : [-0.3333333, -0.3706535, 0.1388888, 1.310228, 0.3472222, 1.5], 24 | "outtan" : [0.06944441, 1.020345, 0.2777777, 1.689772, 0.75, 1.5] 25 | }, 26 | "X": 27 | { 28 | "pos" : [0, 0, 0], 29 | "intan" : [-0.3333333, 0, 0.1388888, 0, 0.3472222, 0], 30 | "outtan" : [0.06944441, 0, 0.2777777, 0, 0.75, 0] 31 | }, 32 | "Z": 33 | { 34 | "pos" : [8.349084, 6.888485, 4.418359], 35 | "intan" : [-0.3333333, 10.68604, 0.1388888, 7.6686, 0.3472222, 5.241734], 36 | "outtan" : [0.06944441, 7.862217, 0.2777777, 6.10837, 0.75, 0.4661572] 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /json/walkable-area.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "WalkableArea_geo", "translate" : [0, 0.4286164, 0], "rotate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 5 | { "type" : "mesh", "file" : "./json/walkable-area/WalkableArea_geoShape-mesh.json" } 6 | ]} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /json/walkable-area/WalkableArea_geoShape-mesh.json: -------------------------------------------------------------------------------- 1 | { 2 | "materials" : 3 | [ 4 | ], 5 | "indices" : [0, 1, 2, 0, 3, 1, 3, 0, 4, 4, 5, 3, 4, 6, 5, 7, 5, 6, 8, 6, 9, 10, 6, 4, 6, 11, 7, 12, 13, 6, 12, 6, 8, 14, 6, 10, 15, 6, 14, 6, 16, 11, 17, 9, 6, 6, 15, 17, 18, 16, 6, 6, 13, 18], 6 | "vertexPositions" : [[-0.3904955, -0.2, 2.941502, 0.3725318, -0.2, 20.91103, -0.3871012, -0.2, 20.92238, 0.3695374, -0.2, 2.9354, -0.4286587, -0.2, 2.118621, 0.4134358, -0.2, 2.120568, -5.80177e-4, -0.2000001, 0.4722952, 1.326089, -0.2, 1.635458, -0.3976236, -0.2, -1.043107, -0.816115, -0.2, -0.7678418, -1.356303, -0.2, 1.609164, 1.810754, -0.2, 0.9595599, 0.4102145, -0.2, -1.043106, 0.827382, -0.2, -0.7678409, -1.819566, -0.2, 0.9792788, -2.007732, -0.2, 0.1240239, 2.014973, -0.2, 0.1240248, -1.651396, -0.2, -0.7037807, 1.660438, -0.2, -0.6446204]] 7 | } -------------------------------------------------------------------------------- /mobile/OperaMobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/OperaMobile.png -------------------------------------------------------------------------------- /mobile/backdrop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/backdrop.jpg -------------------------------------------------------------------------------- /mobile/backdrop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/backdrop.png -------------------------------------------------------------------------------- /mobile/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/fullscreen.png -------------------------------------------------------------------------------- /mobile/idle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/idle.png -------------------------------------------------------------------------------- /mobile/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Opera Mobile WebGL demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 256 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | -------------------------------------------------------------------------------- /mobile/json/character.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "persp", "translate" : [18.29561, 21.46406, -36.40822], "rotate" : [-15.33843, 10591.8, 0], "scale" : [1, 1, 1], "rotatePivot" : [0, 0, 0], "children" : [ 5 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 0.1, "zfar" : 10000.0 } 6 | ]}, 7 | { "type" : "node", "name" : "top", "translate" : [0, 100.1053, 0], "rotate" : [-90, 0, 0], "scale" : [1, 1, 1], "children" : [ 8 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 25.60255, "znear" : 0.1, "zfar" : 10000.0 } 9 | ]}, 10 | { "type" : "node", "name" : "front", "translate" : [-0.4470711, 8.269901, 100.1161], "scale" : [1, 1, 1], "children" : [ 11 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 3.622956, "znear" : 0.1, "zfar" : 10000.0 } 12 | ]}, 13 | { "type" : "node", "name" : "side", "translate" : [100.5196, 9.145576, -0.6957142], "rotate" : [0, 90, 0], "scale" : [1, 1, 1], "children" : [ 14 | { "type" : "camera", "subtype" : "orthographic", "xmag" : 15.77639, "znear" : 0.1, "zfar" : 10000.0 } 15 | ]}, 16 | { "type" : "node", "name" : "RIG_solo", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 17 | { "type" : "node", "name" : "RIG_noScale_grp", "translate" : [0, 0, 0], "scale" : [0.117, 0.117, 0.117], "children" : [ 18 | { "type" : "mesh", "file" : "./json/character/merged.json" } 19 | ]}, 20 | { "type" : "node", "name" : "RIG_joints_grp", "translate" : [0, 0, 0], "scale" : [1, 1, 1], "children" : [ 21 | { "type" : "joint", "name" : "bj_root", "lod" : "xx", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [0.013951, 0, 0], "postRotate" : [0.7803711, 0, 0], "children" : [ 22 | { "type" : "joint", "name" : "bj_COG", "lod" : "xx", "bindTranslation" :[0, 11.01706, -0.7044944], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.7618697, 0, 0], "postRotate" : [0.7618697, 0, 0], "children" : [ 23 | { "type" : "joint", "name" : "bj_spineRoot", "lod" : "x_", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [-179.1666, 0, 180], "postRotate" : [-3.750809, 0, 0], "children" : [ 24 | { "type" : "joint", "name" : "bj_chest", "lod" : "xx", "bindTranslation" :[0, 1.710774, 0.1100414], "bindRotation" : [0, 0, 0], "jointOrient" : [3.681163, 0, 0], "postRotate" : [-8.20581, 0, 0], "children" : [ 25 | { "type" : "joint", "name" : "bj_neckRoot", "lod" : "x_", "bindTranslation" :[0, 2.872519, -0.2603679], "bindRotation" : [0, 0, 0], "jointOrient" : [25.42642, 0, 0], "postRotate" : [-27.22967, 0, 0], "children" : [ 26 | { "type" : "joint", "name" : "bj_head", "lod" : "x_", "bindTranslation" :[0, 0.8412964, 0.5454057], "bindRotation" : [0, 0, 0], "jointOrient" : [9.970071, 0, 0], "postRotate" : [0, 0, 0]} 27 | ]}, 28 | { "type" : "joint", "name" : "bj_L_clavicle", "lod" : "x_", "bindTranslation" :[0.3181662, 2.147406, 0.03433269], "bindRotation" : [0, 0, 0], "jointOrient" : [0.057488, 8.032577, -89.48751], "postRotate" : [178.5763, -88.61498, 179.7818], "children" : [ 29 | { "type" : "joint", "name" : "bj_L_shoulder", "lod" : "xx", "bindTranslation" :[-0.3487489, 1.85798, -0.2393546], "bindRotation" : [0, 0, 0], "jointOrient" : [-93.73047, 45.64685, -92.62478], "postRotate" : [0, 0, 0], "children" : [ 30 | { "type" : "joint", "name" : "bj_L_elbow", "lod" : "x_", "bindTranslation" :[0.05880454, 2.747025, 0.05386012], "bindRotation" : [0, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, -37.22785, 0], "children" : [ 31 | { "type" : "joint", "name" : "bj_L_wrist", "lod" : "__", "bindTranslation" :[-0.1778838, 2.371249, -0.2293983], "bindRotation" : [0, 0, 0], "jointOrient" : [-7.693209, 39.00606, -2.240701], "postRotate" : [9.006295, -39.32423, -3.586556]} 32 | ]} 33 | ]} 34 | ]}, 35 | { "type" : "joint", "name" : "bj_R_clavicle", "lod" : "x_", "bindTranslation" :[-0.318166, 2.147453, 0.0343399], "bindRotation" : [0, 0, 0], "jointOrient" : [-179.9425, -8.032577, 89.48751], "postRotate" : [0, 0, 0], "children" : [ 36 | { "type" : "joint", "name" : "bj_R_shoulder", "lod" : "xx", "bindTranslation" :[-0.3008852, -1.850326, 0.3417481], "bindRotation" : [0, 0, 0], "jointOrient" : [-0.8608915, 0.8678666, -45.9416], "postRotate" : [0, 0, 0], "children" : [ 37 | { "type" : "joint", "name" : "bj_R_elbow", "lod" : "x_", "bindTranslation" :[-0.0588076, -2.747023, -0.05386006], "bindRotation" : [0, 0, 0], "jointOrient" : [51.93431, -3.153543, 0.6189273], "postRotate" : [0, 0, 0], "children" : [ 38 | { "type" : "joint", "name" : "bj_R_wrist", "lod" : "__", "bindTranslation" :[0.00285297, -2.371255, 0.2902752], "bindRotation" : [0, 0, 0], "jointOrient" : [-6.337167, 1.798823, -1.741885], "postRotate" : [0, 0, 0]} 39 | ]} 40 | ]} 41 | ]}, 42 | { "type" : "joint", "name" : "bj_harness_main", "lod" : "x_", "bindTranslation" :[0, 2.784781, 0.188085], "bindRotation" : [0, 0, 0], "jointOrient" : [171.7636, 0, 180], "postRotate" : [0, 0, 0], "children" : [ 43 | { "type" : "joint", "name" : "bj_harness_padBig", "lod" : "__", "bindTranslation" :[-1.6953, 0.141024, 0.2607302], "bindRotation" : [0, 0, 0], "jointOrient" : [1.975576, 6.676362, 106.5253], "postRotate" : [6.961252, 0, -106.4101]}, 44 | { "type" : "joint", "name" : "bj_harness_padSmall", "lod" : "__", "bindTranslation" :[1.641814, 0.141024, 0.3744311], "bindRotation" : [0, 0, 0], "jointOrient" : [2.037478, -6.657809, -107.0585], "postRotate" : [6.961252, 0, 106.94]} 45 | ]} 46 | ]} 47 | ]}, 48 | { "type" : "joint", "name" : "bj_pelvis", "lod" : "xx", "bindTranslation" :[0, 0, 0], "bindRotation" : [0, 0, 0], "jointOrient" : [179.0654, 0, 0], "postRotate" : [1.728904, 0, 0], "children" : [ 49 | { "type" : "joint", "name" : "bj_L_hip", "lod" : "xx", "bindTranslation" :[-1.093311, 1.517099, -0.03888182], "bindRotation" : [0, 0, 0], "jointOrient" : [-1.671761, 0, 0], "postRotate" : [3.99778, 0, 0], "children" : [ 50 | { "type" : "joint", "name" : "bj_L_knee", "lod" : "xx", "bindTranslation" :[0, 4.464725, -0.3169275], "bindRotation" : [0, 0, 0], "jointOrient" : [-13.69354, 0.04425968, -0.001797784], "postRotate" : [0.2320798, 0, 180], "children" : [ 51 | { "type" : "joint", "name" : "bj_L_ankle", "lod" : "__", "bindTranslation" :[-6.08286e-4, -4.110774, 0.04058781], "bindRotation" : [0, 0, 0], "jointOrient" : [77.73943, -0.0433915, 179.9911], "postRotate" : [0, 0, 0], "children" : [ 52 | { "type" : "joint", "name" : "bj_L_toe", "lod" : "__", "bindTranslation" :[0, 1.741616, -0.1062748], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 53 | { "type" : "joint", "name" : "bj_L_toeTip", "lod" : "__", "bindTranslation" :[0, 0.7852713, -0.02177926], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 54 | ]} 55 | ]} 56 | ]} 57 | ]}, 58 | { "type" : "joint", "name" : "bj_R_hip", "lod" : "xx", "bindTranslation" :[1.09331, 1.517104, -0.03888154], "bindRotation" : [0, 0, 0], "jointOrient" : [178.3282, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 59 | { "type" : "joint", "name" : "bj_R_knee", "lod" : "xx", "bindTranslation" :[0, -4.475952, 0.00488591], "bindRotation" : [0, 0, 0], "jointOrient" : [-9.695761, 0.04427732, 0.001292279], "postRotate" : [0, 0, 0], "children" : [ 60 | { "type" : "joint", "name" : "bj_R_ankle", "lod" : "__", "bindTranslation" :[-6.08285e-4, -4.110905, -0.02393664], "bindRotation" : [0, 0, 0], "jointOrient" : [77.50735, -0.04342722, -0.008730851], "postRotate" : [0, 0, 0], "children" : [ 61 | { "type" : "joint", "name" : "bj_R_toe", "lod" : "__", "bindTranslation" :[0, -1.741618, 0.1062741], "bindRotation" : [0, 0, 0], "jointOrient" : [23.8602, 0, 0], "postRotate" : [0, 0, 0], "children" : [ 62 | { "type" : "joint", "name" : "bj_R_toeTip", "lod" : "__", "bindTranslation" :[0, -0.785268, 0.02177917], "bindRotation" : [0, 0, 0], "jointOrient" : [0, 0, 0], "postRotate" : [0, 0, 0]} 63 | ]} 64 | ]} 65 | ]} 66 | ]}, 67 | { "type" : "joint", "name" : "bj_hipPlate", "lod" : "__", "bindTranslation" :[1.606056, 0.3496374, 0.548943], "bindRotation" : [0, 0, 0], "jointOrient" : [-4.313083, -25.6316, -11.85807], "postRotate" : [10.22947, 23.99762, 15.01932]} 68 | ]} 69 | ]} 70 | ]} 71 | ]} 72 | ]} 73 | ] 74 | } 75 | -------------------------------------------------------------------------------- /mobile/json/character/blinn2-fx.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "blinn2-fx", 3 | "stitched" : true, 4 | "type" : "phong", 5 | "ambient" : [0.0,0.0,0.0,1], 6 | "diffuse" : "textures/Color_512.jpg", 7 | "diffuse_uv" : 1, 8 | "emission" : "textures/SI%20512.jpg", 9 | "emission_uv" : 0, 10 | "shininess" : [10], 11 | "specular" : "textures/S_512.jpg", 12 | "specular_uv" : 3 13 | } -------------------------------------------------------------------------------- /mobile/json/mobile-a.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodes" : 3 | [ 4 | { "type" : "node", "name" : "persp", "translate" : [-2.874382, 2.822253, 17.2629], "rotate" : [-5.938341, 6470.6, 0], "scale" : [1, 1, 1], "rotatePivot" : [0, 0, 0], "children" : [ 5 | { "type" : "camera", "subtype" : "perspective", "yfov" : 37.84928, "znear" : 1.0, "zfar" : 100.0 } 6 | ]}, 7 | { "type" : "node", "name" : "lights", "translate" : [0, -0.5, -9], "scale" : [1, 1, 1], "children" : [ 8 | { "type" : "node", "name" : "pathPointLight", "translate" : [0, 2.658036, 10], "scale" : [1, 1, 1], "children" : [ 9 | { "type" : "light", "subtype" : "point", "color" : [0.6282199, 0.7024043, 0.8431373], "constant_attenuation" : 0.0, "linear_attenuation" : 1.0, "quadratic_attenuation" : 0.0 } 10 | ]} 11 | ]} 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /mobile/shaders/standard_fragment.txt: -------------------------------------------------------------------------------- 1 | ##ifdef GL_FRAGMENT_PRECISION_HIGH 2 | precision highp float; 3 | ##else 4 | precision mediump float; 5 | ##endif 6 | 7 | #ifdef MATTE 8 | #ifdef DIFFUSE_TEXTURE 9 | varying vec2 vTextureCoord; 10 | uniform sampler2D uSampler; 11 | #endif 12 | uniform vec4 uDiffuseColor; 13 | void main(void) { 14 | #ifdef DIFFUSE_TEXTURE 15 | gl_FragColor = texture2D(uSampler, vTextureCoord.st); 16 | #else 17 | gl_FragColor = uDiffuseColor; 18 | #endif 19 | } 20 | #else 21 | 22 | #ifdef SHADOWMAP 23 | varying vec4 vPosition; 24 | uniform vec4 uLightLocation; 25 | uniform int uLightType; // 0 = point, 1 = spot, 2 = directional 26 | uniform mat4 uLightViewMatrix; 27 | 28 | void main(void) { 29 | /*float lightLen; 30 | if (uLightType == 2) { 31 | vec4 lightDir = uLightViewMatrix * vPosition; 32 | lightLen = -lightDir.z/uLightLocation.w; 33 | } else { 34 | vec3 lightDir = uLightLocation.xyz - vPosition.xyz; 35 | lightLen = length(lightDir)/uLightLocation.w; 36 | } 37 | vec4 pack = vec4(1.0, 256.0, 65536.0, 16777216.0); 38 | gl_FragColor = pack*lightLen;*/ 39 | gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); 40 | } 41 | #else 42 | 43 | #ifdef NORMAL_TEXTURE 44 | // Enable OES_standard_derivatives if available and normalmapping is enabled 45 | ##ifdef GL_OES_standard_derivatives 46 | #extension GL_OES_standard_derivatives : enable 47 | ##endif 48 | #endif 49 | 50 | varying vec4 vPosition; 51 | varying vec4 vTransformedNormal; 52 | #ifdef DIFFUSE_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE || SPECULAR_TEXTURE 53 | varying vec2 vTextureCoord; 54 | #endif 55 | #ifdef EMISSIVE_TEXTURE 56 | varying vec2 vEmissiveTexCoord; 57 | #endif 58 | 59 | #ifdef PHONG 60 | ##ifndef MAX_LIGHTS 61 | ##define MAX_LIGHTS 8 62 | ##endif 63 | #ifndef SHININESS_TEXTURE 64 | uniform float uMaterialShininess; 65 | #endif 66 | uniform vec3 uCameraPosition; 67 | #endif 68 | 69 | uniform vec3 uAmbientColor; 70 | 71 | /* Light sources */ 72 | uniform int uNumLights; 73 | uniform int uLightType[MAX_LIGHTS]; // 0 = point, 1 = spot, 2 = directional 74 | uniform vec4 uLightLocation[MAX_LIGHTS]; 75 | uniform mat4 uLightViewMatrix[MAX_LIGHTS]; 76 | uniform mat4 uLightVPMatrix[MAX_LIGHTS]; 77 | #ifdef PHONG 78 | uniform vec3 uLightSpecularColor[MAX_LIGHTS]; 79 | #endif 80 | uniform vec3 uLightDiffuseColor[MAX_LIGHTS]; 81 | #ifdef SHADOWED 82 | uniform int uCastsShadows[MAX_LIGHTS]; 83 | uniform sampler2D uShadowSampler[MAX_LIGHTS]; 84 | #endif 85 | 86 | #ifdef DIFFUSE_TEXTURE 87 | uniform sampler2D uSampler; 88 | #else 89 | uniform vec4 uDiffuseColor; 90 | #endif 91 | #ifdef SHININESS_TEXTURE 92 | uniform sampler2D uShininessSampler; 93 | #endif 94 | #ifdef NORMAL_TEXTURE 95 | uniform sampler2D uNormalSampler; 96 | #endif 97 | uniform sampler2D uLightConeSampler; 98 | #ifdef EMISSIVE_TEXTURE 99 | uniform sampler2D uEmissiveSampler; 100 | #else 101 | uniform vec4 uEmissiveColor; 102 | #endif 103 | #ifdef SPECULAR_TEXTURE 104 | uniform sampler2D uSpecularSampler; 105 | #endif 106 | 107 | 108 | void main(void) { 109 | #ifdef PHONG 110 | #ifdef SHININESS_TEXTURE 111 | float shininess = 30.0 * texture2D(uShininessSampler, vTextureCoord.st).r; 112 | #else 113 | float shininess = uMaterialShininess; 114 | #endif 115 | #endif 116 | 117 | vec3 normal = normalize(vTransformedNormal.xyz); 118 | #ifdef NORMAL_TEXTURE 119 | ##ifdef GL_OES_standard_derivatives 120 | vec2 deltaTexX = dFdx(vTextureCoord); 121 | vec2 deltaTexY = dFdy(vTextureCoord); 122 | vec4 deltaPosX = dFdx(vPosition); 123 | vec4 deltaPosY = dFdy(vPosition); 124 | vec3 tangent = normalize(deltaTexY.t * deltaPosX.xyz - deltaTexX.t * deltaPosY.xyz); 125 | vec3 bitangent = normalize(-deltaTexY.s * deltaPosX.xyz + deltaTexX.s * deltaPosY.xyz); 126 | mat3 tsTransform = mat3(tangent, bitangent, normal); 127 | normal = texture2D(uNormalSampler, vTextureCoord.st).xyz * 2.0 - vec3(1.0); 128 | normal = normalize(tsTransform * normal); 129 | ##endif 130 | #endif 131 | 132 | vec3 diffuseContrib = uAmbientColor; 133 | #ifdef PHONG 134 | vec3 specularContrib = vec3(0); 135 | #endif 136 | 137 | // Iterate light sources 138 | float lightDist, attenuation, diffuseLightWeighting; 139 | vec2 lightTextureCoord; 140 | vec3 lightLength, lightDirection, lightContrib; 141 | vec4 lsPos; 142 | #ifdef PHONG 143 | vec3 specular, viewDirection, reflectionDirection; 144 | #endif 145 | #ifdef SHADOWED 146 | float shadowDist; 147 | vec4 shadow, lvsPos; 148 | const vec4 unpack = vec4(1.0, 1.0/256.0, 1.0/65536.0, 1.0/16777216.0); 149 | #endif 150 | for (int l = 0; l < MAX_LIGHTS; ++l) 151 | { 152 | if (l >= uNumLights) 153 | continue; 154 | 155 | if (uLightType[l] == 2) { 156 | lightDirection = normalize(-uLightLocation[l].xyz); 157 | } else { 158 | lightLength = uLightLocation[l].xyz - vPosition.xyz; 159 | lightDirection = normalize(lightLength); 160 | } 161 | 162 | #ifdef SHADOWED 163 | shadowDist = 1.0e5; 164 | #endif 165 | if (uLightType[l] != 0) { 166 | lsPos = uLightVPMatrix[l] * vPosition; 167 | //if (lsPos.z < 0.0) 168 | //continue; 169 | lightTextureCoord = (lsPos.xy/lsPos.w)*0.5+vec2(0.5); 170 | #ifdef SHADOWED 171 | if (uCastsShadows[l] != 0) { 172 | if (l == 0) shadow = texture2D(uShadowSampler[0], lightTextureCoord); 173 | else if (l == 1) shadow = texture2D(uShadowSampler[1], lightTextureCoord); 174 | else if (l == 2) shadow = texture2D(uShadowSampler[2], lightTextureCoord); 175 | else if (l == 3) shadow = texture2D(uShadowSampler[3], lightTextureCoord); 176 | else if (l == 4) shadow = texture2D(uShadowSampler[4], lightTextureCoord); 177 | else if (l == 5) shadow = texture2D(uShadowSampler[5], lightTextureCoord); 178 | else if (l == 6) shadow = texture2D(uShadowSampler[6], lightTextureCoord); 179 | else shadow = texture2D(uShadowSampler[7], lightTextureCoord); 180 | shadowDist = dot(shadow, unpack); 181 | } 182 | #endif 183 | } 184 | if (uLightType[l] == 2) { 185 | #ifdef SHADOWED 186 | lvsPos = uLightViewMatrix[l] * vPosition; 187 | lightDist = -lvsPos.z / uLightLocation[l].w; 188 | lightDist *= 0.9999; 189 | #endif 190 | attenuation = 1.0; 191 | } else { 192 | lightDist = length(lightLength) / uLightLocation[l].w; 193 | lightDist *= 0.9999; 194 | attenuation = clamp(1.0 - lightDist, 0.0, 1.0); 195 | } 196 | #ifdef SHADOWED 197 | if (lightDist > shadowDist) 198 | continue; 199 | #endif 200 | 201 | diffuseLightWeighting = dot(normal, lightDirection); 202 | if (diffuseLightWeighting > 0.0) { 203 | lightContrib = vec3(attenuation); 204 | if (uLightType[l] == 1) 205 | lightContrib *= texture2D(uLightConeSampler, lightTextureCoord).rgb; 206 | diffuseContrib += uLightDiffuseColor[l] * lightContrib * diffuseLightWeighting; 207 | 208 | #ifdef PHONG 209 | #ifdef SPECULAR_TEXTURE 210 | specular = uLightSpecularColor[l] * texture2D(uSpecularSampler, vTextureCoord.st).rgb; 211 | #else 212 | specular = uLightSpecularColor[l]; 213 | #endif 214 | viewDirection = normalize(vPosition.xyz-uCameraPosition); 215 | reflectionDirection = reflect(lightDirection, normal); 216 | specular *= pow(max(dot(reflectionDirection, viewDirection), 0.0), shininess); 217 | specularContrib += specular * lightContrib; 218 | #endif 219 | } 220 | } 221 | 222 | #ifdef DIFFUSE_TEXTURE 223 | gl_FragColor = texture2D(uSampler, vTextureCoord.st); 224 | #else 225 | gl_FragColor = uDiffuseColor; 226 | #endif 227 | 228 | gl_FragColor.rgb *= diffuseContrib; 229 | 230 | #ifdef EMISSIVE_TEXTURE 231 | gl_FragColor.rgb += texture2D(uEmissiveSampler, vEmissiveTexCoord).rgb; 232 | #else 233 | gl_FragColor.rgb += uEmissiveColor.rbg; 234 | #endif 235 | 236 | #ifdef PHONG 237 | gl_FragColor.rgb += specularContrib; 238 | #endif 239 | } 240 | 241 | #endif 242 | #endif 243 | -------------------------------------------------------------------------------- /mobile/shaders/standard_vertex.txt: -------------------------------------------------------------------------------- 1 | attribute vec3 aVertexPosition; 2 | 3 | #ifndef SHADOWMAP 4 | #ifdef EMISSIVE_TEXTURE 5 | attribute vec2 aEmissiveTexCoord; 6 | #endif 7 | #ifndef MATTE 8 | attribute vec3 aVertexNormal; 9 | #endif 10 | #ifdef DIFFUSE_TEXTURE || SPECULAR_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE 11 | attribute vec2 aTextureCoord; 12 | #endif 13 | #endif 14 | #ifdef SKINNED 15 | attribute vec4 aVertexWeights; 16 | #endif 17 | #ifdef SKINNED || STITCHED 18 | attribute vec4 aJointIndices; 19 | #endif 20 | 21 | uniform mat4 uMMatrix; 22 | uniform mat4 uVPMatrix; 23 | #ifndef MATTE || SHADOWMAP 24 | uniform mat4 uNMatrix; 25 | #endif 26 | #ifdef SKINNED || STITCHED 27 | ##ifndef MAX_BONES 28 | ##define MAX_BONES 30 29 | ##endif 30 | uniform mat4 uJointInvBindMatrices[MAX_BONES]; 31 | uniform mat4 uJointMatrices[MAX_BONES]; 32 | #endif 33 | 34 | #ifdef MATTE 35 | vec4 vPosition; 36 | #else 37 | varying vec4 vPosition; 38 | #endif 39 | #ifdef EMISSIVE_TEXTURE 40 | varying vec2 vEmissiveTexCoord; 41 | #endif 42 | #ifndef MATTE || SHADOWMAP 43 | varying vec4 vTransformedNormal; 44 | #endif 45 | #ifdef DIFFUSE_TEXTURE || SPECULAR_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE 46 | varying vec2 vTextureCoord; 47 | #endif 48 | 49 | void main(void) { 50 | #ifdef SKINNED || STITCHED 51 | vec4 skinnedPos = vec4(0,0,0,0); 52 | #ifndef MATTE || SHADOWMAP 53 | vec4 skinnedNorm = vec4(0,0,0,0); 54 | #endif 55 | #ifdef STITCHED 56 | int i = int(aJointIndices[0]); 57 | mat4 temp = uJointMatrices[i] * uJointInvBindMatrices[i]; 58 | skinnedPos = temp * vec4(aVertexPosition, 1.0); 59 | #ifndef MATTE || SHADOWMAP 60 | skinnedNorm = temp * vec4(aVertexNormal, 0.0); 61 | #endif 62 | #else 63 | for (int j = 0; j < 4; ++j) 64 | { 65 | int i = int(aJointIndices[j]); 66 | mat4 temp = uJointMatrices[i] * uJointInvBindMatrices[i]; 67 | skinnedPos += temp * vec4(aVertexPosition, 1.0) * aVertexWeights[j]; 68 | #ifndef MATTE || SHADOWMAP 69 | skinnedNorm += temp * vec4(aVertexNormal, 0.0) * aVertexWeights[j]; 70 | #endif 71 | } 72 | #endif 73 | vPosition = uMMatrix * skinnedPos; 74 | #ifndef MATTE || SHADOWMAP 75 | vTransformedNormal = uNMatrix * skinnedNorm; 76 | #endif 77 | #else 78 | vPosition = uMMatrix * vec4(aVertexPosition, 1.0); 79 | #ifndef MATTE || SHADOWMAP 80 | vTransformedNormal = uNMatrix * vec4(aVertexNormal, 0.0); 81 | #endif 82 | #endif 83 | gl_Position = uVPMatrix * vPosition; 84 | #ifdef EMISSIVE_TEXTURE 85 | vEmissiveTexCoord = aEmissiveTexCoord; 86 | #endif 87 | #ifdef DIFFUSE_TEXTURE || SPECULAR_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE 88 | vTextureCoord = aTextureCoord; 89 | #endif 90 | } 91 | -------------------------------------------------------------------------------- /mobile/textures/Color_512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/textures/Color_512.jpg -------------------------------------------------------------------------------- /mobile/textures/SI 512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/textures/SI 512.jpg -------------------------------------------------------------------------------- /mobile/textures/S_512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/textures/S_512.jpg -------------------------------------------------------------------------------- /mobile/walk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/mobile/walk.png -------------------------------------------------------------------------------- /preprocess-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 29 |
30 | defined: 31 | 32 |
33 |
34 |
35 | -------------------------------------------------------------------------------- /py/ColladaBone.py: -------------------------------------------------------------------------------- 1 | import xml.dom.minidom 2 | 3 | # Get a child of 'parentNode' with the specified type and name. 4 | def GetChildNode(parentNode, nodeType, nodeName): 5 | n = parentNode.firstChild 6 | while n != None: 7 | if n.nodeType == n.ELEMENT_NODE: 8 | if n.tagName == nodeType: 9 | if n.getAttribute("sid") == nodeName: 10 | return n 11 | n = n.nextSibling 12 | return None 13 | 14 | 15 | class Bone(): 16 | def __init__(self, node): 17 | self.name = node.getAttribute("name") 18 | 19 | # According to the collada spec we should be able to just convert 20 | # the transforms to column matrices and do pre multiplication in the 21 | # listed order, but the exporters seem to be buggy so we'll specifically 22 | # get the attributes by name. 23 | self.AddVecAttr(node, "translate", "translate") 24 | self.AddVecAttr(node, "rotate", "rotateZ") 25 | self.AddVecAttr(node, "rotate", "rotateY") 26 | self.AddVecAttr(node, "rotate", "rotateX") 27 | self.AddVecAttr(node, "rotate", "jointOrientZ") 28 | self.AddVecAttr(node, "rotate", "jointOrientY") 29 | self.AddVecAttr(node, "rotate", "jointOrientX") 30 | self.AddVecAttr(node, "rotate", "rotateAxisZ") 31 | self.AddVecAttr(node, "rotate", "rotateAxisY") 32 | self.AddVecAttr(node, "rotate", "rotateAxisX") 33 | 34 | self.bindTranslation = [0, 0, 0] 35 | if hasattr(self, 'translate'): 36 | self.bindTranslation = self.translate 37 | 38 | self.bindRotation = [0, 0, 0] 39 | if hasattr(self, 'rotateX'): 40 | self.bindRotation[0] = getattr(self, 'rotateX')[3] 41 | if hasattr(self, 'rotateY'): 42 | self.bindRotation[1] = getattr(self, 'rotateY')[3] 43 | if hasattr(self, 'rotateZ'): 44 | self.bindRotation[2] = getattr(self, 'rotateZ')[3] 45 | 46 | self.jointOrient = [0, 0, 0] 47 | if hasattr(self, 'jointOrientX'): 48 | self.jointOrient[0] = getattr(self, 'jointOrientX')[3] 49 | if hasattr(self, 'jointOrientY'): 50 | self.jointOrient[1] = getattr(self, 'jointOrientY')[3] 51 | if hasattr(self, 'jointOrientZ'): 52 | self.jointOrient[2] = getattr(self, 'jointOrientZ')[3] 53 | 54 | self.postRotate = [0, 0, 0] 55 | if hasattr(self, 'rotateAxisX'): 56 | self.postRotate[0] = getattr(self, 'rotateAxisX')[3] 57 | if hasattr(self, 'rotateAxisY'): 58 | self.postRotate[1] = getattr(self, 'rotateAxisY')[3] 59 | if hasattr(self, 'rotateAxisZ'): 60 | self.postRotate[2] = getattr(self, 'rotateAxisZ')[3] 61 | 62 | self.children = [] 63 | 64 | def AddVecAttr(self, parentNode, nodeType, attrName): 65 | n = GetChildNode(parentNode, nodeType, attrName) 66 | if n != None: 67 | setattr(self, attrName, [str(s) for s in n.firstChild.data.strip().split(' ')]) 68 | 69 | def Write(self, outFolder): 70 | for c in self.children: 71 | c.Write(outFolder); 72 | 73 | def WriteToScene(self, fileHandle, indent, outFolder): 74 | for i in range(indent): 75 | fileHandle.write(' ') 76 | fileHandle.write('{ "type" : "joint"') 77 | fileHandle.write(', "name" : "' + self.name + '"') 78 | fileHandle.write(', "bindTranslation" :' + str(getattr(self, 'bindTranslation')).replace("'", '')) 79 | fileHandle.write(', "bindRotation" : ' + str(getattr(self, 'bindRotation')).replace("'", '')) 80 | fileHandle.write(', "jointOrient" : ' + str(getattr(self, 'jointOrient')).replace("'", '')) 81 | fileHandle.write(', "postRotate" : ' + str(getattr(self, 'postRotate')).replace("'", '')) 82 | 83 | if len(self.children) != 0: 84 | fileHandle.write(', "children" : [\n') 85 | for c in range(len(self.children)): 86 | if c != 0: 87 | fileHandle.write(',\n') 88 | self.children[c].WriteToScene(fileHandle, indent + 2, outFolder) 89 | fileHandle.write('\n') 90 | for i in range(indent): 91 | fileHandle.write(' ') 92 | fileHandle.write(']') 93 | fileHandle.write('}') 94 | 95 | 96 | -------------------------------------------------------------------------------- /py/ColladaCamera.py: -------------------------------------------------------------------------------- 1 | # Get a child of 'parentNode' with the specified type and name. 2 | def GetChildNodeMatchingAttr(parentNode, nodeType, nodeName, attrName): 3 | n = parentNode.firstChild 4 | while n != None: 5 | if n.nodeType == n.ELEMENT_NODE: 6 | if n.tagName == nodeType: 7 | if n.getAttribute(attrName) == nodeName: 8 | return n 9 | n = n.nextSibling 10 | return None 11 | 12 | def GetChildNode(parentNode, nodeType): 13 | n = parentNode.firstChild 14 | while n != None: 15 | if n.nodeType == n.ELEMENT_NODE: 16 | if n.tagName == nodeType: 17 | return n 18 | n = n.nextSibling 19 | return None 20 | 21 | def GetChildElement(parentNode): 22 | n = parentNode.firstChild 23 | while n != None: 24 | if n.nodeType == n.ELEMENT_NODE: 25 | return n 26 | n = n.nextSibling 27 | return None 28 | 29 | 30 | class Camera: 31 | def __init__(self, doc, node): 32 | cameraURL = node.getAttribute('url') 33 | library_cameras = doc.getElementsByTagName('library_cameras')[0] 34 | camera = GetChildNodeMatchingAttr(library_cameras, 'camera', cameraURL[1:], 'id') 35 | optics = GetChildNode(camera, 'optics') 36 | technique_common = GetChildNode(optics, 'technique_common') 37 | cameraNode = GetChildElement(technique_common) 38 | 39 | self.type = 'camera' 40 | self.subtype = cameraNode.tagName 41 | 42 | self.GetCameraParameter(cameraNode, 'znear') 43 | self.GetCameraParameter(cameraNode, 'zfar') 44 | if cameraNode.tagName == 'perspective': 45 | self.GetCameraParameter(cameraNode, 'xfov') 46 | self.GetCameraParameter(cameraNode, 'yfov') 47 | elif cameraNode.tagName == 'orthographic': 48 | self.GetCameraParameter(cameraNode, 'xmag') 49 | self.GetCameraParameter(cameraNode, 'ymag') 50 | 51 | 52 | def GetCameraParameter(self, cameraNode, param): 53 | tmp = GetChildNode(cameraNode, param) 54 | if tmp != None: 55 | setattr(self, param, float(tmp.firstChild.data.strip())) 56 | 57 | 58 | def WriteToScene(self, fileHandle, indent, outFolder): 59 | for i in range(indent): 60 | fileHandle.write(' ') 61 | fileHandle.write('{ "type" : "' + self.type + '", "subtype" : "' + self.subtype + '"') 62 | if hasattr(self, 'xfov'): 63 | fileHandle.write(', "xfov" : ' + str(self.xfov)) 64 | if hasattr(self, 'yfov'): 65 | fileHandle.write(', "yfov" : ' + str(self.yfov)) 66 | if hasattr(self, 'xmag'): 67 | fileHandle.write(', "xmag" : ' + str(self.xmag)) 68 | if hasattr(self, 'ymag'): 69 | fileHandle.write(', "ymag" : ' + str(self.ymag)) 70 | if hasattr(self, 'znear'): 71 | fileHandle.write(', "znear" : ' + str(self.znear)) 72 | if hasattr(self, 'zfar'): 73 | fileHandle.write(', "zfar" : ' + str(self.zfar)) 74 | fileHandle.write(' }') 75 | 76 | def Write(self, outFolder): 77 | return; 78 | -------------------------------------------------------------------------------- /py/ColladaLight.py: -------------------------------------------------------------------------------- 1 | # Get a child of 'parentNode' with the specified type and name. 2 | def GetChildNodeMatchingAttr(parentNode, nodeType, nodeName, attrName): 3 | n = parentNode.firstChild 4 | while n != None: 5 | if n.nodeType == n.ELEMENT_NODE: 6 | if n.tagName == nodeType: 7 | if n.getAttribute(attrName) == nodeName: 8 | return n 9 | n = n.nextSibling 10 | return None 11 | 12 | def GetChildNode(parentNode, nodeType): 13 | n = parentNode.firstChild 14 | while n != None: 15 | if n.nodeType == n.ELEMENT_NODE: 16 | if n.tagName == nodeType: 17 | return n 18 | n = n.nextSibling 19 | return None 20 | 21 | def GetChildElement(parentNode): 22 | n = parentNode.firstChild 23 | while n != None: 24 | if n.nodeType == n.ELEMENT_NODE: 25 | return n 26 | n = n.nextSibling 27 | return None 28 | 29 | 30 | class Light: 31 | def __init__(self, doc, node): 32 | lightURL = node.getAttribute('url') 33 | library_lights = doc.getElementsByTagName('library_lights')[0] 34 | light = GetChildNodeMatchingAttr(library_lights, 'light', lightURL[1:], 'id') 35 | technique_common = GetChildNode(light, 'technique_common') 36 | lightNode = GetChildElement(technique_common) 37 | self.type = 'light' 38 | self.subtype = lightNode.tagName 39 | color = GetChildNode(lightNode, 'color') 40 | if color != None: 41 | self.color = [str(s) for s in color.firstChild.data.strip().split(' ')] 42 | else: 43 | self.color = [1,1,1] 44 | 45 | if lightNode.tagName == 'spot' or lightNode.tagName == 'point': 46 | self.GetLightParameter(lightNode, 'constant_attenuation') 47 | self.GetLightParameter(lightNode, 'linear_attenuation') 48 | self.GetLightParameter(lightNode, 'quadratic_attenuation') 49 | if lightNode.tagName == 'spot': 50 | self.GetLightParameter(lightNode, 'falloff_angle') 51 | self.GetLightParameter(lightNode, 'falloff_exponent') 52 | 53 | def GetLightParameter(self, lightNode, param): 54 | tmp = GetChildNode(lightNode, param) 55 | if tmp != None: 56 | setattr(self, param, float(tmp.firstChild.data.strip())) 57 | 58 | 59 | def WriteToScene(self, fileHandle, indent, outFolder): 60 | for i in range(indent): 61 | fileHandle.write(' ') 62 | fileHandle.write('{ "type" : "' + self.type + '", "subtype" : "' + self.subtype + '", "color" : ' + str(self.color).replace("'",'')) 63 | if hasattr(self, 'constant_attenuation'): 64 | fileHandle.write(', "constant_attenuation" : ' + str(self.constant_attenuation)) 65 | if hasattr(self, 'linear_attenuation'): 66 | fileHandle.write(', "linear_attenuation" : ' + str(self.linear_attenuation)) 67 | if hasattr(self, 'quadratic_attenuation'): 68 | fileHandle.write(', "quadratic_attenuation" : ' + str(self.quadratic_attenuation)) 69 | if hasattr(self, 'falloff_angle'): 70 | fileHandle.write(', "falloff_angle" : ' + str(self.falloff_angle)) 71 | if hasattr(self, 'falloff_exponent'): 72 | fileHandle.write(', "falloff_exponent" : ' + str(self.falloff_exponent)) 73 | fileHandle.write(' }') 74 | 75 | def Write(self, outFolder): 76 | return; 77 | -------------------------------------------------------------------------------- /py/ColladaMaterial.py: -------------------------------------------------------------------------------- 1 | import xml.dom.minidom 2 | import os 3 | 4 | # Basic material info. 5 | class Material(): 6 | def __init__(self, fx, doc, skin): 7 | if hasattr(fx, "name"): 8 | self.name = fx.getAttribute("name") 9 | else: 10 | self.name = fx.getAttribute("id") 11 | self.count = 0 12 | self.diffuse = "0,0,0,1" 13 | self.materialType = "unknown" 14 | self.ambient = "0,0,0,1" 15 | self.shininessTex = "" 16 | self.shininess = "10" 17 | self.skinned = skin 18 | self.channelNames = ["ambient", "bump", "diffuse", "emission", "shininess", "specular"] 19 | 20 | if len(fx.getElementsByTagName("lambert")) != 0: 21 | self.materialType = "lambert" 22 | if len(fx.getElementsByTagName("phong")) != 0: 23 | self.materialType = "phong" 24 | if len(fx.getElementsByTagName("blinn")) != 0: 25 | self.materialType = "phong" 26 | 27 | self.commonLUT = dict() 28 | for profile in fx.getElementsByTagName('profile_COMMON'): 29 | for newparam in profile.getElementsByTagName('newparam'): 30 | sid = newparam.getAttribute('sid') 31 | for node in newparam.childNodes: 32 | if node.nodeType == node.ELEMENT_NODE: 33 | if node.tagName == 'surface': 34 | self.commonLUT[sid] = ('surface', str(node.childNodes[1].childNodes[0].nodeValue)) 35 | elif node.tagName == 'sampler2D': 36 | self.commonLUT[sid] = ('sampler2D', str(node.childNodes[1].childNodes[0].nodeValue)) 37 | 38 | for channel in self.channelNames: 39 | self.AddChannel(doc, fx, channel); 40 | 41 | 42 | def AddChannel(self, doc, fx, channelName): 43 | for channel in fx.getElementsByTagName(channelName): 44 | for col in channel.getElementsByTagName("color"): 45 | setattr(self, channelName, col.firstChild.data.strip().replace(' ', ',').replace(' ', ',')) 46 | for tex in channel.getElementsByTagName("texture"): 47 | texName = tex.getAttribute("texture") 48 | uvSetName = tex.getAttribute("texcoord") 49 | while texName in self.commonLUT: 50 | texName = self.commonLUT[texName][1] 51 | libraryImages = doc.getElementsByTagName('library_images')[0] 52 | for img in libraryImages.getElementsByTagName("image"): 53 | if img.getAttribute("id") == texName: 54 | for src in img.getElementsByTagName("init_from"): 55 | texName = src.firstChild.data 56 | setattr(self, channelName, texName) 57 | setattr(self, channelName + "_uv", uvSetName) 58 | 59 | def ChannelHasTexture(self, channel): 60 | return hasattr(self, channel) and not getattr(self, channel)[0].isdigit() 61 | 62 | def HasTextureChannel(self): 63 | for channel in self.channelNames: 64 | if self.ChannelHasTexture(channel): 65 | return True 66 | return False 67 | 68 | def WriteChannel(self, channel, fileHandle): 69 | if hasattr(self, channel): 70 | if getattr(self, channel)[0].isdigit(): 71 | fileHandle.write(',\n "' + channel + '" : [' + getattr(self, channel) + ']') 72 | else: 73 | fileHandle.write(',\n "' + channel + '" : "' + 'textures/' + getattr(self, channel).split("/")[-1] + '"') 74 | fileHandle.write(',\n "' + channel + '_uv" : ' + getattr(self, channel + "_uv")[3:]) 75 | 76 | 77 | def Write(self, outFolder): 78 | fileHandle = open(outFolder + '/' + self.name + '.json', 'w') 79 | fileHandle.write('{\n "name" : "' + self.name + '",\n "skinned" : ' + str(self.skinned).lower() + ',\n "type" : "' + self.materialType + '"') 80 | 81 | for channel in self.channelNames: 82 | self.WriteChannel(channel, fileHandle) 83 | 84 | fileHandle.write('\n}') 85 | fileHandle.close() 86 | 87 | 88 | -------------------------------------------------------------------------------- /py/ColladaNode.py: -------------------------------------------------------------------------------- 1 | import xml.dom.minidom 2 | 3 | # Get a child of 'parentNode' with the specified type and name. 4 | def GetChildNodeMatchingAttr(parentNode, nodeType, nodeName, attrName): 5 | n = parentNode.firstChild 6 | while n != None: 7 | if n.nodeType == n.ELEMENT_NODE: 8 | if n.tagName == nodeType: 9 | if n.getAttribute(attrName) == nodeName: 10 | return n 11 | n = n.nextSibling 12 | return None 13 | 14 | 15 | class Node(): 16 | def __init__(self, node): 17 | self.name = node.getAttribute("name") 18 | self.children = [] 19 | 20 | # According to the collada spec we should be able to just convert 21 | # the transforms to column matrices and do pre multiplication in the 22 | # listed order, but the exporters seem to be buggy so we'll specifically 23 | # get the attributes by name. 24 | self.AddVecAttr(node, "translate", "translate") 25 | self.AddVecAttr(node, "rotate", "rotateZ") 26 | self.AddVecAttr(node, "rotate", "rotateY") 27 | self.AddVecAttr(node, "rotate", "rotateX") 28 | self.AddVecAttr(node, "scale", "scale") 29 | self.AddVecAttr(node, "translate", "rotatePivot") 30 | #self.AddVecAttr(node, "translate", "rotatePivotInverse") 31 | #self.AddVecAttr(node, "translate", "rotatePivotTranslation") 32 | self.AddVecAttr(node, "translate", "scalePivot") 33 | #self.AddVecAttr(node, "translate", "scalePivotInverse") 34 | #self.AddVecAttr(node, "translate", "scalePivotTranslation") 35 | 36 | self.rotate = [0, 0, 0] 37 | if hasattr(self, 'rotateX'): 38 | self.rotate[0] = getattr(self, 'rotateX')[3] 39 | if hasattr(self, 'rotateY'): 40 | self.rotate[1] = getattr(self, 'rotateY')[3] 41 | if hasattr(self, 'rotateZ'): 42 | self.rotate[2] = getattr(self, 'rotateZ')[3] 43 | 44 | 45 | def AddVecAttr(self, parentNode, nodeType, attrName): 46 | n = GetChildNodeMatchingAttr(parentNode, nodeType, attrName, 'sid') 47 | if n != None: 48 | setattr(self, attrName, [str(s) for s in n.firstChild.data.strip().split(' ')]) 49 | 50 | def Write(self, outFolder): 51 | for c in self.children: 52 | c.Write(outFolder); 53 | 54 | def WriteToScene(self, fileHandle, indent, outFolder): 55 | for i in range(indent): 56 | fileHandle.write(' ') 57 | fileHandle.write('{ "type" : "node"') 58 | fileHandle.write(', "name" : "' + self.name + '"') 59 | if hasattr(self, 'translate') and self.translate != [0,0,0]: 60 | fileHandle.write(', "translate" : ' + str(self.translate).replace("'", '')) 61 | if hasattr(self, 'rotate') and self.rotate != [0,0,0]: 62 | fileHandle.write(', "rotate" : ' + str(self.rotate).replace("'", '')) 63 | if hasattr(self, 'scale') and self.scale != [1,1,1]: 64 | fileHandle.write(', "scale" : ' + str(self.scale).replace("'", '')) 65 | if hasattr(self, 'rotatePivot') and self.rotatePivot != [0,0,0]: 66 | fileHandle.write(', "rotatePivot" : ' + str(self.rotatePivot).replace("'", '')) 67 | if hasattr(self, 'scalePivot') and self.scalePivot != [0,0,0]: 68 | fileHandle.write(', "scalePivot" : ' + str(self.scalePivot).replace("'", '')) 69 | 70 | 71 | if len(self.children) != 0: 72 | fileHandle.write(', "children" : [\n') 73 | for c in range(len(self.children)): 74 | if c != 0: 75 | fileHandle.write(',\n') 76 | self.children[c].WriteToScene(fileHandle, indent + 2, outFolder) 77 | fileHandle.write('\n') 78 | for i in range(indent): 79 | fileHandle.write(' ') 80 | fileHandle.write(']') 81 | fileHandle.write('}') 82 | 83 | 84 | -------------------------------------------------------------------------------- /py/ColladaScene.py: -------------------------------------------------------------------------------- 1 | import ColladaMesh 2 | import ColladaBone 3 | import ColladaNode 4 | import ColladaLight 5 | import ColladaCamera 6 | import os 7 | 8 | class Scene: 9 | def __init__(self, doc, visualScene, outFolder): 10 | self.jnodes = [] 11 | for node in visualScene.childNodes: 12 | if node.nodeType == node.ELEMENT_NODE and node.tagName == 'node': 13 | self.jnodes.append(self.ProcessElement(doc, node)) 14 | 15 | def ProcessElement(self, doc, node): 16 | ret = None 17 | if node.getAttribute('type') == 'JOINT': 18 | ret = ColladaBone.Bone(node) 19 | else: 20 | ret = ColladaNode.Node(node) 21 | for child in node.childNodes: 22 | if child.nodeType == node.ELEMENT_NODE: 23 | if child.tagName == 'instance_controller' or child.tagName == 'instance_geometry': 24 | ret.children.append(ColladaMesh.Mesh(doc, child)) 25 | elif child.tagName == 'instance_light': 26 | ret.children.append(ColladaLight.Light(doc, child)) 27 | elif child.tagName == 'instance_camera': 28 | ret.children.append(ColladaCamera.Camera(doc, child)) 29 | elif child.tagName == 'node': 30 | ret.children.append(self.ProcessElement(doc, child)) 31 | return ret 32 | 33 | # Write the scene as a JSON file. 34 | def Write(self, fFolder, fName): 35 | fileHandle = open(fFolder + fName + '.json', 'w') 36 | fileHandle.write('{\n') 37 | fileHandle.write(' "nodes" : \n [\n') 38 | 39 | sceneFolder = fFolder + fName 40 | if not os.path.exists(sceneFolder): 41 | os.makedirs(sceneFolder) 42 | 43 | for m in range(len(self.jnodes)): 44 | if m != 0: 45 | fileHandle.write(',\n') 46 | self.jnodes[m].WriteToScene(fileHandle, 4, sceneFolder) 47 | self.jnodes[m].Write(sceneFolder) 48 | 49 | fileHandle.write('\n ]\n}\n') 50 | fileHandle.close() 51 | -------------------------------------------------------------------------------- /shaders/Pillar-fx_fragment.txt: -------------------------------------------------------------------------------- 1 | ##ifdef GL_ES 2 | precision highp float; 3 | ##endif 4 | 5 | varying vec4 vPosition; 6 | #ifdef DIFFUSE_TEXTURE 7 | varying vec2 vTextureCoord; 8 | uniform sampler2D uSampler; 9 | #endif 10 | uniform float uTime; 11 | void main(void) { 12 | #ifdef DIFFUSE_TEXTURE 13 | vec2 uv1 = vec2(vTextureCoord.s * 5.0 - uTime / 40.0, vTextureCoord.t * 5.0 - uTime / 20.0); 14 | vec2 uv2 = vec2(vTextureCoord.s * 7.0 - uTime / 40.0, vTextureCoord.t * 7.0 + uTime / 20.0); 15 | vec2 uv3 = vec2(vTextureCoord.s * 5.0 + uTime / 20.0, vTextureCoord.t * 5.0 - uTime / 20.0); 16 | vec4 col = (texture2D(uSampler, uv1) + texture2D(uSampler, uv2) + texture2D(uSampler, uv3)) / 2.0; 17 | #else 18 | vec4 col = vec4(1,0,0,1); 19 | #endif 20 | gl_FragColor = vec4(col.rgb, col.r); 21 | } 22 | -------------------------------------------------------------------------------- /shaders/Pillar-fx_vertex.txt: -------------------------------------------------------------------------------- 1 | attribute vec3 aVertexPosition; 2 | 3 | #ifdef DIFFUSE_TEXTURE 4 | attribute vec2 aTextureCoord; 5 | #endif 6 | 7 | uniform mat4 uMMatrix; 8 | uniform mat4 uVPMatrix; 9 | 10 | varying vec4 vPosition; 11 | #ifdef DIFFUSE_TEXTURE 12 | varying vec2 vTextureCoord; 13 | #endif 14 | 15 | void main(void) { 16 | vPosition = uMMatrix * vec4(aVertexPosition, 1.0); 17 | gl_Position = uVPMatrix * vPosition; 18 | #ifdef DIFFUSE_TEXTURE 19 | vTextureCoord = aTextureCoord; 20 | #endif 21 | } 22 | -------------------------------------------------------------------------------- /shaders/standard_fragment.txt: -------------------------------------------------------------------------------- 1 | ##ifdef GL_FRAGMENT_PRECISION_HIGH 2 | precision highp float; 3 | ##else 4 | precision mediump float; 5 | ##endif 6 | 7 | #ifdef SHADOWMAP || SHADOWED 8 | const float pack_max = 256.0*256.0*256.0*256.0-1.0; 9 | const vec4 pack_weight = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0) / pack_max; 10 | #endif 11 | #ifdef SHADOWMAP 12 | vec4 packFloat(float val) 13 | { 14 | vec4 packedVal = floor(vec4(val)/pack_weight); 15 | packedVal = mod(packedVal, 256.0); 16 | return packedVal/255.0; 17 | } 18 | #endif 19 | 20 | #ifdef SHADOWED 21 | float unpackFloat(vec4 val) 22 | { 23 | vec4 packedVal = val*255.0; 24 | return dot(packedVal, pack_weight); 25 | } 26 | #ifdef SHADOWED_PCF 27 | uniform vec2 uShadowTexSize; 28 | float texture2DBilinearUnpack(sampler2D tex, vec2 tc) 29 | { 30 | tc *= uShadowTexSize; 31 | tc -= 0.5; 32 | vec2 w = fract(tc); 33 | tc -= w; 34 | tc += 0.5; 35 | tc /= uShadowTexSize; 36 | vec2 tcTR = tc + vec2(1.0, 0.0)/uShadowTexSize; 37 | vec2 tcBL = tc + vec2(0.0, 1.0)/uShadowTexSize; 38 | vec2 tcBR = tc + vec2(1.0, 1.0)/uShadowTexSize; 39 | return unpackFloat(texture2D(tex, tc))*(1.0-w.x)*(1.0-w.y) + 40 | unpackFloat(texture2D(tex, tcTR))*w.x*(1.0-w.y) + 41 | unpackFloat(texture2D(tex, tcBL))*(1.0-w.x)*w.y + 42 | unpackFloat(texture2D(tex, tcBR))*w.x*w.y; 43 | } 44 | 45 | float texture2DProjBilinearUnpack(sampler2D tex, vec4 tc) 46 | { 47 | return texture2DBilinearUnpack(tex, tc.st/tc.w); 48 | } 49 | #endif 50 | #endif 51 | 52 | #ifdef MATTE 53 | #ifdef DIFFUSE_TEXTURE 54 | varying vec2 vTextureCoord; 55 | uniform sampler2D uSampler; 56 | #endif 57 | uniform vec4 uDiffuseColor; 58 | void main(void) { 59 | #ifdef DIFFUSE_TEXTURE 60 | gl_FragColor = texture2D(uSampler, vTextureCoord.st); 61 | #else 62 | gl_FragColor = uDiffuseColor; 63 | #endif 64 | } 65 | #else 66 | 67 | #ifdef SHADOWMAP 68 | void main(void) { 69 | gl_FragColor = packFloat(gl_FragCoord.z); 70 | } 71 | #else 72 | 73 | #ifdef NORMAL_TEXTURE 74 | // Enable OES_standard_derivatives if available and normalmapping is enabled 75 | ##ifdef GL_OES_standard_derivatives 76 | #extension GL_OES_standard_derivatives : enable 77 | ##endif 78 | #endif 79 | 80 | varying vec4 vPosition; 81 | varying vec4 vTransformedNormal; 82 | #ifdef DIFFUSE_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE || SPECULAR_TEXTURE 83 | varying vec2 vTextureCoord; 84 | #endif 85 | #ifdef EMISSIVE_TEXTURE 86 | varying vec2 vEmissiveTexCoord; 87 | #endif 88 | 89 | #ifdef PHONG 90 | #ifndef SHININESS_TEXTURE 91 | uniform float uMaterialShininess; 92 | #endif 93 | uniform vec3 uCameraPosition; 94 | #endif 95 | 96 | uniform vec3 uAmbientColor; 97 | 98 | /* Light sources */ 99 | uniform int uNumLights; 100 | uniform int uLightType[8]; // 0 = point, 1 = spot, 2 = directional 101 | uniform vec4 uLightLocation[8]; 102 | uniform mat4 uLightViewMatrix[8]; 103 | uniform mat4 uLightVPMatrix[8]; 104 | #ifdef PHONG 105 | uniform vec3 uLightSpecularColor[8]; 106 | #endif 107 | uniform vec3 uLightDiffuseColor[8]; 108 | #ifdef SHADOWED 109 | uniform int uCastsShadows[8]; 110 | uniform sampler2D uShadowSampler[8]; 111 | #endif 112 | 113 | #ifdef DIFFUSE_TEXTURE 114 | uniform sampler2D uSampler; 115 | #else 116 | uniform vec4 uDiffuseColor; 117 | #endif 118 | #ifdef SHININESS_TEXTURE 119 | uniform sampler2D uShininessSampler; 120 | #endif 121 | #ifdef NORMAL_TEXTURE 122 | uniform sampler2D uNormalSampler; 123 | #endif 124 | uniform sampler2D uLightConeSampler; 125 | #ifdef EMISSIVE_TEXTURE 126 | uniform sampler2D uEmissiveSampler; 127 | #else 128 | uniform vec4 uEmissiveColor; 129 | #endif 130 | #ifdef SPECULAR_TEXTURE 131 | uniform sampler2D uSpecularSampler; 132 | #endif 133 | 134 | #ifdef SHADOWED 135 | float calcShadow(sampler2D shadowTex, vec4 lightPos) 136 | { 137 | float lightDist = lightPos.z/lightPos.w; 138 | #ifdef SHADOWED_PCF 139 | vec2 offset = step(0.4, fract(gl_FragCoord.xy * 0.5)); 140 | offset.y += offset.x; 141 | if (offset.y > 1.1) 142 | offset.y = 0.0; 143 | float shadowDepth = texture2DProjBilinearUnpack(shadowTex, lightPos + vec4((vec2(-1.5, 0.5) + offset)*lightPos.ww/uShadowTexSize, 0.0, 0.0)); 144 | float shadow = step(lightDist, shadowDepth); 145 | shadowDepth = texture2DProjBilinearUnpack(shadowTex, lightPos + vec4((vec2(0.5, 0.5) + offset)*lightPos.ww/uShadowTexSize, 0.0, 0.0)); 146 | shadow += step(lightDist, shadowDepth); 147 | shadowDepth = texture2DProjBilinearUnpack(shadowTex, lightPos + vec4((vec2(-1.5, -1.5) + offset)*lightPos.ww/uShadowTexSize, 0.0, 0.0)); 148 | shadow += step(lightDist, shadowDepth); 149 | shadowDepth = texture2DProjBilinearUnpack(shadowTex, lightPos + vec4((vec2(0.5, -1.5) + offset)*lightPos.ww/uShadowTexSize, 0.0, 0.0)); 150 | shadow += step(lightDist, shadowDepth); 151 | 152 | return shadow / 4.0; 153 | #else 154 | float shadowDepth = unpackFloat(texture2DProj(shadowTex, lightPos)); 155 | return step(lightDist, shadowDepth); 156 | #endif 157 | } 158 | #endif 159 | 160 | void main(void) { 161 | #ifdef PHONG 162 | #ifdef SHININESS_TEXTURE 163 | float shininess = 30.0 * texture2D(uShininessSampler, vTextureCoord.st).r; 164 | #else 165 | float shininess = uMaterialShininess; 166 | #endif 167 | #endif 168 | 169 | vec3 normal = normalize(vTransformedNormal.xyz); 170 | #ifdef NORMAL_TEXTURE 171 | ##ifdef GL_OES_standard_derivatives 172 | vec2 deltaTexX = dFdx(vTextureCoord); 173 | vec2 deltaTexY = dFdy(vTextureCoord); 174 | vec4 deltaPosX = dFdx(vPosition); 175 | vec4 deltaPosY = dFdy(vPosition); 176 | vec3 tangent = normalize(deltaTexY.t * deltaPosX.xyz - deltaTexX.t * deltaPosY.xyz); 177 | vec3 bitangent = normalize(-deltaTexY.s * deltaPosX.xyz + deltaTexX.s * deltaPosY.xyz); 178 | mat3 tsTransform = mat3(tangent, bitangent, normal); 179 | normal = texture2D(uNormalSampler, vTextureCoord.st).xyz * 2.0 - vec3(1.0); 180 | normal = normalize(tsTransform * normal); 181 | ##endif 182 | #endif 183 | 184 | vec3 diffuseContrib = uAmbientColor; 185 | #ifdef PHONG 186 | vec3 specularContrib = vec3(0); 187 | #endif 188 | 189 | // Iterate light sources 190 | float lightDist, attenuation, diffuseLightWeighting; 191 | vec3 lightLength, lightDirection, lightContrib; 192 | vec4 lsPos; 193 | #ifdef PHONG 194 | vec3 specular, viewDirection, reflectionDirection; 195 | #endif 196 | for (int l = 0; l < 8; ++l) 197 | { 198 | if (l >= uNumLights) 199 | continue; 200 | 201 | if (uLightType[l] == 2) { 202 | lightDirection = normalize(-uLightLocation[l].xyz); 203 | } else { 204 | lightLength = uLightLocation[l].xyz - vPosition.xyz; 205 | lightDirection = normalize(lightLength); 206 | } 207 | 208 | attenuation = 1.0; 209 | if (uLightType[l] != 0) { 210 | lsPos = uLightVPMatrix[l] * vPosition; 211 | #ifdef SHADOWED 212 | if (uCastsShadows[l] != 0) { 213 | if (l == 0) attenuation = calcShadow(uShadowSampler[0], lsPos); 214 | else if (l == 1) attenuation = calcShadow(uShadowSampler[1], lsPos); 215 | else if (l == 2) attenuation = calcShadow(uShadowSampler[2], lsPos); 216 | else if (l == 3) attenuation = calcShadow(uShadowSampler[3], lsPos); 217 | else if (l == 4) attenuation = calcShadow(uShadowSampler[4], lsPos); 218 | else if (l == 5) attenuation = calcShadow(uShadowSampler[5], lsPos); 219 | else if (l == 6) attenuation = calcShadow(uShadowSampler[6], lsPos); 220 | else attenuation = calcShadow(uShadowSampler[7], lsPos); 221 | } 222 | #endif 223 | } 224 | if (uLightType[l] != 2) { 225 | lightDist = length(lightLength) / uLightLocation[l].w; 226 | attenuation *= clamp(1.0 - lightDist, 0.0, 1.0); 227 | } 228 | 229 | diffuseLightWeighting = dot(normal, lightDirection); 230 | if (diffuseLightWeighting > 0.0) { 231 | lightContrib = vec3(attenuation); 232 | if (uLightType[l] == 1) 233 | lightContrib *= texture2DProj(uLightConeSampler, lsPos).rgb; 234 | diffuseContrib += uLightDiffuseColor[l] * lightContrib * diffuseLightWeighting; 235 | 236 | #ifdef PHONG 237 | #ifdef SPECULAR_TEXTURE 238 | specular = uLightSpecularColor[l] * texture2D(uSpecularSampler, vTextureCoord.st).rgb; 239 | #else 240 | specular = uLightSpecularColor[l]; 241 | #endif 242 | viewDirection = normalize(vPosition.xyz-uCameraPosition); 243 | reflectionDirection = reflect(lightDirection, normal); 244 | specular *= pow(max(dot(reflectionDirection, viewDirection), 0.0), shininess); 245 | specularContrib += specular * lightContrib; 246 | #endif 247 | } 248 | } 249 | 250 | #ifdef DIFFUSE_TEXTURE 251 | gl_FragColor = texture2D(uSampler, vTextureCoord.st); 252 | #else 253 | gl_FragColor = uDiffuseColor; 254 | #endif 255 | 256 | gl_FragColor.rgb *= diffuseContrib; 257 | 258 | #ifdef EMISSIVE_TEXTURE 259 | gl_FragColor.rgb += texture2D(uEmissiveSampler, vEmissiveTexCoord).rgb; 260 | #else 261 | gl_FragColor.rgb += uEmissiveColor.rbg; 262 | #endif 263 | 264 | #ifdef PHONG 265 | gl_FragColor.rgb += specularContrib; 266 | #endif 267 | } 268 | 269 | #endif 270 | #endif 271 | -------------------------------------------------------------------------------- /shaders/standard_vertex.txt: -------------------------------------------------------------------------------- 1 | attribute vec3 aVertexPosition; 2 | 3 | #ifndef SHADOWMAP 4 | #ifdef EMISSIVE_TEXTURE 5 | attribute vec2 aEmissiveTexCoord; 6 | #endif 7 | #ifndef MATTE 8 | attribute vec3 aVertexNormal; 9 | #endif 10 | #ifdef DIFFUSE_TEXTURE || SPECULAR_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE 11 | attribute vec2 aTextureCoord; 12 | #endif 13 | #endif 14 | #ifdef SKINNED 15 | attribute vec4 aVertexWeights; 16 | #endif 17 | #ifdef SKINNED || STITCHED 18 | attribute vec4 aJointIndices; 19 | #endif 20 | 21 | uniform mat4 uMMatrix; 22 | uniform mat4 uVPMatrix; 23 | #ifndef MATTE || SHADOWMAP 24 | uniform mat4 uNMatrix; 25 | #endif 26 | #ifdef SKINNED || STITCHED 27 | uniform mat4 uJointInvBindMatrices[30]; 28 | uniform mat4 uJointMatrices[30]; 29 | #endif 30 | 31 | #ifdef MATTE 32 | vec4 vPosition; 33 | #else 34 | varying vec4 vPosition; 35 | #endif 36 | #ifdef EMISSIVE_TEXTURE 37 | varying vec2 vEmissiveTexCoord; 38 | #endif 39 | #ifndef MATTE || SHADOWMAP 40 | varying vec4 vTransformedNormal; 41 | #endif 42 | #ifdef DIFFUSE_TEXTURE || SPECULAR_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE 43 | varying vec2 vTextureCoord; 44 | #endif 45 | 46 | void main(void) { 47 | #ifdef SKINNED || STITCHED 48 | vec4 skinnedPos = vec4(0,0,0,0); 49 | #ifndef MATTE || SHADOWMAP 50 | vec4 skinnedNorm = vec4(0,0,0,0); 51 | #endif 52 | #ifdef STITCHED 53 | int i = int(aJointIndices[0]); 54 | mat4 temp = uJointMatrices[i] * uJointInvBindMatrices[i]; 55 | skinnedPos = temp * vec4(aVertexPosition, 1.0); 56 | #ifndef MATTE || SHADOWMAP 57 | skinnedNorm += temp * vec4(aVertexNormal, 0.0); 58 | #endif 59 | #else 60 | for (int j = 0; j < 4; ++j) 61 | { 62 | int i = int(aJointIndices[j]); 63 | mat4 temp = uJointMatrices[i] * uJointInvBindMatrices[i]; 64 | skinnedPos += temp * vec4(aVertexPosition, 1.0) * aVertexWeights[j]; 65 | #ifndef MATTE || SHADOWMAP 66 | skinnedNorm += temp * vec4(aVertexNormal, 0.0) * aVertexWeights[j]; 67 | #endif 68 | } 69 | #endif 70 | vPosition = uMMatrix * skinnedPos; 71 | #ifndef MATTE || SHADOWMAP 72 | vTransformedNormal = uNMatrix * skinnedNorm; 73 | #endif 74 | #else 75 | vPosition = uMMatrix * vec4(aVertexPosition, 1.0); 76 | #ifndef MATTE || SHADOWMAP 77 | vTransformedNormal = uNMatrix * vec4(aVertexNormal, 0.0); 78 | #endif 79 | #endif 80 | gl_Position = uVPMatrix * vPosition; 81 | #ifdef EMISSIVE_TEXTURE 82 | vEmissiveTexCoord = aEmissiveTexCoord; 83 | #endif 84 | #ifdef DIFFUSE_TEXTURE || SPECULAR_TEXTURE || SHININESS_TEXTURE || NORMAL_TEXTURE 85 | vTextureCoord = aTextureCoord; 86 | #endif 87 | } 88 | -------------------------------------------------------------------------------- /textures/Color_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/Color_1024.png -------------------------------------------------------------------------------- /textures/Color_2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/Color_2048.png -------------------------------------------------------------------------------- /textures/ConcreteTile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/ConcreteTile.png -------------------------------------------------------------------------------- /textures/ConcreteTile2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/ConcreteTile2.png -------------------------------------------------------------------------------- /textures/ConcreteTile2_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/ConcreteTile2_S.png -------------------------------------------------------------------------------- /textures/ConcreteTile3B.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/ConcreteTile3B.png -------------------------------------------------------------------------------- /textures/ConcreteTile3B_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/ConcreteTile3B_S.png -------------------------------------------------------------------------------- /textures/ConcreteTile_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/ConcreteTile_S.png -------------------------------------------------------------------------------- /textures/MechWall2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/MechWall2.png -------------------------------------------------------------------------------- /textures/MechWall_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/MechWall_S.png -------------------------------------------------------------------------------- /textures/MetalTile2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/MetalTile2.png -------------------------------------------------------------------------------- /textures/MetalTile2_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/MetalTile2_S.png -------------------------------------------------------------------------------- /textures/N_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/N_1024.png -------------------------------------------------------------------------------- /textures/N_2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/N_2048.png -------------------------------------------------------------------------------- /textures/Ridges1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/Ridges1.png -------------------------------------------------------------------------------- /textures/Ridges1_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/Ridges1_S.png -------------------------------------------------------------------------------- /textures/SI 512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/SI 512.png -------------------------------------------------------------------------------- /textures/S_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/S_1024.png -------------------------------------------------------------------------------- /textures/S_2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/S_2048.png -------------------------------------------------------------------------------- /textures/checker.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/checker.jpeg -------------------------------------------------------------------------------- /textures/circle_pad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/circle_pad.png -------------------------------------------------------------------------------- /textures/circle_pad_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/circle_pad_S.png -------------------------------------------------------------------------------- /textures/glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/glass.png -------------------------------------------------------------------------------- /textures/glass_Color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/glass_Color.png -------------------------------------------------------------------------------- /textures/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/keyboard.png -------------------------------------------------------------------------------- /textures/keyboard_S.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/keyboard_S.png -------------------------------------------------------------------------------- /textures/main_lightmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/main_lightmap.png -------------------------------------------------------------------------------- /textures/main_lightmap_2k.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/main_lightmap_2k.png -------------------------------------------------------------------------------- /textures/mattePainting_pow2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/mattePainting_pow2.png -------------------------------------------------------------------------------- /textures/monitorDisplay2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/monitorDisplay2.png -------------------------------------------------------------------------------- /textures/monitorDisplay3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/monitorDisplay3.png -------------------------------------------------------------------------------- /textures/plasma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/plasma.png -------------------------------------------------------------------------------- /textures/red_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/red_light.png -------------------------------------------------------------------------------- /textures/walls_lightmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/operasoftware/Odin/7217b691020580cb3dad6da087835a2de75045e8/textures/walls_lightmap.png -------------------------------------------------------------------------------- /viewer.css: -------------------------------------------------------------------------------- 1 | #rtArea { 2 | position: absolute; 3 | left: 50%; 4 | top: 50%; 5 | } 6 | 7 | #my-canvas { 8 | display: block; 9 | } 10 | 11 | #configview { 12 | -o-transition-property: left; 13 | -o-transition-duration: 1s; 14 | -moz-transition-property: left; 15 | -moz-transition-duration: 1s; 16 | -webkit-transition-property: left; 17 | -webkit-transition-duration: 1s; 18 | border: 10px; 19 | position: fixed; 20 | height: 100%; 21 | width: 200px; 22 | top: 0; 23 | left: 0; 24 | opacity: 0.8; 25 | font-size: 16px; 26 | text-align: left; 27 | color: white; 28 | background: gray; 29 | } 30 | 31 | #text { 32 | -o-transition-property: bottom; 33 | -o-transition-duration: 1s; 34 | -moz-transition-property: bottom; 35 | -moz-transition-duration: 1s; 36 | -webkit-transition-property: bottom; 37 | -webkit-transition-duration: 1s; 38 | position: fixed; 39 | width: 100%; 40 | height: 20px; 41 | bottom: -20; 42 | opacity: 0.5; 43 | font-size: 18px; 44 | text-align: center; 45 | color: white; 46 | background: red; 47 | } 48 | 49 | #nav-bar { 50 | position: fixed; 51 | top: 0; 52 | right: 0; 53 | background: gray; 54 | opacity: 0.8; 55 | } 56 | 57 | #file-dialog { 58 | display: none; 59 | position: fixed; 60 | top: 35%; 61 | right: 35%; 62 | width: 30%; 63 | height: 30%; 64 | min-width:200px; 65 | min-height:200px; 66 | background: gray; 67 | opacity: 0.75; 68 | border:solid 1px black; 69 | } 70 | 71 | div.sidebar-title { 72 | padding-left:10px; 73 | box-sizing:border-box; 74 | width: 100%; 75 | background-color:black; 76 | color:#05a5e0 77 | } 78 | 79 | div.sidebar-scrolled-content { 80 | width: 100%; 81 | background-color:#777; 82 | overflow:auto 83 | } 84 | 85 | div.sidebar-content { 86 | width:100%; 87 | box-sizing:border-box; 88 | padding-left:10px; 89 | padding-right:10px 90 | } 91 | 92 | div.sidebar-content select, input[type=checkbox] { 93 | border:solid 1px black; 94 | } 95 | 96 | #nav-bar div { 97 | border: solid 1px black; 98 | } --------------------------------------------------------------------------------