├── 3d.css ├── 3d ├── bed-2.jpg ├── bone-icon.png ├── bone.png ├── book-icon.png ├── book-page.jpg ├── candle-body-1.jpg ├── caret-1.png ├── ceiling_x2_lossy.jpg ├── debug_square.jpg ├── decal-web-1.png ├── door-dungeon-1-250x200_lossy.png ├── dungeon-ceiling-2.jpg ├── dungeon-ceiling-2_lossy.jpg ├── dungeon-floor-3.jpg ├── dungeon-floor-3.png ├── dungeon-floor-3_lossy.jpg ├── fonts │ ├── EvOJzAlL3oU5AQl2mP5KdgptMqZwMinUPDhdog.woff2 │ └── EvOJzAlL3oU5AQl2mP5KdgptMqhwMinUPDg.woff2 ├── game-bg-3.jpg ├── guard-2.png ├── icons │ ├── del_intro-mouse.svg │ ├── intro-desktop.svg │ └── intro-mobile.svg ├── js │ ├── debug.js │ ├── engine.geom.js │ ├── engine.geom.struct.js │ ├── engine.inventory.js │ ├── engine.js │ ├── engine.player.js │ ├── engine.sound.js │ ├── engine.utils.js │ ├── level-01.js │ ├── level-02.js │ ├── level-03.js │ ├── level-04.js │ ├── level-05.js │ ├── level-06.js │ ├── level.js │ └── vectors.js ├── lands.jpg ├── meat-3.jpg ├── new-cover.jpg ├── out_lighter.gif ├── out_lighter_single.gif ├── rusty-knife-icon.png ├── rusty-wood.jpg ├── sound │ ├── breathing-1.mp3 │ ├── candle-1.mp3 │ ├── candle-1.mp3~.mp3 │ ├── candle-2.mp3 │ ├── candle-2.mp3~.mp3 │ ├── church-organ-main.mp3 │ ├── crying-1.mp3 │ ├── door-creak-1.mp3 │ ├── door-lock.mp3 │ ├── food-1.mp3 │ ├── food-3.mp3 │ ├── footsteps-1.mp3 │ ├── footsteps-2.mp3 │ ├── guard-1.mp3 │ ├── guard-2.mp3 │ ├── item-pickup-1.mp3 │ ├── metal-roll-1.mp3 │ ├── puzzle-solve-1.mp3 │ ├── rust-1.mp3 │ ├── water-dripping-1.mp3 │ ├── water-running-1.mp3 │ ├── water-step-1.mp3 │ ├── water-step-11.mp3 │ ├── water-step-12.mp3 │ ├── water-step-13.mp3 │ ├── water-step-14.mp3 │ ├── water-step-2.mp3 │ ├── water-step-3.mp3 │ └── water-step-4.mp3 ├── spider-sprite.png ├── trapdoor-2.png ├── wall-dungeon-2-window.png ├── wall-dungeon.jpg ├── wall-dungeon2.jpg ├── wall-dungeon2_lossy.jpg ├── wall-dungeon_lossy.jpg ├── wood-1.jpg └── wood-2.jpg ├── LICENSE ├── README.md ├── index.html └── three ├── .DS_Store ├── leech ├── .DS_Store └── leech │ ├── scene.bin │ ├── scene.gltf │ └── textures │ ├── UVMAP_PIAVKA1_Default_baseColor.png │ ├── UVMAP_PIAVKA1_Default_metallicRoughness.png │ └── UVMAP_PIAVKA1_Default_normal.png ├── three-gltf-loader.min.js └── three.build.js /3d/bed-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/bed-2.jpg -------------------------------------------------------------------------------- /3d/bone-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/bone-icon.png -------------------------------------------------------------------------------- /3d/bone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/bone.png -------------------------------------------------------------------------------- /3d/book-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/book-icon.png -------------------------------------------------------------------------------- /3d/book-page.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/book-page.jpg -------------------------------------------------------------------------------- /3d/candle-body-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/candle-body-1.jpg -------------------------------------------------------------------------------- /3d/caret-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/caret-1.png -------------------------------------------------------------------------------- /3d/ceiling_x2_lossy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/ceiling_x2_lossy.jpg -------------------------------------------------------------------------------- /3d/debug_square.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/debug_square.jpg -------------------------------------------------------------------------------- /3d/decal-web-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/decal-web-1.png -------------------------------------------------------------------------------- /3d/door-dungeon-1-250x200_lossy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/door-dungeon-1-250x200_lossy.png -------------------------------------------------------------------------------- /3d/dungeon-ceiling-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/dungeon-ceiling-2.jpg -------------------------------------------------------------------------------- /3d/dungeon-ceiling-2_lossy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/dungeon-ceiling-2_lossy.jpg -------------------------------------------------------------------------------- /3d/dungeon-floor-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/dungeon-floor-3.jpg -------------------------------------------------------------------------------- /3d/dungeon-floor-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/dungeon-floor-3.png -------------------------------------------------------------------------------- /3d/dungeon-floor-3_lossy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/dungeon-floor-3_lossy.jpg -------------------------------------------------------------------------------- /3d/fonts/EvOJzAlL3oU5AQl2mP5KdgptMqZwMinUPDhdog.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/fonts/EvOJzAlL3oU5AQl2mP5KdgptMqZwMinUPDhdog.woff2 -------------------------------------------------------------------------------- /3d/fonts/EvOJzAlL3oU5AQl2mP5KdgptMqhwMinUPDg.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/fonts/EvOJzAlL3oU5AQl2mP5KdgptMqhwMinUPDg.woff2 -------------------------------------------------------------------------------- /3d/game-bg-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/game-bg-3.jpg -------------------------------------------------------------------------------- /3d/guard-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/guard-2.png -------------------------------------------------------------------------------- /3d/icons/del_intro-mouse.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /3d/icons/intro-desktop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /3d/icons/intro-mobile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /3d/js/debug.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | // helpers (delete) 5 | var MatrixCSSClass = window.WebKitCSSMatrix || 6 | window.MozCSSMatrix || 7 | window.MsCSSMatrix || 8 | window.OCSSMatrix || 9 | window.CSSMatrix; 10 | 11 | window.makeCube = function (width, height, length) { 12 | var move = document.getElementById('move'); 13 | 14 | var parent = document.createElement('div'); 15 | var parent_trans = 'translate3d(0,0,100px)'; 16 | 17 | 18 | 19 | parent_trans = 'translate3d(330px, 80px, 100px) rotateX(-40deg)'; 20 | 21 | parent.id = 'custom_el'; 22 | parent.className = 'obj'; 23 | 24 | parent.style.cssText = 'transform-style:preserve-3d;z-index:99999;transform:' + parent_trans + ';width: 2px; height: 2px; background: blue;'; 25 | // 100px Z hack so that it is visible 26 | 27 | var matrix_parent_css = new MatrixCSSClass( parent_trans ); 28 | var matrix_parent = [ matrix_parent_css.m11, 29 | matrix_parent_css.m12, 30 | matrix_parent_css.m13, 31 | matrix_parent_css.m14, 32 | matrix_parent_css.m21, 33 | matrix_parent_css.m22, 34 | matrix_parent_css.m23, 35 | matrix_parent_css.m24, 36 | matrix_parent_css.m31, 37 | matrix_parent_css.m32, 38 | matrix_parent_css.m33, 39 | matrix_parent_css.m34, 40 | matrix_parent_css.m41, 41 | matrix_parent_css.m42, 42 | matrix_parent_css.m43, 43 | matrix_parent_css.m44]; 44 | 45 | 46 | 47 | // -- top 48 | var top = document.createElement('div'); 49 | top.className = 'obj'; 50 | top.style.background = 'green'; 51 | 52 | top.style.width = width + 'px'; 53 | top.style.height = length + 'px'; 54 | top.style.transform = 'translate3d(' + (-width/2) + 'px,' + (-height/2) + 'px, 0px) rotateX(90deg) translate3d(0,0,' + (length/2) + 'px)'; 55 | 56 | 57 | parent.appendChild( top ); 58 | 59 | 60 | 61 | var top_geom = { 62 | id : 'cude-whatever-1', 63 | clss: 'class-whatever-1', 64 | width: width, 65 | height:length, 66 | 67 | vertices: function( width, height ) { 68 | // return [ 69 | // new Vector( -width/2, 0, height/2 ), 70 | // new Vector( width/2, 0, height/2 ), 71 | // new Vector( width/2, 0, -height/2 ), 72 | // new Vector( -width/2, 0, -height/2 ) 73 | // ]; 74 | } 75 | }; 76 | // top_geom.vertices = top_geom.vertices (top_geom.width, top_geom.height); 77 | 78 | var real_vertices = [ 79 | new Vector( 0, top_geom.height, 0), 80 | new Vector( top_geom.width, top_geom.height, 0), 81 | new Vector( top_geom.width, 0, 0), 82 | new Vector( 0, 0, 0) 83 | ]; 84 | var vertices = []; 85 | 86 | var matrix_css = new MatrixCSSClass( top.style.transform ); 87 | var matrix = [ matrix_css.m11, 88 | matrix_css.m12, 89 | matrix_css.m13, 90 | matrix_css.m14, 91 | matrix_css.m21, 92 | matrix_css.m22, 93 | matrix_css.m23, 94 | matrix_css.m24, 95 | matrix_css.m31, 96 | matrix_css.m32, 97 | matrix_css.m33, 98 | matrix_css.m34, 99 | matrix_css.m41, 100 | matrix_css.m42, 101 | matrix_css.m43, 102 | matrix_css.m44]; 103 | 104 | for (var i = 0; i < real_vertices.length; ++i) 105 | { 106 | var curr = real_vertices[i].clone(); 107 | curr.x -= top_geom.width/2; 108 | curr.y -= top_geom.height/2; 109 | 110 | curr.applyMatrix4( matrix ); 111 | 112 | curr.x += top_geom.width/2; 113 | curr.y += top_geom.height/2; 114 | 115 | vertices[i] = curr.applyMatrix4( matrix_parent ); 116 | } 117 | top_geom.vertices = vertices; 118 | 119 | // now apply the parent's matrix 120 | console.log( vertices ); 121 | window.top_geom = top_geom; 122 | 123 | 124 | 125 | // ---------------------- 126 | 127 | var bottom = document.createElement('div'); 128 | bottom.className = 'obj'; 129 | bottom.style.background = 'brown'; 130 | 131 | bottom.style.width = width + 'px'; 132 | bottom.style.height = length + 'px'; 133 | bottom.style.transform = 'translate3d(' + (-width/2) + 'px,' + (-height/2) + 'px, 0px) rotateX(-90deg) translate3d(0,0,' + ((-length/2)+height) + 'px)'; 134 | 135 | parent.appendChild( bottom ); 136 | // ---------------------- 137 | 138 | 139 | 140 | var front = document.createElement('div'); 141 | front.className = 'obj'; 142 | front.style.background = 'red'; 143 | 144 | front.style.width = width + 'px'; 145 | front.style.height = height + 'px'; 146 | front.style.transform = 'translate3d(' + (-width/2) + 'px, ' + (-height/2) + 'px, ' + (length/2) + 'px)'; 147 | 148 | parent.appendChild( front ); 149 | 150 | 151 | 152 | var back = document.createElement('div'); 153 | back.className = 'obj'; 154 | back.style.background = 'blue'; 155 | 156 | back.style.width = width + 'px'; 157 | back.style.height = height + 'px'; 158 | back.style.transform = 'translate3d(' + (-width/2) + 'px, ' + (-height/2) + 'px, ' + (-length/2) + 'px) rotateY(180deg)'; 159 | 160 | parent.appendChild( back ); 161 | 162 | 163 | 164 | var left = document.createElement('div'); 165 | left.className = 'obj'; 166 | left.style.background = 'teal'; 167 | 168 | left.style.width = length + 'px'; 169 | left.style.height = height + 'px'; 170 | left.style.transform = 'translate3d(' + (-length/2) + 'px,' + (-height/2) + 'px, 0px) rotateY(90deg) translate3d(0,0,' + (width/2) + 'px)'; 171 | 172 | 173 | parent.appendChild( left ); 174 | 175 | 176 | var right = document.createElement('div'); 177 | right.className = 'obj'; 178 | right.style.background = 'pink'; 179 | 180 | right.style.width = length + 'px'; 181 | right.style.height = height + 'px'; 182 | right.style.transform = 'translate3d(' + (-length/2) + 'px,' + (-height/2) + 'px, 0px) rotateY(-90deg) translate3d(0,0,' + (width/2) + 'px)'; 183 | 184 | parent.appendChild( right ); 185 | 186 | 187 | move.appendChild ( parent ); 188 | }; 189 | 190 | window.killCustom = function() { 191 | var cc = document.getElementById('custom_el'); 192 | cc && document.getElementById('move').removeChild( cc ); 193 | } 194 | 195 | window.makeTube = function (diameter, height, faces_num) { 196 | var move = document.getElementById('move'); 197 | 198 | var parent = document.createElement('div'); 199 | parent.id = 'custom_el'; 200 | parent.className = 'obj'; 201 | 202 | parent.style.cssText = 'transform-style:preserve-3d;z-index:99999;transform:translate3d(0,0,100px);width: 2px; height: 2px; background: blue;'; 203 | // 100px Z hack so that it is visible 204 | 205 | //--- 206 | var side_angle = (Math.PI / faces_num) * 2; 207 | var side_len = diameter * Math.tan(Math.PI/faces_num); 208 | 209 | for (var c = 0; c < faces_num; c++) { 210 | var x = Math.sin(side_angle * c) * diameter / 2; 211 | var z = Math.cos(side_angle * c) * diameter / 2; 212 | var ry = Math.atan2(x, z); 213 | parent.appendChild( createFace (side_len + 1, height, x, 0, z, 0, ry, 0, null, side_len * c, 0) ); 214 | } 215 | //--- 216 | 217 | move.appendChild ( parent ); 218 | }; 219 | 220 | function createFace(w, h, x, y, z, rx, ry, rz, tsrc, tx, ty) { 221 | var face = document.createElement("div"); 222 | face.className = "obj"; 223 | face.style.cssText = "background:" + randomColor () + ';' + 224 | //"background: url(" + tsrc + ") -" + tx.toFixed(2) + "px " + ty.toFixed(2) + "px;" + 225 | "width:" + w.toFixed(2) + "px;" + 226 | "height:" + h.toFixed(2) + "px;" + 227 | "transform: translate3d(" + (x - (w / 2)).toFixed(2) + "px," + (y - (h / 2)).toFixed(2) + "px," + z.toFixed(2) + "px)" + 228 | "rotateX(" + rx.toFixed(2) + "rad) rotateY(" + ry.toFixed(2) + "rad) rotateY(" + rz.toFixed(2) + "rad);"; 229 | return face; 230 | } 231 | 232 | function randomColor() { 233 | return ('#'+(Math.random()*0xFFFFFF<<0).toString(16)); 234 | } 235 | 236 | function makeRandId(length) { 237 | var text = ""; 238 | var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 239 | 240 | for (var i = 0; i < length; i++) 241 | text += possible.charAt(Math.floor(Math.random() * possible.length)); 242 | 243 | return text; 244 | } 245 | 246 | window.DrawPoint = function ( vert ) { 247 | var id = 'point-' + makeRandId(5); 248 | 249 | var el = document.createElement('div'); 250 | el.className = 'vertex'; 251 | el.id = id; 252 | el.style.transform = 'translate3d('+ vert.x +'px,'+ vert.y +'px,'+ vert.z +'px)'; 253 | el.style.backgroundColor = '#'+(Math.random()*0xFFFFFF<<0).toString(16); 254 | 255 | console.log( id, vert.x, vert.y, vert.z ); 256 | 257 | move.appendChild( el ); 258 | }; 259 | 260 | window.DrawVertex = function ( node, real_vertices ) { 261 | if (!node.vertices) return ; 262 | 263 | var vertices = []; 264 | 265 | if (real_vertices) 266 | { 267 | var _GetMatrixCSS = (function() { 268 | var MatrixCSS = window.WebKitCSSMatrix || 269 | window.MozCSSMatrix || 270 | window.MsCSSMatrix || 271 | window.OCSSMatrix || 272 | window.CSSMatrix; 273 | var matrix_css = new MatrixCSS (); 274 | 275 | if (!matrix_css.toFloat32Array) 276 | { 277 | MatrixCSS.prototype.toFloat32Array = function() { 278 | return ([this.m11, this.m12, this.m13, this.m14, 279 | this.m21, this.m22, this.m23, this.m24, 280 | this.m31, this.m32, this.m33, this.m34, 281 | this.m41, this.m42, this.m43, this.m44]); 282 | }; 283 | } 284 | 285 | return function ( trans ) { 286 | matrix_css.setMatrixValue ( trans ); 287 | return (matrix_css.toFloat32Array()); 288 | }; 289 | })(); 290 | 291 | if (real_vertices === 1 || real_vertices === true) 292 | { 293 | /* 294 | real_vertices = [ 295 | new Vector(-node.width/2, node.height/2, 0), 296 | new Vector( node.width/2, node.height/2, 0), 297 | new Vector( node.width/2, -node.height/2, 0), 298 | new Vector(-node.width/2, -node.height/2, 0) 299 | ]; 300 | */ 301 | real_vertices = [ 302 | new Vector( 0, node.height, 0), 303 | new Vector( node.width, node.height, 0), 304 | new Vector( node.width, 0, 0), 305 | new Vector( 0, 0, 0) 306 | ]; 307 | } 308 | 309 | // var magic = getComputedStyle( node.el ).transform.replace('matrix3d(','').replace(')','').split(' '); 310 | var matrix = [], mat_rev = []; 311 | 312 | matrix = _GetMatrixCSS (node.el.style.transform); 313 | 314 | //debugger; 315 | /*if (magic.length > 8) 316 | { 317 | for (var i = 0; i < magic.length; ++i) 318 | { 319 | matrix[i] = ((magic[i].replace(',', ''))/1).toFixed(2) / 1; 320 | } 321 | }*/ 322 | 323 | for (var i = 0; i < real_vertices.length; ++i) 324 | { 325 | var curr = real_vertices[i].clone(); 326 | if (matrix.length > 8) 327 | { 328 | curr.x -= node.width/2; 329 | curr.y -= node.height/2; 330 | 331 | curr.applyMatrix4( matrix ); 332 | 333 | curr.x += node.width/2; 334 | curr.y += node.height/2; 335 | 336 | } 337 | vertices[i] = curr; 338 | } 339 | } 340 | else 341 | { 342 | vertices = node.vertices; 343 | } 344 | 345 | 346 | for (var i = 0; i < vertices.length; ++i) 347 | { 348 | var vert = vertices[i]; 349 | 350 | var el = document.createElement('div'); 351 | el.className = 'vertex'; 352 | el.style.transform = 'translate3d('+ vert.x +'px,'+ vert.y +'px,'+ vert.z +'px)'; 353 | el.style.backgroundColor = '#'+(Math.random()*0xFFFFFF<<0).toString(16); 354 | el.setAttribute('vertex-id', i); 355 | 356 | console.log( vert.x, vert.y, vert.z ); 357 | 358 | move.appendChild( el ); 359 | } 360 | }; 361 | 362 | 363 | 364 | 365 | window.DrawVertex222 = function ( node, real_vertices ) { 366 | if (!node.vertices) return ; 367 | 368 | var vertices = []; 369 | 370 | 371 | var GetMatrixCSS = (function() { 372 | var MatrixCSS = window.WebKitCSSMatrix || 373 | window.MozCSSMatrix || 374 | window.MsCSSMatrix || 375 | window.OCSSMatrix || 376 | window.CSSMatrix; 377 | var matrix_css = new MatrixCSS (); 378 | 379 | if (!matrix_css.toFloat32Array) 380 | { 381 | MatrixCSS.prototype.toFloat32Array = function() { 382 | return ([this.m11, this.m12, this.m13, this.m14, 383 | this.m21, this.m22, this.m23, this.m24, 384 | this.m31, this.m32, this.m33, this.m34, 385 | this.m41, this.m42, this.m43, this.m44]); 386 | }; 387 | } 388 | 389 | return function ( trans ) { 390 | matrix_css.setMatrixValue ( trans ); 391 | return (matrix_css.toFloat32Array()); 392 | }; 393 | })(); 394 | 395 | if (real_vertices === 1 || real_vertices === true) 396 | { 397 | /* 398 | real_vertices = [ 399 | new Vector(-node.width/2, node.height/2, 0), 400 | new Vector( node.width/2, node.height/2, 0), 401 | new Vector( node.width/2, -node.height/2, 0), 402 | new Vector(-node.width/2, -node.height/2, 0) 403 | ]; 404 | */ 405 | real_vertices = [ 406 | new Vector( 0, node.height, 0), 407 | new Vector( node.width, node.height, 0), 408 | new Vector( node.width, 0, 0), 409 | new Vector( 0, 0, 0) 410 | ]; 411 | } 412 | 413 | var transform = getComputedStyle( node.el ).transform.replace('matrix3d(','').replace(')','').split(' '); 414 | var matrix = [], mat_rev = []; 415 | 416 | matrix = _GetMatrixCSS (node.el.style.transform); 417 | 418 | 419 | for (var i = 0; i < real_vertices.length; ++i) 420 | { 421 | var curr = real_vertices[i].clone(); 422 | if (matrix.length > 8) 423 | { 424 | curr.x -= node.width/2; 425 | curr.y -= node.height/2; 426 | 427 | curr.applyMatrix4( matrix ); 428 | 429 | curr.x += node.width/2; 430 | curr.y += node.height/2; 431 | 432 | } 433 | vertices[i] = curr; 434 | } 435 | 436 | 437 | for (var i = 0; i < vertices.length; ++i) 438 | { 439 | var vert = vertices[i]; 440 | 441 | var el = document.createElement('div'); 442 | el.className = 'vertex'; 443 | el.style.transform = 'translate3d('+ vert.x +'px,'+ vert.y +'px,'+ vert.z +'px)'; 444 | el.style.backgroundColor = '#'+(Math.random()*0xFFFFFF<<0).toString(16); 445 | el.setAttribute('vertex-id', i); 446 | 447 | console.log( vert.x, vert.y, vert.z ); 448 | 449 | move.appendChild( el ); 450 | } 451 | }; -------------------------------------------------------------------------------- /3d/js/engine.geom.struct.js: -------------------------------------------------------------------------------- 1 | (function ( w, d, GAME ) { 2 | 'use strict'; 3 | 4 | if (!GAME.GEOM) GAME.GEOM = {}; 5 | 6 | var _id = -1; 7 | 8 | GAME.GEOM.Node = function ( config ) { 9 | var q = this; 10 | 11 | q.id = 'id'; 12 | q.type = ''; 13 | q.type_ref = {}; // template 14 | q._parent; // parent obj 15 | 16 | q.hidden = false; // do not render 17 | q.object; // is object 18 | q.tag = 'img'; // img or div 19 | 20 | q.el = null; // node element 21 | q.clss = 'class_name'; 22 | 23 | q.width; 24 | q.height; 25 | 26 | q.img; 27 | 28 | 29 | q.geom = []; // has children -- (only render children) 30 | 31 | 32 | // --------- 33 | q.tri; 34 | q.tri_verts; 35 | q.vertices; 36 | q.vertexNormals; 37 | q.complexNormals; 38 | q.centroid; 39 | q.triangles = [ 40 | { 41 | point_edge : null, 42 | edge1 : null, 43 | edge2 : null, 44 | normal : null, 45 | normal_unit : null, 46 | points : [null, null, null] 47 | } 48 | ]; 49 | 50 | q.alpha; 51 | q.alpha_mask; 52 | q.alpha_rect; 53 | 54 | q.brightness; 55 | q.light_map; 56 | q.light_bitmap; 57 | q.light_ctx; 58 | q.no_shadow; 59 | q.cast_shadow; 60 | 61 | q.shadow_w; 62 | q.shadow_h; 63 | 64 | 65 | q.transform; 66 | q.matrix; 67 | q.parent_matrix; 68 | 69 | 70 | q.walk; 71 | q.innerHTML; 72 | q.hide_frustrum; 73 | q.face_camera; 74 | 75 | q.interact; 76 | q.pickable; 77 | q.icon; 78 | q.desc; 79 | 80 | 81 | q.needsUpdate; 82 | }; 83 | 84 | 85 | })( window, document, GAME ); -------------------------------------------------------------------------------- /3d/js/engine.inventory.js: -------------------------------------------------------------------------------- 1 | (function ( w, d, GAME ) { 2 | 'use strict'; 3 | 4 | var goods = d.getElementById('goods'); 5 | var items = goods.getElementsByClassName('item'); 6 | var scncont = d.getElementById('scn-cntr'); 7 | var gm = d.getElementById('gm'); 8 | var inv_preview = d.createElement('img'); 9 | inv_preview.id = 'inv-prvw'; 10 | scncont.appendChild( inv_preview ); 11 | 12 | 13 | var char_vis = false; 14 | var charmn = d.getElementById('char-mn'); 15 | var fcls = d.getElementById('cls'); 16 | charmn.onclick = fcls.onclick = function() { 17 | var char = d.getElementById('char'); 18 | if (char_vis) 19 | { 20 | char.style.display = 'none'; 21 | char.style.right = '-250px'; 22 | } 23 | else 24 | { 25 | char.style.display = 'block'; 26 | char.style.right = '0px'; 27 | } 28 | 29 | char_vis = !char_vis; 30 | }; 31 | 32 | var mousemove = function( e ) { 33 | var x = e.pageX - scncont.parentNode.offsetLeft - 16; 34 | var y = e.pageY - scncont.parentNode.offsetTop - 16; 35 | 36 | inv_preview.style.transform = 'translate3d(' + x + 'px,' + y + 'px, 0px)'; 37 | }; 38 | 39 | goods.addEventListener('click', function( e ) { 40 | e.stopPropagation();e.preventDefault(); 41 | 42 | if (!GAME.State.control) return ; 43 | 44 | var target = (e.target || e.srcElement); 45 | 46 | if (target.tagName !== 'IMG') return ; 47 | 48 | if (GAME.INV.active_item) 49 | { 50 | if (target === GAME.INV.active_item) 51 | { 52 | target.className = ''; 53 | GAME.INV.active_item = null; 54 | } 55 | else 56 | { 57 | GAME.INV.active_item.className = ''; 58 | GAME.INV.active_item = target; 59 | target.className = 'act'; 60 | } 61 | } 62 | else 63 | { 64 | GAME.INV.active_item = target; 65 | target.className = 'act'; 66 | 67 | d.addEventListener('mousemove', mousemove); 68 | } 69 | 70 | if (GAME.INV.active_item) 71 | { 72 | inv_preview.src = GAME.INV.active_item.src; 73 | inv_preview.style.display = 'block'; 74 | } 75 | else 76 | { 77 | d.removeEventListener('mousemove', mousemove); 78 | inv_preview.style.display = 'none'; 79 | inv_preview.style.transform = 'translate3d(-150px,-150px, 0px)'; 80 | } 81 | 82 | // - 83 | }, false); 84 | 85 | GAME.INV = { 86 | preview: inv_preview, 87 | active_item : null, 88 | slots : new Array (items.length) 89 | }; 90 | 91 | GAME.INV.FindItemById = function ( id ) { 92 | var slots = GAME.INV.slots; 93 | var ind = -1; 94 | 95 | for (var i = 0; i < slots.length; ++i) 96 | { 97 | if (slots[i] && slots[i].id === id) 98 | { 99 | ind = i; 100 | break; 101 | } 102 | } 103 | 104 | if (ind === -1) return (false); 105 | 106 | return (slots[ind]); 107 | }; 108 | 109 | GAME.INV.AddItem = function ( item ) { 110 | // first find empty slot 111 | 112 | var slots = GAME.INV.slots; 113 | var index = -1; 114 | 115 | for (var i = 0; i < slots.length; ++i) 116 | { 117 | if (!slots[i]) 118 | { 119 | index = i; 120 | break; 121 | } 122 | } 123 | 124 | if (index === -1) return (false); 125 | 126 | slots[index] = item; 127 | item.picked_up = true; 128 | 129 | // render inventory 130 | GAME.INV.Render (); 131 | }; 132 | 133 | GAME.INV.RemoveItem = function ( index ) { 134 | var slots = GAME.INV.slots; 135 | 136 | if (!slots[ index ]) return ; 137 | if (GAME.INV.active_item && items[ index ] === GAME.INV.active_item.parentNode) 138 | { 139 | GAME.INV.active_item = null; 140 | d.removeEventListener('mousemove', mousemove); 141 | inv_preview.style.display = 'none'; 142 | inv_preview.style.transform = 'translate3d(-150px,-150px, 0px)'; 143 | } 144 | 145 | slots.splice (index, 1); 146 | slots.push(null); 147 | 148 | GAME.INV.Render (); 149 | }; 150 | 151 | GAME.INV.Render = function () { 152 | var slots = GAME.INV.slots; 153 | var index = -1; 154 | 155 | for (var i = 0; i < slots.length; ++i) 156 | { 157 | if (!slots[i]) items[i].innerHTML = ''; 158 | else 159 | { 160 | var xtr = ''; 161 | if (!GAME.UTILS.Mobile && slots[i].desc) xtr = 'title="' + slots[i].desc + '"'; 162 | if (slots[i].use) xtr += ' data-use="' + slots[i].use + '"'; 163 | 164 | items[i].innerHTML = ''; 165 | } 166 | // --- 167 | } 168 | }; 169 | 170 | GAME.INV.Deselect = function () { 171 | if (!GAME.INV.active_item) return ; 172 | 173 | GAME.INV.active_item.className = ''; 174 | GAME.INV.active_item = null; 175 | d.removeEventListener('mousemove', mousemove); 176 | inv_preview.style.display = 'none'; 177 | inv_preview.style.transform = 'translate3d(-150px,-150px, 0px)'; 178 | }; 179 | 180 | GAME.INV.DragEnd = function ( el ) { 181 | var element = document.elementFromPoint ( drag_x - window.scrollX, drag_y - window.scrollY ); 182 | if (!element) return ; 183 | // check to see if the element is a target for interaction 184 | 185 | var use = el.getAttribute('data-use'); 186 | if (use) 187 | { 188 | if (element.getAttribute('data-use') === use) 189 | { 190 | var slots = GAME.INV.slots; 191 | var ind = -1; 192 | var id = el.getAttribute('data-id'); 193 | 194 | for (var i = 0; i < slots.length; ++i) 195 | { 196 | if (slots[i] && slots[i].id === id) 197 | { 198 | ind = i; 199 | break; 200 | } 201 | } 202 | 203 | slots[ind] && slots[ind].use_cb(slots[i], el, element); 204 | 205 | GAME.INV.Deselect(); 206 | return ; 207 | } 208 | } 209 | 210 | GAME.INV.Deselect(); 211 | 212 | for (var k in GAME.LEVEL.MAP.NODES) 213 | { 214 | var node = GAME.LEVEL.MAP.NODES[k]; 215 | 216 | if (!node || !node.object || node.hidden || !node.interact) continue; 217 | 218 | if (node.el === element || node.el === element.parentNode) { 219 | // var previous_active = GAME.INV.active_item; 220 | GAME.INV.active_item = el; 221 | node.interact.call(node.el); 222 | 223 | GAME.INV.active_item = null; 224 | 225 | break; 226 | } 227 | } 228 | }; 229 | 230 | var drag_x = 0, drag_y = 0; 231 | gm.addEventListener('drop', function( event ) { 232 | event.preventDefault(); 233 | }, false); 234 | gm.addEventListener('dragover', function( event ) { 235 | event.preventDefault(); 236 | 237 | drag_x = event.pageX; drag_y = event.pageY; 238 | //# console.log( document.elementFromPoint ( event.pageX, event.pageY ), document.elementsFromPoint ( event.pageX, event.pageY ) ); 239 | }, false); 240 | 241 | })( window, document, GAME ); -------------------------------------------------------------------------------- /3d/js/engine.js: -------------------------------------------------------------------------------- 1 | (function ( w, d ) { 2 | 'use strict'; 3 | 4 | /////////////////////////////////////////////////////// 5 | // DEBUG INFO 6 | var _log_level = 0, 7 | _debug = false; 8 | 9 | 10 | /////////////////////////////////////////////////////// 11 | // MAIN OBJECT, accessible from the window 12 | var GAME = {}; 13 | w.GAME = GAME; 14 | 15 | 16 | /////////////////////////////////////////////////////// 17 | // INIT GAME STATE 18 | _makeState ( GAME ); 19 | _makeDebug ( GAME, _log_level, _debug ); 20 | 21 | 22 | /////////////////////////////////////////////////////// 23 | // EVENTS (GAME.On for listening, Game.Fire for firing, Off for removal) 24 | // 25 | // For example, 26 | // GAME.On ( 'LoadProgress', function ( percentage ) { console.log( percentage ); }); 27 | // would fire while the LoadProgress event is fired. 28 | // 29 | // GAME.Fire ( 'LoadProgress', 0.3 ); 30 | // would fire the event and trigger any 'On' listeners 31 | // 32 | // GAME.Off ( 'LoadProgress', func_ref ); 33 | // Lastly, Off would remove the listener, as far as a refference 34 | // to the function has been kept. 35 | /////////////////////////////////////////////////////// 36 | var _events = {}; 37 | GAME.Fire = function ( event_name, value, value2 ) { 38 | var group = _events[ event_name ]; 39 | if (!group) return (false); 40 | 41 | var l = group.length; 42 | while (l-- > 0) { 43 | group[l] && group[ l ] ( value, value2 ); 44 | } 45 | }; 46 | GAME.On = function ( event_name, callback ) { 47 | if (!_events[ event_name ]) 48 | _events[ event_name ] = [ callback ]; 49 | else 50 | _events[ event_name ].unshift ( callback ); 51 | }; 52 | 53 | GAME.Off = function ( event_name, callback ) { 54 | var group = _events[ event_name ]; 55 | if (!group) return (false); 56 | 57 | var l = group.length; 58 | while (l-- > 0) { 59 | if (group[l] === callback) { break; } 60 | } 61 | 62 | if (l !== -1) group.splice ( l, 1 ); 63 | }; 64 | 65 | 66 | /////////////////////////////////////////////////////// 67 | // Main Listeners 68 | 69 | // makes state checks and attempts to start the game 70 | GAME.Start = function ( cb_success ) { 71 | if (GAME.State.running || GAME.State.loading) return (false); 72 | 73 | if (GAME.State.loaded) 74 | { 75 | SetState ('running', true); 76 | 77 | w.requestAnimationFrame(function() { 78 | GAME.Fire ( 'ReqStart', 0 ); 79 | cb_success && cb_success (); 80 | }); 81 | 82 | return (true); 83 | } 84 | }; 85 | 86 | 87 | // Called by the levels themselves. 88 | // Attempts to clean up, update object registry and start preloading assets 89 | GAME.On ('ReqLoadLevel', function ( level, objects ) { 90 | 91 | // if the level is already loaded, skip 92 | if (GAME.LEVEL === level) return ; 93 | 94 | // a level already exists, unload it 95 | if (GAME.LEVEL) GAME.LEVEL.DESTROY (); 96 | 97 | GAME.LEVEL = level; 98 | 99 | // make a copy of the level's objects #### 100 | if (!GAME.GAME_OBJ) GAME.GAME_OBJ = objects; 101 | else { 102 | for (var k in objects) GAME.GAME_OBJ[k] = objects[ k ]; 103 | } 104 | 105 | // mark the game as loading 106 | SetState ('loading', true); 107 | 108 | // check and download/preload the required assets 109 | if (!level.PRELOAD_IMG) level.PRELOAD_IMG = {}; 110 | if (level.PRELOAD.length === 0) 111 | { 112 | GAME.Fire ( 'LoadProgress', 100 ); 113 | GAME.Fire ( 'ReqBuildLevel', level, GAME.GAME_OBJ ); 114 | 115 | return ; 116 | } 117 | 118 | // actual preloading 119 | var empty_pixel = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDABsSFBcUERsXFhceHBsgKEIrKCUlKFE6P"+ 120 | "TBCYFVlZF9VXVtqeJmBanGQc1tdhbWGkJ6jq62rZ4C8ybqmx5moq6T/2wBDARweHigjKE4rK06kbl1upKSkpKSkpK"+ 121 | "SkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKSkpKT/wAARCAABAAEDASIAAhEBAxEB/8QAFQABA"+ 122 | "QAAAAAAAAAAAAAAAAAAAAb/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AKYAH//Z"; 123 | 124 | var total = level.PRELOAD.length, sofar = 0; 125 | for (var i = 0; i < total; ++i) 126 | { 127 | var pic = new Image (); 128 | 129 | pic.crossOrigin = 'Anonymous'; 130 | pic.onload = function () 131 | { 132 | if (++sofar === total) 133 | { 134 | GAME.Fire ( 'LoadProgress', 100 ); 135 | GAME.Fire ( 'ReqBuildLevel', level, GAME.GAME_OBJ ); 136 | } 137 | else 138 | { 139 | GAME.Fire ( 'LoadProgress', ((sofar / total) * 100) >> 0 ); 140 | } 141 | }; 142 | 143 | // if we failed to load the image, replace with 1px base64 jpeg 144 | pic.onerror = function () { 145 | pic.src = empty_pixel; 146 | }; 147 | 148 | var src = level.PRELOAD[i]; 149 | pic.src = src; 150 | 151 | level.PRELOAD_IMG[ src ] = pic; 152 | } 153 | 154 | // - 155 | }); 156 | 157 | 158 | GAME.On ( 'ReqStart', function ( level, objects ) { 159 | SetState ('control', true); 160 | }); 161 | 162 | 163 | var __ai_nodes = []; 164 | GAME.AI = { 165 | Add : function (node) { 166 | __ai_nodes.push (node); 167 | 168 | if (__ai_nodes.length === 1) { 169 | this.Init (); 170 | } 171 | }, 172 | 173 | Remove : function (index) { 174 | if (index === 0) { 175 | GAME.__ai = null; 176 | __ai_nodes = []; 177 | } 178 | }, 179 | 180 | Init : function () { 181 | GAME.__ai = function ( e ) { 182 | var node = __ai_nodes[0]; 183 | !node.hidden && node.onframe (node, e); 184 | }; 185 | } 186 | }; 187 | 188 | 189 | /////////////////////////////////////////////////////// 190 | // Execute with X frame rate. If much bigger time gaps are seen 191 | // then you can use that info to make bigger changes 192 | // eg, if you have a 30 frame per second bullet, but the game runs at 10 fps, you can still 193 | // keep the 30 frame per second speed, instead of having users get shot 3 times slower. 194 | // Also requestAnimationFrame uses the screen refresh rate, so this way super fast screens 195 | // will not influence render calls into firing 144 times per second or other unholly frequencies. 196 | // This is good logic. 197 | GAME.OnFrame = function ( frame_rate, repeat_times, callback ) { 198 | var time_per_frame = (1000 / frame_rate) >> 0; 199 | var remove = ((time_per_frame / 16.6) >> 0) + 1; 200 | 201 | if (time_per_frame > 29) time_per_frame -= remove; 202 | 203 | //# console.log( 'time_per_frame ', time_per_frame, ' repeat_times ', repeat_times ); 204 | 205 | var old_ms = w.performance.now (); 206 | var orig_times = 0; 207 | var total = 0; 208 | 209 | if (!repeat_times) repeat_times = 0; 210 | else orig_times = repeat_times; 211 | 212 | var func = function ( e ) { 213 | 214 | // if we are out of focus prevent execution 215 | if (!GAME.State.focus || GAME.State.dialog) 216 | { 217 | old_ms = e; 218 | w.requestAnimationFrame ( func ); 219 | return ; 220 | } 221 | 222 | var gap = e - old_ms; 223 | if (gap >= time_per_frame) 224 | { 225 | total += gap; 226 | 227 | //# console.log( 'total time ', total >> 0, ' count ', orig_times - repeat_times ); 228 | 229 | var skip = 0; 230 | if (callback) 231 | { 232 | skip = callback ( (orig_times - repeat_times), (total >> 0), (gap / (time_per_frame + remove)) ); // gap between the calls 233 | } 234 | 235 | if (skip && skip/1 === skip) repeat_times -= (skip/1) >> 0; 236 | 237 | if (--repeat_times > 0) {} 238 | else return ; 239 | 240 | old_ms = e; 241 | } 242 | 243 | w.requestAnimationFrame ( func ); 244 | }; 245 | 246 | w.requestAnimationFrame ( func ); 247 | }; 248 | 249 | 250 | 251 | 252 | 253 | /////////////////////////////////////////////////////// 254 | // ACTIONS 255 | (function ( w, d, GAME ) { 256 | 'use strict'; 257 | 258 | // txt holder 259 | var txt = d.getElementById ( 'txt' ), 260 | dialog = d.getElementById ( 'dialog' ); 261 | 262 | // overlay that covers the main window 263 | var dialog_cnt = dialog.childNodes[ 0 ]; 264 | 265 | var more_btn = d.createElement ( 'a' ); 266 | var done_btn = d.createElement ( 'a' ); 267 | 268 | 269 | if (!GAME.ACTIONS) GAME.ACTIONS = {}; 270 | 271 | GAME.ACTIONS.GameOver = function (game_over_txt) { 272 | __disable_controls (); 273 | __show_dialog (false); 274 | 275 | if (!game_over_txt) game_over_txt = 'GAME OVER'; 276 | 277 | var container = d.getElementById('scn-cntr'); // gm 278 | 279 | var modal = d.createElement ('div'); 280 | modal.id = 'gameover'; 281 | modal.innerHTML = '

' + game_over_txt + '

'; 282 | 283 | if (GAME.Sound.ON) 284 | { 285 | GAME.Sound.Toggle (); 286 | } 287 | 288 | if (d.getElementById('mob_cntrl')) 289 | { 290 | d.getElementById('mob_cntrl').style.display = 'none'; 291 | } 292 | 293 | container.appendChild (modal); 294 | }, 295 | 296 | // Creates or removes the dialog cover (depeds on argument) 297 | GAME.ACTIONS.DialogCover = function ( make ) { 298 | if (make) 299 | { 300 | __disable_controls (); 301 | __show_dialog (false); 302 | 303 | var cover = d.createElement('div'); 304 | cover.className = 'cvr'; 305 | 306 | dialog.appendChild (cover); 307 | setTimeout(function() { 308 | cover.style.opacity = '1.0'; 309 | },24); 310 | } 311 | else 312 | { 313 | setTimeout(function() { 314 | var covers = dialog.getElementsByClassName('cvr'); 315 | for (var i = 0; i < covers.length; ++i) 316 | { 317 | (function ( cover ) { 318 | if (!cover.parentNode) return ; 319 | 320 | cover.style.opacity = '0'; 321 | setTimeout(function() { 322 | cover.parentNode && cover.parentNode.removeChild( cover ); 323 | },1520); 324 | })( covers[i] ); 325 | } 326 | },24); 327 | } 328 | 329 | return (true); 330 | }; 331 | 332 | 333 | // hides the dialog 334 | GAME.ACTIONS.DialogClose = function () { 335 | 336 | dialog.style.display = 'none'; 337 | dialog_cnt.innerHTML = ''; 338 | 339 | __hide_more_done (); 340 | 341 | if (GAME.INV.active_item) GAME.INV.preview.style.display = 'block'; 342 | 343 | GAME.State.dialog = false; 344 | SetState ('control', true); 345 | }; 346 | 347 | GAME.ACTIONS.DialogAsk = function ( type, index, sub_index, callback ) { 348 | 349 | __disable_controls (); 350 | __show_dialog (false); 351 | 352 | GAME.State.dialog = true; 353 | 354 | var check = GAME.LEVEL.TXT[ type ]; 355 | if (!check) check = GAME.State.txt[ type ]; 356 | if (!check) return ; 357 | 358 | var data = check[ index ]; 359 | if (sub_index !== undefined && sub_index/1 === sub_index) data = data[ sub_index ]; 360 | 361 | if (data.type === 'choice') 362 | { 363 | var clss = 'inl-bl row'; 364 | if (data.text.length < 46) clss += ' anim_fast'; 365 | else if (data.text.length < 64) clss += ' anim_med'; 366 | 367 | var html = '
' + data.text + '

'; 368 | dialog_cnt.innerHTML = html; 369 | 370 | if (data.options) 371 | { 372 | for (var i = 0; i < data.options.length; ++i) 373 | { 374 | var curr = data.options[i]; 375 | var el = d.createElement('a'); 376 | el.className = 'btn'; 377 | el.innerHTML = curr.text; 378 | 379 | el.setAttribute('data-index', i); 380 | el.onclick = function( e ) { 381 | e.stopPropagation(); e.preventDefault (); 382 | var index = this.getAttribute('data-index') / 1; 383 | callback ( index, this.innerHTML ); 384 | }; 385 | 386 | dialog_cnt.appendChild( el ); 387 | } 388 | } 389 | // - 390 | } 391 | 392 | else if (typeof data === 'string' ) 393 | { 394 | setTimeout(function () { 395 | var clss = 'row'; 396 | if (data.length < 46) clss += ' anim_fast'; 397 | else if (data.length < 64) clss += ' anim_med'; 398 | 399 | var html = '
' + data + '
'; 400 | dialog_cnt.innerHTML = html; 401 | 402 | var el = d.createElement('a'); 403 | el.className = 'btn nxt'; 404 | el.innerHTML = 'CONTINUE'; 405 | 406 | el.onclick = function() { 407 | var index = this.getAttribute('data-index') / 1; 408 | callback ( index, this.innerHTML ); 409 | }; 410 | dialog_cnt.appendChild( el ); 411 | }, 400); 412 | } 413 | 414 | // ----- 415 | }; 416 | 417 | 418 | var prev_ts = 0; 419 | var __tm_line; 420 | GAME.ACTIONS.nextLine = function ( el, delay ) { 421 | if (!GAME.State.dialog) return ; 422 | 423 | clearTimeout (__tm_line); 424 | 425 | var remaining = 0; 426 | var active_txt = GAME.LEVEL.TXT.ACTIVE; 427 | var clear_anim; 428 | 429 | // check to see if a next entry exists 430 | var type = GAME.LEVEL.TXT[ active_txt.type ]; 431 | if (!type) type = GAME.State.txt[ active_txt.type ]; 432 | if (!type) return ; 433 | 434 | var entry = type[ active_txt.index ]; 435 | if (!entry) return ; // exit converation 436 | 437 | if (entry.title) entry = entry.body; 438 | 439 | clear_anim = function () { 440 | if (active_txt.el) 441 | { 442 | active_txt.el.className = 'caret'; 443 | active_txt.anim = false; 444 | } 445 | 446 | __show_done_btn (); 447 | }; 448 | 449 | if (typeof entry === 'string') 450 | { 451 | clear_anim (); 452 | return ; 453 | } 454 | 455 | if (entry.length > 1) 456 | { 457 | remaining = (entry.length - 1) - active_txt.sub_index; 458 | } 459 | 460 | if (remaining === 0) clear_anim (); 461 | else 462 | { 463 | if (delay) 464 | { 465 | __tm_line = setTimeout(function(){ 466 | GAME.ACTIONS.nextLine( el ); 467 | }, delay); 468 | return ; 469 | } 470 | 471 | var target_txt = entry[ ++active_txt.sub_index ]; 472 | if (active_txt.el) active_txt.el.className = ''; 473 | 474 | __make_body (target_txt, -1, '', active_txt, true); 475 | __show_more_btn (); 476 | } 477 | // - 478 | }; 479 | 480 | 481 | GAME.ACTIONS.NextText = function ( e ) { 482 | if (!GAME.State.dialog) return ; 483 | 484 | if (e) 485 | { 486 | if (e.timeStamp - prev_ts < 150) return ; 487 | prev_ts = e.timeStamp; 488 | } 489 | 490 | var remaining = 0; 491 | var active_txt = GAME.LEVEL.TXT.ACTIVE; 492 | 493 | // check to see if a next entry exists 494 | var type = GAME.LEVEL.TXT[ active_txt.type ]; 495 | if (!type) type = GAME.State.txt[ active_txt.type ]; 496 | if (!type) return ; 497 | 498 | var entry = type[ active_txt.index ]; 499 | if (!entry) return ; 500 | 501 | if (entry.title) entry = entry.body; // no multiple lines for title (by design) 502 | 503 | // if still animating -- display in full the current line 504 | if (active_txt.anim) // active_txt.el && (active_txt.el.className !== '' && active_txt.el.className !== 'caret')) 505 | { 506 | if (typeof entry === 'string'){} 507 | else if (entry.length > 1) 508 | { 509 | remaining = (entry.length - 1) - active_txt.sub_index; 510 | } 511 | 512 | if (remaining > 0) 513 | { 514 | var target_txt = entry[ ++active_txt.sub_index ]; 515 | 516 | active_txt.el.className = ''; 517 | __make_body (target_txt, -1, '', active_txt, true); 518 | __show_more_btn (); 519 | } 520 | else 521 | { 522 | active_txt.anim = false; 523 | active_txt.el.className = 'caret'; 524 | 525 | __show_done_btn (); 526 | } 527 | 528 | return ; 529 | } 530 | 531 | var spans = txt.getElementsByTagName ( 'span' ); 532 | for (var i = 0; i < spans.length; ++i) 533 | spans[i].className = 'old'; 534 | 535 | if (!active_txt.callback) GAME.ACTIONS.DialogClose (); 536 | else __hide_more_done (); 537 | 538 | GAME.State.dialog = false; 539 | SetState ('control', true); 540 | 541 | active_txt.sub_index = -1; 542 | active_txt.index = -1; 543 | active_txt.type = null; 544 | active_txt.el = null; 545 | 546 | active_txt.callback && active_txt.callback (); 547 | // -- 548 | }; 549 | 550 | 551 | 552 | // ------------------------- 553 | // 554 | // 555 | GAME.ACTIONS.SetText = function ( section_name, index, callback ) { 556 | 557 | var section = GAME.LEVEL.TXT[ section_name ]; 558 | if (!section) section = GAME.State.txt[ section_name ]; 559 | if (!section) return ; 560 | 561 | var target_txt = section[ index ]; 562 | var active_txt = GAME.LEVEL.TXT.ACTIVE; 563 | var sub_ind = 0; 564 | var extra_class = ''; 565 | 566 | if (!target_txt) return ; 567 | 568 | __disable_controls (); 569 | __show_dialog (true); 570 | __show_more_btn (); 571 | 572 | GAME.State.dialog = true; 573 | 574 | active_txt.callback = callback; 575 | 576 | if (target_txt.title) 577 | { 578 | __make_headline (target_txt.title); 579 | 580 | // now render the rest... 581 | target_txt = target_txt.body; 582 | extra_class = ' anim_delay'; 583 | } 584 | 585 | // just one string 586 | if (typeof target_txt === 'string') 587 | { 588 | sub_ind = -1; 589 | __make_body (target_txt, sub_ind, extra_class, active_txt, false ); 590 | } 591 | 592 | else if (target_txt.length > 0) 593 | { 594 | __make_body (target_txt, sub_ind, extra_class, active_txt, false ); 595 | } 596 | 597 | active_txt.sub_index = sub_ind; 598 | active_txt.type = section_name; 599 | active_txt.index = index; 600 | // --- 601 | }; 602 | 603 | GAME.ACTIONS.SaveText = function ( id ) { 604 | GAME.State.txt[id] = GAME.LEVEL.TXT[id]; 605 | }; 606 | 607 | GAME.ACTIONS.SetActiveText = function ( type, index, clear_all, force_clss ) { 608 | 609 | if (GAME.State.dialog) 610 | { 611 | w.requestAnimationFrame (function() { 612 | GAME.ACTIONS.SetActiveText ( type, index, clear_all, force_clss ); 613 | }); 614 | return ; 615 | } 616 | 617 | var act = GAME.LEVEL.TXT.ACTIVE; 618 | var act_text, clss; 619 | 620 | if (clear_all) 621 | { 622 | act.sub_index = -1; 623 | act.index = -1; 624 | act.el = null; 625 | act.anim = false; 626 | clear_all = true; 627 | } 628 | else if (act.el) 629 | { 630 | act.el.className = 'old'; 631 | act.el = null; 632 | act.sub_index = -1; 633 | // -- 634 | } 635 | 636 | act_text = GAME.LEVEL.TXT[ type ]; 637 | if (!act_text) { 638 | if (clear_all) txt.innerHTML = ''; 639 | return ; 640 | } 641 | 642 | act_text = act_text[ index ]; 643 | if (!act_text) return ; 644 | 645 | clss = 'anim'; 646 | if (act_text.length < 46) clss = 'anim anim_fast'; 647 | else if (act_text.length < 64) clss = 'anim anim_med'; 648 | 649 | 650 | if (force_clss) { clss = force_clss; } 651 | 652 | act.index = index; 653 | act.active = type; 654 | act.sub_index = -1; 655 | act.anim = false; 656 | 657 | w.requestAnimationFrame(function() { 658 | txt.scrollTo (0,3000); 659 | 660 | if (clear_all) 661 | txt.innerHTML = '
' + act_text + '
'; 662 | else 663 | txt.innerHTML += '
' + act_text + '
'; 664 | 665 | var spans = txt.getElementsByTagName('span'); 666 | act.el = spans[spans.length - 1]; 667 | 668 | w.requestAnimationFrame(function() { setTimeout(function() { txt.scrollTo (0,3000); }, 30 ); }); 669 | }); 670 | // - 671 | }; 672 | 673 | 674 | txt.addEventListener ( 'click', GAME.ACTIONS.NextText, false ); 675 | dialog.addEventListener ( 'click', GAME.ACTIONS.NextText, false ); 676 | 677 | more_btn.className = done_btn.className = 'btn'; 678 | more_btn.innerHTML = '(MORE)'; 679 | done_btn.innerHTML = '(DONE)'; 680 | 681 | // make more and done buttons 682 | txt.parentNode.appendChild ( more_btn ); 683 | txt.parentNode.appendChild ( done_btn ); 684 | 685 | 686 | // Helpers 687 | function __disable_controls () { 688 | GAME.ACTIONS.ResetControls (); 689 | SetState ('control', false); 690 | }; 691 | 692 | function __show_dialog ( clear ) { 693 | if (clear) dialog_cnt.innerHTML = ''; 694 | dialog.style.display = 'block'; 695 | 696 | GAME.INV.preview.style.display = 'none'; 697 | }; 698 | 699 | function __make_headline ( content ) { 700 | dialog_cnt.innerHTML = '
' + content + '
'; //
701 | }; 702 | 703 | function __make_body ( target_txt, sub_index, extra_class, active_txt, append ) { 704 | var clss = 'anim'; 705 | var spans; 706 | var html; 707 | var last_char; 708 | var txt_len = 0; 709 | var line_delay = 'null'; 710 | 711 | if (sub_index !== -1) target_txt = target_txt[ sub_index ]; 712 | 713 | txt_len = target_txt.length; 714 | 715 | if (txt_len < 2) clss = 'anim anim_inst'; 716 | else if (txt_len < 46) clss = 'anim anim_fast'; 717 | else if (txt_len < 64) clss = 'anim anim_med'; 718 | 719 | // if the last line is a dot or an exclamation mark 720 | last_char = target_txt.substr(-1); 721 | if (last_char === ' ') last_char = target_txt.substr(-2,1); 722 | if (last_char === '.' || last_char === '!') { 723 | line_delay = 512; 724 | } 725 | else if (last_char === ',') { 726 | line_delay = 84; 727 | } 728 | 729 | html = '
' + target_txt + '
'; 730 | 731 | if (append) 732 | txt.innerHTML += html; 733 | else 734 | txt.innerHTML = html; 735 | 736 | spans = txt.getElementsByTagName('span'); 737 | active_txt.el = spans[spans.length - 1]; 738 | 739 | active_txt.anim = true; 740 | } 741 | 742 | function __show_more_btn () { 743 | more_btn.style.display = 'block'; 744 | done_btn.style.display = 'none'; 745 | } 746 | 747 | function __show_done_btn () { 748 | more_btn.style.display = 'none'; 749 | done_btn.style.display = 'block'; 750 | } 751 | 752 | function __hide_more_done () { 753 | more_btn.style.display = 'none'; 754 | done_btn.style.display = 'none'; 755 | } 756 | 757 | // - 758 | })( w, d, GAME ); 759 | // ENDOF ACTIONS 760 | /////////////////////////////////////////////////////// 761 | 762 | 763 | 764 | /////////////////////////////////////////////////////// 765 | // helper methods 766 | function _makeState ( game ) { 767 | game.State = { 768 | focus : true, 769 | control: false, 770 | running: false, 771 | loading: false, 772 | loaded: false, 773 | paused: false, 774 | dialog: false, 775 | perf : { 776 | tx: 65, 777 | dist_min: 600, 778 | dist_max: 1840 779 | }, 780 | 781 | txt:{}, 782 | flags:{} 783 | }; 784 | } 785 | 786 | 787 | function SetState ( name, val ) { 788 | var prev_val = GAME.State[ name ]; 789 | 790 | if (prev_val === val) return ; 791 | 792 | GAME.State[ name ] = val; 793 | 794 | GAME.Fire ('StateUpdate', name, [val, prev_val] ); 795 | }; 796 | 797 | function _makeDebug ( game, _log_level, _debug ) { 798 | game.LOG = function ( a,b,c,d,e,f,g,h,i ) { 799 | if (a > _log_level ) return ; 800 | 801 | var log = console.log; 802 | if (i !== undefined) { log (b,c,d,e,f,g,h,i); return ;} 803 | if (h !== undefined) { log (b,c,d,e,f,g,h); return ;} 804 | if (g !== undefined) { log (b,c,d,e,f,g); return ;} 805 | if (f !== undefined) { log (b,c,d,e,f); return ;} 806 | if (e !== undefined) { log (b,c,d,e); return ;} 807 | if (d !== undefined) { log (b,c,d); return ;} 808 | if (c !== undefined) { log (b, c ); return ;} 809 | 810 | log( b ); 811 | }; 812 | 813 | game.DEBUG = _debug; 814 | game.__camera = function(){}; 815 | game.__move = function(){}; 816 | } 817 | 818 | })(window, document); -------------------------------------------------------------------------------- /3d/js/engine.sound.js: -------------------------------------------------------------------------------- 1 | (function ( w, d, GAME ) { 2 | 'use strict'; 3 | 4 | var container = d.getElementById('snd-cntr'); 5 | 6 | var steps_switch = 0; 7 | var step1 = d.getElementById('sound-footsteps-1'), 8 | step2 = d.getElementById('sound-footsteps-2'); 9 | var steps_extra = null, prev_step = null; 10 | 11 | var loop_arr = []; 12 | 13 | GAME.Sound = { 14 | ON : true, 15 | PlayStep : function() { 16 | if (!GAME.Sound.ON) return (false); 17 | 18 | var step = null; 19 | if (steps_switch === 0) 20 | { 21 | step = step1; 22 | steps_switch = 1; 23 | } 24 | else if (steps_switch === 1) 25 | { 26 | step = step2; 27 | steps_switch = 0; 28 | } 29 | 30 | if (steps_extra && Math.random () > steps_extra.chance) 31 | { 32 | var rand = Math.random (); 33 | var l = steps_extra.sounds.length; 34 | while (l-- > 0) 35 | { 36 | if (rand > steps_extra.sounds[l].chance && prev_step !== steps_extra.sounds[l].sound) { 37 | step = steps_extra.sounds[l].sound; 38 | break; 39 | } 40 | } 41 | // - 42 | } 43 | 44 | if (step.readyState >= 2) 45 | { 46 | step.currentTime = 0.0; 47 | var p = step.play(); 48 | if (p) p.catch(function(e){}); 49 | 50 | prev_step = step; 51 | return (true); 52 | } 53 | 54 | return (false); 55 | }, 56 | 57 | SetSteps : function (step_1, step_2, extra) { 58 | if (typeof step_1 === 'string') step_1 = d.getElementById ( step_1 ); 59 | if (typeof step_2 === 'string') step_2 = d.getElementById ( step_2 ); 60 | 61 | if (step_1 && step_2) 62 | { 63 | step1 = step_1; 64 | step2 = step_2; 65 | } 66 | 67 | if (extra) 68 | { 69 | for (var i = 0; i < extra.sounds.length; ++i) 70 | { 71 | if (typeof extra.sounds[i].sound === 'string') 72 | extra.sounds[i].sound = d.getElementById ( extra.sounds[i].sound ); 73 | } 74 | 75 | steps_extra = extra; 76 | } 77 | else steps_extra = null; 78 | }, 79 | 80 | Volume : function ( sound_id, val ) { 81 | var el = d.getElementById( sound_id ); 82 | if (!el) return (false); 83 | 84 | el.setAttribute ('data-volume', val); 85 | el.volume = val; 86 | }, 87 | 88 | Play : function ( sound_id, distance, interupt ) { 89 | if (!GAME.Sound.ON) return (false); 90 | if (distance/1 === distance && distance < 0.02) return (false); 91 | 92 | var el = d.getElementById( sound_id ); 93 | if (!el) return (false); 94 | if (!interupt && !el.paused) return (false); 95 | 96 | if (el.readyState >= 2) 97 | { 98 | var default_volume = (el.getAttribute('data-volume') / 1); 99 | if (distance) 100 | el.volume = (default_volume * distance).toFixed(2) / 1; 101 | else if (el.volume !== default_volume) 102 | el.volume = default_volume; 103 | 104 | if (interupt && !el.paused) { 105 | el.currentTime = 0; 106 | return (true); 107 | } 108 | 109 | var p = el.play(); 110 | if (p) p.catch(function(e){}); 111 | return (true); 112 | } 113 | 114 | return (false); 115 | }, 116 | 117 | Stop : function ( sound_id ) { 118 | // if (!GAME.Sound.ON) return (false); 119 | var el = d.getElementById( sound_id ); 120 | if (!el) /*|| el.readyState !== 4)*/ return (false); 121 | 122 | if (!el.paused) el.pause (); 123 | el.currentTime = 0.0; 124 | 125 | return (true); 126 | }, 127 | 128 | Load : function ( sound_id, path, volume, loop ) { 129 | if (d.getElementById (sound_id)) return (false); 130 | 131 | var el = d.createElement('audio'); 132 | el.id = sound_id; 133 | el.setAttribute('preload', 'auto'); 134 | 135 | if (volume) { 136 | el.setAttribute('data-volume', volume); 137 | el.volume = volume / 1; 138 | } else { 139 | el.setAttribute('data-volume', '1'); 140 | } 141 | 142 | if (loop) { 143 | el.setAttribute('loop', 'loop'); 144 | loop_arr.push ( el ); 145 | } 146 | 147 | el.src = path; 148 | container.appendChild( el ); 149 | 150 | return (true); 151 | }, 152 | 153 | Toggle : function () { 154 | GAME.Sound.ON = !GAME.Sound.ON; 155 | 156 | if (!GAME.Sound.ON) 157 | { 158 | // for (var i = 0; i < loop_arr.length; ++i) 159 | // { 160 | // if (!loop_arr[i].paused) { 161 | // loop_arr[i].pause (); 162 | // } 163 | // } 164 | 165 | // -- now find playing elements 166 | var audio_els = container.getElementsByTagName ('audio'); 167 | for (var i = 0; i < audio_els.length; ++i) 168 | { 169 | if (!audio_els[i].paused) { 170 | audio_els[i].pause (); 171 | } 172 | } 173 | } 174 | else 175 | { 176 | for (var i = 0; i < loop_arr.length; ++i) 177 | { 178 | GAME.Sound.Play( loop_arr[i].id ); 179 | } 180 | } 181 | 182 | return (GAME.Sound.ON); 183 | // --- 184 | } 185 | }; 186 | 187 | })( window, document, GAME ); -------------------------------------------------------------------------------- /3d/js/engine.utils.js: -------------------------------------------------------------------------------- 1 | (function ( w, d, GAME ) { 2 | 'use strict'; 3 | 4 | var UTILS = {}; 5 | 6 | if (!GAME.UTILS) GAME.UTILS = UTILS; 7 | 8 | 9 | ////////////////////////////////////////////// 10 | // modifies an element and fires the callback 11 | // once the object's transition ended 12 | UTILS.RunAfterTransition = function ( obj ) { 13 | 14 | w.requestAnimationFrame(function () { 15 | var el = obj.el; 16 | var comp_style = getComputedStyle ( el ); 17 | var el_style = el.style; 18 | var attr = obj.attr; 19 | var offset = obj.offset || 1; 20 | var cb = obj.cb; 21 | var transition_duration = (parseFloat (comp_style.transitionDuration) + parseFloat (comp_style.transitionDelay)); 22 | 23 | var finale = function () { 24 | if (obj.del > 0 && el.parentNode) 25 | { 26 | if (obj.del === 2) el_style.display = 'none'; 27 | el.parentNode.removeChild ( el ); 28 | } 29 | 30 | cb && cb (); 31 | }; 32 | 33 | if (obj.dur) transition_duration = obj.dur; 34 | if (!attr) attr = comp_style.transitionProperty; 35 | 36 | el_style[attr] = (obj.val + ''); 37 | 38 | if (!transition_duration) { 39 | finale (); 40 | return ; 41 | } 42 | 43 | setTimeout ( finale, offset + transition_duration * 1000 ); 44 | }); 45 | 46 | }; 47 | 48 | 49 | ////////////////////////////////////////////// 50 | // Loads js script asynchronously 51 | GAME.UTILS.LoadScript = function ( src, callback ) { 52 | var s = d.createElement('script'), r = false, t; 53 | s.type = 'text/javascript'; 54 | s.src = src; 55 | s.onload = s.onreadystatechange = function() { 56 | if ( !r && (!this.readyState || this.readyState == 'complete') ) 57 | { 58 | r = true; 59 | callback && callback(); 60 | } 61 | }; 62 | t = d.getElementsByTagName('head')[0]; 63 | t.appendChild ( s ); 64 | }; 65 | 66 | GAME.UTILS.DummyEl = function (x, y, z) { 67 | var el = d.createElement('div'); 68 | el.className = 'vertex'; 69 | el.style.transform = 'translate3d('+ x +'px,'+ y +'px,'+ z +'px)'; 70 | el.style.backgroundColor = '#'+(Math.random()*0xFFFFFF<<0).toString(16); 71 | el.setAttribute('vertex-id', 'random'); 72 | 73 | move.appendChild( el ); 74 | }; 75 | 76 | GAME.UTILS.RandomColor = function () { 77 | return ('#'+(Math.random()*0xFFFFFF<<0).toString(16)); 78 | }; 79 | 80 | GAME.UTILS.Distance = function ( el ) { 81 | if (!el) return (0); 82 | 83 | if (el.tagName === 'DIV') 84 | { 85 | var trans = el.style.transform; 86 | var arr = trans.replace('translate3d(','').split(')')[0].replace(')','') 87 | .replace('px','').replace('px','').replace('px','') 88 | .replace(' ', '').replace(' ', '').split(','); 89 | var el_pos = new Vector (arr[0] / 1, arr[1] / 1, arr[2] / 1); 90 | 91 | return (el_pos.subtract ( GAME.DIMS.pos ).length () >> 0); 92 | } 93 | 94 | if (el.vertices) 95 | { 96 | if (!el.centroid) 97 | { 98 | if (el.vertices && el.vertices[0]) 99 | { 100 | var nv = el.vertices; 101 | el.centroid = new Vector ( (nv[2].x + nv[0].x)/2, (nv[2].y + nv[0].y)/2, (nv[2].z + nv[0].z)/2 ); 102 | } 103 | else 104 | { 105 | var temp = el.el.style.transform.replace('translate3d(','').split(')')[0]; 106 | temp = temp.replace('px', '').replace('px', '').replace('px', '').replace(' ', '').replace(' ', '').replace(' ', '').split(','); 107 | 108 | el.centroid = new Vector( temp[0]/1, temp[1]/1, temp[2]/1 ); 109 | } 110 | } 111 | 112 | return (el.centroid.subtract ( GAME.DIMS.pos ).length () >> 0); 113 | } 114 | 115 | return (0); 116 | }; 117 | 118 | 119 | GAME.UTILS.IsVisible = function ( node ) { 120 | var vv = new Vector(); 121 | var projection_matrix = [1.9403849094557126, 0, 0, 0, 0, 2.7474774194546225, 0, 0, 0, 0, -1.0002000200020003, -1, 0, 0, -2.000200020002, 0]; 122 | var cam_mat = __getCamMatrix (); 123 | var mat_rev = GetInverse( cam_mat ); 124 | 125 | if (!node.centroid) 126 | { 127 | if (node.vertices && node.vertices[0]) 128 | { 129 | var nv = node.vertices; 130 | node.centroid = new Vector ( (nv[2].x + nv[0].x)/2, (nv[2].y + nv[0].y)/2, (nv[2].z + nv[0].z)/2 ); 131 | } 132 | else 133 | { 134 | var temp = node.el.style.transform.replace('translate3d(','').split(')')[0]; 135 | temp = temp.replace('px', '').replace('px', '').replace('px', '').replace(' ', '').replace(' ', '').replace(' ', '').split(','); 136 | 137 | node.centroid = new Vector( temp[0]/1, temp[1]/1, temp[2]/1 ); 138 | } 139 | } 140 | 141 | // check if the element is visible on screen 142 | vv.x = node.centroid.x; 143 | vv.y = node.centroid.y; 144 | vv.z = node.centroid.z; 145 | 146 | vv.applyMatrix4( mat_rev ).applyMatrix4( projection_matrix ); 147 | 148 | if ( Math.abs (vv.x) < 1 && Math.abs (vv.y) < 1 && vv.z < 1.0001 ) { 149 | return (true); 150 | } 151 | else { 152 | return (false); 153 | } 154 | }; 155 | 156 | GAME.UTILS.RotateNodeToCamera = function (node) { 157 | var cam_mat = __getCamMatrix (); 158 | var mat_rev = GetInverse (cam_mat); 159 | var vv = node.centroid.clone (); 160 | 161 | if (!node.orig_trans) 162 | { 163 | node.orig_trans = node.transform; 164 | } 165 | 166 | var new_trans = node.orig_trans + ' rotateY(' + (-GAME.DIMS.deg.y) + 'deg)'; 167 | new_trans += ' rotateX(' + (-GAME.DIMS.deg.x) + 'deg)'; 168 | node.el.style.transform = new_trans; 169 | }; 170 | 171 | GAME.UTILS.ProjectMouse = function (x, y) { 172 | var ray_origin = new Vector(GAME.DIMS.pos.x, GAME.DIMS.pos.y, GAME.DIMS.pos.z); 173 | var ray_direction = new Vector(x, y, 0.5); 174 | 175 | var cam_mat = __getCamMatrix (); 176 | var mat_rev = GetInverse (cam_mat); 177 | var mat_rev = MultiplyMatrices([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 900, 1], mat_rev); 178 | var new_mat = GetInverse (mat_rev); 179 | 180 | ray_direction.applyMatrix4( new_mat ); //.applyMatrix4( FOV_MAT_SELF_45 ); 181 | 182 | // console.log( ray_origin, ray_direction); // .subtract (ray_origin) ); 183 | 184 | if (!window.temp_debug) 185 | { 186 | window.temp_debug = document.createElement('div'); 187 | window.temp_debug.id = 'temp_debug'; 188 | window.temp_debug.className = 'obj'; 189 | var sss = document.getElementById('scn-cntr'); 190 | window.temp_debug.style.cssText = 'width:12px;height:12px;position:absolute;z-index:999;background:red;backface-visibility:visible;'; 191 | move.appendChild( window.temp_debug ); 192 | } 193 | 194 | window.temp_debug.style.transform = 'translate3d(' + ray_direction.x + 'px,' + ray_direction.y + 'px,'+ray_direction.z+'px)'; 195 | 196 | // if ( _intersectsPlane( ray_origin, ray_direction, GAME.LEVEL.MAP.NODES['wall-door'], false ) ) { 197 | // console.log( "INTERSTS" ); 198 | // } 199 | }; 200 | 201 | function __getCamMatrix () { 202 | var x = DegToRad(-GAME.DIMS.deg.x); 203 | var y = DegToRad(-GAME.DIMS.deg.y); 204 | var z = 0; 205 | 206 | var cos = Math.cos; 207 | var sin = Math.sin; 208 | 209 | var c1 = cos( x / 2 ); 210 | var c2 = cos( y / 2 ); 211 | var c3 = cos( z / 2 ); 212 | 213 | var s1 = sin( x / 2 ); 214 | var s2 = sin( y / 2 ); 215 | var s3 = sin( z / 2 ); 216 | 217 | 218 | x = s1 * c2 * c3 + c1 * s2 * s3; 219 | y = c1 * s2 * c3 - s1 * c2 * s3; 220 | z = c1 * c2 * s3 - s1 * s2 * c3; 221 | var w_ = c1 * c2 * c3 + s1 * s2 * s3; 222 | 223 | 224 | var x2 = x + x, y2 = y + y, z2 = z + z; 225 | var xx = x * x2, xy = x * y2, xz = x * z2; 226 | var yy = y * y2, yz = y * z2, zz = z * z2; 227 | var wx = w_ * x2, wy = w_ * y2, wz = w_ * z2; 228 | 229 | var sx = 1, sy = 1, sz = 1; 230 | var cam_mat = []; 231 | cam_mat[ 0 ] = ( 1 - ( yy + zz ) ) * sx; 232 | cam_mat[ 1 ] = ( xy + wz ) * sx; 233 | cam_mat[ 2 ] = ( xz - wy ) * sx; 234 | cam_mat[ 3 ] = 0; 235 | 236 | cam_mat[ 4 ] = ( xy - wz ) * sy; 237 | cam_mat[ 5 ] = ( 1 - ( xx + zz ) ) * sy; 238 | cam_mat[ 6 ] = ( yz + wx ) * sy; 239 | cam_mat[ 7 ] = 0; 240 | 241 | cam_mat[ 8 ] = ( xz + wy ) * sz; 242 | cam_mat[ 9 ] = ( yz - wx ) * sz; 243 | cam_mat[ 10 ] = ( 1 - ( xx + yy ) ) * sz; 244 | cam_mat[ 11 ] = 0; 245 | 246 | cam_mat[ 12 ] = GAME.DIMS.pos.x; 247 | cam_mat[ 13 ] = GAME.DIMS.pos.y; 248 | cam_mat[ 14 ] = GAME.DIMS.pos.z; 249 | cam_mat[ 15 ] = 1; 250 | 251 | return (cam_mat); 252 | } 253 | 254 | GAME.UTILS.iframe = (window === window.parent) ? false : true; 255 | 256 | GAME.UTILS.RotateCameraTo = function ( point ) { 257 | var cam_mat = __getCamMatrix (); 258 | // var mat_rev = GetInverse( cam_mat ); 259 | // console.log( mat_rev ); 260 | 261 | /* 262 | var _GetMatrixCSS = (function() { 263 | var MatrixCSS = w.WebKitCSSMatrix || 264 | w.MozCSSMatrix || 265 | w.MsCSSMatrix || 266 | w.OCSSMatrix || 267 | w.CSSMatrix; 268 | var matrix_css = new MatrixCSS (); 269 | 270 | if (!matrix_css.toFloat32Array) 271 | { 272 | MatrixCSS.prototype.toFloat32Array = function() { 273 | return ([this.m11, this.m12, this.m13, this.m14, 274 | this.m21, this.m22, this.m23, this.m24, 275 | this.m31, this.m32, this.m33, this.m34, 276 | this.m41, this.m42, this.m43, this.m44]); 277 | }; 278 | } 279 | 280 | return function ( trans ) { 281 | matrix_css.setMatrixValue ( trans ); 282 | return (matrix_css.toFloat32Array()); 283 | }; 284 | })(); 285 | 286 | var matt = _GetMatrixCSS (move.style.transform); 287 | 288 | // var xxx = MultiplyMatrices([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 900, 1], GetInverse(cam_mat) ); 289 | matt = GetInverse (matt); 290 | var tg_node = document.getElementById('floor-1'); 291 | 292 | tg_node.style.transform = 'matrix3d(' + matt.join(',') + ') translate3d(-250px, -250px, 100px)'; 293 | tg_node.style.transformOrigin = '0 0'; 294 | return ; 295 | */ 296 | 297 | var world_arr = LookAt( GetInverse (cam_mat), 298 | GAME.DIMS.pos.clone(), 299 | point.clone(), 300 | new Vector(0,1,0)); 301 | 302 | world_arr = MultiplyMatrices([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 900, 1], GetInverse(world_arr) ); 303 | 304 | var clamp = function (value, min, max) { 305 | if (min > max) { 306 | var tmp = max; 307 | max = min; 308 | min = tmp; 309 | } 310 | return (value < min) ? min : ((value > max) ? max : value); 311 | }; 312 | 313 | var _getRotation = function ( m ) { 314 | var ret = new Vector(); 315 | 316 | // ----------------------------------------- 317 | var m11 = m[ 0 ], m12 = m[ 4 ], m13 = m[ 8 ]; 318 | var m21 = m[ 1 ], m22 = m[ 5 ], m23 = m[ 9 ]; 319 | var m31 = m[ 2 ], m32 = m[ 6 ], m33 = m[ 10 ]; 320 | 321 | ret.x = Math.asin( clamp( m32, - 1, 1 ) ) * (180 / Math.PI); 322 | if ( Math.abs( m32 ) < 0.9999999 ) { 323 | ret.y = Math.atan2( - m31, m33 ) * (180 / Math.PI); 324 | ret.z = Math.atan2( - m12, m22 ) * (180 / Math.PI); 325 | } else { 326 | ret.y = 0; 327 | ret.z = Math.atan2( m21, m11 ) * (180 / Math.PI); 328 | } 329 | 330 | ret.z = 0; 331 | return (ret); 332 | 333 | /* 334 | var order = 'XYZ'; 335 | if ( order === 'XYZ' ) 336 | { 337 | ret.y = Math.asin( clamp( m13, - 1, 1 ) ) * (180 / Math.PI); 338 | 339 | if ( Math.abs( m13 ) < 0.9999999 ) { 340 | ret.x = Math.atan2( - m23, m33 ) * (180 / Math.PI); 341 | ret.z = Math.atan2( - m12, m11 ) * (180 / Math.PI); 342 | } else { 343 | ret.x = Math.atan2( m32, m22 ) * (180 / Math.PI); 344 | ret.z = 0; 345 | } 346 | } 347 | console.log( order, ret.clone () ); 348 | 349 | ret = new Vector(); 350 | order = 'YXZ'; 351 | if ( order === 'YXZ' ) 352 | { 353 | ret.x = Math.asin( - clamp( m23, - 1, 1 ) ) * (180 / Math.PI); 354 | 355 | if ( Math.abs( m23 ) < 0.9999999 ) { 356 | ret.y = Math.atan2( m13, m33 ) * (180 / Math.PI); 357 | ret.z = Math.atan2( m21, m22 ) * (180 / Math.PI); 358 | } else { 359 | ret.y = Math.atan2( - m31, m11 ) * (180 / Math.PI); 360 | ret.z = 0; 361 | } 362 | } 363 | console.log( order, ret.clone () ); 364 | 365 | 366 | 367 | ret = new Vector(); 368 | order = 'ZXY'; 369 | if ( order === 'ZXY' ) 370 | { 371 | ret.x = Math.asin( clamp( m32, - 1, 1 ) ) * (180 / Math.PI); 372 | if ( Math.abs( m32 ) < 0.9999999 ) { 373 | ret.y = Math.atan2( - m31, m33 ) * (180 / Math.PI); 374 | ret.z = Math.atan2( - m12, m22 ) * (180 / Math.PI); 375 | } else { 376 | ret.y = 0; 377 | ret.z = Math.atan2( m21, m11 ) * (180 / Math.PI); 378 | } 379 | 380 | ret.z = 0; 381 | return (ret); 382 | } 383 | console.log( order, ret.clone () ); 384 | 385 | 386 | ret = new Vector(); 387 | order = 'ZYX'; 388 | if ( order === 'ZYX' ) 389 | { 390 | ret.y = Math.asin( - clamp( m31, - 1, 1 ) ) * (180 / Math.PI); 391 | 392 | if ( Math.abs( m31 ) < 0.9999999 ) { 393 | 394 | ret.x = Math.atan2( m32, m33 ) * (180 / Math.PI); 395 | ret.z = Math.atan2( m21, m11 ) * (180 / Math.PI); 396 | 397 | } else { 398 | ret.x = 0; 399 | ret.z = Math.atan2( - m12, m22 ) * (180 / Math.PI); 400 | } 401 | 402 | } 403 | console.log( order, ret.clone () ); 404 | 405 | 406 | ret = new Vector(); 407 | order = 'YZX'; 408 | if ( order === 'YZX' ) { 409 | ret.z = Math.asin( clamp( m21, - 1, 1 ) ) * (180 / Math.PI); 410 | 411 | if ( Math.abs( m21 ) < 0.9999999 ) { 412 | 413 | ret.x = Math.atan2( - m23, m22 ) * (180 / Math.PI); 414 | ret.y = Math.atan2( - m31, m11 ) * (180 / Math.PI); 415 | 416 | } else { 417 | 418 | ret.x = 0; 419 | ret.y = Math.atan2( m13, m33 ) * (180 / Math.PI); 420 | 421 | } 422 | 423 | } 424 | console.log( order, ret.clone () ); 425 | 426 | 427 | ret = new Vector(); 428 | order = 'XZY'; 429 | if ( order === 'XZY' ) { 430 | 431 | ret.z = Math.asin( - clamp( m12, - 1, 1 ) ) * (180 / Math.PI); 432 | 433 | if ( Math.abs( m12 ) < 0.9999999 ) { 434 | ret.x = Math.atan2( m32, m22 ) * (180 / Math.PI); 435 | ret.y = Math.atan2( m13, m11 ) * (180 / Math.PI); 436 | } else { 437 | ret.x = Math.atan2( - m23, m33 ) * (180 / Math.PI); 438 | ret.y = 0; 439 | } 440 | } 441 | console.log( order, ret.clone () ); 442 | 443 | ret = new Vector(); 444 | 445 | // ret.x = Math.asin( - clamp( m[9], - 1, 1 ) ) * (180 / Math.PI); 446 | // ret.x = Math.atan2(m[9], m[5]) * (180 / Math.PI); 447 | if ( Math.abs( m[9] ) < 0.99999 ) { 448 | ret.y = Math.atan2( m[8], m[10] ) * (180 / Math.PI); 449 | ret.x = -Math.atan2( m[1], m[5] ) * (180 / Math.PI); 450 | } else { 451 | ret.y = Math.atan2( -m[2], m[0] ) * (180 / Math.PI); 452 | ret.x = 0; 453 | } 454 | 455 | return (ret); 456 | */ 457 | }; 458 | 459 | var rot = _getRotation( world_arr ); 460 | 461 | 462 | 463 | return (rot); 464 | }; 465 | 466 | GAME.UTILS.GetRotation = function ( m ) { 467 | var ret = new Vector(); 468 | var clamp = function (value, min, max) { 469 | if (min > max) { 470 | var tmp = max; 471 | max = min; 472 | min = tmp; 473 | } 474 | return (value < min) ? min : ((value > max) ? max : value); 475 | }; 476 | 477 | // ----------------------------------------- 478 | var m11 = m[ 0 ], m12 = m[ 4 ], m13 = m[ 8 ]; 479 | var m21 = m[ 1 ], m22 = m[ 5 ], m23 = m[ 9 ]; 480 | var m31 = m[ 2 ], m32 = m[ 6 ], m33 = m[ 10 ]; 481 | 482 | ret.x = Math.asin( clamp( m32, - 1, 1 ) ) * (180 / Math.PI); 483 | if ( Math.abs( m32 ) < 0.9999999 ) { 484 | ret.y = Math.atan2( - m31, m33 ) * (180 / Math.PI); 485 | ret.z = Math.atan2( - m12, m22 ) * (180 / Math.PI); 486 | } else { 487 | ret.y = 0; 488 | ret.z = Math.atan2( m21, m11 ) * (180 / Math.PI); 489 | } 490 | 491 | ret.z = 0; 492 | return (ret); 493 | }; 494 | 495 | 496 | GAME.UTILS.UnpackColor = function ( val ) { 497 | var color = val; 498 | var a = color >> 24 & 255; // 255 499 | var r = color >> 16 & 255; // 255 500 | var g = color >> 8 & 255; // 122 501 | var b = color >> 0 & 255; 502 | 503 | return ({r:r,g:g,b:b,a:a}); 504 | }; 505 | 506 | GAME.UTILS.PackColor = function (r, g, b, a) { 507 | var color = a << 24 | r << 16 | g << 8 | b << 0; 508 | 509 | return (color); 510 | }; 511 | 512 | GAME.UTILS.DrawCanvas = function (el, node, type, color) { 513 | if (!type || (type !== 'img' && type !== 'canvas')) { 514 | type = 'canvas'; 515 | } 516 | 517 | if (!color) { 518 | color = 'darkgreen'; 519 | } 520 | 521 | var cont = document.createElement ('div'); 522 | var ee; 523 | 524 | if (type === 'canvas') { 525 | ee = el; 526 | } else { 527 | ee = new Image (); 528 | ee.src = el.toDataURL ('image/png', 0.8); 529 | } 530 | 531 | if (node) { 532 | ee.title = node.id; 533 | 534 | var ttl = document.createElement('span'); 535 | ttl.innerHTML = node.id; 536 | ttl.style.cssText = 'display:block;text-align:center'; 537 | cont.appendChild ( ttl ); 538 | } 539 | 540 | ee.style.margin = '6px'; 541 | cont.style.border = '1px solid ' + color; 542 | cont.style.margin = '8px'; 543 | cont.style.padding = '4px'; 544 | cont.style.textAlign = 'center'; 545 | cont.style.display = 'inline-block'; 546 | cont.style.position = 'relative'; 547 | 548 | cont.appendChild ( ee ); 549 | document.body.appendChild( cont ); 550 | }; 551 | 552 | GAME.UTILS._filterGameObjects = function (objects) { 553 | for (var k in objects) 554 | { 555 | var curr = objects[k]; 556 | 557 | if (!curr.extends) continue; 558 | 559 | var clone = objects[curr.extends]; 560 | 561 | for (var j in clone) 562 | { 563 | if (!curr.hasOwnProperty (j)) { 564 | curr[j] = clone[j]; 565 | } 566 | } 567 | 568 | curr.extends = null; 569 | } 570 | }; 571 | 572 | 573 | GAME.UTILS.LoadLevel2 = function ( lvl, val, trans ) { 574 | GAME.ACTIONS.DialogCover (1); 575 | 576 | var lvl_load = function () { 577 | var callback = null; 578 | 579 | if (val) { 580 | (function(val) { 581 | callback = function() { 582 | GAME.LEVEL.CONF && GAME.LEVEL.CONF(val); 583 | }; 584 | })(val); 585 | } 586 | 587 | GAME.UTILS.LoadScript ( '3d/js/level-' + lvl + '.js', callback ); 588 | }; 589 | 590 | if (!trans) trans = 300; 591 | 592 | setTimeout(function() { 593 | lvl_load ( lvl, val ); 594 | }, trans); 595 | }; 596 | 597 | GAME.UTILS.LoadLevel = function ( lvl, val ) { 598 | // check to see if level exists 599 | GAME.ACTIONS.ResetControls (); 600 | 601 | var callback = null; 602 | 603 | if (val) { 604 | (function(val) { 605 | callback = function() { 606 | GAME.LEVEL.CONF && GAME.LEVEL.CONF(val); 607 | }; 608 | })(val); 609 | } 610 | 611 | GAME.UTILS.LoadScript ( '3d/js/level-' + lvl + '.js', callback ); 612 | }; 613 | 614 | 615 | var agent = navigator.userAgent; 616 | var browser = ''; 617 | var mob = (/Mobi/.test(agent)) ? true : false; 618 | 619 | GAME.UTILS.Mobile = mob; 620 | 621 | d.body.className = mob ? 'mob' : 'dsk'; 622 | 623 | if ( (window.chrome && window.chrome.webstore) || agent.indexOf('Chrome/') > 0 ) { 624 | browser = 'chrome'; 625 | } 626 | else if ( (window.opr && opr.addons) || window.opera || agent.indexOf(' OPR/') > 0 ) { 627 | browser = 'opera'; 628 | } 629 | else if (window.ApplePayError || /constructor/i.test(window.HTMLElement) || (function(p) { 630 | return p.toString() === "[object SafariRemoteNotification]"; 631 | })(!window['safari'] || safari.pushNotification)) { 632 | browser = 'safari'; 633 | } 634 | else if (typeof InstallTrigger !== 'undefined') { 635 | browser = 'firefox'; 636 | } 637 | else if (false || document.documentMode) { 638 | browser = 'ie'; 639 | } 640 | else if (window.StyleMedia) { 641 | browser = 'edge'; 642 | } 643 | else if (agent.indexOf('UCBrowser/') > 0) { 644 | browser = 'uc'; 645 | } 646 | GAME.UTILS.Browser = browser; 647 | 648 | 649 | })( window, document, GAME ); -------------------------------------------------------------------------------- /3d/js/level-03.js: -------------------------------------------------------------------------------- 1 | (function ( w, d, GAME ) { 2 | 'use strict'; 3 | 4 | var _y_zero = 250; 5 | 6 | 7 | var GAME_OBJ = { 8 | 9 | /////////////////////////////////////////////////////////////////// 10 | // OBJECTS (TOOLS, ITEMS, DECORATIONS ETC) 11 | /////////////////////////////////////////////////////////////////// 12 | 'obj-decal-web-1' : { 13 | id:'obj-decal-web-1', 14 | type: 'object', 15 | clss:'decal-web', 16 | walk: true, 17 | cast_shadow: false, 18 | geom:[] 19 | }, 20 | 21 | // invisible plane 22 | 'obj-invis-1' : { 23 | id:'obj-invis-1', 24 | type: 'object', 25 | clss:'invis', 26 | walk: true, 27 | cast_shadow: false, 28 | geom:[] 29 | }, 30 | 31 | // stairs up 32 | 'obj-stairs-1' : { 33 | id:'obj-stairs-1', 34 | // img : '3d/debug_square.jpg', 35 | img:'3d/dungeon-floor-3_lossy.jpg', 36 | type: 'object', 37 | clss: 'book', 38 | walk: true, 39 | cast_shadow:true, 40 | isnew:true, 41 | 42 | geom:[ 43 | { 44 | //tag:'div', 45 | clss:'face_quad', 46 | shape:'face_quad', 47 | shape_args:[150, 15, false, new Vector(0, 0, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 48 | }, 49 | { 50 | //tag:'div', 51 | clss:'face_quad', 52 | shape:'face_quad', 53 | shape_args:[150, 15, false, new Vector(-15/2, -15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 54 | }, 55 | { 56 | //tag:'div', 57 | clss:'face_quad', 58 | shape:'face_quad', 59 | shape_args:[150, 15, false, new Vector(-15, -15, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 60 | }, 61 | { 62 | //tag:'div', 63 | clss:'face_quad', 64 | shape:'face_quad', 65 | shape_args:[150, 15, false, new Vector(-15-15/2, -15-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 66 | }, 67 | { 68 | //tag:'div', 69 | clss:'face_quad', 70 | shape:'face_quad', 71 | shape_args:[150, 15, false, new Vector(-15*2, -15*2, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 72 | }, 73 | { 74 | //tag:'div', 75 | clss:'face_quad', 76 | shape:'face_quad', 77 | shape_args:[150, 15, false, new Vector(-15*2-15/2, -15*2-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 78 | }, 79 | { 80 | //tag:'div', 81 | clss:'face_quad', 82 | shape:'face_quad', 83 | shape_args:[150, 15, false, new Vector(-15*3, -15*3, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 84 | }, 85 | { 86 | //tag:'div', 87 | clss:'face_quad', 88 | shape:'face_quad', 89 | shape_args:[150, 15, false, new Vector(-15*3-15/2, -15*3-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 90 | }, 91 | { 92 | //tag:'div', 93 | clss:'face_quad', 94 | shape:'face_quad', 95 | shape_args:[150, 15, false, new Vector(-15*4, -15*4, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 96 | }, 97 | { 98 | //tag:'div', 99 | clss:'face_quad', 100 | shape:'face_quad', 101 | shape_args:[150, 15, false, new Vector(-15*4-15/2, -15*4-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 102 | }, 103 | { 104 | //tag:'div', 105 | clss:'face_quad', 106 | shape:'face_quad', 107 | shape_args:[150, 15, false, new Vector(-15*5, -15*5, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 108 | }, 109 | { 110 | //tag:'div', 111 | clss:'face_quad', 112 | shape:'face_quad', 113 | shape_args:[150, 15, false, new Vector(-15*5-15/2, -15*5-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 114 | }, 115 | { 116 | //tag:'div', 117 | clss:'face_quad', 118 | shape:'face_quad', 119 | shape_args:[150, 15, false, new Vector(-15*6, -15*6, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 120 | }, 121 | { 122 | //tag:'div', 123 | clss:'face_quad', 124 | shape:'face_quad', 125 | shape_args:[150, 15, false, new Vector(-15*6-15/2, -15*6-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 126 | }, 127 | { 128 | //tag:'div', 129 | clss:'face_quad', 130 | shape:'face_quad', 131 | shape_args:[150, 15, false, new Vector(-15*7, -15*7, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 132 | }, 133 | { 134 | //tag:'div', 135 | clss:'face_quad', 136 | shape:'face_quad', 137 | shape_args:[150, 15, false, new Vector(-15*7-15/2, -15*7-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 138 | }, 139 | { 140 | //tag:'div', 141 | clss:'face_quad', 142 | shape:'face_quad', 143 | shape_args:[150, 15, false, new Vector(-15*8, -15*8, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 144 | }, 145 | { 146 | //tag:'div', 147 | clss:'face_quad', 148 | shape:'face_quad', 149 | shape_args:[150, 15, false, new Vector(-15*8-15/2, -15*8-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 150 | }, 151 | { 152 | //tag:'div', 153 | clss:'face_quad', 154 | shape:'face_quad', 155 | shape_args:[150, 15, false, new Vector(-15*9, -15*9, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 156 | }, 157 | { 158 | //tag:'div', 159 | clss:'face_quad', 160 | shape:'face_quad', 161 | shape_args:[150, 15, false, new Vector(-15*9-15/2, -15*9-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 162 | }, 163 | { 164 | //tag:'div', 165 | clss:'face_quad', 166 | shape:'face_quad', 167 | shape_args:[150, 15, false, new Vector(-15*10, -15*10, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 168 | }, 169 | { 170 | //tag:'div', 171 | clss:'face_quad', 172 | shape:'face_quad', 173 | shape_args:[150, 15, false, new Vector(-15*10-15/2, -15*10-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 174 | }, 175 | { 176 | //tag:'div', 177 | clss:'face_quad', 178 | shape:'face_quad', 179 | shape_args:[150, 15, false, new Vector(-15*11, -15*11, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 180 | }, 181 | { 182 | //tag:'div', 183 | clss:'face_quad', 184 | shape:'face_quad', 185 | shape_args:[150, 15, false, new Vector(-15*11-15/2, -15*11-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 186 | }, 187 | /* 188 | { 189 | //tag:'div', 190 | clss:'face_quad', 191 | shape:'face_quad', 192 | shape_args:[150, 15, false, new Vector(-15*12, -15*12, 0), 'middle', 'rotateY(90deg) rotateX(0deg)'] 193 | }, 194 | { 195 | //tag:'div', 196 | clss:'face_quad', 197 | shape:'face_quad', 198 | shape_args:[150, 15, false, new Vector(-15*12-15/2, -15*12-15/2, 0), 'middle', 'rotateY(90deg) rotateX(90deg)'] 199 | },*/ 200 | 201 | /////////// side 202 | { 203 | //tag:'div', 204 | clss:'face_quad', 205 | shape:'face_quad', 206 | shape_args:[180, 180, false, new Vector(-90, -90 + 15/2, 75), 'middle', 'rotateY(180deg) rotateX(0deg)'] 207 | }, 208 | { 209 | //tag:'div', 210 | clss:'face_quad', 211 | shape:'face_quad', 212 | shape_args:[180, 180, false, new Vector(-90, -90 + 15/2, -75), 'middle', 'rotateY(0deg) rotateX(0deg)'] 213 | } 214 | ] 215 | }, 216 | 217 | // test shape 218 | 'obj-shape-chair' : { 219 | id:'obj-shape-chair', 220 | img : '3d/blank.jpg', 221 | type: 'object', 222 | clss: 'chair', 223 | walk: true, 224 | cast_shadow:false, 225 | no_shadow:true, 226 | isnew:true, 227 | 228 | geom:[ 229 | 230 | { 231 | clss:'box', 232 | shape:'rectangle', 233 | transform:'translate3d(14px, 0px, 14px)', 234 | shape_args:[5, 40, 5] 235 | }, 236 | 237 | { 238 | clss:'box', 239 | shape:'rectangle', 240 | transform:'translate3d(-14px, 0px, 14px)', 241 | shape_args:[5, 40, 5] 242 | }, 243 | 244 | { 245 | clss:'box', 246 | shape:'rectangle', 247 | transform:'translate3d(-14px, 0px, -14px)', 248 | shape_args:[5, 40, 5] 249 | }, 250 | 251 | { 252 | clss:'box', 253 | shape:'rectangle', 254 | transform:'translate3d(14px, 0px, -14px)', 255 | shape_args:[5, 40, 5] 256 | }, 257 | 258 | { 259 | clss:'box', 260 | shape:'rectangle', 261 | transform:'translate3d(0px, -20px, 0px)', 262 | // sides:{top:1, back:1, left:1}, 263 | shape_args:[40, 2, 40] 264 | }, 265 | 266 | ] 267 | }, 268 | 269 | 270 | /////////////////////////////////////////////////////////////////// 271 | // GEOMETRY (WALLS, FLOORS, LANDSCAPE ETC) 272 | /////////////////////////////////////////////////////////////////// 273 | // floors 274 | 'dungeon-floor-1': { 275 | clss:'dungeon-floor-1', 276 | img:'3d/dungeon-floor-3_lossy.jpg', 277 | width: 500, 278 | height: 500, 279 | walk: true, 280 | cast_shadow:false, 281 | isnew:true, 282 | 283 | x:-250, y:0, z:0, 284 | transform:' rotateX(90deg)', 285 | 286 | vertices: function (width, height) {} 287 | }, 288 | 289 | 'floor-350-180':{ 290 | extends:'dungeon-floor-1', 291 | width:350, 292 | height:180, 293 | transform:' rotateX(90deg) translate3d(100px,0,-1px)' 294 | }, 295 | 296 | // ceilings 297 | 'dungeon-ceil-1': { 298 | clss:'dungeon-ceil-1', 299 | img:'3d/dungeon-ceiling-2_lossy.jpg', 300 | width: 500, 301 | height: 500, 302 | walk: true, 303 | cast_shadow:false, 304 | isnew:true, 305 | 306 | x:-250, y:0, z:500, 307 | transform:' rotateX(-90deg)', 308 | 309 | vertices: function (width, height) {} 310 | }, 311 | 312 | 313 | // walls 314 | 'dungeon-wall-1': { 315 | clss:'dungeon-wall-1', 316 | img:'3d/wall-dungeon2_lossy.jpg', 317 | 318 | width: 500, 319 | height: 400, 320 | walk: false, 321 | cast_shadow: true, // true 322 | isnew:true, 323 | 324 | x:-250, 325 | y:0, 326 | z:0, 327 | 328 | transform:'', 329 | vertices: function (width, height) {} 330 | }, 331 | 332 | 333 | 'dungeon-wall-2': { 334 | clss:'dungeon-wall-1', 335 | img:'3d/wall-dungeon2_lossy.jpg', 336 | 337 | width: 500, 338 | height: 400, 339 | walk: false, 340 | cast_shadow: true, // true 341 | isnew:true, 342 | 343 | x:-250, 344 | y:0, 345 | z:0, 346 | 347 | transform:' rotateY(180deg)', 348 | vertices: function (width, height) {} 349 | }, 350 | 351 | 'dungeon-wall-3': { 352 | extends: 'dungeon-wall-1', 353 | img:'3d/wall-dungeon2_lossy.jpg', 354 | transform:' rotateY(90deg)', 355 | isnew:true, 356 | x:-250, y:0, z:0, 357 | vertices: function (width, height) {} 358 | }, 359 | 360 | 'dungeon-wall-4': { 361 | extends: 'dungeon-wall-1', 362 | img:'3d/wall-dungeon2_lossy.jpg', 363 | 364 | x:-250, y:0, z:0, 365 | transform:' rotateY(-90deg)', 366 | isnew:true, 367 | vertices: function (width, height) {} 368 | }, 369 | 370 | 371 | 372 | 'ramp-water-1': { 373 | qv:256, 374 | 375 | clss:'cave-water-1 dirt', 376 | width: 340, 377 | height: 500, 378 | walk: true, 379 | cast_shadow:false, 380 | isnew:true, 381 | 382 | img:'3d/wall-dungeon2_lossy.jpg', 383 | 384 | x:-250, y:0, z:0, 385 | transform:'rotateX(90deg) rotateY(30deg) rotateZ(-90deg)', 386 | vertices: function (width, height) {} 387 | }, 388 | 'cave-door-2-w340': { 389 | clss:'cave-door-1-w340', 390 | width: 340, 391 | height: 300, 392 | walk: false, 393 | cast_shadow: false, 394 | isnew:true, 395 | 396 | img:'3d/level-2/cave-door-1.jpg', 397 | 398 | x:-250, 399 | y:0,//-300 + _y_zero, // -height + _y_zero 400 | z:0,//-250, 401 | 402 | transform:'rotateY(-90deg)', 403 | vertices: function (width, height) {} 404 | }, 405 | 406 | 'cave-door-3-w340':{ 407 | extends:'cave-door-2-w340', 408 | transform:'rotateY(-180deg)' 409 | }, 410 | 411 | 412 | 'little-wall-2': { 413 | clss:'', 414 | width: 80, 415 | height: 400, 416 | walk: false, 417 | cast_shadow: false, 418 | isnew:true, 419 | 420 | img:'3d/wall-dungeon2_lossy.jpg', 421 | 422 | x:-250, 423 | y:0,//-300 + _y_zero, // -height + _y_zero 424 | z:0,//-250, 425 | 426 | transform:'rotateY(-90deg)', 427 | vertices: function (width, height) {} 428 | }, 429 | 'little-wall-3': { 430 | extends:'little-wall-2', 431 | x:-200+25, 432 | y:-150+40 433 | }, 434 | 'ramp-invis-1': { 435 | qv:1, 436 | 437 | clss:'cave-water-ramp', 438 | width: 250, 439 | height: 150, 440 | walk: true, 441 | cast_shadow:false, 442 | no_shadow:true, 443 | isnew:true, 444 | 445 | x:-250-250+75, y:0, z:0, 446 | transform:'rotateZ(-90deg) rotateY(-45deg)', 447 | vertices: function (width, height) {} 448 | }, 449 | 'cave-water-2-h340': { 450 | clss:'cave-water-1-h340', 451 | width: 340, 452 | height: 340, 453 | walk: true, 454 | cast_shadow:false, 455 | isnew:true, 456 | 457 | use: 'water', 458 | useval:'dirty', 459 | 460 | img:'3d/wall-dungeon2_lossy.jpg', 461 | 462 | x:-250, y:0, z:0, 463 | transform:' rotateX(90deg) rotateZ(-90deg)', 464 | 465 | vertices: function (width, height) {} 466 | }, 467 | 'cave-wall-1': { 468 | clss:'cave-wall-1', 469 | width: 340, 470 | height: 300, 471 | walk: false, 472 | cast_shadow: true, 473 | isnew:true, 474 | 475 | img:'3d/wall-dungeon2_lossy.jpg', 476 | 477 | x:-250, 478 | y:0,//-300 + _y_zero, // -height + _y_zero 479 | z:0,//-250, 480 | 481 | transform:'', 482 | vertices: function (width, height) {} 483 | }, 484 | 'cave-wall-2': { 485 | qv:256, 486 | clss:'cave-wall-1', 487 | width: 340, 488 | height: 340, 489 | walk: false, 490 | cast_shadow: true, 491 | isnew:true, 492 | img:'3d/wall-dungeon2_lossy.jpg', 493 | 494 | x:-250, 495 | y:0,//-300 + _y_zero, // -height + _y_zero 496 | z:0,//-250, 497 | 498 | transform:'rotateY(-90deg)', 499 | vertices: function (width, height) {} 500 | }, 501 | 502 | 'cave-wall-4': { 503 | extends:'cave-wall-2', 504 | qv:32, 505 | transform:'rotateY(90deg)', 506 | }, 507 | 508 | 'cave-wall-3-w340': { 509 | clss:'cave-wall-1-w340', 510 | width: 350, 511 | height: 180, 512 | walk: false, 513 | cast_shadow: true, 514 | isnew:true, 515 | 516 | img:'3d/level-2/cave-wall-grate-1.png', 517 | alpha:true, 518 | 519 | x:-200+25, 520 | y:0,//-300 + _y_zero, // -height + _y_zero 521 | z:0,//-250, 522 | 523 | transform:'rotateY(180deg)', 524 | vertices: function (width, height) {} 525 | }, 526 | 'ramp-wall-1': { 527 | qv:256, 528 | 529 | clss:'cave-ramp-wall-1', 530 | width: 433, 531 | height: 425, 532 | walk: false, 533 | cast_shadow:false, 534 | isnew:true, 535 | 536 | img:'3d/wall-dungeon2_lossy.jpg', 537 | 538 | x:-250, y:125, z:0, 539 | transform:'rotateZ(0deg)', 540 | vertices: function (width, height) {} 541 | }, 542 | 'ramp-wall-4': { 543 | qv:256, 544 | 545 | clss:'cave-ramp-wall-1', 546 | width: 433, 547 | height: 425, 548 | walk: false, 549 | cast_shadow:false, 550 | isnew:true, 551 | 552 | img:'3d/wall-dungeon2_lossy.jpg', 553 | 554 | x:-250, y:125, z:0, 555 | transform:'rotateY(180deg)', 556 | vertices: function (width, height) {} 557 | } 558 | // ----- 559 | }; 560 | 561 | 562 | var LEVEL = { 563 | TITLE:'01-PRISON', 564 | 565 | SETTINGS: { 566 | FRUSTRUM_SKIP : 3 567 | }, 568 | PRELOAD:[ 569 | '3d/caret-1.png', 570 | '3d/level-2/wall-moss.png' 571 | ], 572 | MOVE : { 573 | rot:{x:-12.5,y:257.1,z:0}, 574 | move:{x:-217,y:0,z:-207} 575 | }, 576 | INIT: function ( lvl ) { 577 | }, 578 | 579 | DESTROY: function() { 580 | // remove all elements 581 | var move = document.getElementById('move'); 582 | move.innerHTML = ''; 583 | }, 584 | 585 | ACTIVE_MAP : [], 586 | LIT : [], 587 | WALLS:[], 588 | MAP: 589 | { 590 | MAIN: 'floor-1', 591 | NODES : { 592 | 593 | 'floor-1' : { type:'dungeon-floor-1', clss:'debug', 594 | connected:[ 595 | { id:'ramp-invis-1', source:2, target:3 }, 596 | { id:'stairs-grate', source:2, target:2 }, 597 | { id:'wall-1', source:0, target:2 }, 598 | { id:'ramp-1', source:1, target:0 } 599 | ]}, 600 | //'floor-2' : { clss:'debug', type:'dungeon-floor-1', connected:[ 601 | // { id:'ramp-1', source:1, target:0 } 602 | //]}, 603 | 604 | 'ramp-invis-1': {type:'ramp-invis-1', ramp:1, ramp_start:-150, angle:155}, 605 | 606 | 'ramp-1': { type:'ramp-water-1', clss:'dirt', ramp:1, ramp_start:0, angle: ((45/90) * 500) >> 0, hide_frustrum: 1, connected:[ 607 | { id:'floor-room-path-right-2', source:2, target:0 }, 608 | { id:'wall-room-left-2', source:1, target:2 }, 609 | { id:'wall-room-left-8', source:3, target:2 } 610 | ]}, 611 | 612 | 'floor-room-path-right-2': { type:'cave-water-2-h340', clss:'dirt', hide_frustrum: 1, hide_dist_max:2200, beacon:['2'], connected:[ 613 | { id:'wall-room-left-3', source:1, target:2 }, 614 | { id:'floor-room-path-right-3', source:3, target:1 }, 615 | { id:'ramp-3', source:2, target:0 }, 616 | { id:'ramp-2', source:3, target:0 } 617 | ]}, 618 | 'floor-room-path-right-3': { type:'cave-water-2-h340', clss:'dirt', hide_frustrum: 1, hide_dist_max:2200, beacon:['2'], connected:[ 619 | {id:'wall-room-coffin-1', source:2, target:2}, 620 | {id:'wall-room-coffin-2', source:0, target:2}, 621 | {id:'door-room-right-1', source:3, target:2} 622 | ]}, 623 | 624 | 'ramp-3': { type:'ramp-water-1', clss:'dirt', ramp:1, ramp_start:((45/90) * 500) >> 0, angle: ((45/90) * 500) >> 0, hide_frustrum: 1, beacon:['2'], connected:[ 625 | { id:'wall-room-left-4', source:2, target:2 }, 626 | { id:'wall-room-left-5', source:1, target:2 }, 627 | { id:'wall-room-left-7', source:3, target:2 } 628 | ]}, 629 | 'wall-room-left-4': {type: 'cave-door-2-w340', hide_frustrum: 1, beacon:['2'] }, 630 | 'wall-room-left-3': {type: 'cave-wall-1', hide_frustrum: 1, beacon:['2'] }, 631 | 'wall-room-left-7': {type: 'ramp-wall-4', hide_frustrum: 1, beacon:['2'] }, 632 | 'wall-room-left-8': {type: 'ramp-wall-4', hide_frustrum: 1, beacon:['2'] }, 633 | 634 | 'wall-room-coffin-1': {type: 'cave-wall-2', decal:'3d/level-2/wall-moss.png', hide_frustrum: 1, beacon:['2'] }, 635 | 'wall-room-coffin-2': {type: 'cave-wall-4', hide_frustrum: 1, beacon:['2'] }, 636 | 637 | 638 | 'door-room-right-1': {type: 'cave-door-3-w340', hide_frustrum: 1, beacon:['2'] }, 639 | 640 | 'wall-1' : { type:'dungeon-wall-1', clss:'debug', connected:[ 641 | { id:'little-wall-1', source:1, target:3} 642 | ]}, 643 | 644 | 'little-wall-1' : {type:'little-wall-2', hide_frustrum: 1}, 645 | 'little-wall-2' : {type:'little-wall-3', hide_frustrum: 1}, 646 | 647 | 'stairs-grate' : {type:'cave-wall-3-w340', hide_frustrum:1, connected:[ 648 | { id:'little-wall-2', source:3, target:1}, 649 | { id:'top-floor-1', source:0, target:0}, 650 | ]}, 651 | 652 | 653 | 'top-floor-1': {type: 'floor-350-180', hide_frustrum: 1, beacon:['2'] }, 654 | 655 | 'wall-room-left-2': {type: 'ramp-wall-1', hide_frustrum: 1, beacon:['2'] }, 656 | 'wall-room-left-5': {type: 'ramp-wall-1', hide_frustrum: 1, beacon:['2'] }, 657 | 658 | 'stairs-1' : { 659 | object:1, 660 | type:'obj-stairs-1', 661 | //transform:'translate3d(-247px, 246px, 75px)', 662 | transform:'rotateY(90deg) translate3d(-500px, 243px, -175px)' 663 | //ramp:1, ramp_start:-150, angle:155 664 | }, 665 | 'shape-chair' : { 666 | object:1, 667 | type:'obj-shape-chair', 668 | // transform:'translate3d(0px, 150px, 250px)' 669 | transform:'translate3d(5px, 230px, 300px)' 670 | //transform:'translate3d(-270px, 100px, 220px) rotateY(66deg)' 671 | } 672 | }, 673 | 674 | 675 | LIGHTS: { 676 | 'ambience' : {color:{r:255,g:255,b:255}, intensity: 0.5, active: 1} 677 | //'light-1' : {x:-310, y:70, z:250, intensity:1, color:{r:255,g:20,b:20}, shadow:1, max_distance:980, drawIcon:1, active:1}, 678 | //'light-3' : { x:640, y: 40, z:280 + 250, intensity:0.9, color:{r:255,g:20,b:20}, shadow:1, max_distance:542, drawIcon:1, active:1}, 679 | // 'light-2' : {x:-380, y: 80, z:15 + 250, intensity:1, color:{r:80,g:80,b:255}, shadow:1, max_distance:980, drawIcon:1, active:1} 680 | //'light-2' : {x:-315, y: 70, z:230, intensity:2, color:{r:20,g:20,b:255}, shadow:1, max_distance:990, drawIcon:1, active:1} 681 | }, 682 | 683 | SOUNDS : { } 684 | // --- 685 | }, 686 | 687 | 688 | TXT: { 689 | ACTIVE : { 690 | 'active' : null, 691 | 'index': -1, 'sub_index': -1, 692 | 'el' : null 693 | }, 694 | 695 | 'warn' : ['Cannot reach object.'] 696 | // -- 697 | } 698 | }; 699 | 700 | 701 | GAME.UTILS._filterGameObjects (GAME_OBJ); 702 | GAME.Fire ('ReqLoadLevel', LEVEL, GAME_OBJ); 703 | // --- 704 | 705 | })( window, document, GAME ); -------------------------------------------------------------------------------- /3d/js/level-06.js: -------------------------------------------------------------------------------- 1 | (function ( w, d, GAME ) { 2 | 'use strict'; 3 | 4 | 5 | var _y_zero = 250; 6 | var GAME_OBJ = { 7 | 8 | /////////////////////////////////////////////////////////////////// 9 | // OBJECTS (TOOLS, ITEMS, DECORATIONS ETC) 10 | /////////////////////////////////////////////////////////////////// 11 | // invisible plane 12 | 'obj-invis-1' : { 13 | id:'obj-invis-1', 14 | type: 'object', 15 | clss:'invis', 16 | walk: true, 17 | cast_shadow: false, 18 | geom:[] 19 | }, 20 | 'obj-decal-normals' : { 21 | id:'obj-decal-normals', 22 | type: 'object', 23 | clss:'decal', 24 | width:80, height:240, 25 | walk: true, 26 | cast_shadow: false, 27 | geom:[] 28 | }, 29 | 'obj-decal-web-1' : { 30 | id:'obj-decal-web-1', 31 | type: 'object', 32 | clss:'decal-web', 33 | walk: true, 34 | cast_shadow: false, 35 | geom:[] 36 | }, 37 | 38 | /////////////////////////////////////////////////////////////////// 39 | // GEOMETRY (WALLS, FLOORS, LANDSCAPE ETC) 40 | /////////////////////////////////////////////////////////////////// 41 | 42 | // floors 43 | 'dungeon-floor-1': { 44 | clss:'cave-floor-1', 45 | img:'3d/level-06/dirt-ground-1.jpg', 46 | width: 500, 47 | height: 500, 48 | walk: true, 49 | cast_shadow:false, 50 | isnew:true, 51 | tag:'img', 52 | 53 | x:-250, y:0, z:0, 54 | transform:'rotateX(90deg)', 55 | 56 | vertices: function (width, height) {} 57 | }, 58 | 'dungeon-floor-1-h150': { 59 | extends:'dungeon-floor-1', 60 | clss:'dungeon-floor-1 h300', 61 | height: 300, 62 | z:-100, 63 | vertices: function (width, height) {} 64 | }, 65 | 'dungeon-floor-1-w180': { 66 | extends:'dungeon-floor-1', 67 | clss:'dungeon-floor-1 w180', 68 | width: 180, 69 | vertices: function (width, height) {} 70 | }, 71 | 'dungeon-floor-1-h175': { 72 | extends:'dungeon-floor-1', 73 | clss:'dungeon-floor-1 h175', 74 | height: 175, 75 | cast_shadow:true, 76 | vertices: function (width, height) {} 77 | }, 78 | 'dungeon-floor-1-h175-w180': { 79 | extends:'dungeon-floor-1', 80 | clss:'dungeon-floor-1 h175 w180', 81 | height: 175, 82 | cast_shadow:true, 83 | width: 180, 84 | vertices: function (width, height) {} 85 | }, 86 | 87 | 88 | 89 | 'dungeon-wall-1': { 90 | clss:'dungeon-wall-1', 91 | img:'3d/wall-dungeon2_lossy.jpg', 92 | width: 500, 93 | height: 400, 94 | walk: false, 95 | cast_shadow: true, 96 | isnew:true, 97 | tag:'img', 98 | 99 | x:-250, 100 | y:0, 101 | z:0, 102 | 103 | transform:'rotateY(-90deg)', 104 | vertices: function (width, height) {} 105 | }, 106 | 'dungeon-wall-3': { 107 | extends: 'dungeon-wall-1', 108 | transform:'rotateY(90deg)', 109 | vertices: function (width, height) {} 110 | }, 111 | 'dungeon-wall-2': { 112 | extends: 'dungeon-wall-1', 113 | // clss:'dungeon-wall-1 h260', 114 | // height: 260, 115 | transform:' rotateY(180deg) rotateX(-18deg)', 116 | vertices: function (width, height) {} 117 | }, 118 | 'dungeon-wall-2-norm': { 119 | extends: 'dungeon-wall-1', 120 | // clss:'dungeon-wall-1 h260', 121 | // height: 260, 122 | 123 | z:-100, 124 | transform:' rotateY(180deg)', 125 | vertices: function (width, height) {} 126 | }, 127 | 'dungeon-wall-4': { 128 | extends: 'dungeon-wall-1', 129 | transform:' rotateY(0deg) rotateX(-16deg)', 130 | vertices: function (width, height) {} 131 | }, 132 | // ----- 133 | 134 | 135 | // MAGICSHAPES #### 136 | 'obj-lake-shore-1' : { 137 | id:'obj-lake-shore-1', 138 | img:'3d/dungeon-floor-3_lossy.jpg', 139 | type: 'object', 140 | clss: 'book', 141 | walk: false, 142 | cast_shadow:false, 143 | isnew:true, 144 | 145 | geom:[ 146 | 147 | { 148 | clss:'face', 149 | shape:'face', 150 | img:'3d/level-06/dirt-ground-1.jpg', 151 | shape_args:[ new Vector(0, 250, 0), new Vector(0, 250, -160), new Vector(-180, 250, 0) ] 152 | }, 153 | 154 | { 155 | clss:'face', 156 | shape:'face', 157 | img:'3d/level-06/dirt-ground-1.jpg', 158 | shape_args:[ new Vector(0, 250, -160), new Vector(0, 250, -500), new Vector(-500, 680, -500) ] 159 | }, 160 | 161 | { 162 | clss:'face', 163 | shape:'face', 164 | img:'3d/level-06/dirt-ground-1.jpg', 165 | shape_args:[ new Vector(-180, 250, 0), new Vector(-500, 680, -500), new Vector(-500, 250, 0) ] 166 | }, 167 | 168 | { 169 | clss:'face', 170 | shape:'face', 171 | img:'3d/level-06/dirt-ground-1.jpg', 172 | shape_args:[ new Vector(-180, 250, 0), new Vector(-500, 680, -500), new Vector(0, 250, -160) ] 173 | } 174 | ] 175 | }, 176 | 177 | 178 | 179 | 'obj-lake-wall-1' : { 180 | id:'obj-lake-wall-1', 181 | img:'3d/dungeon-floor-3_lossy.jpg', 182 | type: 'object', 183 | clss: 'book', 184 | walk: false, 185 | cast_shadow:false, 186 | isnew:true, 187 | 188 | geom:[ 189 | 190 | { 191 | clss:'face', 192 | shape:'face', 193 | img:'3d/level-06/dirt-ground-1.jpg', 194 | shape_args:[ new Vector(-750, 250, 300), new Vector(-920, 250, 300), new Vector(-750, 250, 500) ] 195 | }, 196 | 197 | { 198 | clss:'face', 199 | shape:'face', 200 | img:'3d/wall-dungeon2_lossy.jpg', 201 | shape_args:[ new Vector(-750, -130.4, 376.3), new Vector(-750, 250, 500), new Vector(-920, 250, 300) ] 202 | }, 203 | 204 | { 205 | clss:'face', 206 | shape:'face', 207 | img:'3d/wall-dungeon2_lossy.jpg', 208 | shape_args:[ new Vector(-920, 250, 300), new Vector(-1250, 250, 300), new Vector(-1250, -150, 300) ] 209 | }, 210 | 211 | { 212 | clss:'face', 213 | shape:'face', 214 | img:'3d/wall-dungeon2_lossy.jpg', 215 | shape_args:[ new Vector(-920, 250, 300), new Vector(-1250, -150, 300), new Vector(-750, -130.4, 376.3) ] 216 | } 217 | 218 | ] 219 | } 220 | 221 | 222 | // ------ 223 | }; 224 | 225 | 226 | var LEVEL = { 227 | TITLE:'06-CAVE-LAIR', 228 | 229 | SETTINGS: { 230 | FRUSTRUM_SKIP : 3 231 | }, 232 | PRELOAD:[ 233 | '3d/caret-1.png', 234 | '3d/wall-dungeon_lossy.jpg' 235 | ], 236 | MOVE : { 237 | rot:{x:-13,y:-90,z:0}, 238 | move:{x:-610,y:0,z:-240} 239 | }, 240 | INIT: function ( lvl ) { 241 | if (!GAME.State.flags.lvl6) GAME.State.flags.lvl6 = {}; 242 | 243 | setTimeout(function(){ 244 | GAME.ACTIONS.DialogCover (0); 245 | 246 | if (false) // !GAME.State.flags.lvl6.intro) 247 | { 248 | GAME.State.flags.lvl5.intro = true; 249 | 250 | setTimeout(function(){ 251 | GAME.ACTIONS.SetText ( 'intro', 0); 252 | },300); 253 | } 254 | else 255 | { 256 | setTimeout(function(){ 257 | GAME.ACTIONS.DialogClose (); 258 | },300); 259 | } 260 | 261 | }, 500); 262 | // --- 263 | }, 264 | 265 | DESTROY: function() { 266 | // remove all elements 267 | GAME.OnRender = null; 268 | 269 | var move = document.getElementById('move'); 270 | move.innerHTML = ''; 271 | }, 272 | 273 | ACTIVE_MAP : [], 274 | LIT : [], 275 | WALLS:[], 276 | MAP: 277 | { 278 | MAIN: 'floor-1', 279 | NODES : { 280 | 'shape-1' : { 281 | object:1, 282 | type:'obj-lake-shore-1', 283 | transform:'translate3d(-1750px, 0px, 0px) rotateY(-90deg)', 284 | angle:180 285 | }, 286 | 287 | 288 | 'shape-2' : { 289 | object:1, 290 | type:'obj-lake-shore-1', 291 | transform:'translate3d(-750px, 0px, 0px)', 292 | angle:180 293 | }, 294 | 295 | 296 | 'shape-wall-shore-1' : { 297 | object:1, 298 | type:'obj-lake-wall-1', 299 | transform:'translate3d(0px, 0px, 0px)', 300 | angle:180 301 | }, 302 | 303 | 304 | 'floor-1' : { type:'dungeon-floor-1', 305 | connected:[ 306 | // { id:'ramp-1', source:3, target:2 }, 307 | { id:'wall-left-1', source:2, target:2 }, 308 | { id:'wall-right-1', source:0, target:2 }, 309 | 310 | // { id:'wall-right-1', source:0, target:2 }, 311 | { id:'floor-0', source:1, target:3 }, 312 | { id:'floor-2', source:3, target:1 } 313 | ]}, 314 | 315 | 'floor-0' : { type:'dungeon-floor-1', connected:[ 316 | { id:'wall-left-3', source:2, target:2 }, 317 | { id:'wall-right-3', source:0, target:2 } 318 | // { id:'door-0', source:1, target:2 } 319 | ]}, 320 | 'floor-2' : { type:'dungeon-floor-1', connected:[ 321 | { id:'floor-3', source:3, target:1 }, 322 | { id:'floor-4', source:0, target:2 }, 323 | 324 | { id:'wall-left-2', source:2, target:2 } 325 | ]}, 326 | 327 | 'floor-3' : { type:'dungeon-floor-1-h150', connected:[ 328 | { id:'floor-6', source:3, target:1 } 329 | ]}, 330 | 'floor-4' : { type:'dungeon-floor-1', connected:[ 331 | { id:'floor-5', source:0, target:2 }, 332 | { id:'wall-right-4', source:1, target:2 } 333 | ]}, 334 | 335 | 'floor-5' : { type:'dungeon-floor-1', connected:[ 336 | 337 | ]}, 338 | 339 | 'floor-6' : { type:'dungeon-floor-1-h150', connected:[ 340 | { id:'wall-left-5', source:2, target:2 } 341 | ]}, 342 | 343 | 344 | 'wall-left-1' : { type:'dungeon-wall-2', connected:[]}, 345 | 'wall-left-2' : { type:'dungeon-wall-2', connected:[]}, 346 | 'wall-left-3' : { type:'dungeon-wall-2', connected:[]}, 347 | 'wall-left-4' : { type:'dungeon-wall-2', connected:[]}, 348 | 'wall-left-5' : { type:'dungeon-wall-2-norm', connected:[]}, 349 | 350 | 'wall-right-1' : { type:'dungeon-wall-4', connected:[]}, 351 | 'wall-right-3' : { type:'dungeon-wall-4', connected:[]}, 352 | 353 | 'wall-right-4' : { type:'dungeon-wall-1', connected:[]}, 354 | 355 | 'lvl-2-door' : { 356 | object:1, 357 | width:100, 358 | height:240, 359 | type:'obj-invis-1', 360 | interact: function( e ) { 361 | if (!GAME.State.control) return ; 362 | 363 | var dist = GAME.UTILS.Distance ( this ); 364 | if (dist > 600) { 365 | GAME.ACTIONS.SetActiveText ( 'warn', 0, false, 'old' ); 366 | return ; 367 | } 368 | 369 | var dist_min = 180, dist_max = 700; 370 | 371 | if (dist < dist_min) dist = 1; 372 | else if (dist > dist_max) dist = 0; 373 | else { 374 | dist = 1 - ((dist - dist_min) / (dist_max - dist_min)); 375 | dist = dist.toFixed(2) / 1; 376 | } 377 | 378 | // GAME.Sound.Play ('sound-door-creak-1', dist, true); 379 | GAME.UTILS.LoadLevel2('02', 'cave'); 380 | }, 381 | transform:'translate3d(648px, 0px, 75px) rotateY(-90deg)' 382 | } 383 | 384 | // --- 385 | }, 386 | 387 | LIGHTS: { 388 | 'ambience' : {color:{r:200,g:200,b:200}, intensity: 0.5, active: 1} 389 | 390 | // 'light-hang-focus' : {x:-540, y:-265, z:-440, intensity:2, color:{r:160,g:40,b:30}, shadow:1, max_distance:460, drawIcon:0, active:1, spot:1, target:new Vector(-525, -0, -520), radius:400}, // active 1 391 | // 'light-barrel' : {x:-440, y:-10, z:-80, intensity:1.25, color:{r:80,g:80,b:240}, shadow:1, max_distance:500, drawIcon:0, active:1, spot:1, target:new Vector(-404, 0, -50), radius:910 }, 392 | // 'light-torch' : {x:-480, y:32, z:80, intensity:1, color:{r:185,g:90,b:40}, shadow:1, max_distance:600, drawIcon:1, active:1}, 393 | 394 | }, 395 | 396 | TRIGGERS: {}, 397 | 398 | SOUNDS : { 399 | } 400 | // --- 401 | }, 402 | 403 | 404 | TXT: { 405 | ACTIVE : { 406 | 'active' : null, 407 | 'index': -1, 'sub_index': -1, 408 | 'el' : null 409 | }, 410 | 411 | 'warn' : ['Cannot reach object.'], 412 | 'warn-2' : ['Cannot reach.'], 413 | 414 | 'intro' : [{ 415 | title: 'Abandoned Cells', 416 | body: ['You reach a seemingly out of place tunnel.', 'Among the empty cells stands an imposing reinforced gate.', 417 | 'Perhaps its just your imagination, but you think you can hear faint sighs ', 418 | 'coming from the other side...'] 419 | }] 420 | // -- 421 | } 422 | }; 423 | 424 | 425 | GAME.UTILS._filterGameObjects (GAME_OBJ); 426 | GAME.Fire ('ReqLoadLevel', LEVEL, GAME_OBJ); 427 | // --- 428 | 429 | })( window, document, GAME ); -------------------------------------------------------------------------------- /3d/lands.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/lands.jpg -------------------------------------------------------------------------------- /3d/meat-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/meat-3.jpg -------------------------------------------------------------------------------- /3d/new-cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/new-cover.jpg -------------------------------------------------------------------------------- /3d/out_lighter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/out_lighter.gif -------------------------------------------------------------------------------- /3d/out_lighter_single.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/out_lighter_single.gif -------------------------------------------------------------------------------- /3d/rusty-knife-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/rusty-knife-icon.png -------------------------------------------------------------------------------- /3d/rusty-wood.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/rusty-wood.jpg -------------------------------------------------------------------------------- /3d/sound/breathing-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/breathing-1.mp3 -------------------------------------------------------------------------------- /3d/sound/candle-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/candle-1.mp3 -------------------------------------------------------------------------------- /3d/sound/candle-1.mp3~.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/candle-1.mp3~.mp3 -------------------------------------------------------------------------------- /3d/sound/candle-2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/candle-2.mp3 -------------------------------------------------------------------------------- /3d/sound/candle-2.mp3~.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/candle-2.mp3~.mp3 -------------------------------------------------------------------------------- /3d/sound/church-organ-main.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/church-organ-main.mp3 -------------------------------------------------------------------------------- /3d/sound/crying-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/crying-1.mp3 -------------------------------------------------------------------------------- /3d/sound/door-creak-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/door-creak-1.mp3 -------------------------------------------------------------------------------- /3d/sound/door-lock.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/door-lock.mp3 -------------------------------------------------------------------------------- /3d/sound/food-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/food-1.mp3 -------------------------------------------------------------------------------- /3d/sound/food-3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/food-3.mp3 -------------------------------------------------------------------------------- /3d/sound/footsteps-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/footsteps-1.mp3 -------------------------------------------------------------------------------- /3d/sound/footsteps-2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/footsteps-2.mp3 -------------------------------------------------------------------------------- /3d/sound/guard-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/guard-1.mp3 -------------------------------------------------------------------------------- /3d/sound/guard-2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/guard-2.mp3 -------------------------------------------------------------------------------- /3d/sound/item-pickup-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/item-pickup-1.mp3 -------------------------------------------------------------------------------- /3d/sound/metal-roll-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/metal-roll-1.mp3 -------------------------------------------------------------------------------- /3d/sound/puzzle-solve-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/puzzle-solve-1.mp3 -------------------------------------------------------------------------------- /3d/sound/rust-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/rust-1.mp3 -------------------------------------------------------------------------------- /3d/sound/water-dripping-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-dripping-1.mp3 -------------------------------------------------------------------------------- /3d/sound/water-running-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-running-1.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-1.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-11.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-11.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-12.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-12.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-13.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-13.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-14.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-14.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-2.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-3.mp3 -------------------------------------------------------------------------------- /3d/sound/water-step-4.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/sound/water-step-4.mp3 -------------------------------------------------------------------------------- /3d/spider-sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/spider-sprite.png -------------------------------------------------------------------------------- /3d/trapdoor-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/trapdoor-2.png -------------------------------------------------------------------------------- /3d/wall-dungeon-2-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/wall-dungeon-2-window.png -------------------------------------------------------------------------------- /3d/wall-dungeon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/wall-dungeon.jpg -------------------------------------------------------------------------------- /3d/wall-dungeon2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/wall-dungeon2.jpg -------------------------------------------------------------------------------- /3d/wall-dungeon2_lossy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/wall-dungeon2_lossy.jpg -------------------------------------------------------------------------------- /3d/wall-dungeon_lossy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/wall-dungeon_lossy.jpg -------------------------------------------------------------------------------- /3d/wood-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/wood-1.jpg -------------------------------------------------------------------------------- /3d/wood-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/3d/wood-2.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Pantelis Kalogiros 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # css3d-game 2 | 3 | First person adventure game rendered in CSS/HTML - play online here -> https://pantel.is/projects/css3d/ 4 | 5 | 6 | This is a 3D game written in Vanilla Javascript, and rendered entirely in HTML/CSS. You can use the developer tools for example and inspect the geometry 7 | 8 | ![css geometry](https://pantelis.s3-us-west-2.amazonaws.com/0/css3d/readme/css-geom.png) 9 | ![css geometry 2](https://pantelis.s3-us-west-2.amazonaws.com/0/css3d/readme/moon.png) 10 | 11 | 12 | It supports lighting, shadows, interactions, and complex geometry that can consist of triangles. 13 | 14 | ![triangle 1](https://pantelis.s3-us-west-2.amazonaws.com/0/css3d/readme/triangles/triangle1.png) 15 | ![triangle 2](https://pantelis.s3-us-west-2.amazonaws.com/0/css3d/readme/triangles/triangle2.png) 16 | ![triangle 3](https://pantelis.s3-us-west-2.amazonaws.com/0/css3d/readme/triangles/triangle3.png) 17 | ![triangle 4](https://pantelis.s3-us-west-2.amazonaws.com/0/css3d/readme/triangles/css-render.png) 18 | 19 | --- 20 | 21 | (code currently is a but messy, but I am refactoring it!) 22 | 23 | 24 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | CSS 3D ENGINE 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | 47 |
48 |
49 |
50 |
51 | 52 | 53 |
54 |
55 |

CSS 3D Adventure

56 |

A game rendered entirely in CSS, relying as much as possible on traditional html/css features instead of modern APIs.

57 | 58 | 59 | 60 |
61 | Start 62 | About 63 |
64 | 65 |
66 | 67 | 68 |
69 | 70 |
71 |
72 | 73 |
74 | 75 |
76 |
Examine
77 | 78 | 79 | 80 | Location: ??? 81 | Status: Malnourished, Injured, Blind 82 | Attire: Prisoner (poor) 83 | 84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | 100 | CHAR 101 | 102 |
103 | 104 | Brightness 105 | Audio: On 106 |
107 |
108 | 109 |
Made by Pantelis Kalogiros -> src: Github (v0.5)
110 | 111 | 112 |
113 | 114 | 115 | 116 |
117 | 118 |
PAUSED
119 |
120 |
121 |
Part 1
122 |
Part 2
123 |
Part 3
124 |
125 | 126 |
Adjust your screen brightness, until text on the left is not visible, and the text in the center is barely visible.
127 |
128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | -------------------------------------------------------------------------------- /three/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/three/.DS_Store -------------------------------------------------------------------------------- /three/leech/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/three/leech/.DS_Store -------------------------------------------------------------------------------- /three/leech/leech/scene.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/three/leech/leech/scene.bin -------------------------------------------------------------------------------- /three/leech/leech/textures/UVMAP_PIAVKA1_Default_baseColor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/three/leech/leech/textures/UVMAP_PIAVKA1_Default_baseColor.png -------------------------------------------------------------------------------- /three/leech/leech/textures/UVMAP_PIAVKA1_Default_metallicRoughness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/three/leech/leech/textures/UVMAP_PIAVKA1_Default_metallicRoughness.png -------------------------------------------------------------------------------- /three/leech/leech/textures/UVMAP_PIAVKA1_Default_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkalogiros/css3d-game/dc3ff4ac8121297617df1ba92e7bf9ebd541e941/three/leech/leech/textures/UVMAP_PIAVKA1_Default_normal.png -------------------------------------------------------------------------------- /three/three-gltf-loader.min.js: -------------------------------------------------------------------------------- 1 | THREE.GLTFLoader=function(){function e(e){this.manager=void 0!==e?e:THREE.DefaultLoadingManager,this.dracoLoader=null}e.prototype={constructor:e,crossOrigin:"Anonymous",load:function(e,t,a,r){var s=this,i=void 0!==this.path?this.path:THREE.LoaderUtils.extractUrlBase(e),n=new THREE.FileLoader(s.manager);n.setResponseType("arraybuffer"),n.load(e,function(e){try{s.parse(e,i,t,r)}catch(e){if(void 0===r)throw e;r(e)}},a,r)},setCrossOrigin:function(e){return this.crossOrigin=e,this},setPath:function(e){return this.path=e,this},setDRACOLoader:function(e){return this.dracoLoader=e,this},parse:function(e,o,l,p){var u,c={};if("string"==typeof e)u=e;else if(THREE.LoaderUtils.decodeText(new Uint8Array(e,0,4))===r){try{c[t.KHR_BINARY_GLTF]=new function(e){this.name=t.KHR_BINARY_GLTF,this.content=null,this.body=null;var a=new DataView(e,0,s);if(this.header={magic:THREE.LoaderUtils.decodeText(new Uint8Array(e.slice(0,4))),version:a.getUint32(4,!0),length:a.getUint32(8,!0)},this.header.magic!==r)throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");if(this.header.version<2)throw new Error("THREE.GLTFLoader: Legacy binary file detected. Use LegacyGLTFLoader instead.");for(var n=new DataView(e,s),o=0;o=2.0 are supported. Use LegacyGLTFLoader instead.")):(d.extensionsUsed&&(d.extensionsUsed.indexOf(t.KHR_LIGHTS)>=0&&(c[t.KHR_LIGHTS]=new function(e){this.name=t.KHR_LIGHTS,this.lights={};var a=(e.extensions&&e.extensions[t.KHR_LIGHTS]||{}).lights||{};for(var r in a){var s,i=a[r],n=(new THREE.Color).fromArray(i.color);switch(i.type){case"directional":(s=new THREE.DirectionalLight(n)).position.set(0,0,1);break;case"point":s=new THREE.PointLight(n);break;case"spot":(s=new THREE.SpotLight(n)).position.set(0,0,1);break;case"ambient":s=new THREE.AmbientLight(n)}s&&(void 0!==i.constantAttenuation&&(s.intensity=i.constantAttenuation),void 0!==i.linearAttenuation&&(s.distance=1/i.linearAttenuation),void 0!==i.quadraticAttenuation&&(s.decay=i.quadraticAttenuation),void 0!==i.fallOffAngle&&(s.angle=i.fallOffAngle),void 0!==i.fallOffExponent&&console.warn("THREE.GLTFLoader:: light.fallOffExponent not currently supported."),s.name=i.name||"light_"+r,this.lights[r]=s)}}(d)),d.extensionsUsed.indexOf(t.KHR_MATERIALS_UNLIT)>=0&&(c[t.KHR_MATERIALS_UNLIT]=new a(d)),d.extensionsUsed.indexOf(t.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS)>=0&&(c[t.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS]=new function(){return{name:t.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS,specularGlossinessParams:["color","map","lightMap","lightMapIntensity","aoMap","aoMapIntensity","emissive","emissiveIntensity","emissiveMap","bumpMap","bumpScale","normalMap","displacementMap","displacementScale","displacementBias","specularMap","specular","glossinessMap","glossiness","alphaMap","envMap","envMapIntensity","refractionRatio"],getMaterialType:function(){return THREE.ShaderMaterial},extendParams:function(e,t,a){var r=t.extensions[this.name],s=THREE.ShaderLib.standard,i=THREE.UniformsUtils.clone(s.uniforms),n=["#ifdef USE_SPECULARMAP","\tuniform sampler2D specularMap;","#endif"].join("\n"),o=["#ifdef USE_GLOSSINESSMAP","\tuniform sampler2D glossinessMap;","#endif"].join("\n"),l=["vec3 specularFactor = specular;","#ifdef USE_SPECULARMAP","\tvec4 texelSpecular = texture2D( specularMap, vUv );","\ttexelSpecular = sRGBToLinear( texelSpecular );","\t// reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture","\tspecularFactor *= texelSpecular.rgb;","#endif"].join("\n"),p=["float glossinessFactor = glossiness;","#ifdef USE_GLOSSINESSMAP","\tvec4 texelGlossiness = texture2D( glossinessMap, vUv );","\t// reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture","\tglossinessFactor *= texelGlossiness.a;","#endif"].join("\n"),u=["PhysicalMaterial material;","material.diffuseColor = diffuseColor.rgb;","material.specularRoughness = clamp( 1.0 - glossinessFactor, 0.04, 1.0 );","material.specularColor = specularFactor.rgb;"].join("\n"),c=s.fragmentShader.replace("#include ","").replace("uniform float roughness;","uniform vec3 specular;").replace("uniform float metalness;","uniform float glossiness;").replace("#include ",n).replace("#include ",o).replace("#include ",l).replace("#include ",p).replace("#include ",u);delete i.roughness,delete i.metalness,delete i.roughnessMap,delete i.metalnessMap,i.specular={value:(new THREE.Color).setHex(1118481)},i.glossiness={value:.5},i.specularMap={value:null},i.glossinessMap={value:null},e.vertexShader=s.vertexShader,e.fragmentShader=c,e.uniforms=i,e.defines={STANDARD:""},e.color=new THREE.Color(1,1,1),e.opacity=1;var d=[];if(Array.isArray(r.diffuseFactor)){var h=r.diffuseFactor;e.color.fromArray(h),e.opacity=h[3]}if(void 0!==r.diffuseTexture&&d.push(a.assignTexture(e,"map",r.diffuseTexture.index)),e.emissive=new THREE.Color(0,0,0),e.glossiness=void 0!==r.glossinessFactor?r.glossinessFactor:1,e.specular=new THREE.Color(1,1,1),Array.isArray(r.specularFactor)&&e.specular.fromArray(r.specularFactor),void 0!==r.specularGlossinessTexture){var E=r.specularGlossinessTexture.index;d.push(a.assignTexture(e,"glossinessMap",E)),d.push(a.assignTexture(e,"specularMap",E))}return Promise.all(d)},createMaterial:function(e){var t=new THREE.ShaderMaterial({defines:e.defines,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,uniforms:e.uniforms,fog:!0,lights:!0,opacity:e.opacity,transparent:e.transparent});return t.isGLTFSpecularGlossinessMaterial=!0,t.color=e.color,t.map=void 0===e.map?null:e.map,t.lightMap=null,t.lightMapIntensity=1,t.aoMap=void 0===e.aoMap?null:e.aoMap,t.aoMapIntensity=1,t.emissive=e.emissive,t.emissiveIntensity=1,t.emissiveMap=void 0===e.emissiveMap?null:e.emissiveMap,t.bumpMap=void 0===e.bumpMap?null:e.bumpMap,t.bumpScale=1,t.normalMap=void 0===e.normalMap?null:e.normalMap,e.normalScale&&(t.normalScale=e.normalScale),t.displacementMap=null,t.displacementScale=1,t.displacementBias=0,t.specularMap=void 0===e.specularMap?null:e.specularMap,t.specular=e.specular,t.glossinessMap=void 0===e.glossinessMap?null:e.glossinessMap,t.glossiness=e.glossiness,t.alphaMap=null,t.envMap=void 0===e.envMap?null:e.envMap,t.envMapIntensity=1,t.refractionRatio=.98,t.extensions.derivatives=!0,t},cloneMaterial:function(e){var t=e.clone();t.isGLTFSpecularGlossinessMaterial=!0;for(var a=this.specularGlossinessParams,r=0,s=a.length;r=0&&(c[t.KHR_DRACO_MESH_COMPRESSION]=new n(this.dracoLoader))),console.time("GLTFLoader"),new S(d,c,{path:o||this.path||"",crossOrigin:this.crossOrigin,manager:this.manager}).parse(function(e,t,a,r,s){console.timeEnd("GLTFLoader"),l({scene:e,scenes:t,cameras:a,animations:r,asset:s})},p))}};var t={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS:"KHR_lights",KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:"KHR_materials_pbrSpecularGlossiness",KHR_MATERIALS_UNLIT:"KHR_materials_unlit"};function a(e){this.name=t.KHR_MATERIALS_UNLIT}a.prototype.getMaterialType=function(e){return THREE.MeshBasicMaterial},a.prototype.extendParams=function(e,t,a){var r=[];e.color=new THREE.Color(1,1,1),e.opacity=1;var s=t.pbrMetallicRoughness;if(s){if(Array.isArray(s.baseColorFactor)){var i=s.baseColorFactor;e.color.fromArray(i),e.opacity=i[3]}void 0!==s.baseColorTexture&&r.push(a.assignTexture(e,"map",s.baseColorTexture.index))}return Promise.all(r)};var r="glTF",s=12,i={JSON:1313821514,BIN:5130562};function n(e){if(!e)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=t.KHR_DRACO_MESH_COMPRESSION,this.dracoLoader=e}function o(e,t,a,r){THREE.Interpolant.call(this,e,t,a,r)}n.prototype.decodePrimitive=function(e,t){var a=this.dracoLoader,r=e.extensions[this.name].bufferView,s=e.extensions[this.name].attributes,i={};for(var n in s)n in E&&(i[E[n]]=s[n]);return t.getDependency("bufferView",r).then(function(e){return new Promise(function(t){a.decodeDracoFile(e,t,i)})})},o.prototype=Object.create(THREE.Interpolant.prototype),o.prototype.constructor=o,o.prototype.interpolate_=function(e,t,a,r){for(var s=this.resultBuffer,i=this.sampleValues,n=this.valueSize,o=2*n,l=3*n,p=r-t,u=(a-t)/p,c=u*u,d=c*u,h=e*l,E=h-l,m=2*d-3*c+1,f=d-2*c+u,v=-2*d+3*c,T=d-c,R=0;R!==n;R++){var g=i[E+R+n],M=i[E+R+o]*p,S=i[h+R+n],H=i[h+R]*p;s[R]=m*g+f*M+v*S+T*H}return s};var l=(Number,THREE.Matrix3,THREE.Matrix4,THREE.Vector2,THREE.Vector3,THREE.Vector4,THREE.Texture,{5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array}),p={9728:THREE.NearestFilter,9729:THREE.LinearFilter,9984:THREE.NearestMipMapNearestFilter,9985:THREE.LinearMipMapNearestFilter,9986:THREE.NearestMipMapLinearFilter,9987:THREE.LinearMipMapLinearFilter},u={33071:THREE.ClampToEdgeWrapping,33648:THREE.MirroredRepeatWrapping,10497:THREE.RepeatWrapping},c={6406:THREE.AlphaFormat,6407:THREE.RGBFormat,6408:THREE.RGBAFormat,6409:THREE.LuminanceFormat,6410:THREE.LuminanceAlphaFormat},d={5121:THREE.UnsignedByteType,32819:THREE.UnsignedShort4444Type,32820:THREE.UnsignedShort5551Type,33635:THREE.UnsignedShort565Type},h=(THREE.BackSide,THREE.FrontSide,THREE.NeverDepth,THREE.LessDepth,THREE.EqualDepth,THREE.LessEqualDepth,THREE.GreaterEqualDepth,THREE.NotEqualDepth,THREE.GreaterEqualDepth,THREE.AlwaysDepth,THREE.AddEquation,THREE.SubtractEquation,THREE.ReverseSubtractEquation,THREE.ZeroFactor,THREE.OneFactor,THREE.SrcColorFactor,THREE.OneMinusSrcColorFactor,THREE.SrcAlphaFactor,THREE.OneMinusSrcAlphaFactor,THREE.DstAlphaFactor,THREE.OneMinusDstAlphaFactor,THREE.DstColorFactor,THREE.OneMinusDstColorFactor,THREE.SrcAlphaSaturateFactor,{SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16}),E={POSITION:"position",NORMAL:"normal",TEXCOORD_0:"uv",TEXCOORD0:"uv",TEXCOORD:"uv",TEXCOORD_1:"uv2",COLOR_0:"color",COLOR0:"color",COLOR:"color",WEIGHTS_0:"skinWeight",WEIGHT:"skinWeight",JOINTS_0:"skinIndex",JOINT:"skinIndex"},m={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},f={CUBICSPLINE:THREE.InterpolateSmooth,LINEAR:THREE.InterpolateLinear,STEP:THREE.InterpolateDiscrete};function v(e,t){return"string"!=typeof e||""===e?"":/^(https?:)?\/\//i.test(e)?e:/^data:.*,.*$/i.test(e)?e:/^blob:.*$/i.test(e)?e:t+e}function T(e,t,a,r){var s=e.geometry,i=e.material,n=a.targets,o=s.morphAttributes;o.position=[],o.normal=[],i.morphTargets=!0;for(var l=0,p=n.length;l=2&&(r[s+1]=e.getY(s)),a>=3&&(r[s+2]=e.getZ(s)),a>=4&&(r[s+3]=e.getW(s));return new THREE.BufferAttribute(r,a,e.normalized)}return e.clone()}function S(e,t,a){this.json=e||{},this.extensions=t||{},this.options=a||{},this.cache=new function(){var e={};return{get:function(t){return e[t]},add:function(t,a){e[t]=a},remove:function(t){delete e[t]},removeAll:function(){e={}}}},this.primitiveCache=[],this.textureLoader=new THREE.TextureLoader(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.fileLoader=new THREE.FileLoader(this.options.manager),this.fileLoader.setResponseType("arraybuffer")}function H(e,t,a){var r=t.attributes;for(var s in r){var i=E[s],n=a[r[s]];i&&(i in e.attributes||e.addAttribute(i,n))}void 0===t.indices||e.index||e.setIndex(a[t.indices])}return S.prototype.parse=function(e,t){var a=this.json;this.cache.removeAll(),this.markDefs(),this.getMultiDependencies(["scene","animation","camera"]).then(function(t){var r=t.scenes||[],s=r[a.scene||0],i=t.animations||[],n=a.asset,o=t.cameras||[];e(s,r,o,i,n)}).catch(t)},S.prototype.markDefs=function(){for(var e=this.json.nodes||[],t=this.json.skins||[],a=this.json.meshes||[],r={},s={},i=0,n=t.length;i=2&&i.setY(x,H[y*o+1]),o>=3&&i.setZ(x,H[y*o+2]),o>=4&&i.setW(x,H[y*o+3]),o>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}}return i})},S.prototype.loadTexture=function(e){var t=this.json,a=this.options,r=this.textureLoader,s=window.URL||window.webkitURL,i=t.textures[e],n=t.images[i.source],o=n.uri,l=!1;return void 0!==n.bufferView&&(o=this.getDependency("bufferView",n.bufferView).then(function(e){l=!0;var t=new Blob([e],{type:n.mimeType});return o=s.createObjectURL(t)})),Promise.resolve(o).then(function(e){var t=THREE.Loader.Handlers.get(e)||r;return new Promise(function(r,s){t.load(v(e,a.path),r,void 0,s)})}).then(function(e){!0===l&&s.revokeObjectURL(o),e.flipY=!1,void 0!==i.name&&(e.name=i.name),e.format=void 0!==i.format?c[i.format]:THREE.RGBAFormat,void 0!==i.internalFormat&&e.format!==c[i.internalFormat]&&console.warn("THREE.GLTFLoader: Three.js does not support texture internalFormat which is different from texture format. internalFormat will be forced to be the same value as format."),e.type=void 0!==i.type?d[i.type]:THREE.UnsignedByteType;var a=(t.samplers||{})[i.sampler]||{};return e.magFilter=p[a.magFilter]||THREE.LinearFilter,e.minFilter=p[a.minFilter]||THREE.LinearMipMapLinearFilter,e.wrapS=u[a.wrapS]||THREE.RepeatWrapping,e.wrapT=u[a.wrapT]||THREE.RepeatWrapping,e})},S.prototype.assignTexture=function(e,t,a){return this.getDependency("texture",a).then(function(a){e[t]=a})},S.prototype.loadMaterial=function(e){this.json;var a,r=this.extensions,s=this.json.materials[e],i={},n=s.extensions||{},o=[];if(n[t.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS]){var l=r[t.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS];a=l.getMaterialType(s),o.push(l.extendParams(i,s,this))}else if(n[t.KHR_MATERIALS_UNLIT]){var p=r[t.KHR_MATERIALS_UNLIT];a=p.getMaterialType(s),o.push(p.extendParams(i,s,this))}else if(void 0!==s.pbrMetallicRoughness){a=THREE.MeshStandardMaterial;var u=s.pbrMetallicRoughness;if(i.color=new THREE.Color(1,1,1),i.opacity=1,Array.isArray(u.baseColorFactor)){var c=u.baseColorFactor;i.color.fromArray(c),i.opacity=c[3]}if(void 0!==u.baseColorTexture&&o.push(this.assignTexture(i,"map",u.baseColorTexture.index)),i.metalness=void 0!==u.metallicFactor?u.metallicFactor:1,i.roughness=void 0!==u.roughnessFactor?u.roughnessFactor:1,void 0!==u.metallicRoughnessTexture){var d=u.metallicRoughnessTexture.index;o.push(this.assignTexture(i,"metalnessMap",d)),o.push(this.assignTexture(i,"roughnessMap",d))}}else a=THREE.MeshPhongMaterial;!0===s.doubleSided&&(i.side=THREE.DoubleSide);var h=s.alphaMode||"OPAQUE";return"BLEND"===h?i.transparent=!0:(i.transparent=!1,"MASK"===h&&(i.alphaTest=void 0!==s.alphaCutoff?s.alphaCutoff:.5)),void 0!==s.normalTexture&&a!==THREE.MeshBasicMaterial&&(o.push(this.assignTexture(i,"normalMap",s.normalTexture.index)),i.normalScale=new THREE.Vector2(1,1),void 0!==s.normalTexture.scale&&i.normalScale.set(s.normalTexture.scale,s.normalTexture.scale)),void 0!==s.occlusionTexture&&a!==THREE.MeshBasicMaterial&&(o.push(this.assignTexture(i,"aoMap",s.occlusionTexture.index)),void 0!==s.occlusionTexture.strength&&(i.aoMapIntensity=s.occlusionTexture.strength)),void 0!==s.emissiveFactor&&a!==THREE.MeshBasicMaterial&&(i.emissive=(new THREE.Color).fromArray(s.emissiveFactor)),void 0!==s.emissiveTexture&&a!==THREE.MeshBasicMaterial&&o.push(this.assignTexture(i,"emissiveMap",s.emissiveTexture.index)),Promise.all(o).then(function(){var e;return e=a===THREE.ShaderMaterial?r[t.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS].createMaterial(i):new a(i),void 0!==s.name&&(e.name=s.name),e.normalScale&&(e.normalScale.x=-e.normalScale.x),e.map&&(e.map.encoding=THREE.sRGBEncoding),e.emissiveMap&&(e.emissiveMap.encoding=THREE.sRGBEncoding),s.extras&&(e.userData=s.extras),e})},S.prototype.loadGeometries=function(e){var a=this,r=this.extensions,s=this.primitiveCache;return this.getDependencies("accessor").then(function(i){for(var n=[],o=[],l=0,p=e.length;l1))return E;E.name+="_"+p,n.add(E)}return n})})},S.prototype.loadCamera=function(e){var t,a=this.json.cameras[e],r=a[a.type];if(r){if("perspective"===a.type){var s=r.aspectRatio||1,i=r.yfov*s;t=new THREE.PerspectiveCamera(THREE.Math.radToDeg(i),s,r.znear||1,r.zfar||2e6)}else"orthographic"===a.type&&(t=new THREE.OrthographicCamera(r.xmag/-2,r.xmag/2,r.ymag/2,r.ymag/-2,r.znear,r.zfar));return void 0!==a.name&&(t.name=a.name),a.extras&&(t.userData=a.extras),Promise.resolve(t)}console.warn("THREE.GLTFLoader: Missing camera parameters.")},S.prototype.loadSkin=function(e){var t=this.json.skins[e],a={joints:t.joints};return void 0===t.inverseBindMatrices?Promise.resolve(a):this.getDependency("accessor",t.inverseBindMatrices).then(function(e){return a.inverseBindMatrices=e,a})},S.prototype.loadAnimation=function(e){this.json;var t=this.json.animations[e];return this.getMultiDependencies(["accessor","node"]).then(function(a){for(var r=[],s=0,i=t.channels.length;s1&&(n.name+="_instance_"+s[i.mesh]++)}else n=void 0!==i.camera?e.cameras[i.camera]:i.extensions&&i.extensions[t.KHR_LIGHTS]&&void 0!==i.extensions[t.KHR_LIGHTS].light?a[t.KHR_LIGHTS].lights[i.extensions[t.KHR_LIGHTS].light]:new THREE.Object3D;if(void 0!==i.name&&(n.name=THREE.PropertyBinding.sanitizeNodeName(i.name)),i.extras&&(n.userData=i.extras),void 0!==i.matrix){var c=new THREE.Matrix4;c.fromArray(i.matrix),n.applyMatrix(c)}else void 0!==i.translation&&n.position.fromArray(i.translation),void 0!==i.rotation&&n.quaternion.fromArray(i.rotation),void 0!==i.scale&&n.scale.fromArray(i.scale);return n})},S.prototype.loadScene=function(){function e(t,a,r,s,i){var n=s[t],o=r.nodes[t];if(void 0!==o.skin)for(var l=!0===n.isGroup?n.children:[n],p=0,u=l.length;p