PythagoraSwitch
/**
* Copyright tencho ( http://wonderfl.net/user/tencho )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/2F0r
*/
/**
* ねぎ玉牛丼
*/
package {
import alternativ7.engine3d.core.Geometry;
import alternativ7.engine3d.core.Object3DContainer;
import alternativ7.engine3d.core.Sorting;
import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.objects.Mesh;
import com.actionsnippet.qbox.QuickBox2D;
import com.actionsnippet.qbox.QuickContacts;
import com.bit101.components.PushButton;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.StageQuality;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Vector3D;
import net.hires.debug.Stats;
public class NegitamaGyudon extends Sprite {
private var _sim:QuickBox2D;
private var _contact:QuickContacts;
private var _boxScene:BoxSceneData;
private var _scene:Scene3D;
private var _canvas:MovieClip;
private var _cameraDrag:SphericalDragger;
private var _lookAtPoint:Vector3D = new Vector3D();
private var _isPlaying:Boolean = true;
private var _cameraType:int = 0;
private var _hitbits:uint = 0x000;
private var _gyudon:Mesh;
private var _isComplete:Boolean = false;
//BOX2Dサイズ→Alt3Dサイズ
private const SCALE_ALT3D:Number = 20;
public function NegitamaGyudon() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(...arg):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.frameRate = 60;
stage.quality = StageQuality.MEDIUM;
_canvas = new MovieClip();
_canvas.visible = false;
_scene = new Scene3D(Scene3D.BSP, 465, 465, 0xC0CCDE);
_cameraDrag = new SphericalDragger(_scene.display);
_cameraDrag.wheelEnabled = false;
_cameraDrag.notify();
//フルスクリーンにしたらホイールズームを有効にする
_scene.onResizeStage = function(w:Number, h:Number):void {
if (w != 465 || h != 465) _cameraDrag.wheelEnabled = true;
}
_scene.startAutoResize(stage);
addChild(_canvas);
addChild(_scene.display);
addChild(new Stats());
new PushButton(this, 75, 5, "PAUSE", onClickPause);
new PushButton(this, 180, 5, "CAMERA", onClickCamera);
new PushButton(this, 285, 5, "RESET", onClickReset);
//牛丼とテーブルを作る
_gyudon = createDonburi();
_gyudon.x = 17.8 * SCALE_ALT3D;
_gyudon.z = -17.5 * SCALE_ALT3D;
_gyudon.y = 1 * SCALE_ALT3D;
_gyudon.scaleX = _gyudon.scaleY = _gyudon.scaleZ = 0.125 * SCALE_ALT3D;
var table:Mesh = createTable();
table.matrix = _gyudon.matrix.clone();
table.sorting = _gyudon.sorting = Sorting.DYNAMIC_BSP;
table.z -= 0.15 * SCALE_ALT3D;
_scene.root.addChild(table);
_scene.root.addChild(_gyudon);
format();
}
private function format():void {
_isComplete = false;
_isPlaying = true;
_hitbits = 0x000;
_cameraType = 0;
updateCamera();
_sim = new QuickBox2D(_canvas);
_contact = _sim.addContactListener();
_contact.addEventListener(QuickContacts.ADD, onCollide);
_boxScene = QboxModeler.createByXML(_sim, Box2DXML.data, 1, SCALE_ALT3D);
//Alt3Dオブジェクトをルートコンテナに配置
var qdata:QboxData;
for each (qdata in _boxScene.groupList)
_scene.root.addChild(qdata.primitive);
for each (qdata in _boxScene.bodyList)
if (!qdata.inGroup) _scene.root.addChild(qdata.primitive);
//シミュレーション開始
_sim.start();
addEventListener(Event.ENTER_FRAME, onTickSimulate);
}
//全衝突判定
private function onCollide(e:Event):void {
//青い板が跳ね上がって上のストッパーにあたった
if (!(_hitbits & 0x00F) && _contact.isCurrentContact(_boxScene.root["bar"].qobject, _boxScene.root["barstopper"].qobject)) _hitbits |= 0x00F;
//卵が牛丼に乗った
if (!(_hitbits & 0x0F0) && _contact.isCurrentContact(_boxScene.root["egg"].qobject, _boxScene.root["donburi"].qobject)) _hitbits |= 0x0F0;
//ネギを運ぶ箱がストッパーにあたった
if (!(_hitbits & 0xF00) && _contact.isCurrentContact(_boxScene.root["negibox"].qobject, _boxScene.root["negistopper"].qobject)) _hitbits |= 0xF00;
//たぶん完成
if (_hitbits == 0xFFF) {
_contact.removeEventListener(QuickContacts.ADD, onCollide);
_isComplete = true;
_cameraType = 0;
updateCamera();
}
}
//全部リセット
private function onClickReset(e:MouseEvent):void {
_contact.removeEventListener(QuickContacts.ADD, onCollide);
_boxScene.destroy();
_sim.destroy();
while (_canvas.numChildren) _canvas.removeChildAt(_canvas.numChildren-1);
format();
}
//カメラ切り替え
private function onClickCamera(e:MouseEvent):void {
_cameraType = ++_cameraType % 2;
updateCamera();
}
//一時停止/再生
private function onClickPause(e:MouseEvent):void{
_isPlaying = !_isPlaying;
if (_isPlaying) _sim.start();
else _sim.stop();
}
//テーブルを作る
private function createTable():Mesh {
var materials:Array = [new FillMaterial(0x502a1e),new FillMaterial(0x2a2a2a),new FillMaterial(0x6e532e),new FillMaterial(0xa79660),new FillMaterial(0xa47638)];
var vts:Array = [[-41,-142,0],[41,-142,0],[-41,142,0],[41,142,0],[-41,-142,-12],[41,-142,-12],[-41,142,-12],[41,142,-12],[20,142,-12],[20,-142,-12],[-19,142,-12],[-19,-142,-12],[20,-142,-100],[-19,-142,-100],[-19,142,-100],[20,142,-100]];
var ids:Array = [[0,1,3],[3,2,0],[6,10,11],[11,4,6],[7,5,9],[9,8,7],[15,12,13],[13,14,15],[0,4,11],[0,11,9],[0,9,5],[0,5,1],[3,7,8],[3,8,10],[3,10,6],[3,6,2],[9,11,13],[13,12,9],[10,8,15],[15,14,10],[1,5,7],[7,3,1],[2,6,4],[4,0,2],[11,10,14],[14,13,11],[8,9,12],[12,15,8]];
var mts:Array = [0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,4,4,4,4];
var geom:Geometry = new Geometry();
for each (var vt:Array in vts) geom.addVertex(vt[0], vt[1], vt[2]);
for (var i:int; i < ids.length; i++) geom.addTriFace(geom.vertices[ids[i][0]], geom.vertices[ids[i][1]], geom.vertices[ids[i][2]], materials[mts[i]]);
var mesh:Mesh = new Mesh();
mesh.geometry = geom;
return mesh;
}
//牛丼を作る
private function createDonburi():Mesh {
var scale:Number = 0.1;
var materials:Array = [new FillMaterial(0xd3caae),new FillMaterial(0xa79660),new FillMaterial(0x2a2a2a),new FillMaterial(0xa47638),new FillMaterial(0x20439d),new FillMaterial(0x1d2b68),new FillMaterial(0xffffff)];
var vts:Array = [
[129,8,0],[68,114,0],[-55,114,0],[-116,8,0],[-55,-98,0],[68,-98,0],[129,8,60],[68,114,60],[-55,114,60],[-116,8,60],[-55,-98,60],[68,-98,60],[227,8,129],[117,199,129],[-104,199,129],[-214,8,129],[-104,-183,129],[117,-183,129],[254,8,252],[130,222,252],[-117,222,252],[-240,8,252],[-117,-206,252],[130,-206,252],[223,8,211],[115,195,211],[-101,195,211],[-209,8,211],[-101,-179,211],[115,-179,211],
[186,28,211],[96,176,211],[-74,172,211],[-167,50,211],[-114,-109,211],[83,-151,211]
];
var ids:Array = [
[0,1,7],[7,6,0],[4,5,11],[11,10,4],[5,0,6],[6,11,5],[19,20,26],[26,25,19],[20,21,27],[27,26,20],[21,22,28],[28,27,21],[1,2,8],[8,7,1],[2,3,9],[9,8,2],[3,4,10],[10,9,3],[18,19,25],[25,24,18],[22,23,29],[29,28,22],[23,18,24],[24,29,23],[4,3,2],[2,1,0],[4,2,0],[5,4,0],[31,32,33],[33,34,35],
[31,33,35],[30,31,35],[6,7,13],[13,12,6],[10,11,17],[17,16,10],[11,6,12],[12,17,11],[12,13,19],[19,18,12],[16,17,23],[23,22,16],[17,12,18],[18,23,17],[7,8,14],[14,13,7],[8,9,15],[15,14,8],[9,10,16],[16,15,9],[13,14,20],[20,19,13],[14,15,21],[21,20,14],[15,16,22],[22,21,15],[24,25,31],[31,30,24],[25,26,32],[32,31,25],
[26,27,33],[33,32,26],[27,28,34],[34,33,27],[28,29,35],[35,34,28],[29,24,30],[30,35,29]
];
var mts:Array = [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6];
var geom:Geometry = new Geometry();
for each (var vt:Array in vts) geom.addVertex(vt[0] * scale, vt[1] * scale, vt[2] * scale);
for (var i:int; i < ids.length; i++) geom.addTriFace(geom.vertices[ids[i][0]], geom.vertices[ids[i][1]], geom.vertices[ids[i][2]], materials[mts[i]]);
var mesh:Mesh = new Mesh();
mesh.geometry = geom;
return mesh;
}
//シミュレーション中
private function onTickSimulate(e:Event):void {
if (_cameraType == 0) {
if (_isComplete) {
_lookAtPoint = _gyudon.matrix.position;
_lookAtPoint.z += 2.5 * SCALE_ALT3D;
} else if (_boxScene.trackingList.length) {
//カメラで追跡するオブジェクトがあれば追う
var p:Point = _boxScene.getTrackingPoint();
_lookAtPoint.x = p.x * SCALE_ALT3D;
_lookAtPoint.z = -p.y * SCALE_ALT3D;
}
} else {
_lookAtPoint.x = 2.5 * SCALE_ALT3D;
_lookAtPoint.z = 0;
}
var qdata:QboxData;
//グループオブジェクトの位置更新
for each(qdata in _boxScene.groupList) {
var obj:Object3DContainer = qdata.primitive as Object3DContainer;
//可動オブジェクト
if (!qdata.qobject.body.IsStatic()) {
obj.x = qdata.qobject.x * SCALE_ALT3D;
obj.z = -qdata.qobject.y * SCALE_ALT3D;
obj.rotationY = qdata.qobject.angle;
}
}
//剛体オブジェクトの位置更新
for each(qdata in _boxScene.bodyList) {
//可動オブジェクト
if (!qdata.qobject.body.IsStatic()) {
if (!qdata.inGroup) {
qdata.primitive.x = qdata.qobject.x * SCALE_ALT3D;
qdata.primitive.z = -qdata.qobject.y * SCALE_ALT3D;
}
//角度が大きすぎると色々と問題があるので-360~360°に収める
if (Math.abs(qdata.qobject.angle) > Math.PI * 2) qdata.qobject.angle = qdata.qobject.angle % (Math.PI * 2);
qdata.primitive.rotationY = qdata.qobject.angle;
}
}
//カメラ位置更新
_scene.controller.setObjectPos(_cameraDrag.position.add(_lookAtPoint));
_scene.controller.lookAt(_lookAtPoint);
_scene.render();
}
//カメラ位置設定
private function updateCamera():void {
if (_isComplete && !_cameraType) {
_cameraDrag.angle.position = 45;
_cameraDrag.rotation.position = -45;
_cameraDrag.distance.position = 25 * SCALE_ALT3D;
} else {
_cameraDrag.rotation.position = -70;
_cameraDrag.angle.position = 12;
_cameraDrag.distance.position = [27, 50][_cameraType] * SCALE_ALT3D;
}
_cameraDrag.updatePosition();
}
}
}
import alternativ7.engine3d.containers.BSPContainer;
import alternativ7.engine3d.containers.ConflictContainer;
import alternativ7.engine3d.containers.DistanceSortContainer;
import alternativ7.engine3d.containers.KDContainer;
import alternativ7.engine3d.controllers.SimpleObjectController;
import alternativ7.engine3d.core.Camera3D;
import alternativ7.engine3d.core.Geometry;
import alternativ7.engine3d.core.Object3D;
import alternativ7.engine3d.core.Object3DContainer;
import alternativ7.engine3d.core.Sorting;
import alternativ7.engine3d.core.View;
import alternativ7.engine3d.materials.FillMaterial;
import alternativ7.engine3d.materials.TextureMaterial;
import alternativ7.engine3d.objects.Mesh;
import alternativ7.engine3d.primitives.Box;
import alternativ7.engine3d.primitives.Plane;
import Box2D.Collision.Shapes.b2MassData;
import Box2D.Dynamics.b2Body;
import com.actionsnippet.qbox.QuickBox2D;
import com.actionsnippet.qbox.QuickObject;
import flash.display.BitmapData;
import flash.display.InteractiveObject;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Vector3D;
import flash.utils.Dictionary;
/**
* 簡単なサンプル用のAlternativa3Dテンプレート
*/
class Scene3D {
public var display:Sprite = new Sprite();
public var bg:Sprite = new Sprite();
public var root:Object3DContainer;
public var camera:Camera3D;
public var controller:SimpleObjectController;
public var onResizeStage:Function;
private var _bgColor:uint;
private var _stage:Stage;
static public const DISTANCE:String = "distance";
static public const BSP:String = "bsp";
static public const KD:String = "kd";
static public const CONFLICT:String = "conflict";
public function Scene3D(container:String = CONFLICT, width:Number = 465, height:Number = 465, bgColor:uint = 0x000000) {
switch(container) {
case DISTANCE: root = new DistanceSortContainer(); break;
case BSP: root = new BSPContainer(); break;
case KD: root = new KDContainer(); break;
case CONFLICT: root = new ConflictContainer(); break;
default: root = new ConflictContainer();
}
camera = new Camera3D();
camera.view = new View(width, height, true);
camera.fov = 60 * Math.PI / 180;
root.addChild(camera);
display.addChild(bg);
display.addChild(camera.view);
_bgColor = bgColor;
controller = new SimpleObjectController(display, camera, 1);
setSize(width, height);
}
public function render():void {
if (camera.view.stage) camera.render();
}
public function startAutoResize(stage:Stage):void {
_stage = stage;
_stage.scaleMode = StageScaleMode.NO_SCALE;
_stage.align = StageAlign.TOP_LEFT;
_stage.addEventListener(Event.RESIZE, onResize);
onResize(null);
}
private function onResize(e:Event):void {
setSize(_stage.stageWidth, _stage.stageHeight);
if (onResizeStage != null) onResizeStage(_stage.stageWidth, _stage.stageHeight);
}
public function setSize(width:Number, height:Number):void {
camera.view.width = width;
camera.view.height = height;
bg.graphics.clear();
bg.graphics.beginFill(_bgColor, 1);
bg.graphics.drawRect(0, 0, width, height);
bg.graphics.endFill();
}
}
/**
* 円テクスチャを貼ってポリ数を減らした円柱
*/
class ColorCylinder extends Mesh {
public function ColorCylinder(radius:Number = 50, height:Number = 50, segmentsW:int = 8, segmentsH:int = 1, color1:uint = 0x808080, color2:uint = 0x808080, fillAlpha:Number = 1) {
var material:FillMaterial = new FillMaterial(color1, fillAlpha);
var bmd:BitmapData = new BitmapData(100, 100, true, 0);
var sp:Sprite = new Sprite();
sp.graphics.beginFill(color2, fillAlpha);
sp.graphics.drawCircle(50, 50, 50);
sp.graphics.beginFill(0x000000, 0.5 * fillAlpha);
sp.graphics.drawRect(50, 48, 50, 4);
bmd.draw(sp);
var texture:TextureMaterial = new TextureMaterial(bmd, false, false);
var geom:Geometry = new Geometry();
var i:int, px:Number, py:Number;
for (i = 0; i <= segmentsW; i++) {
var rot:Number = (i % segmentsW) / segmentsW * Math.PI * 2;
px = Math.cos(rot) * radius;
py = Math.sin(rot) * radius;
geom.addVertex(px, height / 2, py, 0, 0);
geom.addVertex(px, -height / 2, py, 0, 0);
}
for (i = 0; i < segmentsW * 2; i += 2)
geom.addQuadFace(geom.vertices[i], geom.vertices[i+2], geom.vertices[i+3], geom.vertices[i+1], material);
var h:Number = height / 2;
for (var n:int = i + 2; n <= i + 6; n += 4) {
geom.addVertex( -radius, h, -radius, 0, 0);
geom.addVertex(radius, h, -radius, 1, 0);
geom.addVertex(radius, h, radius, 1, 1);
geom.addVertex( -radius, h, radius, 0, 1);
if (h < 0) geom.addQuadFace(geom.vertices[n], geom.vertices[n + 1], geom.vertices[n + 2], geom.vertices[n + 3], texture);
else geom.addQuadFace(geom.vertices[n], geom.vertices[n + 3], geom.vertices[n + 2], geom.vertices[n + 1], texture);
h *= -1;
}
this.geometry = geom;
}
}
/**
* シーンデータ
*/
class BoxSceneData {
public var trackingList:Vector.<QboxData> = new Vector.<QboxData>();
public var jointList:Vector.<QboxData> = new Vector.<QboxData>();
public var bodyList:Vector.<QboxData> = new Vector.<QboxData>();
public var groupList:Vector.<QboxData> = new Vector.<QboxData>();
public var group:Object = {};
public var body:Object = {};
public var root:Object = {};
public function BoxSceneData() {
}
public function destroy():void {
var item:QboxData;
for each (item in bodyList) item.destroy();
for each (item in groupList) item.destroy();
for each (item in jointList) item.destroy();
trackingList.length = jointList.length = bodyList.length = groupList.length = 0;
group = { };
body = { };
root = { };
}
public function getTrackingPoint():Point {
var p:Point = new Point(), add:Point = new Point(), qdata:QboxData, rp:Point;
for each(qdata in trackingList) {
add.x = add.y = 0;
if (qdata.inGroup) {
rp = PointUtil.rotatePoint(qdata.qobject.x, qdata.qobject.y, qdata.parentGroup.qobject.angle);
add.x = qdata.parentGroup.qobject.x + rp.x;
add.y = qdata.parentGroup.qobject.y + rp.y;
} else {
add.x = qdata.qobject.x;
add.y = qdata.qobject.y;
}
if (isNaN(add.x) || isNaN(add.y)) {
trackingList.splice(trackingList.indexOf(qdata), 1);
} else {
p.x += add.x;
p.y += add.y;
}
}
if (trackingList.length) {
p.x /= trackingList.length;
p.y /= trackingList.length;
} else p.x = p.y = 0;
return p;
}
}
class QboxData {
public var tag:String = "";
public var qobject:QuickObject;
public var parentGroup:QboxData;
public var primitive:Object3D;
public var inGroup:Boolean = false;
public function QboxData() {
}
public function destroy():void {
if (primitive && primitive.parent) primitive.parent.removeChild(primitive);
parentGroup = null;
primitive = null;
qobject = null;
}
}
class QboxModeler {
static private var _objectsGID:Object;
static private var _objectsID:Object;
static private var _primitives:Array;
/**
* XMLからQuickBoxシーンとAlt3Dメッシュモデルを生成
*/
static public function createByXML(sim:QuickBox2D, xml:XML, boxScale:Number = 1, altScale:Number = 20):BoxSceneData {
var layerDepth:Number = 30;
var scene:BoxSceneData = new BoxSceneData();
var S:Number = boxScale;
var joints:Array = [];
var groups:Array = [];
var node:Object;
var primitiveOffset:Dictionary = new Dictionary();
_primitives = [];
_objectsGID = { };
_objectsID = { };
//オブジェクトの種類別にリストに格納
for each(var item:XML in xml.children()) {
node = { density:2, fricyion:0.5, restitution:0.5, strength:0.25, damping:0.1, density:2, motorSpeed:15, reverse:false, motorTorque:100 };
for each(var atr:XML in item.attributes()) node[String(atr.name())] = XMLtoVALUE(atr.toString());
if(item.name() == "primitive") _primitives.push(node);
if(item.name() == "joint") joints.push(node);
if(item.name() == "list") groups.push(node);
}
_primitives.sortOn("z", Array.NUMERIC);
//背景固定用ダミーオブジェクト
var bgData:QboxData = new QboxData();
bgData.qobject = sim.addCircle( { x:0, y:0, radius:0.1, density:0, maskBits:0, categoryBits:0, skin:"none" } );
primitiveOffset[bgData] = new Point();
var fixList:Object = new Object();
var qdata:QboxData;
var qbox:QuickObject;
//剛体
for each(node in _primitives) {
var unitOffset:Point = new Point();
if (node.maskbits == null) node.maskbits = 1;
//衝突判定のレイヤーからポリゴンの厚みを決める
var min:int = 6;
var max:int = 0;
for (var i:int = 0; i < 7; i++) {
if (node.maskbits >> i & 1) {
if (i > max) max = i;
if (i < min) min = i;
}
}
if (min > max) min = max = 0;
var depth:int = (max - min + 1) * layerDepth;
var offsetY:Number = 0;
//衝突判定無効
if (node.nocollision) node.maskbits = 0;
//Box2Dオブジェクト生成時に渡すパラメータ
var param:Object = {
skin: "none",
lineAlpha: int(node.border),
fillColor: node.color,
fillAlpha: node.alpha,
x: node.position[0] * S,
y: -node.position[1] * S,
angle: -node.angle,
friction: node.friction,
restitution: node.restitution,
maskBits:node.maskbits,
categoryBits:node.maskbits,
density: node.density,
isBullet: false
}
var mesh:Mesh;
var map0:FillMaterial = new FillMaterial(param.fillColor, node.alpha);
var map1:FillMaterial = new FillMaterial(Palette.mix(param.fillColor, 0xFFFFFF, 0.2), node.alpha);
var map2:FillMaterial = new FillMaterial(Palette.mix(param.fillColor, 0xFFFFFF, 0.1), node.alpha);
//地面・壁
if (node.type == "wall") {
var unitPos:Point = new Point(node.position[0] * S, -node.position[1] * S);
var adjust:Point = adjustPlanePos(unitPos.x, unitPos.y, node.angle + Math.PI / 2).subtract(unitPos);
var wallSize:Number = 30;
var heightOffset:Point = new Point(Math.cos(node.angle) * -wallSize / 2 * S, Math.sin(node.angle) * wallSize / 2 * S);
unitOffset = heightOffset.add(adjust);
param.x = unitPos.x + unitOffset.x,
param.y = unitPos.y + unitOffset.y,
param.width = wallSize * S;
param.height = 300 * S;
param.density = 0;
qbox = sim.addBox(param);
mesh = new Plane(param.height * altScale, depth, 1, 1, true, false, false, null, map0);
mesh.x = (param.x - heightOffset.x) * altScale;
mesh.z = -(param.y - heightOffset.y) * altScale;
mesh.y = min * layerDepth + depth/2 + offsetY;
mesh.rotationY = param.angle + Math.PI / 2;
}
//ボックス
if (node.type == "box") {
param.width = node.size[0] * S;
param.height = node.size[1] * S;
qbox = sim.addBox(param);
if (node.plane) {
mesh = new Plane(param.width * altScale, param.height * altScale, 1, 1, true, false, false, map1, map1);
mesh.rotationX = Math.PI / 2;
offsetY = layerDepth / 2;
} else {
mesh = new Box(param.width * altScale, depth, param.height * altScale, 1, 1, 1, false, false, map0, map0, map1, map1, map2, map2);
}
}
//円
if (node.type == "circle") {
param.radius = node.radius * S;
qbox = sim.addCircle(param);
var seg:int = (param.radius>3)? 16 : (param.radius>0.3)? 8 : 4;
mesh = new ColorCylinder(param.radius * altScale, depth, seg, 1, param.fillColor, Palette.mix(param.fillColor, 0xFFFFFF, 0.3), param.fillAlpha);
}
if (node.type != "wall") {
mesh.x = param.x * altScale;
mesh.z = -param.y * altScale;
mesh.y = min * layerDepth + depth/2 + offsetY;
mesh.rotationY = param.angle;
}
mesh.visible = node.visible !== false && param.fillAlpha;
mesh.sorting = (node.type == "wall" || node.sort == "bsp")? Sorting.DYNAMIC_BSP : Sorting.AVERAGE_Z;
if (node.scalez != null) mesh.scaleY *= node.scalez;
qdata = new QboxData();
qdata.tag = node.tag;
qdata.primitive = mesh;
qdata.qobject = qbox;
primitiveOffset[qdata] = unitOffset;
scene.bodyList.push(qdata);
if(node.group != null) _objectsGID[node.group] = qdata;
if(node.id != null) _objectsID[node.id] = qdata;
//タグがついていたら
if (node.tag != null) {
scene.body[node.tag] = qdata;
scene.root[node.tag] = qdata;
}
if (node.fix != null) {
if (fixList["_" + node.fix] == null) fixList["_" + node.fix] = [qdata];
else fixList["_" + node.fix].push(qdata);
}
}
//グループ
for (var k:String in fixList) {
if (k == "_0") {
//背景に固定
for each(var qdt:QboxData in fixList[k]) qdt.qobject.body.SetMass(new b2MassData());
} else {
//グループ化
var qd:QboxData;
var xy:Point = new Point();
for each(qd in fixList[k]) xy.offset(qd.qobject.x, qd.qobject.y);
var center:Point = new Point(xy.x / fixList[k].length, xy.y / fixList[k].length);
for each(qd in fixList[k]) qd.qobject.setLoc(qd.qobject.x - center.x, qd.qobject.y - center.y);
var objects:Array = [];
for each(qd in fixList[k]) objects.push(qd.qobject);
var container3d:Object3DContainer = new Object3DContainer();
qdata = new QboxData();
qdata.qobject = sim.addGroup( { objects:objects, x:center.x, y:center.y, skin:"none" } );
qdata.primitive = container3d;
for each(qd in fixList[k]) {
qd.inGroup = true;
qd.parentGroup = qdata;
qd.primitive.x = qd.qobject.x * altScale;
qd.primitive.z = -qd.qobject.y * altScale;
container3d.addChild(qd.primitive);
//グループ内のオブジェクトにタグがついていたら
if (qd.tag != null) {
scene.group[qd.tag] = qdata;
scene.root[qd.tag] = qdata;
}
}
scene.groupList.push(qdata);
}
}
//カメラ追跡オブジェクトがあれば配列に保存
for each(node in groups) {
if (node.name == "tracked") {
for each(var id:Number in node.groups) {
if (_objectsGID[id]) scene.trackingList.push(_objectsGID[id]);
}
}
}
//ヒンジ・バネ
for each(node in joints) {
var prim0:QboxData = (!node.target0)? bgData : _objectsID[node.target0];
var prim1:QboxData = (!node.target1)? bgData : _objectsID[node.target1];
if (!prim0 || !prim1 || (!node.target0 && !node.target1) || (prim0.qobject.body.IsStatic() && prim1.qobject.body.IsStatic())) continue;
var pos0:Point = new Point(prim0.qobject.x, prim0.qobject.y).add(PointUtil.rotatePoint(node.offset0[0] * S, -node.offset0[1] * S, prim0.qobject.angle)).subtract(primitiveOffset[prim0]);
var pos1:Point = new Point(prim1.qobject.x, prim1.qobject.y).add(PointUtil.rotatePoint(node.offset1[0] * S, -node.offset1[1] * S, prim1.qobject.angle)).subtract(primitiveOffset[prim1]);
if (prim0.inGroup) pos0.offset(prim0.parentGroup.qobject.x, prim0.parentGroup.qobject.y);
if (prim1.inGroup) pos1.offset(prim1.parentGroup.qobject.x, prim1.parentGroup.qobject.y);
var pos:Point = Point.interpolate(pos0, pos1, 0.5);
var body0:b2Body = (prim0.inGroup)? prim0.parentGroup.qobject.body : prim0.qobject.body;
var body1:b2Body = (prim1.inGroup)? prim1.parentGroup.qobject.body : prim1.qobject.body;
//バネ
if (node.type == "spring")
qbox = sim.addJoint({
type: "distance",
lineAlpha: 1,
a: body0,
b: body1,
x1: pos0.x,
y1: pos0.y,
x2: pos1.x,
y2: pos1.y,
length: node.length * S,
collideConnected: true,
dampingRatio: node.damping,
frequencyHz: node.strength * 100
});
//ヒンジ
if (node.type == "hinge")
qbox = sim.addJoint( {
type: "revolute",
lineAlpha: 0,
enableMotor: node.motor,
maxMotorTorque: node.motorTorque,
motorSpeed: node.motorSpeed * (int(node.reverse)*2 - 1),
collideConnected: false,
a: body0,
b: body1,
x1: pos.x,
y1: pos.y
});
qdata = new QboxData();
qdata.qobject = qbox;
scene.jointList.push(qdata);
}
_primitives = null;
_objectsGID = null;
_objectsID = null;
return scene;
}
static private function XMLtoVALUE(data:String):* {
if (data == "true" || data == "false") return (data == "true");
if (data.substr(0, 1) == "[" && data.substr( -1) == "]") {
var values:Array = data.substr(1, data.length - 2).split(",");
for (var i:int = 0; i < values.length; i++) values[i] = Number(values[i]);
return values;
}
if (isNaN(Number(data))) return String(data);
return Number(data);
}
static private function adjustPlanePos(x:Number, y:Number, angle:Number):Point {
return PointUtil.crossVertical(new Point(x, y), new Point(x + Math.cos(angle) * 100, y - Math.sin(angle) * 100), new Point(0, 0));
}
}
class Palette {
/**
* 色を混ぜる
*/
static public function mix(rgb1:uint, rgb2:uint, per:Number = 1):Number {
var per2:Number = (1 - per);
var r:uint = (rgb1 >> 16 & 0xFF) * per2 + (rgb2 >> 16 & 0xFF) * per;
var g:uint = (rgb1 >> 8 & 0xFF) * per2 + (rgb2 >> 8 & 0xFF) * per;
var b:uint = (rgb1 & 0xFF) * per2 + (rgb2 & 0xFF) * per;
return r << 16 | g << 8 | b;
}
}
class PointUtil {
/**
* 2点を通る直線とある点からおろした垂線との交点を求める
*/
static public function crossVertical(p1:Point, p2:Point, p3:Point):Point {
var x1:Number = p1.x, y1:Number = p1.y;
var x2:Number = p2.x, y2:Number = p2.y;
var x3:Number = p3.x, y3:Number = p3.y;
var xgap:Number = x1 - x2, ygap:Number = y1 - y2;
if (ygap == 0) return new Point(p3.x, p1.y);
var a1:Number = -xgap / ygap;
var c1:Number = xgap * x3 / ygap + y3;
var a2:Number = -ygap;
var b2:Number = xgap;
var c2:Number = -x1 * a2 + y1 * -b2;
var z:Number = a1 * b2 + a2;
return new Point(( -c2 - b2 * c1) / z, (a2 * c1 - a1 * c2) / z);
}
static public function rotatePoint(x:Number, y:Number, rad:Number):Point {
var px:Number = x * Math.cos(rad) - y * Math.sin(rad);
var py:Number = x * Math.sin(rad) + y * Math.cos(rad);
return new Point(px, py);
}
}
/**
* シーンをマウスでぐるぐる(Alternativa3D軸)
*/
class SphericalDragger extends EventDispatcher {
/**カメラの距離*/
public var distance:Range = new Range();
/**横方向の回転*/
public var rotation:Range = new Range();
/**縦方向の回転*/
public var angle:Range = new Range();
/**ドラッグが可能か*/
public var dragEnabled:Boolean = true;
/**ホイールズームが可能か*/
public var wheelEnabled:Boolean = true;
private var _eventObject:InteractiveObject;
private var _clickPoint:Point;
private var _position:Vector3D = new Vector3D();
private const RADIAN:Number = Math.PI / 180;
/**座標が変わると呼ばれる*/
public var onMovePosition:Function;
/**球面座標*/
public function get position():Vector3D { return _position; }
/**
* @param obj マウスイベントを登録する場所
* @param rotation 初期の横方向角度
* @param angle 初期の縦方向角度
* @param distance 初期の中心点からの距離
*/
public function SphericalDragger(obj:InteractiveObject, rotation:Number = 0, angle:Number = 30, distance:Number = 1000) {
this.distance.position = distance;
this.distance.speed = 1.2;
this.angle.position = angle;
this.angle.min = -(this.angle.max = 89);
this.rotation.position = rotation;
_eventObject = obj;
_eventObject.addEventListener(MouseEvent.MOUSE_DOWN, onMsDown);
_eventObject.addEventListener(MouseEvent.MOUSE_WHEEL, onMsWheel);
updatePosition();
}
public function notify():void {
dispatchEvent(new Event(Event.CHANGE));
if (onMovePosition != null) onMovePosition(_position);
}
private function onMsWheel(e:MouseEvent):void {
if (!dragEnabled || !wheelEnabled) return;
distance.position *= Math.pow(distance.speed, (e.delta < 0)? 1 : -1);
distance.checkLimit();
updatePosition();
}
private function onMsDown(e:MouseEvent):void {
if (!dragEnabled) return;
_eventObject.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMsMove);
_eventObject.stage.addEventListener(MouseEvent.MOUSE_UP, onMsUp);
rotation.save = rotation.position;
angle.save = angle.position;
_clickPoint = new Point(_eventObject.mouseX, _eventObject.mouseY);
}
private function onMsMove(e:MouseEvent):void {
if (!dragEnabled) return;
var dragOffset:Point = new Point(_eventObject.mouseX, _eventObject.mouseY).subtract(_clickPoint);
rotation.position = rotation.save - dragOffset.x * rotation.speed;
rotation.checkLimit();
angle.position = angle.save + dragOffset.y * angle.speed;
angle.checkLimit();
updatePosition();
}
private function onMsUp(...rest):void {
_eventObject.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMsMove);
_eventObject.stage.removeEventListener(MouseEvent.MOUSE_UP, onMsUp);
updatePosition();
}
public function updatePosition():void {
var per:Number = Math.cos(RADIAN * angle.position);
var px:Number = Math.cos(RADIAN * rotation.position) * distance.position * per;
var py:Number = Math.sin(RADIAN * rotation.position) * distance.position * per;
var pz:Number = Math.sin(RADIAN * angle.position) * distance.position;
_position = new Vector3D(px, py, pz);
notify();
}
}
class Range {
public var min:Number = NaN;
public var max:Number = NaN;
public var save:Number = NaN;
public var speed:Number = 1;
public var position:Number = 0;
public function Range() {
}
public function checkLimit():void {
if (!isNaN(min) && position < min) position = min;
else if (!isNaN(max) && position > max) position = max;
}
}
/**
* Box2Dで生成するオブジェクトをまとめたXML
*/
class Box2DXML {
static public var data:XML = <box2d>
<primitive type="circle" position="[-0.0963,9.9165]" id="276" radius="5.3" group="466" alpha="0.76" color="4545841" border="true" fix="373" z="0" angle="-0.6346" maskbits="8"/>
<primitive type="circle" fix="375" position="[15.7505,-5.0704]" id="277" radius="0.8217" group="467" alpha="0.367" color="15825530" border="true" visible="false" z="1" angle="-1.252" maskbits="8"/>
<primitive type="box" size="[0.26,4.3929]" position="[-1.1649,-1.31]" id="278" group="468" alpha="1" color="10172500" border="true" fix="0" z="2" angle="0" maskbits="8"/>
<primitive type="box" size="[14.6,0.25]" position="[5.9277,-4.9381]" id="279" group="469" alpha="1" color="10172500" border="true" fix="0" z="3" angle="-0.1569" maskbits="8"/>
<primitive type="box" size="[24.2878,0.3]" position="[15.8296,0.0894]" id="280" group="470" alpha="1" color="10172500" border="true" fix="0" z="4" angle="0.1373" maskbits="8"/>
<primitive type="box" size="[6.8,0.38]" position="[-5.2535,-3.6529]" id="281" group="471" alpha="1" color="4473924" border="true" fix="380" z="5" angle="-0.1394" maskbits="4"/>
<primitive type="box" size="[0.35,0.76]" position="[-2.0269,-3.8962]" id="282" group="472" alpha="1" color="4473924" border="true" fix="380" z="6" angle="-0.1529" maskbits="6"/>
<primitive type="box" fix="383" size="[0.43,2.283]" position="[-2.2842,-2.7115]" id="283" group="473" alpha="1" color="11972482" border="true" tag="negibox" z="7" angle="-0.1422" maskbits="4"/>
<primitive type="box" size="[0.35,1.8385]" position="[-3.1889,-0.8164]" id="284" group="474" alpha="1" color="11972482" border="true" z="8" maskbits="4" angle="-0.1714"/>
<primitive type="box" size="[1.145,0.155]" position="[-3.3871,-3.1702]" id="285" group="475" alpha="1" color="2643986" border="true" z="9" maskbits="2" angle="-0.1422"/>
<primitive type="box" size="[1.145,0.155]" position="[-3.2727,-2.7758]" id="286" group="476" alpha="1" color="2643986" border="true" z="10" maskbits="2" angle="-0.1422"/>
<primitive type="box" size="[1.145,0.155]" position="[-3.3139,-2.3576]" id="287" group="477" alpha="1" color="2643986" border="true" z="11" maskbits="2" angle="-0.1422"/>
<primitive type="box" size="[1.145,0.155]" position="[-3.2427,-2.987]" id="288" group="478" alpha="1" color="2643986" border="true" z="12" maskbits="2" angle="-0.1422"/>
<primitive type="box" size="[1.145,0.155]" position="[-3.2365,-2.5578]" id="289" group="479" alpha="1" color="2643986" border="true" z="13" maskbits="2" angle="-0.1422"/>
<primitive type="box" size="[1.145,0.155]" position="[-3.2324,-2.1244]" id="290" group="480" alpha="1" color="2643986" border="true" z="14" maskbits="2" angle="-0.1422"/>
<primitive type="box" size="[2.2129,0.4]" restitution="0" friction="0" position="[-3.0087,-1.6452]" id="291" group="481" alpha="1" color="11972482" border="true" z="15" maskbits="2" angle="-0.1422" fix="383"/>
<primitive type="box" size="[2.1906,0.4]" position="[-3.2933,-3.4984]" id="292" group="482" alpha="1" color="11972482" border="true" fix="383" z="16" angle="-0.1422" maskbits="2"/>
<primitive type="box" fix="0" size="[27.2,0.7]" density="2" position="[9.4438,-2.8586]" id="293" group="483" alpha="1" color="3425350" border="true" sort="bsp" z="17" angle="-0.1431" maskbits="2"/>
<primitive type="box" fix="402" size="[0.33,1.18]" density="2" position="[13.0446,-11.5861]" id="294" group="484" alpha="1" color="8043667" border="true" visible="false" z="18" angle="-0.0796" maskbits="0"/>
<primitive type="box" size="[4.5421,1.15]" position="[-17.1227,-9.3686]" id="295" group="485" alpha="1" color="2708131" border="true" fix="0" z="19" angle="0"/>
<primitive type="box" fix="405" size="[2.3723,0.2777]" density="11" friction="0.72" id="296" position="[-2.6795,7.6345]" group="486" alpha="1" color="9211020" border="true" visible="false" z="20" angle="0.001" maskbits="0"/>
<primitive type="circle" position="[6.8612,-10.59]" id="297" radius="4.85" group="487" alpha="0.76" color="3424598" border="true" fix="407" z="21" angle="-1.5987" maskbits="16"/>
<primitive type="box" size="[2.8663,2.834]" density="1.7" position="[3.7519,9.3024]" id="298" group="488" alpha="1" color="2631720" border="true" z="23" maskbits="4" angle="-0.0039" fix="409"/>
<primitive type="box" fix="0" size="[12.95,0.35]" density="2" restitution="0" friction="0" id="299" position="[-10.1504,-8.4162]" group="489" alpha="1" color="14461952" border="true" sort="bsp" z="25" angle="-0.0771" maskbits="12"/>
<primitive type="box" size="[0.53,1.68]" position="[-13.1707,2.581]" id="300" group="490" alpha="1" color="15119877" border="true" fix="0" z="26" angle="0" maskbits="8"/>
<primitive type="box" size="[0.53,1.68]" position="[-12.3192,2.581]" id="301" group="491" alpha="1" color="15119877" border="true" fix="0" z="27" angle="0" maskbits="8"/>
<primitive type="box" size="[0.31,2.8921]" density="30" restitution="0" friction="0.1" id="302" position="[-12.7504,1.8972]" group="492" alpha="1" color="9211020" border="true" z="28" maskbits="8" angle="-0.0084" fix="414"/>
<primitive type="circle" position="[-12.3978,-3.2088]" id="303" radius="4.6593" group="493" alpha="0.76" color="11442770" border="true" fix="416" z="29" angle="-3.1358" maskbits="2"/>
<primitive type="circle" density="1" restitution="0" friction="0.72" id="304" position="[-3.7529,7.6297]" radius="0.4977" group="494" alpha="1" color="3750201" border="true" z="31" angle="2.2577"/>
<primitive type="circle" density="1" restitution="0" friction="0.72" id="305" position="[-1.6041,7.6318]" radius="0.4913" group="495" alpha="1" color="3750201" border="true" z="33" angle="-1.7267"/>
<primitive type="box" size="[7.745,0.5863]" position="[-6.9349,-9.9872]" id="306" group="496" alpha="1" color="2708131" border="true" fix="0" z="35" angle="-0.3125"/>
<primitive type="box" size="[7.4623,0.5617]" restitution="0" position="[-14.1904,-9.1255]" id="307" group="497" alpha="1" color="2708131" border="true" fix="0" z="37" angle="0.0841"/>
<primitive type="box" size="[0.2469,1.6508]" density="1.5" restitution="0" friction="2" id="308" position="[-3.797,9.0089]" group="498" alpha="1" color="7208961" border="true" z="38" fix="405" angle="0.0009"/>
<primitive type="box" size="[0.2469,2.2188]" density="1.5" restitution="0" friction="2" id="309" position="[-2.6596,8.3083]" group="499" alpha="1" color="7208961" border="true" z="39" fix="405" angle="-1.5699"/>
<primitive type="box" size="[0.2469,1.6508]" density="1.5" restitution="0" friction="2" id="310" position="[-1.5027,9.0148]" group="500" alpha="1" color="7208961" border="true" z="40" fix="405" angle="0.0009"/>
<primitive type="circle" restitution="0" friction="0" id="311" position="[-6.6337,10.7505]" radius="0.226" group="501" alpha="1" color="15007744" border="true" z="41" angle="-1.2859"/>
<primitive type="circle" restitution="0" friction="0" id="312" position="[-5.2222,11.004]" radius="0.226" group="502" alpha="1" color="15007744" border="true" z="42" angle="1.1278"/>
<primitive type="circle" restitution="0" friction="0" id="313" position="[-6.1921,10.1755]" radius="0.226" group="503" alpha="1" color="15007744" border="true" z="43" angle="2.222"/>
<primitive type="circle" restitution="0" friction="0" id="314" position="[-5.9103,10.6635]" radius="0.226" group="504" alpha="1" color="15007744" border="true" z="44" angle="2.222"/>
<primitive type="circle" restitution="0" friction="0" id="315" position="[-5.4722,10.3087]" radius="0.226" group="505" alpha="1" color="15007744" border="true" z="45" angle="2.7912"/>
<primitive type="box" size="[3.15,0.329]" density="20" position="[-14.0407,-0.6192]" id="316" group="506" alpha="1" color="7933197" border="true" fix="416" z="46" angle="-1.0472"/>
<primitive type="box" size="[3.15,0.329]" density="20" position="[-14.678,-1.1691]" id="317" group="507" alpha="1" color="7933197" border="true" fix="416" z="47" angle="-0.513"/>
<primitive type="box" size="[2.9561,0.3087]" density="20" restitution="0" position="[-13.9099,-3.1685]" id="318" group="508" alpha="1" color="7933197" border="true" z="48" fix="416" angle="-2.0128"/>
<primitive type="box" size="[6.2178,0.3165]" density="20" restitution="0" friction="0.07" id="319" position="[-11.7056,-2.564]" group="509" alpha="1" color="7933197" border="true" sort="bsp" z="49" angle="-2.1825" fix="416"/>
<primitive type="box" size="[0.717,0.329]" friction="0" position="[-12.4286,1.6163]" id="320" group="510" alpha="1" color="7933197" border="true" z="50" maskbits="4" angle="1.5766" fix="416"/>
<primitive type="box" size="[1.89,0.8]" position="[-16.1977,2.1711]" id="321" group="511" alpha="1" color="10592673" border="true" fix="0" z="53" angle="0" maskbits="2"/>
<primitive type="box" size="[0.31,0.4254]" density="17" restitution="0" friction="0" id="322" position="[-12.7488,1.3902]" group="512" alpha="1" color="4144959" border="true" z="55" maskbits="4" angle="-0.0084" fix="414"/>
<primitive type="box" size="[0.31,0.4254]" density="25" restitution="0" friction="0" id="323" position="[-12.7342,3.1158]" group="513" alpha="1" color="4144959" border="true" z="56" maskbits="4" angle="-0.0084" fix="414"/>
<primitive type="box" size="[11.0801,0.4806]" restitution="0" position="[-2.3091,-3.3722]" id="324" group="514" alpha="1" color="8163669" border="true" sort="bsp" z="61" angle="0.4628" fix="0"/>
<primitive type="box" size="[5.81,0.35]" density="8" restitution="0" friction="0.1" position="[-14.9212,2.744]" id="325" group="515" alpha="1" color="3554128" border="true" z="63" maskbits="2" angle="-0.0034" fix="446"/>
<primitive type="box" size="[0.28,0.34]" friction="0" position="[-12.7352,2.7334]" id="326" group="516" alpha="1" color="4802889" border="true" fix="446" z="64" angle="-0.0034" maskbits="4"/>
<primitive type="box" size="[1.87,1.04]" position="[-16.193,3.4454]" id="327" group="517" alpha="1" color="10592673" border="true" fix="0" z="66" angle="0" maskbits="2"/>
<primitive type="box" size="[3.6178,0.48]" restitution="0" position="[-15.9171,-8.5827]" id="328" group="518" alpha="1" color="3554128" border="true" fix="450" z="69" angle="0"/>
<primitive type="box" size="[0.45,0.7547]" restitution="0" position="[-14.3066,-8.173]" id="329" group="519" alpha="1" color="3554128" border="true" fix="450" z="70" angle="0"/>
<primitive type="box" size="[0.35,11.62]" position="[-17.9616,-2.9526]" id="330" group="520" alpha="1" color="3554128" border="true" sort="bsp" z="71" angle="0.0071" maskbits="3"/>
<primitive type="box" size="[0.615,0.315]" position="[-14.3715,2.7469]" id="331" group="521" alpha="1" color="4802889" border="true" fix="446" z="74" angle="-0.0096"/>
<primitive type="box" size="[0.38,3.241]" position="[-13.9161,4.5913]" id="332" group="522" alpha="1" color="5578013" border="true" fix="0" z="76" angle="0"/>
<primitive type="box" size="[0.38,6.58]" position="[-14.8106,6.2608]" id="333" group="523" alpha="1" color="5578013" border="true" fix="0" z="77" angle="0"/>
<primitive type="box" size="[0.36,1.6472]" position="[-14.9038,1.709]" id="334" group="524" alpha="1" color="5578013" border="true" fix="0" z="79" angle="0"/>
<primitive type="box" size="[0.36,1.2261]" position="[-13.8686,1.9217]" id="335" group="525" alpha="1" color="5578013" border="true" fix="0" z="80" angle="0"/>
<primitive type="box" size="[8.7,0.4]" position="[-9.8906,7.5216]" id="336" group="526" alpha="1" color="4923681" border="true" fix="0" z="84" angle="0.3524"/>
<primitive type="box" size="[8.318,0.4282]" restitution="0" position="[6.6207,-0.7549]" id="337" group="527" alpha="1" color="8163669" border="true" fix="0" z="86" angle="0"/>
<primitive type="box" size="[0.24,0.652]" density="2" restitution="0.61" friction="0" id="338" position="[-2.6665,8.0441]" group="528" alpha="1" color="3750201" border="true" z="88" maskbits="0" angle="0.001" fix="405"/>
<primitive type="box" size="[6.5401,0.6]" position="[0.1664,-11.4697]" id="339" group="529" alpha="1" color="2708131" border="true" fix="0" z="89" angle="0"/>
<primitive type="box" size="[0.65,0.65]" density="2" position="[-2.6671,5.7684]" id="340" group="530" alpha="1" color="2236962" border="true" fix="373" z="91" angle="1.0075" maskbits="7"/>
<primitive type="box" size="[11.3652,0.75]" position="[0.0216,6.5934]" id="341" group="531" alpha="1" color="9838867" border="true" sort="bsp" z="92" angle="0.001"/>
<primitive type="box" size="[0.5,3.1]" density="0.47" position="[2.4559,9.2961]" id="342" group="532" alpha="1" color="4473924" border="true" fix="409" z="94" angle="-0.0039" maskbits="2"/>
<primitive type="box" size="[0.5,3.1]" friction="1.17" position="[-12.152,19.1797]" id="343" group="533" alpha="1" color="4473924" border="true" z="95" maskbits="2" angle="-0.374" fix="468"/>
<primitive type="box" size="[0.5,3.1]" density="0.47" position="[5.0522,9.2506]" id="344" group="534" alpha="1" color="4473924" border="true" fix="409" z="96" angle="-0.0039" maskbits="2"/>
<primitive type="box" size="[0.5,3.1]" position="[-14.721,20.0947]" id="345" group="535" alpha="1" color="4473924" border="true" fix="468" z="97" angle="-0.374" maskbits="2"/>
<primitive type="box" size="[0.5,3.1]" density="0.47" position="[3.749,7.984]" id="346" group="536" alpha="1" color="4473924" border="true" fix="409" z="98" angle="-1.5747" maskbits="2"/>
<primitive type="box" size="[0.5,3.1]" friction="0" position="[-13.9772,18.4366]" id="347" group="537" alpha="1" color="4473924" border="true" z="99" maskbits="2" angle="1.1968" fix="468"/>
<primitive type="box" size="[8.3744,0.75]" restitution="0" position="[9.9539,5.5115]" id="348" group="538" alpha="1" color="9838867" border="true" fix="0" z="105" angle="0"/>
<primitive type="box" fix="0" size="[12.15,0.45]" density="2" position="[-10.1044,16.4401]" id="349" group="539" alpha="1" color="6268250" border="true" sort="bsp" z="107" angle="-0.3631" maskbits="2"/>
<primitive type="box" size="[7.9716,0.45]" position="[-1.952,12.4879]" id="350" group="540" alpha="1" color="6268250" border="true" fix="0" z="108" angle="0" maskbits="2"/>
<primitive type="box" size="[0.45,6.25]" position="[5.072,13.9639]" id="351" group="541" alpha="1" color="6268250" border="true" fix="0" z="109" angle="0" maskbits="2"/>
<primitive type="box" size="[0.7338,9.8784]" density="2" restitution="0" friction="0.78" id="352" position="[15.5295,0.982]" group="542" alpha="1" color="8163669" border="true" z="111" fix="0" angle="-1.2148"/>
<primitive type="box" size="[4.5561,0.3478]" friction="0" position="[-1.3313,-9.0063]" id="353" group="543" alpha="1" color="14461952" border="true" z="116" maskbits="12" angle="0" fix="0"/>
<primitive type="box" size="[0.3565,3.4795]" restitution="0" friction="1.12" position="[3.3208,-8.5503]" id="354" group="544" alpha="1" color="14461952" border="true" z="118" maskbits="4" angle="0" fix="0"/>
<primitive type="box" size="[0.33,1.61]" restitution="0" friction="0.75" position="[3.3249,-11.1134]" id="355" group="545" alpha="1" color="14461952" border="true" z="121" maskbits="4" angle="0" fix="407"/>
<primitive type="box" size="[1,0.33]" restitution="0" friction="0.75" position="[2.8061,-11.7476]" id="356" group="546" alpha="1" color="14461952" border="true" z="122" maskbits="4" angle="0" fix="407"/>
<primitive type="box" size="[0.31,1.295]" restitution="0" friction="0.75" position="[2.3025,-11.2888]" id="357" group="547" alpha="1" color="14461952" border="true" z="123" maskbits="4" angle="0.3317" fix="407"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-12.9609,18.8392]" id="358" group="548" alpha="1" color="12426770" border="true" z="127" maskbits="2" angle="0"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-13.1939,20.3145]" id="359" group="549" alpha="1" color="12426770" border="true" z="128" maskbits="2" angle="0"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-13.6135,19.0894]" id="360" group="550" alpha="1" color="12426770" border="true" z="129" maskbits="2" angle="0"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-13.8216,20.4897]" id="361" group="551" alpha="1" color="12426770" border="true" z="130" maskbits="2" angle="0"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-12.9476,19.4306]" id="362" group="552" alpha="1" color="12426770" border="true" z="131" maskbits="2" angle="0"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-12.5184,20.0312]" id="363" group="553" alpha="1" color="12426770" border="true" z="132" maskbits="2" angle="0"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-13.7003,19.7183]" id="364" group="554" alpha="1" color="12426770" border="true" z="133" maskbits="2" angle="0"/>
<primitive type="box" size="[0.52,0.52]" density="12.5" restitution="0" friction="0" position="[-14.2956,19.2818]" id="365" group="555" alpha="1" color="12426770" border="true" z="134" maskbits="2" angle="0"/>
<primitive type="box" size="[9.3939,0.6]" density="1.3" restitution="0" friction="0.91" id="366" position="[8.4977,-11.8777]" group="556" alpha="1" color="2708131" border="true" sort="bsp" tag="bar" z="135" angle="-0.0631" fix="402"/>
<primitive type="box" size="[0.3359,1.8824]" density="0.028" restitution="0" friction="2" id="367" position="[13.1219,-10.4034]" group="557" alpha="1" color="2708131" border="true" z="136" fix="402" angle="-0.0631"/>
<primitive type="box" size="[2.27,0.4]" position="[-5.5994,9.6537]" id="368" group="558" alpha="1" color="3835913" border="true" fix="502" z="138" angle="0"/>
<primitive type="box" size="[0.4,1.83]" position="[-4.6589,10.4155]" id="369" group="559" alpha="1" color="3835913" border="true" fix="502" z="139" angle="0"/>
<primitive type="box" size="[0.4,1.83]" position="[-7.2167,10.0069]" id="370" group="560" alpha="1" color="3835913" border="true" fix="502" z="140" angle="1.2063"/>
<primitive type="box" size="[0.55,4.7403]" restitution="0" friction="1.08" id="371" position="[12.8844,-3.3366]" group="561" alpha="1" color="2708131" border="true" tag="barstopper" z="149" angle="0" fix="0"/>
<primitive type="box" fix="0" size="[0.75,3]" friction="0" position="[15.5613,-15.6869]" id="372" group="562" alpha="1" color="16777215" border="true" visible="false" z="151" angle="0.3184" maskbits="3"/>
<primitive type="box" fix="0" size="[4.5949,2.9913]" restitution="0.105" position="[17.8138,-16.351]" id="373" group="563" alpha="1" color="16777215" border="true" visible="false" tag="donburi" z="152" angle="0" maskbits="3"/>
<primitive type="box" fix="0" size="[0.7,2.95]" friction="0" position="[20.0534,-15.6321]" id="374" group="564" alpha="1" color="16777215" border="true" visible="false" z="153" angle="-0.2605" maskbits="3"/>
<primitive type="box" size="[0.62,0.62]" density="3.5" position="[10.3224,-12.7117]" id="375" group="565" alpha="1" color="5657913" border="true" fix="407" z="156" angle="-0.7854" maskbits="15"/>
<primitive type="box" size="[1.035,0.268]" density="7.7" position="[-2.6703,7.6346]" id="376" group="566" alpha="1" color="3881787" border="true" fix="405" z="158" angle="0"/>
<primitive type="box" size="[4.9989,0.86]" restitution="0" friction="1.62" position="[21.3173,3.9498]" id="377" group="567" alpha="1" color="7626831" border="true" z="164" maskbits="9" angle="0" fix="0"/>
<primitive type="box" size="[0.7834,6.3022]" density="5" restitution="0" friction="0.21" id="378" position="[18.9998,7.5746]" group="568" alpha="1" color="7626831" border="true" z="165" maskbits="9" angle="0"/>
<primitive type="circle" position="[-3.079,-0.0904]" id="379" radius="0.61" group="569" alpha="1" color="11972482" border="true" z="169" maskbits="2" angle="-1.5201"/>
<primitive type="box" fix="0" size="[0.4,1.4]" restitution="0.39" position="[22.3835,-6.2472]" id="380" group="570" alpha="1" color="3425350" border="true" tag="negistopper" z="173" angle="-0.1688" maskbits="2"/>
<primitive type="circle" restitution="0" friction="0.13" position="[15.7513,-5.0744]" id="381" radius="0.8" group="571" alpha="1" color="14145495" border="true" z="175" maskbits="0" angle="-1.2864" fix="375"/>
<primitive type="box" size="[0.54,0.2831]" density="2.6" restitution="0" friction="0" id="382" position="[15.1828,-5.0518]" group="572" alpha="1" color="9685242" border="true" visible="false" z="176" angle="1.5708" fix="375"/>
<primitive type="box" size="[0.54,0.2831]" restitution="0" friction="0" id="383" position="[16.3364,-5.0648]" group="573" alpha="1" color="9685242" border="true" visible="false" z="177" angle="1.5708" fix="375"/>
<primitive type="box" size="[0.54,0.2988]" restitution="0" friction="0" id="384" position="[15.7668,-5.635]" group="574" alpha="1" color="9685242" border="true" visible="false" z="178" angle="0" fix="375"/>
<primitive type="circle" density="4" restitution="0" friction="0.1" id="385" position="[15.7494,-5.088]" radius="0.4105" group="575" alpha="1" color="16756224" border="true" scalez="0.5" tag="egg" z="179" angle="-1.332"/>
<primitive type="circle" density="1.8" restitution="0" friction="0.01" id="386" position="[23.6239,5.3185]" radius="0.8933" group="576" alpha="1" color="3480582" border="true" z="181" maskbits="8" angle="-1.3258"/>
<primitive type="box" size="[0.303,5.2]" position="[28.0576,4.5735]" id="387" group="577" alpha="1" color="10172500" border="true" fix="0" z="182" angle="0" maskbits="8"/>
<primitive type="box" size="[0.38,0.38]" position="[-10.4292,-7.0538]" id="388" group="578" alpha="1" color="5574661" border="true" fix="416" z="185" angle="0.4957" maskbits="4"/>
<primitive type="box" size="[3.0136,0.278]" position="[14.6942,-6.087]" id="389" group="579" alpha="1" color="10172500" border="true" fix="0" z="189" angle="0" maskbits="9"/>
<primitive type="box" size="[0.28,1.69]" position="[14.7093,-5.0524]" id="390" group="580" alpha="1" color="12462392" border="true" fix="529" z="192" angle="0"/>
<primitive type="box" size="[0.28,1.69]" position="[14.7128,-5.0524]" id="391" group="581" alpha="1" color="12462392" border="true" fix="529" z="193" angle="0" maskbits="8"/>
<primitive type="box" fix="529" size="[0.28,0.3225]" position="[14.7147,-5.7362]" id="392" group="582" alpha="1" color="12462392" border="true" z="194" nocollision="true" angle="0" maskbits="6"/>
<primitive type="box" size="[0.3,1.25]" restitution="0.28" friction="0.1" id="393" position="[16.2942,-8.3399]" group="583" alpha="1" color="5197647" border="true" fix="0" z="197" angle="0"/>
<primitive type="box" size="[0.3,1.25]" restitution="0.28" friction="0.1" id="394" position="[16.6122,-9.1307]" group="584" alpha="1" color="5197647" border="true" fix="0" z="198" angle="0.6888"/>
<primitive type="box" size="[0.3,1.25]" restitution="0.28" friction="0.1" id="395" position="[18.8346,-8.3399]" group="585" alpha="1" color="5197647" border="true" fix="0" z="199" angle="0"/>
<primitive type="box" size="[0.3,1.25]" restitution="0.28" friction="0.1" id="396" position="[18.4959,-9.1521]" group="586" alpha="1" color="5197647" border="true" fix="0" z="200" angle="-0.7456"/>
<primitive type="box" size="[1.3,0.29]" position="[17.5658,-9.5736]" id="397" group="587" alpha="1" color="5197647" border="true" fix="0" z="203" angle="0" maskbits="0"/>
<primitive type="box" size="[2.3,0.3]" position="[19.878,-7.9031]" id="398" group="588" alpha="1" color="5197647" border="true" fix="0" z="207" angle="0"/>
<primitive type="box" fix="0" size="[0.3,1.25]" restitution="0.28" friction="0.1" position="[16.2873,-8.3342]" id="399" group="589" alpha="0.395" color="15566916" border="true" visible="false" z="218" angle="0" maskbits="8"/>
<primitive type="box" fix="0" size="[0.3,1.25]" restitution="0.28" friction="0.1" position="[16.6052,-9.125]" id="400" group="590" alpha="0.395" color="15566916" border="true" visible="false" z="219" angle="0.6888" maskbits="8"/>
<primitive type="box" fix="0" size="[0.3,1.25]" restitution="0.28" friction="0.1" position="[18.8277,-8.3342]" id="401" group="591" alpha="0.395" color="15566916" border="true" visible="false" z="220" angle="0" maskbits="8"/>
<primitive type="box" fix="0" size="[0.3,1.25]" restitution="0.28" friction="0.1" position="[18.489,-9.1464]" id="402" group="592" alpha="0.395" color="15566916" border="true" visible="false" z="221" angle="-0.7456" maskbits="8"/>
<primitive type="box" fix="0" size="[10.2427,7.3]" position="[17.8254,-21.2535]" id="403" group="593" alpha="1" color="16777215" border="true" visible="false" z="222" angle="0" maskbits="3"/>
<primitive type="box" fix="407" size="[0.3262,0.3768]" position="[3.3245,-10.4989]" id="404" group="594" alpha="1" color="13542687" border="true" z="224" nocollision="true" angle="0" maskbits="8"/>
<joint type="hinge" target1="0" group="595" offset1="[6.8612,-10.59]" offset0="[0,0]" size="0.7892" z="22" alpha="1" color="16491386" target0="297"/>
<joint type="hinge" target1="0" group="596" offset1="[-0.0964,9.9165]" offset0="[0,0]" size="0.9064" z="24" alpha="1" color="15766441" target0="276"/>
<joint type="hinge" target1="0" group="597" motorTorque="1.79769313486231e+308" offset1="[-12.3978,-3.2088]" offset0="[0,0]" size="0.3765" z="30" motorSpeed="62.8319" alpha="1" color="4848363" target0="303"/>
<joint type="hinge" target1="296" group="598" offset1="[-1.0733,-0.0038]" offset0="[0,0]" size="0.0941" z="32" alpha="1" color="5633677" target0="304"/>
<joint type="hinge" target1="296" group="599" offset1="[1.0756,-0.0038]" offset0="[0,0]" size="0.0941" z="34" alpha="1" color="5633677" target0="305"/>
<joint type="hinge" target1="0" group="612" offset1="[-17.9895,-1.5295]" offset0="[-0.0179,1.4233]" size="0.7921" z="72" alpha="1" color="4847461" target0="330"/>
<joint type="hinge" target1="0" group="622" offset1="[5.2503,6.6034]" offset0="[5.2288,0.0049]" size="0.598" z="93" alpha="1" color="14718373" target0="341"/>
<joint type="hinge" target1="276" group="627" offset1="[2.7266,2.7824]" offset0="[-0.0078,1.2384]" size="0.3435" z="104" alpha="1" color="10421254" target0="298"/>
<joint type="hinge" target1="0" group="643" offset1="[-6.6817,9.4929]" offset0="[-1.0824,-0.1609]" size="0.1603" z="143" alpha="1" color="1373807" target0="368"/>
<joint type="hinge" target1="0" group="648" offset1="[12.0719,-12.11]" offset0="[3.5817,-0.0064]" size="0.3672" z="148" alpha="1" color="5056852" target0="366"/>
<joint type="hinge" target1="284" group="661" offset1="[-0.0156,0.7342]" offset0="[0,0]" size="0.1013" z="170" alpha="1" color="10027843" target0="379"/>
<joint type="hinge" target1="291" group="663" offset1="[-0.3026,0.0095]" offset0="[0.0163,-0.7852]" size="0.1535" z="172" alpha="1" color="16163646" target0="284"/>
<joint type="hinge" target1="0" group="669" offset1="[-4.7984,-3.6597]" offset0="[0.4516,0.0565]" size="0.5346" z="187" alpha="1" color="1582482" target0="281"/>
<joint type="hinge" target1="0" group="674" offset1="[14.7077,-4.3398]" offset0="[-0.0016,0.7126]" size="0.307" z="196" alpha="1" color="12186424" target0="390"/>
<list type="list" groups="[499]" name="tracked"/>
</box2d>;
}