Phil 2.18.2014

7:00 – 4:00 SR

  • ITK timesheet!
  • Updated JavaUtils.FileUtils to handle selecting a directory. Still need to check in.
  • Installed new certs on the test server
  • Working on integrating threejs with the framework.
  • Got a bunch of 3D directives running in ng-repeat.
  • Added texture maps and an assets folder. Each directive is currently loading its own copy of the texture. And it looks like it has to be that way. If I try to point at a common material, I get the following error: WebGL: INVALID_OPERATION: useProgram: object not from this context
  • Tested across the major browsers, including Chrome and Safari on the iPhone! Check it out here.
  • Working on making some threeJS base classes. This pattern seems to work…
module WGLA1_dirtv {
   // The base class for the webGL 'canvas' has the scene, root object, basic lights and a camera
   class webGLBase {
      myScope:any;
      myElements:any;
      myAttrs:any;

      frameCount:number;
      mouseX:number;
      mouseY:number;
      contW:number;
      contH:number;
      windowHalfX:number;
      windowHalfY:number;
      camera:THREE.PerspectiveCamera;
      scene:THREE.Scene;
      sphere:THREE.Mesh;
      light:THREE.DirectionalLight;
      renderer:THREE.WebGLRenderer;
      redColor:THREE.Color;
      whiteColor:THREE.Color;
      greyColor:THREE.Color;

      constructor(scope:any, element:any, attrs:any) {
         this.myScope = scope;
         this.myElements = element;
         this.myAttrs = attrs;

         this.frameCount = 0;
         this.mouseX = 0;
         this.mouseY = 0;
         this.contW = scope.width;
         this.contH = scope.height;
         this.windowHalfX = this.contW / 2;
         this.windowHalfY = this.contH / 2;
      }


      public init = ():void => {
         this.myElements[0].addEventListener('mousemove', this.onDocumentMouseMove, false);

         this.redColor = new THREE.Color(0xff0000);
         this.whiteColor = new THREE.Color(0xffffff);
         this.greyColor = new THREE.Color(0x080808);

         // Scene
         this.scene = new THREE.Scene();

         // camera
         this.camera = new THREE.PerspectiveCamera(45, this.contW / this.contH, 0.1, 10000);
         // Position is -20 along the Z axis and look at the origin
         this.camera.position = new THREE.Vector3(0, 0, 10);
         this.camera.lookAt(new THREE.Vector3(0, 0, 0));

         var sphereGeometry = new THREE.SphereGeometry(5, 20, 20);

         // This time we create a Phong shader material and provide a texture.
         var sphereMaterial = new THREE.MeshPhongMaterial(
            {
               map: THREE.ImageUtils.loadTexture("assets/earth-day.jpg")
            }
         );

         // Now make a THREE.Mesh using the geometry and a shader
         this.sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);

         // And put it at the origin
         this.sphere.position = new THREE.Vector3(0, 0, 0);

         // Add it to the scene and render the scene using the Scene and Camera objects
         this.scene.add(this.sphere);

         // Lighting
         this.light = new THREE.DirectionalLight(0xffffff);
         this.light.position.set(10, 10, 10);
         this.scene.add(this.light);
         this.scene.add(new THREE.AmbientLight(this.greyColor.getHex()));
         /****/
         this.renderer = new THREE.WebGLRenderer({antialias: true});
         this.renderer.setClearColor(this.whiteColor, 1);
         this.renderer.setSize(this.contW, this.contH);

         // element is provided by the angular directive
         this.myElements[0].appendChild(this.renderer.domElement);

         this.renderer.clear();
      };

      onDocumentMouseMove = (event:MouseEvent):void => {
         this.mouseX = ( event.clientX - this.windowHalfX );
         this.mouseY = ( event.clientY - this.windowHalfY );
      };

      render = ():void=> {
         //camera.position.x = ( mouseX - camera.position.x ) * 0.05;
         //camera.position.y = ( - mouseY - camera.position.y ) * 0.05;

         this.camera.lookAt(this.scene.position);
         this.renderer.render(this.scene, this.camera);
         this.frameCount++;
         //console.log("frameCount = "+frameCount);
      };

      animate = () => {
         this.sphere.rotation.y = this.frameCount * 0.01;
         requestAnimationFrame(this.animate);
         this.render();
      };
   }

   // The webGL directive. Instantiates a webGlBase-derived class for each scope
   export class ngWebgl {
      private myDirective:ng.IDirective;

      constructor() {
         this.myDirective = null;
      }

      private linkFn = (scope:any, element:any, attrs:any) => {
         scope.webGlBase = new webGLBase(scope, element, attrs);
         scope.webGlBase.init();
         scope.webGlBase.animate();
      };

      public ctor = ():ng.IDirective => {
         if (!this.myDirective) {
            this.myDirective = {
               restrict: 'A',
               scope: {
                  'width': '=',
                  'height': '=',
                  'fillcontainer': '=',
                  'scale': '=',
                  'materialType': '='
               },
               link: this.linkFn
            }
         }
         return this.myDirective;
      }
   }
}