Bewahrer: three.js 3D Body

Hallöchen mal wieder.

Ich habe gerade die Aufgabe einen 3D Körper im Browser darzustellen, diesen mit der Maus drehbar zu machen, einzelne Bereiche anklickbar machen und das ganze bitteschön in jedem Browser, ohne Erweiterung.

Etwas derartiges habe ich noch nie gemacht und dann erstmal eine ganze Menge recherchieren müssen, bis ich auf three.js stieß. Leider ist three.js wenig bis lückenhaft dokumentiert und so weiß ich nie was genau eine Funktion jetzt macht. Dazu kommt, dass ich von JS wenig Ahnung habe und das ganze relativ kompliziert ist. Trotzdem habe ich es jetzt hinbekommen einen 3D Körper im Browser zu laden, der mit der Maus drehbar ist. Nun treten jedoch einige Fragen auf, die mir hier hoffentlich einige beantworten können, da das ganze Thema wirklich schlecht dokumentiert ist.

Code:

<!DOCTYPE html>  
<html lang="en">  
	<head>  
		<title>3D Body</title>  
          <script src="three.min.js"></script>  
          <script src="OBJLoader.js"></script>  
		<script src="TrackballControls.js"></script>  
          <style type="text/css">  
               #container {  
                    border:thin solid black;  
               }  
          </style>  
	</head>  
  
	<body>  
		<div id="container"></div>  
  
		<script>  
  
			var container, camera, controls, scene, renderer;  
  
			init();  
			animate();  
  
			function init() {  
                    // Renderer  
				renderer = new THREE.CanvasRenderer();  
				renderer.setSize(window.innerWidth,window.innerHeight);  
				container = document.getElementById('container');  
				container.appendChild(renderer.domElement);  
  
                    // Camera, controls  
				camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,500);  
				camera.position.z = 400;  
				controls = new THREE.TrackballControls(camera,renderer.domElement);  
				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];  
				controls.addEventListener('change',render);  
  
				// Scene  
				scene = new THREE.Scene();  
  
                    // Texture  
  
                    var texture = new THREE.Texture();  
  
				var loader = new THREE.ImageLoader();  
				loader.addEventListener( 'load', function ( event ) {  
  
					texture.image = event.content;  
					texture.needsUpdate = true;  
  
				} );  
				loader.load( 'texture.jpg' );  
  
                    // Model  
  
                    var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );  
                    var loader = new THREE.OBJLoader();  
				loader.addEventListener( 'load', function ( event ) {  
  
					var object = event.content;  
  
					object.traverse( function ( child ) {  
  
						if ( child instanceof THREE.Mesh ) {  
  
							child.material.map = texture;  
  
						}  
  
					} );  
  
					object.position.y = - 80;  
					scene.add( object );  
  
				});  
				loader.load( 'body.obj' );  
			}  
  
			function animate() {  
                    // Animate  
				requestAnimationFrame(animate);  
				controls.update();  
			}  
  
			function render() {  
                    // Render complete scene  
				renderer.render( scene, camera );  
			}  
		</script>  
  
	</body>  
</html>  

(Den obigen Code habe ich aus einigen Beispielen zusammenkopiert, solange dran rumgeschraubt bis es lief. Ich verstehe vllt. 80% des Codes...)

Falls sich jemand das Resultat im Browser selber angucken möchte, braucht er natürlich noch die body.obj, die ich mal hier hochlade: http://www.file-upload.net/download-7672976/body.obj.html

Nun zu meinen Fragen:

1. Sehe ich das richtig, dass WebGL zwar der Quasi Standard für 3D im Internet ist, allerdings noch nicht von allen unterstützt wird (FireFox, Chrome unterstützten ihn, Safari und Opera ist er per default deaktiviert aber trotzdem unterstützt und IE unterstützt ihn garnicht)?
2. Sehe ich das richtig, dass Canvas dann sozusagen eine Art Fallbackmöglichkeit ist, die ich nutzen sollte / kann damit es in allen Browsern läuft? In meinem Skript habe ich den CanvasRenderer verwendet, da es ja in allen Browsern laufen soll und da der IE WebGL nicht unterstützt, habe ich direkt mal auf den WebGLRenderer verzichtet. Ist der CanvasRenderer dann sozusagen ein Renderer, der das ganze wirklich nur als JS Code ausführt (wodurch es in jedem Browser läuft!) und damit prinzipiell langsamer als der WebGLRenderer, der das ganze ja auf die Shader der Grafikkarte ausgelagert hätte?
3. Ich habe dort eine Funktion namens animate(), die aufgerufen wird. Dort gibt es die Zeile requestAnimationFrame(animate);, jedoch verstehe ich nicht was das ganze soll. Klar habe ich gegoogelt und weiß, das das ein neues Sprachkonstrukt ist um Animationen zu erleichtern, so dass man nicht mehr die ganze Zeit mit setTimeout() arbeiten muss und es Ressourcen spart, allerdings wird in meinem Beispiel doch nichts animiert. Das Bild ist so gesehen statisch und ändert sich nicht, bis der User mit der Maus interagiert. Und dann wird render() aufgerufen und das Bild neugezeichnet. Wieso muss ich dann also animate() aufrufen mit der requestAnimationFrame(animate);-Zeile? Lasse ich das ganze Weg, funktioniert es nicht mehr..
4. Wozu ist controls.update(); gut und wieso läuft das Skript nicht mehr, wenn ich es aus der animate Funktion auslager? (update() ist eine Funktion der THREE.TrackballControls.js Bibliothek). Und ja, das ganze ist null dokumentiert. Und ja, ich habe mir die entsprechende js Datei angesehen, werde aber aus dem Code nicht schlau.
5.Hat jemand eine Idee, wie ich es am einfachsten hinkriege, dass der 3D Körper in 6 Bereiche eingeteilt wird, die mit der Maus anklickbar und selektierbar sind? Ich stelle mir das ganze wie Checkboxen vor: Man klickt auf einen Body-Teil und dieser Teil ist dann ausgewählt - will heißen der JS-Code weiß davon. Das einzige was mir jetzt einfallen würde ist mit der THREE Bibliothek die 3D Koordinaten der Maus auszurechnen und damit zu gucken wo genau auf den Körper man geklickt hat..
6. Wenn ich das Skript im IE 8 starte, kommt nur ein Haufen JS-Fehlermeldungen und es lädt nichts. Dabei müsste das ganze doch dank dem CanvasRenderer auch im IE laufen, oder? Was mache ich falsch?

Vielen Dank für jegliche Hilfe bezüglich Three.js / 3D / Javascript, aber das ganze ist wirklich schlecht dokumentiert und ich muss das irgendwie hinbekommen!

    1. Sehe ich das richtig, dass WebGL zwar der Quasi Standard für 3D im Internet ist, allerdings noch nicht von allen unterstützt wird (FireFox, Chrome unterstützten ihn, Safari und Opera ist er per default deaktiviert aber trotzdem unterstützt und IE unterstützt ihn garnicht)?

    Siehst du richtig. Eine geleakte Version vom IE11 schien aber auch eine Implementation mit sich zu bringen.

    1. Sehe ich das richtig, dass Canvas dann sozusagen eine Art Fallbackmöglichkeit ist, die ich nutzen sollte / kann damit es in allen Browsern läuft? In meinem Skript habe ich den CanvasRenderer verwendet, da es ja in allen Browsern laufen soll und da der IE WebGL nicht unterstützt, habe ich direkt mal auf den WebGLRenderer verzichtet. Ist der CanvasRenderer dann sozusagen ein Renderer, der das ganze wirklich nur als JS Code ausführt (wodurch es in jedem Browser läuft!) und damit prinzipiell langsamer als der WebGLRenderer, der das ganze ja auf die Shader der Grafikkarte ausgelagert hätte?

    Erstens langsamer, zweitens mit deutlich weniger Handlungsfreiraum. Es fehtl dir zum Beispiel z-Buffering, was dazu führt, dass ein vermeidlich weiter entferntes Objekt ein näheres Objekt überdecken kann. Shader laufen nicht und so weiter.

    1. Ich habe dort eine Funktion namens animate(), die aufgerufen wird. Dort gibt es die Zeile requestAnimationFrame(animate);, jedoch verstehe ich nicht was das ganze soll. Klar habe ich gegoogelt und weiß, das das ein neues Sprachkonstrukt ist um Animationen zu erleichtern, so dass man nicht mehr die ganze Zeit mit setTimeout() arbeiten muss und es Ressourcen spart, allerdings wird in meinem Beispiel doch nichts animiert. Das Bild ist so gesehen statisch und ändert sich nicht, bis der User mit der Maus interagiert. Und dann wird render() aufgerufen und das Bild neugezeichnet. Wieso muss ich dann also animate() aufrufen mit der requestAnimationFrame(animate);-Zeile? Lasse ich das ganze Weg, funktioniert es nicht mehr..

    Wenn du dich in dem Raum bewegst, findet sozusagen eine Animation statt, auf jedenfall muss die Szene neu gezeichnet werden.

    1. Wozu ist controls.update(); gut und wieso läuft das Skript nicht mehr, wenn ich es aus der animate Funktion auslager? (update() ist eine Funktion der THREE.TrackballControls.js Bibliothek). Und ja, das ganze ist null dokumentiert. Und ja, ich habe mir die entsprechende js Datei angesehen, werde aber aus dem Code nicht schlau.

    Das Trackball-Control muss darüber informiert, wann die Szene neugezeichnet wird und darauf reagieren. Das passiert hier. Was genau alles intern passiert, kann ich dir nicht sagen.

    5.Hat jemand eine Idee, wie ich es am einfachsten hinkriege, dass der 3D Körper in 6 Bereiche eingeteilt wird, die mit der Maus anklickbar und selektierbar sind? Ich stelle mir das ganze wie Checkboxen vor: Man klickt auf einen Body-Teil und dieser Teil ist dann ausgewählt - will heißen der JS-Code weiß davon. Das einzige was mir jetzt einfallen würde ist mit der THREE Bibliothek die 3D Koordinaten der Maus auszurechnen und damit zu gucken wo genau auf den Körper man geklickt hat..

    So funktioniert das auch, es gibt so etwas wie einen PickingRay in der Bib, der dir einen Haufen Arbeit abnimmt.

    1. Wenn ich das Skript im IE 8 starte, kommt nur ein Haufen JS-Fehlermeldungen und es lädt nichts. Dabei müsste das ganze doch dank dem CanvasRenderer auch im IE laufen, oder? Was mache ich falsch?

    Dazu kann ich ohne Beispiel leider nichts sagen. Die Fehler könnten aus deinem Code stammen, oder THREE.js könnte auf den Support von IE8 bewusst verzichten.

    Vielen Dank für jegliche Hilfe bezüglich Three.js / 3D / Javascript, aber das ganze ist wirklich schlecht dokumentiert und ich muss das irgendwie hinbekommen!

    Die Dokumentation ist wirklich stellenweise lückenhaft, aber dafür findet man tonnenweise Beispielcode und Tutorials. Viel Erfolg weiterhin.