[208] | 1 | function GraphicsEngine(context, width, height) { |
---|
[134] | 2 | this._scene = undefined; |
---|
| 3 | this._camera = undefined; |
---|
| 4 | this._renderer = undefined; |
---|
[208] | 5 | this._canvasWidth = width; |
---|
| 6 | this._canvasHeight = height; |
---|
| 7 | this._containerContextName = context; |
---|
[134] | 8 | this._BALL_RADIUS = 0.25; |
---|
| 9 | this._controls = undefined; |
---|
| 10 | this._parts = [] |
---|
| 11 | this._debug1 = 0 |
---|
| 12 | this._showAxis = false; |
---|
[208] | 13 | this._render = true; |
---|
[134] | 14 | } |
---|
| 15 | |
---|
| 16 | GraphicsEngine.prototype.showPartAxis = function () { |
---|
| 17 | this._showAxis = true; |
---|
| 18 | } |
---|
| 19 | |
---|
| 20 | GraphicsEngine.prototype._createRenderer = function () { |
---|
| 21 | this._renderer = new THREE.WebGLRenderer({antialias: true}); |
---|
| 22 | this._renderer.setClearColor(0x000000, 1); |
---|
| 23 | this._renderer.setSize(this._canvasWidth, this._canvasHeight); |
---|
[208] | 24 | this._containerContextName.append(this._renderer.domElement); |
---|
| 25 | |
---|
| 26 | var self = this; |
---|
| 27 | this._renderer.domElement.addEventListener('mousemove', function(evt){ |
---|
| 28 | self._render = true; |
---|
| 29 | }); |
---|
[134] | 30 | } |
---|
| 31 | |
---|
| 32 | GraphicsEngine.prototype._prepareCamera = function () { |
---|
| 33 | this._camera = new THREE.PerspectiveCamera(45, this._canvasWidth / this._canvasHeight, 1, 100); |
---|
| 34 | this._camera.position.set(0, 0, 10); |
---|
| 35 | this._camera.lookAt(this._scene.position); |
---|
| 36 | this._scene.add(this._camera); |
---|
| 37 | } |
---|
| 38 | |
---|
| 39 | GraphicsEngine.prototype._addLight = function () { |
---|
| 40 | var directionalLight = new THREE.DirectionalLight(0xffffff); |
---|
| 41 | |
---|
| 42 | directionalLight.position = this._camera.position; |
---|
| 43 | directionalLight.intensity = 1; |
---|
| 44 | |
---|
| 45 | this._scene.add(directionalLight); |
---|
| 46 | } |
---|
| 47 | |
---|
| 48 | GraphicsEngine.prototype._rotateObject = function (object, part) { |
---|
| 49 | object.rotateX(part.getXrot()); |
---|
[188] | 50 | object.rotateY(-part.getYrot()); |
---|
[134] | 51 | object.rotateZ(part.getZrot()); |
---|
| 52 | } |
---|
| 53 | |
---|
| 54 | GraphicsEngine.prototype._addBall = function (part) { |
---|
| 55 | var segments = 40, |
---|
| 56 | rings = 40; |
---|
| 57 | |
---|
| 58 | var sphereMaterial = |
---|
| 59 | new THREE.MeshPhongMaterial( |
---|
| 60 | { |
---|
| 61 | color: 0xffffff |
---|
| 62 | }); |
---|
| 63 | sphereMaterial.color.setRGB(part.getR(), part.getG(), part.getB()) |
---|
| 64 | |
---|
| 65 | var ball = new THREE.Mesh( |
---|
| 66 | new THREE.SphereGeometry(part.getRadius()/4, |
---|
| 67 | segments, |
---|
| 68 | rings), |
---|
| 69 | sphereMaterial); |
---|
| 70 | |
---|
| 71 | ball.position.set(part.getX(), part.getY(), part.getZ()); |
---|
| 72 | this._rotateObject(ball, part); |
---|
| 73 | |
---|
| 74 | |
---|
| 75 | this._parts.push(ball); |
---|
| 76 | if(this._showAxis) |
---|
| 77 | ball.add(new THREE.AxisHelper(1)); |
---|
| 78 | this._scene.add(ball); |
---|
| 79 | } |
---|
| 80 | |
---|
[188] | 81 | GraphicsEngine.prototype._debugShow = function(object) |
---|
| 82 | { |
---|
| 83 | var pos = object.position; |
---|
| 84 | var scale = object.scale; |
---|
| 85 | var rot = object.rotation |
---|
| 86 | //console.log(pos.x, pos.y, pos.z , "|", rot.x, rot.y, rot.z,"|", scale.x, scale.y, scale.z); |
---|
| 87 | } |
---|
| 88 | |
---|
[134] | 89 | GraphicsEngine.prototype._addEllipsoid = function (part) { |
---|
| 90 | var geometry = new THREE.SphereGeometry(1, 20, 20); |
---|
| 91 | var ellipsoidMaterial = new THREE.MeshPhongMaterial({color: 0xffffff}); |
---|
| 92 | ellipsoidMaterial.color.setRGB(part.getR(), part.getG(), part.getB()) |
---|
| 93 | |
---|
| 94 | var ellipsoid = new THREE.Mesh(geometry, ellipsoidMaterial); |
---|
[188] | 95 | ellipsoid.scale.set(part.getXshape(), part.getYshape(), part.getZshape()) |
---|
[134] | 96 | ellipsoid.position.set(part.getX(), part.getY(), part.getZ()); |
---|
| 97 | this._rotateObject(ellipsoid, part); |
---|
| 98 | |
---|
| 99 | this._parts.push(ellipsoid); |
---|
| 100 | if(this._showAxis) |
---|
| 101 | ellipsoid.add(new THREE.AxisHelper(1)); |
---|
[188] | 102 | |
---|
[134] | 103 | this._scene.add(ellipsoid); |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | GraphicsEngine.prototype._addCylinder = function (part) { |
---|
| 107 | var geometry = new THREE.CylinderGeometry(1, 1, 1, 10, 10, false); |
---|
| 108 | |
---|
| 109 | var material = new THREE.MeshLambertMaterial({color: 0xffffff}); |
---|
| 110 | material.color.setRGB(part.getR(), part.getG(), part.getB()); |
---|
| 111 | |
---|
| 112 | var cylinder = new THREE.Mesh(geometry, material); |
---|
[188] | 113 | |
---|
| 114 | cylinder.scale.set(part.getXshape(), part.getYshape(), part.getZshape()) |
---|
[134] | 115 | cylinder.position.set(part.getX(), part.getY(), part.getZ()); |
---|
| 116 | this._rotateObject(cylinder, part); |
---|
| 117 | |
---|
| 118 | this._parts.push(cylinder); |
---|
| 119 | if(this._showAxis) |
---|
[188] | 120 | cylinder.add(new THREE.AxisHelper(5)); |
---|
| 121 | |
---|
[134] | 122 | this._scene.add(cylinder); |
---|
[188] | 123 | |
---|
[134] | 124 | } |
---|
| 125 | |
---|
| 126 | GraphicsEngine.prototype._addCuboid = function (part) { |
---|
| 127 | var geometry = new THREE.CubeGeometry(2, 2, 2, 10, 10, 10); |
---|
[188] | 128 | //TODO: poprawić getXshape na getXscale |
---|
[134] | 129 | |
---|
| 130 | var material = new THREE.MeshLambertMaterial({color: 0xffffff}); |
---|
| 131 | material.color.setRGB(part.getR(), part.getG(), part.getB()); |
---|
| 132 | |
---|
| 133 | var cube = new THREE.Mesh(geometry, material); |
---|
[188] | 134 | cube.scale.set(part.getXshape(), part.getYshape(), part.getZshape()) |
---|
[134] | 135 | cube.position.set(part.getX(), part.getY(), part.getZ()); |
---|
| 136 | this._rotateObject(cube, part); |
---|
| 137 | |
---|
| 138 | this._parts.push(cube); |
---|
| 139 | if(this._showAxis) |
---|
| 140 | cube.add(new THREE.AxisHelper(1)); |
---|
| 141 | this._scene.add(cube); |
---|
| 142 | } |
---|
| 143 | |
---|
| 144 | GraphicsEngine.prototype.addPart = function (part) { |
---|
[208] | 145 | //console.log(part.getX(),part.getY(),part.getZ(), "|", part.getXshape(),part.getYshape(),part.getZshape(),"|",part.getXrot(),part.getYrot(),part.getZrot()) |
---|
[134] | 146 | switch (part.getType()) { |
---|
| 147 | case 0: |
---|
| 148 | this._addBall(part); |
---|
| 149 | break; |
---|
| 150 | case 1: |
---|
| 151 | this._addEllipsoid(part); |
---|
| 152 | break; |
---|
| 153 | case 2: |
---|
| 154 | this._addCuboid(part); |
---|
| 155 | break; |
---|
| 156 | case 3: |
---|
| 157 | this._addCylinder(part); |
---|
| 158 | break; |
---|
| 159 | default : |
---|
| 160 | throw new Error("Unknown shape of part"); |
---|
| 161 | break; |
---|
| 162 | } |
---|
| 163 | } |
---|
| 164 | |
---|
| 165 | GraphicsEngine.prototype._addStick = function (joint) { |
---|
| 166 | |
---|
| 167 | var p1Pos = this._parts[joint.getP1()].position; |
---|
| 168 | var p2Pos = this._parts[joint.getP2()].position; |
---|
| 169 | var p1Vector = new THREE.Vector3(p1Pos.x, p1Pos.y, p1Pos.z); |
---|
| 170 | var p2Vector = new THREE.Vector3(p2Pos.x, p2Pos.y, p2Pos.z); |
---|
| 171 | |
---|
| 172 | var HALF_PI = Math.PI * .5; |
---|
| 173 | var distance = p1Vector.distanceTo(p2Vector); |
---|
| 174 | var position = p2Vector.clone().add(p1Vector).divideScalar(2); |
---|
| 175 | |
---|
| 176 | var material = new THREE.MeshPhongMaterial({color: 0x0000ff}); |
---|
| 177 | material.color.setRGB(joint.getR(), joint.getG(), joint.getB()); |
---|
| 178 | |
---|
| 179 | var cylinder = new THREE.CylinderGeometry(0.05, 0.05, distance, 20, 20, false); |
---|
| 180 | |
---|
| 181 | var orientation = new THREE.Matrix4();//a new orientation matrix to offset pivot |
---|
| 182 | var offsetRotation = new THREE.Matrix4();//a matrix to fix pivot rotation |
---|
| 183 | orientation.lookAt(p1Vector, p2Vector, new THREE.Vector3(0, 1, 0));//look at destination |
---|
| 184 | offsetRotation.makeRotationX(HALF_PI);//rotate 90 degs on X |
---|
| 185 | orientation.multiply(offsetRotation);//combine orientation with rotation transformations |
---|
| 186 | cylinder.applyMatrix(orientation); |
---|
| 187 | |
---|
| 188 | var mesh = new THREE.Mesh(cylinder, material); |
---|
| 189 | mesh.position = position; |
---|
| 190 | |
---|
| 191 | this._scene.add(mesh); |
---|
| 192 | } |
---|
| 193 | |
---|
| 194 | GraphicsEngine.prototype._hasTranslation = function (joint) { |
---|
| 195 | if (joint.getXtran() != 0) |
---|
| 196 | return true; |
---|
| 197 | if (joint.getYtran() != 0) |
---|
| 198 | return true; |
---|
| 199 | if (joint.getZtran() != 0) |
---|
| 200 | return true; |
---|
| 201 | |
---|
| 202 | return false; |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | GraphicsEngine.prototype._translate = function (joint) { |
---|
| 206 | |
---|
| 207 | if(this._hasTranslation(joint)) |
---|
| 208 | { |
---|
| 209 | var p1 = joint.getP1(); |
---|
| 210 | var p2 = joint.getP2(); |
---|
| 211 | |
---|
| 212 | var copy = this._parts[p1].clone(); |
---|
| 213 | |
---|
| 214 | copy.rotateX(joint.getXrot()); |
---|
[188] | 215 | copy.rotateY(-joint.getYrot()); |
---|
[134] | 216 | copy.rotateZ(joint.getZrot()); |
---|
| 217 | |
---|
| 218 | copy.translateX(joint.getXtran()); |
---|
| 219 | copy.translateY(joint.getYtran()); |
---|
| 220 | copy.translateZ(joint.getZtran()); |
---|
| 221 | |
---|
| 222 | this._parts[p2].position = copy.position.clone(); |
---|
| 223 | this._parts[p2].rotation = copy.rotation.clone(); |
---|
| 224 | |
---|
| 225 | delete copy; |
---|
| 226 | } |
---|
| 227 | } |
---|
| 228 | |
---|
| 229 | GraphicsEngine.prototype.addJoint = function (joint) { |
---|
| 230 | switch (joint.getType()) { |
---|
| 231 | case 0: |
---|
| 232 | this._translate(joint); |
---|
| 233 | this._addStick(joint); |
---|
| 234 | break; |
---|
| 235 | case 1: |
---|
| 236 | this._translate(joint); |
---|
| 237 | break; |
---|
| 238 | default : |
---|
| 239 | throw new Error("Unknown shape of joint"); |
---|
| 240 | break; |
---|
| 241 | } |
---|
| 242 | } |
---|
| 243 | |
---|
| 244 | GraphicsEngine.prototype.initializeScene = function () { |
---|
| 245 | |
---|
| 246 | this._createRenderer(); |
---|
| 247 | this._scene = new THREE.Scene(); |
---|
| 248 | this._prepareCamera(); |
---|
| 249 | this._addLight(); |
---|
| 250 | this._controls = new THREE.TrackballControls(this._camera, this._renderer.domElement) |
---|
| 251 | this._debug(); |
---|
[188] | 252 | |
---|
| 253 | |
---|
| 254 | |
---|
[134] | 255 | } |
---|
| 256 | |
---|
| 257 | GraphicsEngine.prototype.renderScene = function () { |
---|
| 258 | |
---|
| 259 | var self = this; |
---|
| 260 | requestAnimationFrame( |
---|
| 261 | function () { |
---|
| 262 | self.renderScene(); |
---|
| 263 | }); |
---|
[208] | 264 | |
---|
[216] | 265 | /*if(!this._render) |
---|
[208] | 266 | { |
---|
| 267 | return; |
---|
[216] | 268 | }*/ |
---|
[208] | 269 | |
---|
[134] | 270 | this._renderer.render(this._scene, this._camera); |
---|
| 271 | this._controls.update(); |
---|
[208] | 272 | this._render = false; |
---|
[134] | 273 | } |
---|
| 274 | |
---|
| 275 | GraphicsEngine.prototype._debug = function() |
---|
| 276 | { |
---|
[208] | 277 | this._scene.add(new THREE.AxisHelper( 20 )); |
---|
[134] | 278 | } |
---|
| 279 | |
---|
| 280 | GraphicsEngine.prototype.debugTest = function() |
---|
| 281 | { |
---|
[188] | 282 | for(var i = 0; i < this._parts.length; i++) |
---|
| 283 | this._debugShow(this._parts[i]); |
---|
[134] | 284 | } |
---|
| 285 | |
---|