diff options
| author | Jules Laplace <jules@okfoc.us> | 2014-06-19 16:01:25 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2014-06-19 16:01:25 -0400 |
| commit | 615e285aba96554d0e29063d7491645810cb08b8 (patch) | |
| tree | ddc409898299dd90611c73a2ddf62a149c369734 | |
| parent | 9a4730ac59f0cf83b2fdca3672a9f622db6c8aa2 (diff) | |
serialize/deserialize scenery
14 files changed, 188 insertions, 133 deletions
@@ -5,6 +5,7 @@ "dependencies": { "jquery": "1.11.0", "momentjs": "~2.5.1", - "lodash": "" + "lodash": "", + "fiber": "" } } diff --git a/public/assets/javascripts/app.js b/public/assets/javascripts/app.js index a319835..3117112 100644 --- a/public/assets/javascripts/app.js +++ b/public/assets/javascripts/app.js @@ -86,13 +86,17 @@ app.off = function(){ } app.position = function(obj){ - return { + var pos = { x: obj.x, y: obj.y, z: obj.z, rotationX: obj.rotationX, rotationY: obj.rotationY } + if (obj.scale !== 1) { + pos.scale = obj.scale + } + return pos } document.addEventListener('DOMContentLoaded', app.init) diff --git a/public/assets/javascripts/mx/primitives/mx.image.js b/public/assets/javascripts/mx/primitives/mx.image.js index 15bf050..8b11473 100644 --- a/public/assets/javascripts/mx/primitives/mx.image.js +++ b/public/assets/javascripts/mx/primitives/mx.image.js @@ -33,13 +33,14 @@ MX.Image = MX.Object3D.extend({ loadTexture: function(ops){ var layer = this layer.ops = defaults(ops, layer.ops) + console.log(layer.ops.y, layer.y) var image = new Image() image.onload = function(){ layer.scale = layer.ops.scale || 1 layer.width = image.naturalWidth layer.height = image.naturalHeight layer.x = layer.ops.x || 0 - layer.y = (layer.ops.y || 0) + layer.scale * layer.height/2 + 1 + layer.y = layer.ops.y || 0 layer.z = layer.ops.z || 0 layer.rotationX = layer.ops.rotationX || 0 layer.rotationY = layer.ops.rotationY || 0 diff --git a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js index 9839c68..8fea9b5 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js +++ b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js @@ -3,6 +3,7 @@ var Rooms = new function(){ var base = this base.list = {} + base.walls = {} base.regions = [] base.init = function(){ @@ -87,7 +88,6 @@ var Rooms = new function(){ } })() - base.sorted_by_position = function(){ return sort_rooms_by_position( base.values() ) } diff --git a/public/assets/javascripts/rectangles/engine/rooms/builder.js b/public/assets/javascripts/rectangles/engine/rooms/builder.js index 8586a7b..e6625ec 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/builder.js +++ b/public/assets/javascripts/rectangles/engine/rooms/builder.js @@ -39,6 +39,7 @@ Rooms.builder = new function(){ Rooms.forEach(function(room){ room.walls = room.group_mx_walls() room.walls.forEach(function(wall){ + Rooms.walls[ wall.id ] = wall wall.bind() wall.randomize_colors() }) diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js index 0dd1a4d..0a3187c 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js +++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js @@ -10,53 +10,25 @@ var Scenery = new function(){ base.init = function(){ base.resize.init() - - var urls = [ - "http://okfocus.s3.amazonaws.com/office/ducks/duck1.jpg", - "http://okfocus.s3.amazonaws.com/office/ducks/duck2.jpg", - "http://okfocus.s3.amazonaws.com/office/ducks/duck3.jpg", - "http://okfocus.s3.amazonaws.com/office/ducks/duck4.jpg", - "http://okfocus.s3.amazonaws.com/office/ducks/duck5.jpg", - ] - var loader = new Loader(function(){ - base.load(loader.images) - }) - // loader.preloadImages(urls) - } - - base.load = function(images){ - images.forEach(function(img){ - img.width = 300 - img.height = ~~(300 * img.naturalHeight/img.naturalWidth) - }) - - Rooms.forEach(function(room){ - room.walls.forEach(function(wall){ - var img = choice(images) - if (wall.fits(img)) { - var scene_img = new Scenery.image (wall, img) - base.images.push(scene_img) - scene_img.init() - } - }) - }) } base.add = function(wall, media){ var scene_media switch (media.type) { case 'image': - scene_media = new Scenery.image (wall, media) + scene_media = new Scenery.types.image ({ media: media, wall: wall }) break case 'youtube': case 'vimeo': - scene_media = new Scenery.video (wall, media) + scene_media = new Scenery.types.video ({ media: media, wall: wall }) break } + base.media.push(scene_media) - scene_media.init() + return scene_media } + base.addNextToWall = function(wall){ base.add(wall, base.nextMedia) base.nextMedia = null @@ -73,14 +45,19 @@ var Scenery = new function(){ var scenery = base.media.map(function(media){ return media.serialize() }) + console.log(scenery) return scenery } - base.deserialize = function(scenery){ - scenery.forEach(function(function(media){ - // find the wall this is supposed to be on + base.deserialize = function(scenery_data){ + scenery_data.forEach(function(data){ + var wall = Rooms.walls[data.wall_id] + var scene_media = base.add(wall, data.media) + scene_media.deserialize(data) }) } return base } + +Scenery.types = {} diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/move.js b/public/assets/javascripts/rectangles/engine/scenery/move.js index 2921c0a..ce4f297 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/move.js +++ b/public/assets/javascripts/rectangles/engine/scenery/move.js @@ -1,12 +1,11 @@ - -Scenery.image.move = function(base){ +Scenery.move = function(base){ var x, y, z, bounds var dragging = false this.bind = function(){ - Scenery.mouse.bind_el(base.mx_img.el) + Scenery.mouse.bind_el(base.mx.el) Scenery.mouse.on("down", down) Scenery.mouse.on("enter", switch_wall) Scenery.mouse.on("drag", drag) @@ -14,7 +13,7 @@ Scenery.image.move = function(base){ } this.unbind = function(){ - Scenery.mouse.bind_el(base.mx_img.el) + Scenery.mouse.unbind_el(base.mx.el) Scenery.mouse.off("down", down) Scenery.mouse.off("enter", switch_wall) Scenery.mouse.off("drag", drag) @@ -22,11 +21,11 @@ Scenery.image.move = function(base){ } function down (e, cursor){ - if (e.target != base.mx_img.el) return; + if (e.target != base.mx.el) return; dragging = true - x = base.mx_img.x - y = base.mx_img.y - z = base.mx_img.z + x = base.mx.x + y = base.mx.y + z = base.mx.z bounds = base.bounds document.body.classList.add("dragging") } @@ -34,15 +33,15 @@ Scenery.image.move = function(base){ function drag (e, cursor){ if (! dragging) return - base.mx_img.y = bounds.y.clamp( y - cursor.y.magnitude()*cursor_amp ) + base.mx.y = bounds.y.clamp( y - cursor.y.magnitude()*cursor_amp ) switch (base.wall.side) { case FRONT: case BACK: - base.mx_img.x = bounds.x.clamp( x + cos(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) + base.mx.x = bounds.x.clamp( x + cos(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) break case LEFT: case RIGHT: - base.mx_img.z = bounds.x.clamp( z + sin(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) + base.mx.z = bounds.x.clamp( z + sin(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) break } @@ -59,16 +58,17 @@ Scenery.image.move = function(base){ if (new_wall.uid == base.wall.uid) return if (! new_wall.fits(base.media)) return - base.bounds = bounds = new_wall.bounds_for(base.media) - base.center = new_wall.center() + var old_wall_side = base.wall.side + var wall_group = old_wall_side | new_wall.side + + base.set_wall(new_wall) + bounds = base.bounds x = base.center.a z = base.center.b - var wall_group = base.wall.side | new_wall.side - - if (base.wall.side !== new_wall.side && wall_group !== FRONT_BACK && wall_group !== LEFT_RIGHT) { - switch (base.wall.side) { + if (old_wall_side !== new_wall.side && wall_group !== FRONT_BACK && wall_group !== LEFT_RIGHT) { + switch (old_wall_side) { case FRONT: z = bounds.x.a break @@ -86,13 +86,11 @@ Scenery.image.move = function(base){ cursor.x.a = cursor.x.b - base.mx_img.move({ + base.mx.move({ x: x, z: z, rotationY: wall_rotation[ new_wall.side ] }) - - base.wall = new_wall Scenery.resize.rotate_dots() Scenery.resize.move_dots() diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index a0a98c5..2a400f5 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -1,3 +1,4 @@ + Scenery.resize = new function(){ var base = this @@ -54,9 +55,9 @@ Scenery.resize = new function(){ // move all the dots to the object's current position base.move_dots = function(){ - x = obj.mx_img.x + sin(rotationY) * dot_distance_from_picture - y = obj.mx_img.y - z = obj.mx_img.z - cos(rotationY) * dot_distance_from_picture + x = obj.mx.x + sin(rotationY) * dot_distance_from_picture + y = obj.mx.y + z = obj.mx.z - cos(rotationY) * dot_distance_from_picture dots.forEach(function(dot){ base.move_dot(dot) @@ -70,25 +71,24 @@ Scenery.resize = new function(){ dot.z = z if (dot.side & TOP) { - dot.y += obj.mx_img.height * obj.mx_img.scale / 2 + dot.y += obj.mx.height * obj.mx.scale / 2 } if (dot.side & BOTTOM) { - dot.y -= obj.mx_img.height * obj.mx_img.scale / 2 + dot.y -= obj.mx.height * obj.mx.scale / 2 } if (dot.side & LEFT) { - dot.x -= cos(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 - dot.z -= sin(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 + dot.x -= cos(rotationY) * (obj.mx.width * obj.mx.scale) / 2 + dot.z -= sin(rotationY) * (obj.mx.width * obj.mx.scale) / 2 } if (dot.side & RIGHT) { - dot.x += cos(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 - dot.z += sin(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 + dot.x += cos(rotationY) * (obj.mx.width * obj.mx.scale) / 2 + dot.z += sin(rotationY) * (obj.mx.width * obj.mx.scale) / 2 } } // pick a new object to focus on and show the dots base.show = function(new_object) { if (obj === new_object) return - obj = new_object base.add_dots() @@ -102,7 +102,7 @@ Scenery.resize = new function(){ clearTimeout(dotsHideTimeout) dotsHideTimeout = setTimeout(function(){ - if (Scenery.image.hovering || Scenery.resize.hovering || Scenery.mouse.down) return + if (Scenery.hovering || Scenery.resize.hovering || Scenery.mouse.down) return Scenery.resize.hide() }, dot_hide_delay) } @@ -147,8 +147,8 @@ Scenery.resize = new function(){ selected_dot = selection[0] dragging = true - dimensions = new vec2(obj.mx_img.width, obj.mx_img.height) - position = new vec3(obj.mx_img.x, obj.mx_img.y, obj.mx_img.z) + dimensions = new vec2(obj.mx.width, obj.mx.height) + position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z) console.log("down on", sidesToString(selected_dot.side)) @@ -165,26 +165,26 @@ Scenery.resize = new function(){ var translation = new vec2( x_sign * cursor.x.magnitude() * cursor_amp, y_sign * cursor.y.magnitude() * cursor_amp ) if (selected_dot.side & LEFT_RIGHT) { - obj.mx_img.width = dimensions.a + translation.a - obj.mx_img.x = position.a + x_sign * cos(rotationY) * translation.a/2 * obj.mx_img.scale - obj.mx_img.z = position.c + x_sign * sin(rotationY) * translation.a/2 * obj.mx_img.scale + obj.mx.width = dimensions.a + translation.a + obj.mx.x = position.a + x_sign * cos(rotationY) * translation.a/2 * obj.mx.scale + obj.mx.z = position.c + x_sign * sin(rotationY) * translation.a/2 * obj.mx.scale } if (selected_dot.side & TOP_BOTTOM) { - obj.mx_img.height = dimensions.b + translation.b - obj.mx_img.y = position.b - y_sign * translation.b/2 * obj.mx_img.scale + obj.mx.height = dimensions.b + translation.b + obj.mx.y = position.b - y_sign * translation.b/2 * obj.mx.scale } // bounds = obj.wall.bounds_for(dimensions) -// base.mx_img.y = bounds.y.clamp( y - cursor.y.magnitude()*cursor_amp ) +// base.mx.y = bounds.y.clamp( y - cursor.y.magnitude()*cursor_amp ) // switch (base.wall.side) { // case FRONT: // case BACK: -// base.mx_img.x = bounds.x.clamp( x + cos(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) +// base.mx.x = bounds.x.clamp( x + cos(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) // break // case LEFT: // case RIGHT: -// base.mx_img.z = bounds.x.clamp( z + sin(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) +// base.mx.z = bounds.x.clamp( z + sin(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) // break // } diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/_image.js b/public/assets/javascripts/rectangles/engine/scenery/types/_image.js deleted file mode 100644 index bcb7c23..0000000 --- a/public/assets/javascripts/rectangles/engine/scenery/types/_image.js +++ /dev/null @@ -1,49 +0,0 @@ -Scenery.image = function (wall, media) { - - var base = this - - base.wall = wall - base.media = media - base.scale = media.scale = 300 / max(300, media.width) - base.dimensions = new vec2(media.width, media.height) - base.center = wall.center() - base.bounds = wall.bounds_for(media) - - // should be proportional to distance from wall - var cursor_amp = 1.5 - - base.init = function(){ - base.build() - base.bind() - } - - base.build = function(){ - base.mx_img = new MX.Image({ - src: media.url, - x: base.center.a, - y: Rooms.list[wall.room].height/2 - (base.scale * media.height)/2 - 20, - z: base.center.b, - scale: base.scale, - rotationY: wall_rotation[ wall.side ], - backface: false, - }) - scene.add( base.mx_img ) - base.move = new Scenery.image.move (base) - } - - base.bind = function(){ - base.move.bind() - $(base.mx_img.el).bind({ - mouseenter: function(e){ - Scenery.resize.show(base) - Scenery.image.hovering = true - }, - mouseleave: function(e){ - Scenery.resize.defer_hide(base) - Scenery.image.hovering = false - } - }) - } - - return base -} diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js new file mode 100644 index 0000000..f892c0c --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js @@ -0,0 +1,74 @@ +Scenery.types.base = Fiber.extend(function(base){ + + var exports = { + + init: function(opt){ + _.bindAll(this, 'enter', 'leave') + + this.move = new Scenery.move (this) + this.media = opt.media + this.dimensions = new vec2(this.media.width, this.media.height) + + if (opt.wall) { + this.set_wall(opt.wall) + } + }, + + bind: function(){ + this.move.bind() + $(this.mx.el).bind({ + mouseenter: this.enter, + mouseleave: this.leave, + }) + }, + + unbind: function(){ + this.move.unbind() + $(this.mx.el).unbind({ + mouseenter: this.enter, + mouseleave: this.leave, + }) + }, + + enter: function(e){ + Scenery.resize.show(this) + Scenery.hovering = true + }, + + leave: function(e){ + Scenery.resize.defer_hide(this) + Scenery.hovering = false + }, + + set_wall: function(wall){ + this.wall = wall || this.wall + this.bounds = this.wall.bounds_for(this.media) + this.center = this.wall.center() + }, + + recenter: function(){ + this.mx.move({ + x: this.center.a, + y: Rooms.list[this.wall.room].height/2 - 20, + z: this.center.b, + scale: this.scale, + rotationY: wall_rotation[ this.wall.side ], + }) + }, + + serialize: function(){ + var data = { + room_id: this.wall.room_id, + wall_id: this.wall.id, + side: this.wall.side, + dimensions: this.dimensions.serialize(), + position: app.position(this.mx), + media: this.media, + } + return data + }, + } + + return exports + +}) diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/image.js b/public/assets/javascripts/rectangles/engine/scenery/types/image.js new file mode 100644 index 0000000..d9bc1e5 --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/scenery/types/image.js @@ -0,0 +1,38 @@ + +Scenery.types.image = Scenery.types.base.extend(function(base){ +console.log("IM", base.serialize) + + var exports = { + + init: function(opt){ + base.init.call(this, opt) + this.scale = this.media.scale = 300 / max(300, this.media.width) + + this.build() + this.bind() + this.set_wall() + this.recenter() + }, + + build: function(){ + this.mx = new MX.Image({ + src: this.media.url, + y: this.scale * this.media.height/2, + backface: false, + }) + scene.add( this.mx ) + }, + + serialize: function(){ + var data = base.serialize.call(this) + console.log(data) + return data + }, + + deserialize: function(data){ + this.mx.move(data.position) + }, + } + + return exports +}) diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/video.js b/public/assets/javascripts/rectangles/engine/scenery/types/video.js new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/scenery/types/video.js diff --git a/public/assets/javascripts/rectangles/models/room.js b/public/assets/javascripts/rectangles/models/room.js index d0478b3..61a7447 100644 --- a/public/assets/javascripts/rectangles/models/room.js +++ b/public/assets/javascripts/rectangles/models/room.js @@ -87,6 +87,12 @@ window.Room = (function(){ els.sort(compare_z) } + // wall holds state for the last wall we created/saw.. + // right now we keep walls subdivided where there are half-walls to simplify + // calculations involving placing media on walls, calculating wall boundaries, etc.. + // one consequence of this is we can't place things on the walls above "doorways". + // in the future, we should have more robust placement algorithm, which takes + // this into account, and only use one wall "object" per plane var wall els.forEach(function(el){ @@ -116,6 +122,7 @@ window.Room = (function(){ function new_wall (el) { return new Wall ({ + id: base.id + "_" + (el.side | el.half_side) + "_" + walls.length, room: base.id, side: el.side | el.half_side, half_side: el.half_side, diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 1beed5d..2d34480 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -1,6 +1,7 @@ <script type="text/javascript" src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script> <script type="text/javascript" src="/assets/javascripts/vendor/bower_components/momentjs/min/moment.min.js"></script> +<script type="text/javascript" src="/assets/javascripts/vendor/bower_components/fiber/src/fiber.min.js"></script> <script type="text/javascript" src="/assets/javascripts/vendor/tube.js"></script> <script type="text/javascript" src="/assets/javascripts/vendor/loader.js"></script> <script type="text/javascript" src="/assets/javascripts/vendor/polyfill.js"></script> @@ -30,9 +31,11 @@ <script type="text/javascript" src="/assets/javascripts/rectangles/engine/rooms/mover.js"></script> <script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/_scenery.js"></script> -<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/_image.js"></script> -<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/move.js"></script> -<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/resize.js"></script> +<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/move.js"></script> +<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/resize.js"></script> +<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/_object.js"></script> +<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/image.js"></script> +<script type="text/javascript" src="/assets/javascripts/rectangles/engine/scenery/types/video.js"></script> <script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/_map.js"></script> <script type="text/javascript" src="/assets/javascripts/rectangles/engine/map/ui.js"></script> |
