|
From: <ma...@us...> - 2011-12-18 13:27:46
|
Revision: 588
http://openautomation.svn.sourceforge.net/openautomation/?rev=588&view=rev
Author: mayerch
Date: 2011-12-18 13:27:38 +0000 (Sun, 18 Dec 2011)
Log Message:
-----------
Clean up structure by moving source to src
Modified Paths:
--------------
JSFloorPlan/trunk/index.html
Added Paths:
-----------
JSFloorPlan/trunk/src/jsfloorplan.js
JSFloorPlan/trunk/src/jsfloorplan_example_helper.js
Removed Paths:
-------------
JSFloorPlan/trunk/jsfloorplan.js
JSFloorPlan/trunk/jsfloorplan_example_helper.js
Modified: JSFloorPlan/trunk/index.html
===================================================================
--- JSFloorPlan/trunk/index.html 2011-12-18 13:24:06 UTC (rev 587)
+++ JSFloorPlan/trunk/index.html 2011-12-18 13:27:38 UTC (rev 588)
@@ -14,8 +14,8 @@
<script src="lib/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script>
<script src="lib/poly2tri.js" type="text/javascript"></script>
<script src="lib/Three.js" type="text/javascript"></script>
-<script src="jsfloorplan_example_helper.js" type="text/javascript"></script>
-<script src="jsfloorplan.js" type="text/javascript"></script>
+<script src="src/jsfloorplan_example_helper.js" type="text/javascript"></script>
+<script src="src/jsfloorplan.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="css/ui-lightness/jquery-ui-1.8.16.custom.css" />
<link rel="stylesheet" type="text/css" href="demo.css" />
<!-- -->
Deleted: JSFloorPlan/trunk/jsfloorplan.js
===================================================================
--- JSFloorPlan/trunk/jsfloorplan.js 2011-12-18 13:24:06 UTC (rev 587)
+++ JSFloorPlan/trunk/jsfloorplan.js 2011-12-18 13:27:38 UTC (rev 588)
@@ -1,684 +0,0 @@
-/***************************************************************************
- * *
- * JavaScript FloorPlan 3D *
- * *
- * Copyright (C) 2009, 2010 by Christian Mayer *
- * jsfloorplan (at) ChristianMayer.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- * *
- ***************************************************************************/
-
-// setup script here:
-
-// don't change anything below:
-var ELEMENT_NODE = 1;
-
-// calculate the distance between two cartesian 2D points
-function calcLength2D( start, end )
-{
- return Math.sqrt( (end.x-start.x)*(end.x-start.x) +
- (end.y-start.y)*(end.y-start.y) );
-}
-
-// calculate the rotation of a cartesian 2D point around the center
-function rotate2D( angle, point, center )
-{
- var s = Math.sin( angle );
- var c = Math.cos( angle );
- var ret = new Object;
- ret.x = center.x + c * (point.x-center.x) - s * (point.y-center.y);
- ret.y = center.y + s * (point.x-center.x) + c * (point.y-center.y);
- return ret;
-}
-
-// calculate the rotation of a cartesian 2D point around the center
-// but with given sin and cos of the angle
-function rotate2D( s, c, point, center )
-{
- var ret = new Object;
- ret.x = center.x + c * (point.x-center.x) - s * (point.y-center.y);
- ret.y = center.y + s * (point.x-center.x) + c * (point.y-center.y);
- return ret;
-}
-
-// calculate the translation of a cartesian 2D point
-function translate2D( point, translation )
-{
- var ret = new Object;
- ret.x = point.x + translation.x;
- ret.y = point.y + translation.y;
- return ret;
-}
-
-// sort two 2D unit(!) vectors clockwise
-function vecSort( a, b )
-{
- var pseudoangle_a = a.y>=0 ? (1-a.x) : (a.x+3);
- var pseudoangle_b = b.y>=0 ? (1-b.x) : (b.x+3);
- return pseudoangle_a - pseudoangle_b;
-}
-
-function loadFloorplan()
-{
- $.get('floorplan01.xml', parseXMLFloorPlan, 'xml');
-}
-var floor;
-
-// this array will contain all vertices to show in the svg
-var vertices = Array();
-// infos about the building
-var buildingProperties = { floor: [], Object3D: new THREE.Object3D() };
-var imageCenter = new Object;
-
-var noFloorplan = true;
-function parseXMLFloorPlan( xmlDoc )
-{
- noFloorplan = false;
-
- var floorCount = -1;
- var heightOfGround = 0; // the base level of the current floor
-
- // basic check if the document seems right
- // this could be avoided if the XML file would be validated
- // with a DTD
- var building;
- if( 'building' == xmlDoc.documentElement.tagName )
- building = xmlDoc.documentElement;
- else
- return alert( "ERROR: Not a valid floor plan! " +
- "Expected: 'building', found '" + xmlDoc.documentElement.tagName + "'" );
-
- // now we are sure to have a sensible file
- // => iterate over all floors
- for( var i=0; i < building.childNodes.length; i++ )
- {
- floor = building.childNodes[i];
- if (floor.nodeType != ELEMENT_NODE) continue;
-
- if( floor.tagName == 'textures' )
- {
- parseTextures( floor );
- continue;
- }
-
- if( floor.tagName != 'floor' )
- return alert( "ERROR: Not a valid floor plan! " +
- "Expected: 'floor', found '" + floor.tagName + "'" );
-
- floorCount++;
- buildingProperties.floor[floorCount] = {};
-
- var floorName = floor.getAttribute('name');
- buildingProperties.floor[floorCount].name = floorName;
-
- var floorheight = Number( floor.getAttribute('height') );
- buildingProperties.floor[floorCount].height = floorheight;
- buildingProperties.floor[floorCount].heightOfGround = heightOfGround;
-
- var floorWallsStart = floorWalls.length;
-
- // iterate over the content of this floor
- for( var j=0; j < floor.childNodes.length; j++ )
- {
- floorNode = floor.childNodes[j];
- if (floorNode.nodeType != ELEMENT_NODE) continue;
-
- switch( floorNode.tagName )
- {
- case 'nodes':
- parseFloorNodes( floorNode, floorheight );
- break;
-
- case 'walls':
- parseFloorWalls( floorNode );
- break;
-
- case 'rooms':
- parseFloorRooms( floorNode, floorCount );
- break;
- }
- }
-
- // now the content of the floor is stored in easily
- // accessable objects
- // => derive the necessary information
-
- // group all elements on this floor
- var Object3D = new THREE.Object3D();
-
- // add the information to each node to which nodes it's connected to
- for( var j = floorWallsStart; j < floorWalls.length; j++ )
- {
- // note: the ID is shifted by one to avoid an ID of zero
- // as that wouldn't allow me anymore to distinguish
- // start and stop
- floorNodes[ floorWalls[j].start ].neighbour.push( j+1 );
- floorNodes[ floorWalls[j].end ].neighbour.push( -j-1 );
- }
-
- var nodeGroup = new THREE.Object3D(); nodeGroup.name = 'nodeGroup';
- for( var id in floorNodes )
- {
- // calculate the vectors showing to the neighbours
- var vectors = new Array();
- var start = floorNodes[id];
-
- // show them on request as spheres
- var sphere = new THREE.Mesh( new THREE.SphereGeometry(0.1, 4, 4), sphereMaterial);
- sphere.position = new THREE.Vector3( start.x, start.y, heightOfGround );
- nodeGroup.add(sphere);
-
- for( var j=0; j<floorNodes[id].neighbour.length; j++ )
- {
- var vec = new Object;
- vec.id = floorNodes[id].neighbour[j];
- var end;
- if( vec.id < 0 )
- end = floorNodes[ floorWalls[ -vec.id-1 ].start ];
- else
- end = floorNodes[ floorWalls[ vec.id-1 ].end ];
-
- length = calcLength2D( start, end );
- vec.x = (end.x - start.x) / length;
- vec.y = (end.y - start.y) / length;
- vectors.push( vec );
- }
-
- // sort them clockwise
- vectors.sort( vecSort );
-
- // calculate the cutting points of the walls at this node id
- for( var j=0; j<vectors.length; j++ )
- {
- var jj = (j+1) % vectors.length;
- var wj = Math.abs(vectors[j ].id)-1;
- var wjj = Math.abs(vectors[jj].id)-1;
- var dj = floorWalls[wj ].thickness/2;
- var djj = floorWalls[wjj].thickness/2;
- if( floorWalls[wj ].startOffset && vectors[j ].id > 0 )
- dj += floorWalls[wj].startOffset;
- if( floorWalls[wj ].endOffset && vectors[j ].id < 0 )
- dj += floorWalls[wj].endOffset;
- if( floorWalls[wjj].startOffset && vectors[jj].id > 0 )
- djj += -floorWalls[wjj].startOffset;
- if( floorWalls[wjj].endOffset && vectors[jj].id < 0 )
- djj += -floorWalls[wjj].endOffset;
-
- vertex = new Object;
- vertex.x = vectors[j].x*djj + vectors[jj].x*dj;
- vertex.y = vectors[j].y*djj + vectors[jj].y*dj;
- var l = vectors[j].x*vectors[jj].y - vectors[j].y*vectors[jj].x;
- if( Math.abs( l ) < 1e-5 )
- { // the angle between the two vectors is exactly 180°
- // i.e. a straight wall...
- if( Math.abs( dj - djj ) < 1e-5 )
- { // at least the walls have the same thickness...
- vertex.x = start.x - vectors[j].y*dj;
- vertex.y = start.y + vectors[j].x*dj;
- } else {
- alert( "ERROR: A straight wall with different thicknesses " +
- "is currently not supported!" );
- // but we still try our best...
- vertex.x = start.x - vectors[j].y*(dj+djj)/2;
- vertex.y = start.y + vectors[j].x*(dj+djj)/2;
- }
- } else {
- vertex.x = start.x + vertex.x / l;
- vertex.y = start.y + vertex.y / l;
- }
-
- if( vectors[j ].id < 0 )
- floorWalls[wj ].startVertex.push( vertices.length );
- else
- floorWalls[wj ].endVertex.push( vertices.length );
-
- if( 1 == vectors.length )
- {
- var additional = new Object;
- additional.x = 2 * start.x - vertex.x;
- additional.y = 2 * start.y - vertex.y;
- vertices.push( additional );
- }
-
- if( vectors[jj].id < 0 )
- floorWalls[wjj].startVertex.push( vertices.length );
- else
- floorWalls[wjj].endVertex.push( vertices.length );
-
- vertices.push( vertex );
- }
- } // end for( var id in floorNodes )
- Object3D.add( nodeGroup );
-
- // show walls
- var lineGroup = new THREE.Object3D(); lineGroup.name = 'lineGroup';
- var wallGroup = new THREE.Object3D(); wallGroup.name = 'wallGroup';
- for( var j = floorWallsStart; j<floorWalls.length; j++ )
- {
- var vs = floorNodes[ floorWalls[j].start ];
- var ve = floorNodes[ floorWalls[j].end ];
- var lineGeo = new THREE.Geometry();
- lineGeo.vertices.push( new THREE.Vertex( new THREE.Vector3( vs.x, vs.y, heightOfGround ) ) );
- lineGeo.vertices.push( new THREE.Vertex( new THREE.Vector3( ve.x, ve.y, heightOfGround ) ) );
- lineGroup.add( new THREE.Line( lineGeo, lineMaterial ) );
-
- var s1 = vertices[ floorWalls[j].startVertex[0] ];
- var e1 = vertices[ floorWalls[j].endVertex [0] ];
- var s2 = vertices[ floorWalls[j].startVertex[1] ];
- var e2 = vertices[ floorWalls[j].endVertex [1] ];
-
- // check that the start and end points aren't twisted
- var v1 = new Object; v1.x = s1.x-s2.x; v1.y = s1.y-s2.y;
- var v2 = new Object; v2.x = e1.x-s2.x; v2.y = e1.y-s2.y;
- var v3 = new Object; v3.x = e1.x-e2.x; v3.y = e1.y-e2.y;
- if( (v1.x*v2.y - v1.y*v2.x)*(v2.x*v3.y - v2.y*v3.x) > 0 )
- {
- e1 = vertices [ floorWalls[j].endVertex[1] ];
- e2 = vertices [ floorWalls[j].endVertex[0] ];
- }
- var sm = floorNodes[ floorWalls[j].start ];
- var em = floorNodes[ floorWalls[j].end ];
- var sh = floorNodes[ floorWalls[j].start ].z ;
- var eh = floorNodes[ floorWalls[j].end ].z ;
- var wallSideOrder = (s2.x-s1.x)*(e1.y-s1.y) - (s2.y-s1.y)*(e1.x-s1.x);
- var geometry = new THREE.Geometry();
-
- var normal1 = new THREE.Vector3(sm.y-em.y,-sm.x+em.x,0); // fixme? normalize
- var normal2 = new THREE.Vector3(1,0,0);
-
- var sourrounding = [ new poly2tri.Point(0,0), new poly2tri.Point(0,1), new poly2tri.Point(1,1), new poly2tri.Point(1,0) ];
- sourrounding[1].startEndMarker = 'start';
- sourrounding[2].startEndMarker = 'end';
- var holesToAdd = [];
-
- if( floorWalls[j].holes.length )
- {
- var holes = floorWalls[j].holes;
- for( var h = 0; h < holes.length; h++ )
- {
- var wallLength = calcLength2D( sm, em );
- var fLeft = holes[h].distance / wallLength;
- var fRight = (holes[h].distance + holes[h].width) / wallLength;
- if( fLeft <= 0.0 ) fLeft = 0.001; //// FIXME - actually the config file is bad. Leave at least 1mm wall
- if( fRight >= 1.0 ) fRight = 0.999; //// FIXME - actually the config file is bad. Leave at least 1mm wall
- var lintel = (sh - holes[h].lintel) / sh;
- var paparet = holes[h].paparet / sh;
- if( 1 == lintel )
- {
- // not a hole, the sourrounding goes to the groud...
-
- if( paparet == 0 ) continue; // FIXME: Assume paparet != 0 - otherwise it should be two walls...
-
- sourrounding.splice( -2, 0, new poly2tri.Point(fLeft,1), new poly2tri.Point(fLeft,paparet), new poly2tri.Point(fRight,paparet), new poly2tri.Point(fRight,1) );
- continue;
- }
- if( 0 == paparet )
- {
- // not a hole, the sourrounding goes to the groud...
-
- // lintel == 1 can't happen, it's checked in the if clause above
-
- sourrounding.splice( 0, 0, new poly2tri.Point(fRight,0), new poly2tri.Point(fRight,lintel), new poly2tri.Point(fLeft,lintel), new poly2tri.Point(fLeft,0) );
- continue;
- }
-
- holesToAdd.push( [new poly2tri.Point(fLeft,paparet), new poly2tri.Point(fRight,paparet), new poly2tri.Point(fRight,lintel), new poly2tri.Point(fLeft,lintel)] );
- }
- } // if( floorWalls[j].holes.length )
- var swctx = new poly2tri.SweepContext( sourrounding.slice(0) ); // pass a copy of sourrounding
- for( var htA = 0; htA < holesToAdd.length; htA++ )
- swctx.AddHole( holesToAdd[htA] );
-
- // Do the triangulation - FIXME: handle exceptions, don't ignore them...
- try {
- poly2tri.sweep.Triangulate(swctx);
- }catch(err){}
-
- // mark all points to make sure that we don't need to double vertices
- for( var tp = 0; tp < swctx.point_count(); tp++ )
- swctx.GetPoint( tp ).id = tp;
-
- // translate poly2tri triangles to THREE.js faces:
- var p2tF = [];
- $.each(swctx.GetTriangles(), function(idx, val) {
- p2tF.push(new THREE.Face3(val.GetPoint(0).id, val.GetPoint(1).id, val.GetPoint(2).id));
- });
-
- Tvertices = swctx.points_;
- Tfaces = p2tF;
- var wall1vertices = [];
- var wall2vertices = [];
- var sId, eId;
- for( var v = 0; v < Tvertices.length; v++ )
- {
- /* prepare for later...
- // project s1, e1 and s2, e2 onto line sm->em
- var lSquaredInv = 1.0 / ((em.x-sm.x)*(em.x-sm.x) + (em.y-sm.y)*(em.y-sm.y));
- var s1f = 1-((s1.x-sm.x)*(em.x-sm.x) + (s1.y-sm.y)*(em.y-sm.y))*lSquaredInv;
- var e1f = 1-((e1.x-sm.x)*(em.x-sm.x) + (e1.y-sm.y)*(em.y-sm.y))*lSquaredInv;
- var s2f = 1-((s2.x-sm.x)*(em.x-sm.x) + (s2.y-sm.y)*(em.y-sm.y))*lSquaredInv;
- var e2f = 1-((e2.x-sm.x)*(em.x-sm.x) + (e2.y-sm.y)*(em.y-sm.y))*lSquaredInv;
-
- var tv = Tvertices[v];
- var tvx1 = Math.min( 1.0, Math.max( 0.0, (tv.x - s1f) * (e1f - s1f) ) ); // map between s1 and e1
- var tvx2 = Math.min( 1.0, Math.max( 0.0, (tv.x - s2f) * (e2f - s2f) ) ); // map between s2 and e2
- var x1 = s1.x * tvx1 + e1.x * (1 - tvx1);
- var x2 = s2.x * tvx2 + e2.x * (1 - tvx2);
- var y1 = s1.y * tvx1 + e1.y * (1 - tvx1);
- var y2 = s2.y * tvx2 + e2.y * (1 - tvx2);
- console.log( sm, em, s1, e1, tvx1, x1, y1, s2, e2, tvx2, x2, y2 );
- */
- var z = heightOfGround + sh*tv.y;
- if( wallSideOrder > 0 )
- {
- wall1vertices.push(new THREE.Vertex(new THREE.Vector3(x1,y1,z), normal1));
- wall2vertices.push(new THREE.Vertex(new THREE.Vector3(x2,y2,z), normal1));
- } else {
- wall1vertices.push(new THREE.Vertex(new THREE.Vector3(x2,y2,z), normal1));
- wall2vertices.push(new THREE.Vertex(new THREE.Vector3(x1,y1,z), normal1));
- }
- if( 'startEndMarker' in tv )
- {
- if( 'start' == tv.startEndMarker )
- {
- sId = wall1vertices.length - 1;
- } else {
- eId = wall1vertices.length - 1;
- }
- }
- }
- var wall1verticesLength = wall1vertices.length;
- geometry.vertices = wall1vertices.concat( wall2vertices );
- var s1id = sId, s2id = sId + wall1verticesLength, e1id = eId, e2id = eId + wall1verticesLength;
- //geometry.faces = Tfaces;
- for( var f = 0; f < Tfaces.length; f++ )
- {
- var uv_a1 = new THREE.UV( Tvertices[Tfaces[f].a].x, 1-Tvertices[Tfaces[f].a].y );
- var uv_b1 = new THREE.UV( Tvertices[Tfaces[f].b].x, 1-Tvertices[Tfaces[f].b].y );
- var uv_c1 = new THREE.UV( Tvertices[Tfaces[f].c].x, 1-Tvertices[Tfaces[f].c].y );
- var uv_a2 = new THREE.UV( 1-Tvertices[Tfaces[f].c].x, 1-Tvertices[Tfaces[f].c].y );
- var uv_b2 = new THREE.UV( 1-Tvertices[Tfaces[f].b].x, 1-Tvertices[Tfaces[f].b].y );
- var uv_c2 = new THREE.UV( 1-Tvertices[Tfaces[f].a].x, 1-Tvertices[Tfaces[f].a].y );
-
- // wall side 1
- geometry.faces.push( Tfaces[f] );
- geometry.faceVertexUvs[0].push([ uv_a1, uv_b1, uv_c1 ]);
- // wall side 2
- geometry.faces.push(new THREE.Face3(Tfaces[f].c+wall1verticesLength, Tfaces[f].b+wall1verticesLength, Tfaces[f].a+wall1verticesLength ) );
- geometry.faceVertexUvs[0].push([ uv_a2, uv_b2, uv_c2 ]);
- }
- // wall top
- var mId = geometry.vertices.length;
- geometry.vertices.push(new THREE.Vertex(new THREE.Vector3(sm.x,sm.y,heightOfGround )));
- geometry.vertices.push(new THREE.Vertex(new THREE.Vector3(sm.x,sm.y,heightOfGround+sh)));
- geometry.vertices.push(new THREE.Vertex(new THREE.Vector3(em.x,em.y,heightOfGround )));
- geometry.vertices.push(new THREE.Vertex(new THREE.Vector3(em.x,em.y,heightOfGround+eh)));
- geometry.faces.push(new THREE.Face3(s1id, s2id, mId+1) );
- geometry.faces.push(new THREE.Face3(e2id, e1id, mId+3) );
-
- for( var e = 0; e < sourrounding.length; e++ )
- {
- var id1 = sourrounding[e ].id;
- var id2 = sourrounding[(e+1)%sourrounding.length].id;
- geometry.faces.push(new THREE.Face3( id1, id2 , id1 + wall1verticesLength) );
- geometry.faces.push(new THREE.Face3( id2, id2 + wall1verticesLength, id1 + wall1verticesLength) );
- }
-
- // hole sides
- for( var hta = 0; hta < holesToAdd.length; hta++ )
- {
- for( var e = 0; e < holesToAdd[hta].length; e++ )
- {
- var id1 = holesToAdd[hta][e ].id;
- var id2 = holesToAdd[hta][(e+1)%sourrounding.length].id;
- geometry.faces.push(new THREE.Face3( id1, id2 , id1 + wall1verticesLength) );
- geometry.faces.push(new THREE.Face3( id2, id2 + wall1verticesLength, id1 + wall1verticesLength) );
- }
- }
-
- geometry.computeFaceNormals();
- var mesh = new THREE.Mesh(geometry, cubeMaterial);
- mesh.castShadow = true;
- mesh.receiveShadow = true;
- wallGroup.add(mesh);
- } // end for( j=0; j<floorWalls.length; j++ )
- Object3D.add( lineGroup );
- Object3D.add( wallGroup );
-
- buildingProperties.floor[floorCount].Object3D = Object3D;
- buildingProperties.floor[floorCount].nodeGroup = nodeGroup;
- buildingProperties.floor[floorCount].lineGroup = lineGroup;
- buildingProperties.floor[floorCount].wallGroup = wallGroup;
- buildingProperties.Object3D.add( Object3D ); // add / link; note: we use that JavaScript is not copying objects but uses ref counting on them here!
-
- heightOfGround += floorheight;
- } // end floor
-
- buildingProperties.x_center = (buildingProperties.x_max - buildingProperties.x_min) / 2;
- buildingProperties.y_center = (buildingProperties.y_max - buildingProperties.y_min) / 2;
- imageCenter.x = buildingProperties.x_center;
- imageCenter.y = buildingProperties.y_center;
- imageCenter.z = buildingProperties.z_max / 2;
-
- show3D( 35*Math.PI/180, 30*Math.PI/180 );
-}
-
-var floorNodes = new Object();
-function parseFloorNodes( nodes, floorheight )
-{
- for( var i=0; i < nodes.childNodes.length; i++ )
- {
- node = nodes.childNodes[i];
- if (node.nodeType != ELEMENT_NODE) continue;
-
- var id = node.getAttribute('id');
- var point = new Object;
- point.x = Number( node.getAttribute('x') );
- point.y = Number( node.getAttribute('y') );
- point.z = Number( node.hasAttribute('z') ? node.getAttribute('z') : floorheight );
- point.neighbour = new Array;
-
- floorNodes[id] = point;
-
- if( undefined == buildingProperties.x_min )
- {
- buildingProperties.x_min = point.x;
- buildingProperties.x_max = point.x;
- buildingProperties.y_min = point.y;
- buildingProperties.y_max = point.y;
- buildingProperties.z_min = point.z;
- buildingProperties.z_max = point.z;
- } else {
- if( buildingProperties.x_min > point.x ) buildingProperties.x_min = point.x;
- if( buildingProperties.x_max < point.x ) buildingProperties.x_max = point.x;
- if( buildingProperties.y_min > point.y ) buildingProperties.y_min = point.y;
- if( buildingProperties.y_max < point.y ) buildingProperties.y_max = point.y;
- if( buildingProperties.z_min > point.z ) buildingProperties.z_min = point.z;
- if( buildingProperties.z_max < point.z ) buildingProperties.z_max = point.z;
- }
- }
-}
-
-var floorWalls = new Array();
-function parseFloorWalls( nodes )
-{
- for( var i=0; i < nodes.childNodes.length; i++ )
- {
- node = nodes.childNodes[i];
- if (node.nodeType != ELEMENT_NODE) continue;
-
- var wall = new Object;
- wall.start = node.getAttribute('start' );
- wall.startVertex = new Array;
- wall.startOffset = Number( node.getAttribute('startoffset') );
- wall.end = node.getAttribute('end' );
- wall.endVertex = new Array;
- wall.endOffset = Number( node.getAttribute('endoffset' ) );
- wall.thickness = Number( node.getAttribute('thickness' ) );
- wall.texture = node.getAttribute('texture' );
- if( !wall.texture ) wall.texture = 0;
-
- wall.holes = new Array;
- for( var j=0; j < node.childNodes.length; j++ )
- {
- var hole = node.childNodes[j];
- if (hole.nodeType != ELEMENT_NODE) continue;
-
- var thishole = new Object;
- thishole.id = hole.getAttribute('id');
- thishole.distance = Number( hole.getAttribute('distance') );
- thishole.width = Number( hole.getAttribute('width' ) );
- thishole.paparet = Number( hole.getAttribute('paparet' ) );
- thishole.lintel = Number( hole.getAttribute('lintel' ) );
- wall.holes.push( thishole );
- }
-
- floorWalls[floorWalls.length] = wall;
- }
-}
-
-var rooms = new Array;
-function parseFloorRooms( nodes, floor )
-{
- rooms[floor] = new Array;
- for( var i=0; i < nodes.childNodes.length; i++ )
- {
- var node = nodes.childNodes[i];
- if (node.nodeType != ELEMENT_NODE) continue;
-
- var room = new Object;
- room.name = node.getAttribute('name');
- room.zones = new Array;
-
- for( var j=0; j < node.childNodes.length; j++ )
- {
- var zone = node.childNodes[j];
- if (zone.nodeType != ELEMENT_NODE) continue;
-
- var thiszone = new Object;
- thiszone.onclick = zone.getAttribute('onclick');
- thiszone.name = zone.getAttribute('name' );
- thiszone.corners = new Array;
-
- for( var k=0; k < zone.childNodes.length; k++ )
- {
- var corner = zone.childNodes[k];
- if (corner.nodeType != ELEMENT_NODE) continue;
- thiszone.corners.push( corner.getAttribute('nodeid') );
- }
- room.zones.push( thiszone );
- }
- rooms[floor].push( room );
- }
-}
-
-//var textures = new Object();
-function parseTextures( nodes )
-{
- return;
- for( var i=0; i < nodes.childNodes.length; i++ )
- {
- node = nodes.childNodes[i];
- if (node.nodeType != ELEMENT_NODE) continue;
- }
-}
-
-var noSetup = true;
-function setup3D()
-{
- if( noFloorplan ) return;
- noSetup = false;
-
- scene.add( buildingProperties.Object3D );
-
- var showFloor = showStates.showFloor;
-
- ///////////
- scene.add(sunLight);
- //scene.add(pointLight);
- scene.add(ambientLight);
- //scene.add( camera );
- var $container = $('#top_level');
- // attach the render-supplied DOM element
- $container.append(renderer.domElement);
-
- // Init after the scene was set up
- selectChange( 'showNodes' );
- selectChange( 'showWallLines' );
- selectChange( 'showFloor' );
-}
-
-function show3D( rotation, tilt )
-{
- if( noSetup ) setup3D();
-
- // set up camera
- var cx = -Math.cos(rotation) * Math.cos(tilt);
- var cy = Math.sin(rotation) * Math.cos(tilt);
- var cz = Math.sin(tilt);
- var heightOfGround = buildingProperties.floor[ showStates.showFloor ].heightOfGround;
- var target = new THREE.Vector3( buildingProperties.x_center, buildingProperties.y_center, heightOfGround);
- camera.up = new THREE.Vector3( Math.cos(rotation) * Math.sin(tilt), -Math.sin(rotation) * Math.sin(tilt), Math.cos(tilt) );
- camera.position = new THREE.Vector3( cx*dist + buildingProperties.x_center, cy*dist + buildingProperties.y_center, dist * cz + heightOfGround);
- camera.lookAt( target );
- pointLight.position = camera.position;
-
- // set up sun
- var sx = -Math.cos(lightDirection) * Math.cos(lightHeight);
- var sy = Math.sin(lightDirection) * Math.cos(lightHeight);
- var sz = Math.sin(lightHeight);
- sunLight.target.position = target;
- sunLight.position = new THREE.Vector3( sx * lightDistance, sy * lightDistance, sz * lightDistance );
- sunLight.intensity = lightStrength / 100.0;
- sunLightViewLine.geometry.vertices[0].position = sunLight.position;
- sunLightViewLine.geometry.vertices[1].position = sunLight.target.position;
- sunLightViewLine.geometry.__dirtyVertices = true;
-
- if( showStates.showLightView )
- {
- camera.position = sunLight.position;
- camera.lookAt( sunLight.target.position );
- }
-
- // update opacity
- cubeMaterial.opacity = showStates.fillOpacity;
-
- // update color
- switch( showStates.fillColor )
- {
- case 'black':
- cubeMaterial.color.setRGB( 0.1, 0.1, 0.1 );
- break;
- case 'grey':
- cubeMaterial.color.setRGB( 0.5, 0.5, 0.5 );
- break;
- case 'white':
- cubeMaterial.color.setRGB( 1.0, 1.0, 1.0 );
- break;
- case 'blue':
- cubeMaterial.color.setRGB( 0.0, 0.0, 0.8 );
- break;
- case 'red':
- cubeMaterial.color.setRGB( 0.8, 0.0, 0.0 );
- break;
- case 'green':
- cubeMaterial.color.setRGB( 0.0, 0.8, 0.0 );
- break;
- };
-
- render();
-}
\ No newline at end of file
Deleted: JSFloorPlan/trunk/jsfloorplan_example_helper.js
===================================================================
--- JSFloorPlan/trunk/jsfloorplan_example_helper.js 2011-12-18 13:24:06 UTC (rev 587)
+++ JSFloorPlan/trunk/jsfloorplan_example_helper.js 2011-12-18 13:27:38 UTC (rev 588)
@@ -1,510 +0,0 @@
-/***************************************************************************
- * *
- * JavaScript FloorPlan 3D - helper functions for the example *
- * *
- * Copyright (C) 2009 by Christian Mayer *
- * jsfloorplan (at) ChristianMayer.de *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- * *
- ***************************************************************************/
-
-
-function three_init()
-{
- return;
- // get the DOM element to attach to
- // - assume we've got jQuery to hand
- //var $container = $('#container');
- var $container = $('#top_level');
- // attach the render-supplied DOM element
- $container.append(renderer.domElement);
- // draw!
- //scene.add( camera );
- //renderer.render(scene, camera);
- //render();
- animate();
-}
-// set the scene size
-var WIDTH = 800,
- HEIGHT = 400;
-
-// set some camera attributes
-var VIEW_ANGLE = 45,
- ASPECT = WIDTH / HEIGHT,
- NEAR = 0.1,
- FAR = 10000;
-
-
-// create a WebGL renderer, camera
-// and a scene
-var renderer = new THREE.WebGLRenderer({antialias: true});
-var camera = new THREE.PerspectiveCamera(
- VIEW_ANGLE,
- ASPECT,
- NEAR,
- FAR );
-/*
-var controls = new THREE.TrackballControls( camera );
-//controls.rotateSpeed = 1.0;
-//controls.zoomSpeed = 1.2;
-//controls.panSpeed = 0.8;
-
-controls.noZoom = false;
-controls.noPan = false;
-
-controls.staticMoving = true;
-controls.dynamicDampingFactor = 0.3;
-
-controls.keys = [ 65, 83, 68 ];
-*/
-var scene = new THREE.Scene();
-scene.add( camera );
-// the camera starts at 0,0,0 so pull it back
-camera.position.z = 300;
-
-// start the renderer
-renderer.setSize(WIDTH, HEIGHT);
-
-// enable shadows
-var SHADOW_MAP_WIDTH = 2048, SHADOW_MAP_HEIGHT = 1024;
-renderer.shadowCameraNear = 0.1;
-renderer.shadowCameraFar = 100;
-renderer.shadowCameraFov = 45;
-
-renderer.shadowMapBias = 0.0039;
-renderer.shadowMapDarkness = 0.5;
-renderer.shadowMapWidth = SHADOW_MAP_WIDTH;
-renderer.shadowMapHeight = SHADOW_MAP_HEIGHT;
-renderer.shadowMapEnabled = true;
-//renderer.shadowMapSoft = true;
-
-
-// set up the sphere vars
-var radius = 50, segments = 16, rings = 16;
-
-// create the sphere's material
-var sphereMaterial = new THREE.MeshLambertMaterial(
-{
- color: 0xCC0000
-});
-// create a new mesh with sphere geometry -
-// we will cover the sphereMaterial next!
-var sphere = new THREE.Mesh(
- new THREE.SphereGeometry(radius,
- segments,
- rings),
-
- sphereMaterial);
-
-// add the sphere to the scene
-//scene.add(sphere);
-
-var cubeMaterial = new THREE.MeshLambertMaterial(
-{
- color: 0x0000CC
-});
-var cube = new THREE.Mesh(
- new THREE.CubeGeometry(
- 10, 20, 30,
- 2, 2),
- cubeMaterial
-);
-cube.position = new THREE.Vector3(50,50,50);
-//scene.add( cube );
-
-cubeMaterial = new THREE.MeshBasicMaterial({ map: THREE.ImageUtils.loadTexture( 'media/demo_texture_512x512.png' ) });
-//cubeMaterial = new THREE.MeshPhongMaterial( { color: 0xff0000, specular: 0xffffff, ambient: 0xaa0000 } );
-
-var lineMaterial = new THREE.LineBasicMaterial( { color: 0x0099ff, linewidth: 2 } );
-
-// create a point light
-var pointLight = new THREE.PointLight( 0xFFFFFF );
-
-var ambientLight = new THREE.AmbientLight( 0xFFFFFF );
-// set its position
-pointLight.position.x = 10;
-pointLight.position.y = 50;
-pointLight.position.z = 130;
-
-// add to the scene
-//scene.add(pointLight);
-
-var lightDirection = 3.9;
-var lightHeight = 0.25;
-var lightStrength = 80;
-var lightDistance = 50;
-//var sunLight = new THREE.PointLight( 0xFFFFFF );
-//var sunLight = new THREE.DirectionalLight( 0xFFFFFF );
-var sunLight = new THREE.SpotLight( 0xffffff );
-sunLight.position.set( 0, 1500, 1000 );
-sunLight.target.position.set( 0, 0, 0 );
-sunLight.castShadow = true;
-var sunLightView = new THREE.Geometry();
-sunLightView.vertices.push( new THREE.Vertex( sunLight.position ) );
-sunLightView.vertices.push( new THREE.Vertex( sunLight.target.position ) );
-var sunLightViewLine = new THREE.Line( sunLightView, lineMaterial );
-scene.add( sunLightViewLine );
-//var dlight = new THREE.DirectionalLight( 0xffffff, 0.1 );
-// dlight.position.set( 0.5, -1, 0 ).normalize();
-// scene.add( dlight );
-
-
-/**
- * Provides requestAnimationFrame in a cross browser way.
- * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
- */
-
-if ( !window.requestAnimationFrame ) {
- window.requestAnimationFrame = ( function() {
- return window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
- window.setTimeout( callback, 1000 / 60 );
- };
-} )();
-
-}
-function animate() {
- requestAnimationFrame( animate );
- //render();
- show3D( roll, tilt );
- //stats.update();
-}
-
-function render() {
- //controls.update();
- renderer.render( scene, camera );
-}
-
-//}
-
-/////////////////////////////////////////////////////////////////////////////
-$(function() {
- three_init();
-});
-/////////////////////////////////////////////////////////////////////////////
-// setup script here:
-var sc = 40; // overall scaling
-var showStates = {};
-/*
-var showWallSides = true;
-var showWallTop = true;
-var showSideLines = true;
-var showTopLines = true;
-var showBackside = true;
-var showHoles = true;
-var showZones = true;
-var showVisibleZones = false;
-var showFloor = 1;
-var wallMouseOver = true;
-var fillOpacity = 0.5;
-var fillColor = 'black';
-*/
-var redrawInterval = 50; // in milliseconds; = 20 fps
-
-var roll = 35*Math.PI/180;
-var tilt = 30*Math.PI/180;
-var tilt_dir = 1;
-var dist = 10;
- //var plan = createSVGElement( "g" );
-var f_avr = 0;
-var m_avr = 0;
-var avr_factor = 0.1;
-var fps_history = new Array();
-var fps_current = 0;
-
-var t_25d_start;
-var t_25d_after_sort;
-var t_25d_end;
-
-function init()
-{
- $('input').change(function(e){
- showStates[ e.target.name ] = e.target.checked;
- selectChange( e.target.name );
- show3D( roll, tilt );
- }).each(function(){
- showStates[ this.name ] = this.checked; // init
- });
- $('select').change(function(e){
- showStates[ e.target.name ] = e.target.value;
- selectChange( e.target.name );
- show3D( roll, tilt );
- }).each(function(){
- showStates[ this.name ] = this.value; // init
- });
-
- loadFloorplan();
- createSlider();
-}
-
-function selectChange( name )
-{
- switch( name )
- {
- case 'showNodes':
- $( buildingProperties.floor ).each( function(){
- THREE.SceneUtils.traverseHierarchy( this.nodeGroup, function( object ) {
- object.visible = showStates['showNodes'];
- });
- });
- break;
-
- case 'showWallLines':
- $( buildingProperties.floor ).each( function(){
- THREE.SceneUtils.traverseHierarchy( this.lineGroup, function( object ) {
- object.visible = showStates['showWallLines'];
- });
- });
- break;
-
- case 'showFloor':
- $( buildingProperties.floor ).each( function( number ){
- THREE.SceneUtils.traverseHierarchy( this.wallGroup, function( object ) {
- object.visible = ( showStates['showFloor'] == number );
- });
- });
- break;
-
- case 'showWireframe':
- cubeMaterial.wireframe = showStates['showWireframe'];
- break;
- }
-}
-
-var toggle = false;
-var animation;
-function my_click()
-{
- if( toggle )
- {
- clearInterval( animation );
- toggle = false;
- } else {
- animation = setInterval(move, redrawInterval);
- toggle = true;
- }
- return true;
-}
-
-function move()
-{
- var pre = new Date();
-
- //////
- roll += 0.5*Math.PI/180;
- if( roll > 2*Math.PI ) roll -= 2*Math.PI;
- tilt += tilt_dir*0.5*Math.PI/180;
- if( tilt > 60*Math.PI/180 )
- tilt_dir = -1;
- if( tilt < 0 )
- tilt_dir = 1;
-
- show3D( roll, tilt );
- //////
-
- var middle = new Date();
-
- var post = new Date();
-
- //////
- var f = post - pre ; f_avr = f_avr * (1-avr_factor) + f*avr_factor;
- var m = post - middle; m_avr = m_avr * (1-avr_factor) + m*avr_factor;
-
- var fps = Math.floor( 1000/(f>0 ? f:0.1) );
- fps_history[fps_current++] = fps;
- if( fps_current > 10 ) fps_current = 0;
- var fps_min = Math.min.apply( Math, fps_history );
- var fps_max = Math.max.apply( Math, fps_history );
-
- var calc1 = t_25d_after_sort - t_25d_start;
- var calc2 = t_25d_end - t_25d_after_sort;
-
- delete pre;
- delete middle;
- delete post;
- //delete t_25d_start;
- //delete t_25d_after_sort;
- //delete t_25d_end;
-
- var txt = '';//"c1: " + calc1 + "; c2: " + calc2;
-
- var text = "roll: " + roll + "; tilt: " + tilt + " (" + (tilt*180/Math.PI) + "; " + tilt_dir + ")\n" +
- (m_avr<10?"0":"")+Math.floor(m_avr)+" Millisekunden zum Neuzeichnen verwendet\n"
- + Math.floor(f_avr)+" Millisekunden inklusive Neuberechnung verwendet (von " + redrawInterval + " Millisekunden)\n"
- + "Aktuelle, maximale Rate wären "+fps+" fps (aktuell festgesetzt sind "+Math.floor(1000/redrawInterval)+" FPS)\n"
-+ "Die letzten 10 Schritte wären mindestes " + fps_min + " FPS und höchstens " + fps_max + " FPS möglich gewesen.\n"
-+ txt;
- //window.status = (post - pre);//.getMilliseconds();
- var timeout = setTimeout( showStats, 1, text );
-///
-updateSlider();
-}
-
-function showStats( text )
-{
- document.getElementById('status').firstChild.data = text;
-}
-
-/*
-function set_color( event )
-{
- if( 'blue' != fillColor )
- event.setAttribute( 'fill', 'blue' );
- else
- event.setAttribute( 'fill', 'red' );
-}
-
-function unset_color( event )
-{
- event.setAttribute( 'fill', fillColor );
-}
-*/
-/*
-function check( what, redraw )
-{
- eval( what +' = document.forms[0].elements[what].checked' );
-
- switch( what )
- {
- case 'wallMouseOver':
- if( wallMouseOver )
- {
- wrapper.setAttribute( "onmouseover", 'set_color(this);' );
- wrapper.setAttribute( "onmouseout", 'unset_color(this);' );
- } else {
- wrapper.setAttribute( "onmouseover", '' );
- wrapper.setAttribute( "onmouseout", '' );
- }
- break;
- }
-
- if( redraw )
- {
- show3D( roll, tilt, plan );
- }
-}
-*/
-
-/*
-function selectValue( what, redraw )
-{
- var val = document.forms[0].elements[what].options[ document.forms[0].elements[what].selectedIndex ].value;
- eval( what + ' = val' );
-
- switch( what )
- {
- case 'fillOpacity':
- wrapper.setAttribute( "fill-opacity", fillOpacity );
- break;
-
- case 'fillColor':
- wrapper.setAttribute( "fill", fillColor );
- break;
- }
-
- if( redraw )
- {
- show3D( roll, tilt, plan );
- }
-}
-*/
-
-// Create the little graphics for the roll and the tilt angle
-// as well as the buttons to manipulate them
-function createSlider()
-{
- $( "#rollSlider" ).slider({ min: 0, max: 360, change: rollChange, slide: rollChange});
- $( "#tiltSlider" ).slider({ min: 0, max: 90, change: tiltChange, slide: tiltChange});
- $( "#distSlider" ).slider({ min: 5, max: 30, change: distChange, slide: distChange});
- $( "#lightDirectionSlider" ).slider({ min: 0, max: 360, change: lightDirectionChange, slide: lightDirectionChange});
- $( "#lightHeightSlider" ).slider({ min: 0, max: 90, change: lightHeightChange , slide: lightHeightChange });
- $( "#lightStrengthSlider" ).slider({ min: 0, max: 100, change: lightStrengthChange , slide: lightStrengthChange });
- $( "#lightDistanceSlider" ).slider({ min:10, max: 100, change: lightDistanceChange , slide: lightDistanceChange });
- updateSlider();
-}
-
-var globalInUpdateSlider = false;
-function updateSlider()
-{
- globalInUpdateSlider = true;
- var rollAngle = (roll * 180/Math.PI);
- var tiltAngle = (tilt * 180/Math.PI);
- var lightDirectionAngle = (lightDirection * 180/Math.PI);
- var lightHeightAngle = (lightHeight * 180/Math.PI);
- $( "#rollSlider" ).slider( "option", "value", rollAngle );
- $( "#tiltSlider" ).slider( "option", "value", tiltAngle );
- $( "#distSlider" ).slider( "option", "value", dist );
- $( "#lightDirectionSlider" ).slider( "option", "value", lightDirectionAngle );
- $( "#lightHeightSlider" ).slider( "option", "value", lightHeightAngle );
- $( "#lightStrengthSlider" ).slider( "option", "value", lightStrength );
- $( "#lightDistanceSlider" ).slider( "option", "value", lightDistance );
- globalInUpdateSlider = false;
-}
-
-function rollChange( event, ui )
-{
- if( globalInUpdateSlider ) return true;
- roll = ui.value * Math.PI / 180;
- show3D( roll, tilt );
-}
-
-function tiltChange( event, ui )
-{
- if( globalInUpdateSlider ) return true;
- tilt = ui.value * Math.PI / 180;
- show3D( roll, tilt );
-}
-
-function distChange( event, ui )
-{
- if( globalInUpdateSlider ) return true;
- dist = ui.value;
- show3D( roll, tilt );
-}
-
-function lightDirectionChange( event, ui )
-{
- if( globalInUpdateSlider ) return true;
- lightDirection = ui.value * Math.PI / 180;
- show3D( roll, tilt );
-}
-
-function lightHeightChange( event, ui )
-{
- if( globalInUpdateSlider ) return true;
- lightHeight = ui.value * Math.PI / 180;
- show3D( roll, tilt );
-}
-
-function lightStrengthChange( event, ui )
-{
- if( globalInUpdateSlider ) return true;
- lightStrength = ui.value;
- show3D( roll, tilt );
-}
-
-function lightDistanceChange( event, ui )
-{
- if( globalInUpdateSlider ) return true;
- lightDistance = ui.value;
- show3D( roll, tilt );
-}
-
-
Copied: JSFloorPlan/trunk/src/jsfloorplan.js (from rev 587, JSFloorPlan/trunk/jsfloorplan.js)
===================================================================
--- JSFloorPlan/trunk/src/jsfloorplan.js (rev 0)
+++ JSFloorPlan/trunk/src/jsfloorplan.js 2011-12-18 13:27:38 UTC (rev 588)
@@ -0,0 +1,684 @@
+/***************************************************************************
+ * *
+ * JavaScript FloorPlan 3D *
+ * *
+ * Copyright (C) 2009, 2010 by Christian Mayer *
+ * jsfloorplan (at) ChristianMayer.de *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ ***************************************************************************/
+
+// setup script here:
+
+// don't change anything below:
+var ELEMENT_NODE = 1;
+
+// calculate the distance between two cartesian 2D points
+function calcLength2D( start, end )
+{
+ return Math.sqrt( (end.x-start.x)*(end.x-start.x) +
+ (end.y-start.y)*(end.y-start.y) );
+}
+
+// calculate the rotation of a cartesian 2D point around the center
+function rotate2D( angle, point, center )
+{
+ var s = Math.sin( angle );
+ var c = Math.cos( angle );
+ var ret = new Object;
+ ret.x = center.x + c * (point.x-center.x) - s * (point.y-center.y);
+ ret.y = center.y + s * (point.x-center.x) + c * (point.y-center.y);
+ return ret;
+}
+
+// calculate the rotation of a cartesian 2D point around the center
+// but with given sin and cos of the angle
+function rotate2D( s, c, point, center )
+{
+ var ret = new Object;
+ ret.x = center.x + c * (point.x-center.x) - s * (point.y-center.y);
+ ret.y = center.y + s * (point.x-center.x) + c * (point.y-center.y);
+ return ret;
+}
+
+// calculate the translation of a cartesian 2D point
+function translate2D( point, translation )
+{
+ var ret = new Object;
+ ret.x = point.x + translation.x;
+ ret.y = point.y + translation.y;
+ return ret;
+}
+
+// sort two 2D unit(!) vectors clockwise
+function vecSort( a, b )
+{
+ var pseudoangle_a = a.y>=0 ? (1-a.x) : (a.x+3);
+ var pseudoangle_b = b.y>=0 ? (1-b.x) : (b.x+3);
+ return pseudoangle_a - pseudoangle_b;
+}
+
+function loadFloorplan()
+{
+ $.get('floorplan01.xml', parseXMLFloorPlan, 'xml');
+}
+var floor;
+
+// this array will contain all vertices to show in the svg
+var vertices = Array();
+// infos about the building
+var buildingProperties = { floor: [], Object3D: new THREE.Object3D() };
+var imageCenter = new Object;
+
+var noFloorplan = true;
+function parseXMLFloorPlan( xmlDoc )
+{
+ noFloorplan = false;
+
+ var floorCount = -1;
+ var heightOfGround = 0; // the base level of the current floor
+
+ // basic check if the document seems right
+ // this could be avoided if the XML file would be validated
+ // with a DTD
+ var building;
+ if( 'building' == xmlDoc.documentElement.tagName )
+ building = xmlDoc.documentElement;
+ else
+ return alert( "ERROR: Not a valid floor plan! " +
+ "Expected: 'building', found '" + xmlDoc.documentElement.tagName + "'" );
+
+ // now we are sure to have a sensible file
+ // => iterate over all floors
+ for( var i=0; i < building.childNodes.length; i++ )
+ {
+ floor = building.childNodes[i];
+ if (floor.nodeType != ELEMENT_NODE) continue;
+
+ if( floor.tagName == 'textures' )
+ {
+ parseTextures( floor );
+ continue;
+ }
+
+ if( floor.tagName != 'floor' )
+ return alert( "ERROR: Not a valid floor plan! " +
+ "Expected: 'floor', found '" + floor.tagName + "'" );
+
+ floorCount++;
+ buildingProperties.floor[floorCount] = {};
+
+ var floorName = floor.getAttribute('name');
+ buildingProperties.floor[floorCount].name = floorName;
+
+ var floorheight = Number( floor.getAttribute('height') );
+ buildingProperties.floor[floorCount].height = floorheight;
+ buildingProperties.floor[floorCount].heightOfGround = heightOfGround;
+
+ var floorWallsStart = floorWalls.length;
+
+ // iterate over the content of this floor
+ for( var j=0; j < floor.childNodes.length; j++ )
+ {
+ floorNode = floor.childNodes[j];
+ if (floorNode.nodeType != ELEMENT_NODE) continue;
+
+ switch( floorNode.tagName )
+ {
+ case 'nodes':
+ parseFloorNodes( floorNode, floorheight );
+ break;
+
+ case 'walls':
+ parseFloorWalls( floorNode );
+ break;
+
+ case 'rooms':
+ parseFloorRooms( floorNode, floorCount );
+ break;
+ }
+ }
+
+ // now the content of the floor is stored in easily
+ // accessable objects
+ // => derive the necessary information
+
+ // group all elements on this floor
+ var Object3D = new THREE.Object3D();
+
+ // add the information to each node to which nodes it's connected to
+ for( var j = floorWallsStart; j < floorWalls.length; j++ )
+ {
+ // note: the ID is shifted by one to avoid an ID of zero
+ // as that wouldn't allow me anymore to distinguish
+ // start and stop
+ floorNodes[ floorWalls[j].start ].neighbour.push( j+1 );
+ floorNodes[ floorWalls[j].end ].neighbour.push( -j-1 );
+ }
+
+ var nodeGroup = new THREE.Object3D(); nodeGroup.name = 'nodeGroup';
+ for( var id in floorNodes )
+ {
+ // calculate the vectors showing to the neighbours
+ var vectors = new Array();
+ var start = floorNodes[id];
+
+ // show them on request as spheres
+ var sphere = new THREE.Mesh( new THREE.SphereGeometry(0.1, 4, 4), sphereMaterial);
+ sphere.position = new THREE.Vector3( start.x, start.y, heightOfGround );
+ nodeGroup.add(sphere);
+
+ for( var j=0; j<floorNodes[id].neighbour.length; j++ )
+ {
+ var vec = new Object;
+ vec.id = floorNodes[id].neighbour[j];
+ var end;
+ if( vec.id < 0 )
+ end = floorNodes[ floorWalls[ -vec.id-1 ].start ];
+ else
+ end = floorNodes[ floorWalls[ vec.id-1 ].end ];
+
+ length = calcLength2D( start, end );
+ vec.x = (end.x - start.x) / length;
+ vec.y = (end.y - start.y) / length;
+ vectors.push( vec );
+ }
+
+ // sort them clockwise
+ vectors.sort( vecSort );
+
+ // calculate the cutting points of the walls at this node id
+ for( var j=0; j<vectors.length; j++ )
+ {
+ var jj = (j+1) % vectors.length;
+ var wj = Math.abs(vectors[j ].id)-1;
+ var wjj = Math.abs(vectors[jj].id)-1;
+ var dj = floorWalls[wj ].thickness/2;
+ var djj = floorWalls[wjj].thickness/2;
+ if( floorWalls[wj ].startOffset && vectors[j ].id > 0 )
+ dj += floorWalls[wj].startOffset;
+ if( floorWalls[wj ].endOffset && vectors[j ].id < 0 )
+ dj += floorWalls[wj].endOffset;
+ if( floorWalls[wjj].startOffset && vectors[jj].id > 0 )
+ djj += -floorWalls[wjj].startOffset;
+ if( floorWalls[wjj].endOffset && vectors[jj].id < 0 )
+ djj += -floorWalls[wjj].endOffset;
+
+ vertex = new Object;
+ vertex.x = vectors[j].x*djj + vectors[jj].x*dj;
+ vertex.y = vectors[j].y*djj + vectors[jj].y*dj;
+ var l = vectors[j].x*vectors[jj].y - vectors[j].y*vectors[jj].x;
+ if( Math.abs( l ) < 1e-5 )
+ { // the angle between the two vectors is exactly 180°
+ // i.e. a straight wall...
+ if( Math.abs( dj - djj ) < 1e-5 )
+ { // at least the walls have the same thickness...
+ vertex.x = start.x - vectors[j].y*dj;
+ vertex.y = start.y + vectors[j].x*dj;
+ } else {
+ alert( "ERROR: A straight wall with different thicknesses " +
+ "is currently not supported!" );
+ // but we still try our best...
+ vertex.x = start.x - vectors[j].y*(dj+djj)/2;
+ vertex.y = start.y + vectors[j].x*(dj+djj)/2;
+ }
+ } else {
+ vertex.x = start.x + vertex.x / l;
+ vertex.y = start.y + vertex.y / l;
+ }
+
+ if( vectors[j ].id < 0 )
+ floorWalls[wj ].startVertex.push( vertices.length );
+ else
+ floorWalls[wj ].endVertex.push( vertices.length );
+
+ if( 1 == vectors.length )
+ {
+ var additional = new Object;
+ additional.x = 2 * start.x - vertex.x;
+ additional.y = 2 * start.y - vertex.y;
+ vertices.push( additional );
+ }
+
+ if( vectors[jj].id < 0 )
+ floorWalls[wjj].startVertex.push( vertices.length );
+ else
+ floorWalls[wjj].endVertex.push( vertices.length );
+
+ vertices.push( vertex );
+ }
+ } // end for( var id in floorNodes )
+ Object3D.add( nodeGroup );
+
+ // show walls
+ var lineGroup = new THREE.Object3D(); lineGroup.name = 'lineGroup';
+ var wallGroup = new THREE.Object3D(); wallGroup.name = 'wallGroup';
+ for( var j = floorWallsStart; j<floorWalls.length; j++ )
+ {
+ var vs = floorNodes[ floorWalls[j].start ];
+ var ve = floorNodes[ floorWalls[j].end ];
+ var lineGeo = new THREE.Geometry();
+ lineGeo.vertices.push( new THREE.Vertex( new THREE.Vector3( vs.x, vs.y, heightOfGround ) ) );
+ lineGeo.vertices.push( new THREE.Vertex( new THREE.Vector3( ve.x, ve.y, heightOfGround ) ) );
+ lineGroup.add( new THREE.Line( lineGeo, lineMaterial ) );
+
+ var s1 = vertices[ floorWalls[j].startVertex[0] ];
+ var e1 = vertices[ floorWalls[j].endVertex [0] ];
+ var s2 = vertices[ floorWalls[j].startVertex[1] ];
+ var e2 = vertices[ floorWalls[j].endVertex [1] ];
+
+ // check that the start and end points aren't twisted
+ var v1 = new Object; v1.x = s1.x-s2.x; v1.y = s1.y-s2.y;
+ var v2 = new Object; v2.x = e1.x-s2.x; v2.y = e1.y-s2.y;
+ var v3 = new Object; v3.x = e1.x-e2.x; v3.y = e1.y-e2.y;
+ if( (v1.x*v2.y - v1.y*v2.x)*(v2.x*v3.y - v2.y*v3.x) > 0 )
+ {
+ e1 = vertices [ floorWalls[j].endVertex[1] ];
+ e2 = vertices [ floorWalls[j].endVertex[0] ];
+ }
+ var sm = floorNodes[ floorWalls[j].start ];
+ var em = floorNodes[ floorWalls[j].end ];
+ var sh = floorNodes[ floorWalls[j].start ].z ;
+ var eh = floorNodes[ floorWalls[j].end ].z ;
+ var wallSideOrder = (s2.x-s1.x)*(e1.y-s1.y) - (s2.y-s1.y)*(e1.x-s1.x);
+ var geometry = new THREE.Geometry();
+
+ var normal1 = new THREE.Vector3(sm.y-em.y,-sm.x+em.x,0); // fixme? normalize
+ var normal2 = new THREE.Vector3(1,0,0);
+
+ var sourrounding = [ new poly2tri.Point(0,0), new poly2tri.Point(0,1), new poly2tri.Point(1,1), new poly2tri.Point(1,0) ];
+ sourrounding[1].startEndMarker = 'start';
+ sourrounding[2].startEndMarker = 'end';
+ var holesToAdd = [];
+
+ if( floorWalls[j].holes.length )
+ {
+ var holes = floorWalls[j].holes;
+ for( var h = 0; h < holes.length; h++ )
+ {
+ var wallLength = calcLength2D( sm, em );
+ var fLeft = holes[h].distance / wallLength;
+ var fRight = (holes[h].distance + holes[h].width) / wallLength;
+ if( fLeft <= 0.0 ) fLeft = 0.001; //// FIXME - actually the config file is bad. Leave at least 1mm wall
+ if( fRight >= 1.0 ) fRight = 0.999; //// FIXME - actually the config file is bad. Leave at least 1mm wall
+ var lintel = (sh - holes[h].lintel) / sh;
+ var paparet = holes[h].paparet / sh;
+ if( 1 == lintel )
+ {
+ // not a hole, the sourrounding goes to the groud...
+
+ if( paparet == 0 ) continue; // FIXME: Assume paparet != 0 - otherwise it should be two walls...
+
+ sourrounding.splice( -2, 0, new poly2tri.Point(fLeft,1), new poly2tri.Point(fLeft,paparet), new poly2tri.Point(fRight,paparet), new poly2tri.Point(fRight,1) );
+ continue;
+ }
+ if( 0 == paparet )
+ {
+ // not a hole, the sourrounding goes to the groud...
+
+ // lintel == 1 can't happen, it's checked in the if clause above
+
+ sourrounding.splice( 0, 0, new poly2tri.Point(fRight,0), new poly2tri.Point(fRight,lintel), new poly2tri.Point(fLeft,lintel), new poly2tri.Point(fLeft,0) );
+ continue;
+ }
+
+ holesToAdd.push( [new poly2tri.Point(fLeft,paparet), new poly2tri.Point(fRight,paparet), new poly2tri.Point(fRight,lintel), new poly2tri.Point(fLeft,lintel)] );
+ }
+ } // if( floorWalls[j].holes.length )
+ var swctx = new poly2tri.SweepContext( sourrounding.slice(0) ); // pass a copy of sourrounding
+ for( var htA = 0; htA < holesToAdd.length; htA++ )
+ swctx.AddHole( holesToAdd[htA] );
+
+ // Do the triangulation - FIXME: handle exceptions, don't ignore them...
+ try {
+ poly2tri.sweep.Triangulate(swctx);
+ }catch(err){}
+
+ // mark all points to make sure that we don't need to double vertices
+ for( var tp = 0; tp < swctx.point_count(); tp++ )
+ swctx.GetPoint( tp ).id = tp;
+
+ // translate poly2tri triangles to THREE.js faces:
+ var p2tF = [];
+ $.each(swctx.GetTriangles(), function(idx, val) {
+ p2tF.push(new THREE.Face3(val.GetPoint(0).id, val.GetPoint(1).id, val.GetPoint(2).id));
+ });
+
+ Tvertices = swctx.points_;
+ Tfaces = p2tF;
+ var wall1vertices = [];
+ var wall2vertices = [];
+ var sId, eId;
+ for( var v = 0; v < Tvertices.length; v++ )
+ {
+ /* prepare for later...
+ // project s1, e1 and s2, e2 onto line sm->em
+ var lSquaredInv = 1.0 / ((em.x-sm.x)*(em.x-sm.x) + (em.y-sm.y)*(em.y-sm.y));
+ var s1f = 1-((s1.x-sm.x)*(em.x-sm.x) + (s1.y-sm.y)*(em.y-sm.y))*lSquaredInv;
+ var e1f = 1-((e1.x-sm.x)*(em.x-sm.x) + (e1.y-sm.y)*(em.y-sm.y))*lSquaredInv;
+ var s2f = 1-((s2.x-sm.x)*(em.x-sm.x) + (s2.y-sm.y)*(em.y-sm.y))*lSquaredInv;
+ var e2f = 1-((e2.x-sm.x)*(em.x-sm.x) + (e2.y-sm.y)*(em.y-sm.y))*lSquaredInv;
+
+ var tv = Tvertices[v];
+ var tvx1 = Math.min( 1.0, Math.max( 0.0, (tv.x - s1f) * (e1f - s1f) ) ); // map between s1 and e1
+ var tvx2 = Math.min( 1.0, Math.max( 0.0, (tv.x - s2f) * (e2f - s2f) ) ); // map between s2 and e2
+ var x1 = s1.x * tvx1 + e1.x * (1 - tvx1);
+ var x2 = s2.x * tvx2 + e2.x * (1 - tvx2);
+ var y1 = s1.y * tvx1 + e1.y * (1 - tvx1);
+ var y2 = s2.y * tvx2 + e2.y * (1 - tvx2);
+ console.log( sm, em, s1, e1, tvx1, x1, y1, s2, e2, tvx2, x2, y2 );
+ */
+ var z = heightOfGround + sh*tv.y;
+ if( wallSideOrder > 0 )
+ {
+ wall1vertices.push(new THREE.Vertex(new THREE.Vector3(x1,y1,z), normal1));
+ wall2vertices.push(new THREE.Vertex(new THREE.Vector3(x2,y2,z), normal1));
+ } else {
+ wall1vertices.push(new THREE.Vertex(new THREE.Vector3(x2,y2,z), normal1));
+ wall2vertices.push(new THREE.Vertex(new THREE.Vector3(x1,y1,z), normal1));
+ }
+ if( 'startEndMarker' in tv )
+ {
+ if( 'start' == tv.startEndMarker )
+ {
+ sId = wall1vertices.length - 1;
+ } else {
+ eId = wall1vertices.length - 1;
+ }
+ }
+ }
+ var wall1verticesL...
[truncated message content] |