From bbf34fbd13711a4e913e9092a9aaf7d5d811534c Mon Sep 17 00:00:00 2001 From: kevinroast Date: Mon, 4 Nov 2013 17:00:05 +0000 Subject: [PATCH] Refactored global math constants into Phoria namespace (e.g. RADIANS is now Phoria.RADIANS) Normal matrix calculation fixes related to transformed normals - fixes issues with non-uniform object scaling and translation of objects messing up lighting. Optimized some related normal calculations. Improved documentation related to Distant light direction (i.e. normalized direction vector) Improved code comments related to object->world->camera space calculations. Allow a texture index to be set on the 'style' for an Entity - to avoid having to set texture index per polygon when all polygons are using same texture. Tweaked test0uv to demonstrate. Fixed scene JSON serialisation (prototype) related to objects with textures applied. Fixed top and bottom generated cube face orientation (for uv coords). --- index.html | 8 +- scripts/phoria-entity.js | 16 ++-- scripts/phoria-min.js | 2 +- scripts/phoria-renderer.js | 16 ++-- scripts/phoria-scene.js | 62 +++++++------ scripts/phoria-util.js | 37 +++++--- test0.html | 2 +- test0k.html | 10 +-- test0t.html | 8 +- test0uv.html | 31 +++---- test1.html | 8 +- test2.html | 2 +- test3.html | 4 +- test3m.html | 2 +- test3p.html | 4 +- test3s.html | 4 +- test3s_teapot.html | 172 +++++++++++++++++++++++++++++++++++++ test4.html | 2 +- test4p.html | 2 +- test5.html | 9 +- test9.html | 6 +- 21 files changed, 299 insertions(+), 108 deletions(-) create mode 100644 test3s_teapot.html diff --git a/index.html b/index.html index 9df4dee..982f620 100644 --- a/index.html +++ b/index.html @@ -205,14 +205,14 @@ var rotates = [0,0,0]; var fnAnimate = function() {2 // rotate local matrix of an object - testCube.rotateY(0.5*RADIANS); + testCube.rotateY(0.5*Phoria.RADIANS); // translate local matrix of child object - will receive rotation from parent childCube.identity().translateY(Math.sin(Date.now() / 1000) + 3); // translate visible light objects around the origin - will rotate child Light emitters var sine = Math.sin(Date.now() / 500); - blueLightObj.identity().rotateY(rotates[0]+=1*RADIANS).translateY(sine); - redLightObj.identity().rotateY(rotates[1]+=0.5*RADIANS).translateY(sine); - greenLightObj.identity().rotateY(rotates[2]+=1.5*RADIANS).translateY(sine); + blueLightObj.identity().rotateY(rotates[0]+=1*Phoria.RADIANS).translateY(sine); + redLightObj.identity().rotateY(rotates[1]+=0.5*Phoria.RADIANS).translateY(sine); + greenLightObj.identity().rotateY(rotates[2]+=1.5*Phoria.RADIANS).translateY(sine); // execute the model view 3D pipeline scene.modelView(); diff --git a/scripts/phoria-entity.js b/scripts/phoria-entity.js index 5a4a569..dbea5b0 100644 --- a/scripts/phoria-entity.js +++ b/scripts/phoria-entity.js @@ -158,7 +158,7 @@ }; })(); -var CLIP_ARRAY_TYPE = (typeof Uint32Array !== 'undefined') ? Uint32Array : Array; +Phoria.CLIP_ARRAY_TYPE = (typeof Uint32Array !== 'undefined') ? Uint32Array : Array; (function() { "use strict"; @@ -189,7 +189,7 @@ var CLIP_ARRAY_TYPE = (typeof Uint32Array !== 'undefined') ? Uint32Array : Array fillmode: "inflate", linewidth: 1.0, linescale: 0.0, - hiddenangle: -PI/2, + hiddenangle: -Phoria.PIO2, doublesided: false }; @@ -218,7 +218,8 @@ var CLIP_ARRAY_TYPE = (typeof Uint32Array !== 'undefined') ? Uint32Array : Array * linewidth: 1.0, // wireframe line thickness * linescale: 0.0, // depth based scaling factor for wireframes - can be zero for no scaling * hiddenangle: 0.0, // hidden surface test angle - generally between -PI and 0 - depends on perspective fov - * doublesided: false + * doublesided: false, // true to always render polygons - i.e. do not perform hidden surface test + * texture: undefined // default texture index to use for polygons if not specified - e.g. when UVs are used * } * onRender: function() {...} * } @@ -393,7 +394,7 @@ var CLIP_ARRAY_TYPE = (typeof Uint32Array !== 'undefined') ? Uint32Array : Array } if (this._clip === null || this._clip.length < len) { - this._clip = new CLIP_ARRAY_TYPE(len); + this._clip = new Phoria.CLIP_ARRAY_TYPE(len); } }, @@ -777,12 +778,13 @@ Phoria.PhysicsEntity.GRAVITY = {x:0, y:-9.8, z:0}; "use strict"; /** - * DistantLight models an infinitely distant light that has no position only a direction from which light eminates. + * DistantLight models an infinitely distant light that has no position only a normalised direction from which light eminates. */ Phoria.DistantLight = function() { Phoria.DistantLight.superclass.constructor.call(this); + // direction should be a normalised vector this.direction = {x:0, y:0, z:1}; // add scene handler to transform the light direction into world direction @@ -801,7 +803,7 @@ Phoria.PhysicsEntity.GRAVITY = {x:0, y:-9.8, z:0}; Phoria.BaseEntity.create(desc, e); if (desc.color) e.color = desc.color; if (desc.intensity) e.intensity = desc.intensity; - if (desc.direction) e.direction = desc.direction; + if (desc.direction) e.direction = vec3.toXYZ(vec3.normalize(e.direction, vec3.fromXYZ(desc.direction))); return e; }; @@ -811,7 +813,7 @@ Phoria.PhysicsEntity.GRAVITY = {x:0, y:-9.8, z:0}; direction: null, worlddirection: null, - transformToScene: function transformToScene(scene, matLocal, time) + transformToScene: function transformToScene() { this.worlddirection = vec3.fromValues( -this.direction.x, diff --git a/scripts/phoria-min.js b/scripts/phoria-min.js index 7c6b944..299dfd6 100644 --- a/scripts/phoria-min.js +++ b/scripts/phoria-min.js @@ -1 +1 @@ -(function(b){var a={};if(typeof(exports)==="undefined"){if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){a.exports={};define(function(){return a.exports})}else{a.exports=typeof(window)!=="undefined"?window:b}}else{a.exports=exports}(function(j){if(!o){var o=0.000001}if(!e){var e=(typeof Float32Array!=="undefined")?Float32Array:Array}if(!i){var i=Math.random}var f={};f.setMatrixArrayType=function(p){e=p};if(typeof(j)!=="undefined"){j.glMatrix=f}var m={};m.create=function(){var p=new e(2);p[0]=0;p[1]=0;return p};m.clone=function(p){var q=new e(2);q[0]=p[0];q[1]=p[1];return q};m.fromValues=function(p,r){var q=new e(2);q[0]=p;q[1]=r;return q};m.copy=function(q,p){q[0]=p[0];q[1]=p[1];return q};m.set=function(q,p,r){q[0]=p;q[1]=r;return q};m.add=function(r,q,p){r[0]=q[0]+p[0];r[1]=q[1]+p[1];return r};m.subtract=function(r,q,p){r[0]=q[0]-p[0];r[1]=q[1]-p[1];return r};m.sub=m.subtract;m.multiply=function(r,q,p){r[0]=q[0]*p[0];r[1]=q[1]*p[1];return r};m.mul=m.multiply;m.divide=function(r,q,p){r[0]=q[0]/p[0];r[1]=q[1]/p[1];return r};m.div=m.divide;m.min=function(r,q,p){r[0]=Math.min(q[0],p[0]);r[1]=Math.min(q[1],p[1]);return r};m.max=function(r,q,p){r[0]=Math.max(q[0],p[0]);r[1]=Math.max(q[1],p[1]);return r};m.scale=function(r,q,p){r[0]=q[0]*p;r[1]=q[1]*p;return r};m.scaleAndAdd=function(r,q,p,s){r[0]=q[0]+(p[0]*s);r[1]=q[1]+(p[1]*s);return r};m.distance=function(r,q){var p=q[0]-r[0],s=q[1]-r[1];return Math.sqrt(p*p+s*s)};m.dist=m.distance;m.squaredDistance=function(r,q){var p=q[0]-r[0],s=q[1]-r[1];return p*p+s*s};m.sqrDist=m.squaredDistance;m.length=function(q){var p=q[0],r=q[1];return Math.sqrt(p*p+r*r)};m.len=m.length;m.squaredLength=function(q){var p=q[0],r=q[1];return p*p+r*r};m.sqrLen=m.squaredLength;m.negate=function(q,p){q[0]=-p[0];q[1]=-p[1];return q};m.normalize=function(s,r){var q=r[0],t=r[1];var p=q*q+t*t;if(p>0){p=1/Math.sqrt(p);s[0]=r[0]*p;s[1]=r[1]*p}return s};m.dot=function(q,p){return q[0]*p[0]+q[1]*p[1]};m.cross=function(r,q,p){var s=q[0]*p[1]-q[1]*p[0];r[0]=r[1]=0;r[2]=s;return r};m.lerp=function(r,q,p,s){var v=q[0],u=q[1];r[0]=v+s*(p[0]-v);r[1]=u+s*(p[1]-u);return r};m.random=function(p,s){s=s||1;var q=i()*2*Math.PI;p[0]=Math.cos(q)*s;p[1]=Math.sin(q)*s;return p};m.transformMat2=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[2]*t;s[1]=q[1]*p+q[3]*t;return s};m.transformMat2d=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[2]*t+q[4];s[1]=q[1]*p+q[3]*t+q[5];return s};m.transformMat3=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[3]*t+q[6];s[1]=q[1]*p+q[4]*t+q[7];return s};m.transformMat4=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[4]*t+q[12];s[1]=q[1]*p+q[5]*t+q[13];return s};m.forEach=(function(){var p=m.create();return function(s,w,x,v,u,q){var t,r;if(!w){w=2}if(!x){x=0}if(v){r=Math.min((v*w)+x,s.length)}else{r=s.length}for(t=x;t0){p=1/Math.sqrt(p);s[0]=r[0]*p;s[1]=r[1]*p;s[2]=r[2]*p}return s};l.dot=function(q,p){return q[0]*p[0]+q[1]*p[1]+q[2]*p[2]};l.cross=function(q,v,u){var p=v[0],x=v[1],w=v[2],t=u[0],s=u[1],r=u[2];q[0]=x*r-w*s;q[1]=w*t-p*r;q[2]=p*s-x*t;return q};l.lerp=function(r,q,p,s){var w=q[0],v=q[1],u=q[2];r[0]=w+s*(p[0]-w);r[1]=v+s*(p[1]-v);r[2]=u+s*(p[2]-u);return r};l.random=function(p,u){u=u||1;var s=i()*2*Math.PI;var t=(i()*2)-1;var q=Math.sqrt(1-t*t)*u;p[0]=Math.cos(s)*q;p[1]=Math.sin(s)*q;p[2]=t*u;return p};l.transformMat4=function(s,r,q){var p=r[0],u=r[1],t=r[2];s[0]=q[0]*p+q[4]*u+q[8]*t+q[12];s[1]=q[1]*p+q[5]*u+q[9]*t+q[13];s[2]=q[2]*p+q[6]*u+q[10]*t+q[14];return s};l.transformMat3=function(s,r,q){var p=r[0],u=r[1],t=r[2];s[0]=p*q[0]+u*q[3]+t*q[6];s[1]=p*q[1]+u*q[4]+t*q[7];s[2]=p*q[2]+u*q[5]+t*q[8];return s};l.transformQuat=function(w,F,p){var G=F[0],E=F[1],D=F[2],B=p[0],A=p[1],v=p[2],C=p[3],t=C*G+A*D-v*E,s=C*E+v*G-B*D,r=C*D+B*E-A*G,u=-B*G-A*E-v*D;w[0]=t*C+u*-B+s*-v-r*-A;w[1]=s*C+u*-A+r*-B-t*-v;w[2]=r*C+u*-v+t*-A-s*-B;return w};l.forEach=(function(){var p=l.create();return function(s,w,x,v,u,q){var t,r;if(!w){w=3}if(!x){x=0}if(v){r=Math.min((v*w)+x,s.length)}else{r=s.length}for(t=x;t0){p=1/Math.sqrt(p);t[0]=s[0]*p;t[1]=s[1]*p;t[2]=s[2]*p;t[3]=s[3]*p}return t};k.dot=function(q,p){return q[0]*p[0]+q[1]*p[1]+q[2]*p[2]+q[3]*p[3]};k.lerp=function(r,q,p,s){var w=q[0],v=q[1],u=q[2],x=q[3];r[0]=w+s*(p[0]-w);r[1]=v+s*(p[1]-v);r[2]=u+s*(p[2]-u);r[3]=x+s*(p[3]-x);return r};k.random=function(p,q){q=q||1;p[0]=i();p[1]=i();p[2]=i();p[3]=i();k.normalize(p,p);k.scale(p,p,q);return p};k.transformMat4=function(t,s,q){var p=s[0],v=s[1],u=s[2],r=s[3];t[0]=q[0]*p+q[4]*v+q[8]*u+q[12]*r;t[1]=q[1]*p+q[5]*v+q[9]*u+q[13]*r;t[2]=q[2]*p+q[6]*v+q[10]*u+q[14]*r;t[3]=q[3]*p+q[7]*v+q[11]*u+q[15]*r;return t};k.transformQuat=function(w,F,p){var G=F[0],E=F[1],D=F[2],B=p[0],A=p[1],v=p[2],C=p[3],t=C*G+A*D-v*E,s=C*E+v*G-B*D,r=C*D+B*E-A*G,u=-B*G-A*E-v*D;w[0]=t*C+u*-B+s*-v-r*-A;w[1]=s*C+u*-A+r*-B-t*-v;w[2]=r*C+u*-v+t*-A-s*-B;return w};k.forEach=(function(){var p=k.create();return function(s,w,x,v,u,q){var t,r;if(!w){w=4}if(!x){x=0}if(v){r=Math.min((v*w)+x,s.length)}else{r=s.length}for(t=x;t0.999999){v[0]=0;v[1]=0;v[2]=0;v[3]=1;return v}else{l.cross(p,t,s);v[0]=p[0];v[1]=p[1];v[2]=p[2];v[3]=1+u;return h.normalize(v,v)}}}})();h.setAxes=(function(){var p=d.create();return function(s,r,t,q){p[0]=t[0];p[3]=t[1];p[6]=t[2];p[1]=q[0];p[4]=q[1];p[7]=q[2];p[2]=r[0];p[5]=r[1];p[8]=r[2];return h.normalize(s,h.fromMat3(s,p))}})();h.clone=k.clone;h.fromValues=k.fromValues;h.copy=k.copy;h.set=k.set;h.identity=function(p){p[0]=0;p[1]=0;p[2]=0;p[3]=1;return p};h.setAxisAngle=function(q,t,p){p=p*0.5;var r=Math.sin(p);q[0]=r*t[0];q[1]=r*t[1];q[2]=r*t[2];q[3]=Math.cos(p);return q};h.add=k.add;h.multiply=function(r,x,w){var p=x[0],z=x[1],y=x[2],q=x[3],u=w[0],t=w[1],s=w[2],v=w[3];r[0]=p*v+q*u+z*s-y*t;r[1]=z*v+q*t+y*u-p*s;r[2]=y*v+q*s+p*t-z*u;r[3]=q*v-p*u-z*t-y*s;return r};h.mul=h.multiply;h.scale=k.scale;h.rotateX=function(r,v,t){t*=0.5;var p=v[0],x=v[1],w=v[2],q=v[3],s=Math.sin(t),u=Math.cos(t);r[0]=p*u+q*s;r[1]=x*u+w*s;r[2]=w*u-x*s;r[3]=q*u-p*s;return r};h.rotateY=function(r,v,t){t*=0.5;var p=v[0],x=v[1],w=v[2],q=v[3],s=Math.sin(t),u=Math.cos(t);r[0]=p*u-w*s;r[1]=x*u+q*s;r[2]=w*u+p*s;r[3]=q*u-x*s;return r};h.rotateZ=function(r,v,t){t*=0.5;var p=v[0],x=v[1],w=v[2],q=v[3],s=Math.sin(t),u=Math.cos(t);r[0]=p*u+x*s;r[1]=x*u-p*s;r[2]=w*u+q*s;r[3]=q*u-w*s;return r};h.calculateW=function(r,q){var p=q[0],t=q[1],s=q[2];r[0]=p;r[1]=t;r[2]=s;r[3]=-Math.sqrt(Math.abs(1-p*p-t*t-s*s));return r};h.dot=k.dot;h.lerp=k.lerp;h.slerp=function(u,C,B,F){var p=C[0],G=C[1],E=C[2],r=C[3],z=B[0],y=B[1],x=B[2],A=B[3];var D,q,s,w,v;q=p*z+G*y+E*x+r*A;if(q<0){q=-q;z=-z;y=-y;x=-x;A=-A}if((1-q)>0.000001){D=Math.acos(q);s=Math.sin(D);w=Math.sin((1-F)*D)/s;v=Math.sin(F*D)/s}else{w=1-F;v=F}u[0]=w*p+v*z;u[1]=w*G+v*y;u[2]=w*E+v*x;u[3]=w*r+v*A;return u};h.invert=function(v,r){var t=r[0],q=r[1],p=r[2],w=r[3],s=t*t+q*q+p*p+w*w,u=s?1/s:0;v[0]=-t*u;v[1]=-q*u;v[2]=-p*u;v[3]=w*u;return v};h.conjugate=function(q,p){q[0]=-p[0];q[1]=-p[1];q[2]=-p[2];q[3]=p[3];return q};h.length=k.length;h.len=h.length;h.squaredLength=k.squaredLength;h.sqrLen=h.squaredLength;h.normalize=k.normalize;h.fromMat3=(function(){var p=(typeof(Int8Array)!=="undefined"?new Int8Array([1,2,0]):[1,2,0]);return function(u,q){var r=q[0]+q[4]+q[8];var w;if(r>0){w=Math.sqrt(r+1);u[3]=0.5*w;w=0.5/w;u[0]=(q[7]-q[5])*w;u[1]=(q[2]-q[6])*w;u[2]=(q[3]-q[1])*w}else{var v=0;if(q[4]>q[0]){v=1}if(q[8]>q[v*3+v]){v=2}var t=p[v];var s=p[t];w=Math.sqrt(q[v*3+v]-q[t*3+t]-q[s*3+s]+1);u[v]=0.5*w;w=0.5/w;u[3]=(q[s*3+t]-q[t*3+s])*w;u[t]=(q[t*3+v]+q[v*3+t])*w;u[s]=(q[s*3+v]+q[v*3+s])*w}return u}})();h.str=function(p){return"quat("+p[0]+", "+p[1]+", "+p[2]+", "+p[3]+")"};if(typeof(j)!=="undefined"){j.quat=h}})(a.exports)})(this);var RADIANS=Math.PI/180;var PI=Math.PI;var TWOPI=Math.PI*2;var ONEOPI=1/Math.PI;var PIO2=Math.PI/2;var EPSILON=0.000001;glMatrix.setMatrixArrayType(Array);vec3.fromXYZ=function(a){var b=new Array(3);b[0]=a.x;b[1]=a.y;b[2]=a.z;return b};vec4.fromXYZ=function(b,a){var c=new Array(4);c[0]=b.x;c[1]=b.y;c[2]=b.z;c[3]=a;return c};if(typeof Phoria==="undefined"||!Phoria){var Phoria={}}(function(){Phoria.Util={};Phoria.Util.extend=function p(w,x,v){var u=function(){},t;u.prototype=x.prototype;w.prototype=new u();w.prototype.constructor=w;w.superclass=x.prototype;if(x.prototype.constructor==Object.prototype.constructor){x.prototype.constructor=x}if(v){for(t in v){if(v.hasOwnProperty(t)){w.prototype[t]=v[t]}}}};Phoria.Util.augment=function n(u,t){for(var v in t.prototype){if(typeof u.prototype[v]==="undefined"){u.prototype[v]=t.prototype[v]}}};Phoria.Util.merge=function f(t,u){var w=Array.isArray(u),v=w&&[]||{};if(w){t=t||[];v=v.concat(t);u.forEach(function(y,x){if(typeof y==="object"){v[x]=Phoria.Util.merge(t[x],y)}else{v[x]=y}})}else{if(t&&typeof t==="object"){Object.keys(t).forEach(function(x){v[x]=t[x]})}Object.keys(u).forEach(function(x){if(typeof u[x]!=="object"||!u[x]){v[x]=u[x]}else{if(!t||!t[x]){v[x]=u[x]}else{v[x]=Phoria.Util.merge(t[x],u[x])}}})}return v};Phoria.Util.combine=function s(t,u){var v=Array.isArray(u)&&Array.isArray(t);if(v){if(t.lengthC){A=x[(C+y)>>1][2];while(z<=B){while(zC&&x[B][2]>A){B--}if(z<=B){w=D[z];D[z]=D[B];D[B]=w;w=x[z];x[z]=x[B];x[B]=w;z++;B--}}if(C>1,y,y,y);t.addColorStop(0,A);t.addColorStop(1,x);u.fillStyle=t;u.fillRect(0,0,z,z);var w=new Image();w.src=v.toDataURL("image/png");return w}})();(function(){Phoria.Preloader=function(){this.images=[];return this};Phoria.Preloader.prototype={images:null,callback:null,counter:0,addImage:function b(c,d){var e=this;c.url=d;c.onload=function(){e.counter++;if(e.counter===e.images.length){e.callback.call(e)}};this.images.push(c)},onLoadCallback:function a(e){this.counter=0;this.callback=e;for(var d=0,c=this.images.length;dB+L||E[0]<-B-L||E[1]>B+L||E[1]<-B-L||E[2]>B||E[2]<-B)?1:0);E[0]/=B;E[1]/=B;E[2]/=B;E[0]=v*E[0]+u+v;E[1]=i*E[1]+s+i}if(y!==I){if(D.polygons.length!==0){var z=mat4.invert(mat4.clone(A),A);mat4.transpose(z,z);switch(D.style.shademode){case"plain":case"lightsource":for(var G=0,N,K;Gd._gravetime){this.children.splice(j,1)}}var q=e-this._lastEmitTime;var n=Math.floor((this.rate/1000)*q);if(n>0){for(var o=0;o1.5||Math.abs(k[1]-u[q[o]][1])>1.5){k[0]=u[q[o]][0];k[1]=u[q[o]][1]}l[o]=k}return l},intersection:function f(j,i,n,m){var h=i.x-j.x,p=n.x-m.x,l=n.x-j.x,g=i.y-j.y,o=n.y-m.y,k=n.y-j.y,q=(p*k-o*l)/(g*p-h*o);return[j.x+q*(i.x-j.x),j.y+q*(i.y-j.y)]}}})();(function(){Phoria.CanvasRenderer=function(e){Phoria.CanvasRenderer.superclass.constructor.call(this);this.canvas=e;this.ctx=e.getContext("2d");return this};Phoria.Util.extend(Phoria.CanvasRenderer,Phoria.Renderer,{canvas:null,ctx:null,render:function c(k,m){this.sortObjects(k);var f=this.ctx;if(!m){f.clearRect(0,0,this.canvas.width,this.canvas.height)}else{m.call(this,f)}for(var l=0,j;l1){f=1}s.fillStyle="rgba("+k+","+(1-f).toFixed(3)+")"}if(l.length===3){F=0,n=0,E=C.width,m=0,B=C.width,h=C.height;if(g.uvs!==undefined){F=C.width*g.uvs[0];n=C.height*g.uvs[1];E=C.width*g.uvs[2];m=C.height*g.uvs[3];B=C.width*g.uvs[4];h=C.height*g.uvs[5]}var q=this.inflatePolygon(l,x,0.5);r.call(this,q,F,n,E,m,B,h);if(k!==null){s.fill()}}else{if(l.length===4){F=0,n=0,E=C.width,m=0,B=C.width,h=C.height;if(g.uvs!==undefined){F=C.width*g.uvs[0];n=C.height*g.uvs[1];E=C.width*g.uvs[2];m=C.height*g.uvs[3];B=C.width*g.uvs[4];h=C.height*g.uvs[5]}s.save();var q=this.inflatePolygon(l.slice(0,3),x,0.5);r.call(this,q,F,n,E,m,B,h);s.restore();F=C.width,n=C.height,E=0,m=C.height,B=0,h=0;if(g.uvs!==undefined){F=C.width*g.uvs[4];n=C.height*g.uvs[5];E=C.width*g.uvs[6];m=C.height*g.uvs[7];B=C.width*g.uvs[0];h=C.height*g.uvs[1]}s.save();var o=new Array(3);o[0]=l[2];o[1]=l[3];o[2]=l[0];q=this.inflatePolygon(o,x,0.5);r.call(this,q,F,n,E,m,B,h);s.restore();if(k!==null){q=this.inflatePolygon(l,x,0.75);s.beginPath();s.moveTo(q[0][0],q[0][1]);for(var y=1,w=q.length;y>4,0),F=Math.min((Math.max(s,q,o)+15)>>4,L),B=Math.max((Math.min(V,T,S)+15)>>4,0),f=Math.min((Math.max(V,T,S)+15)>>4,m);if(F<=l||f<=B){return}var j=w*s-C*V,i=k*q-p*T,h=N*o-U*S;if(w<0||(w==0&&C>0)){j++}if(k<0||(k==0&&p>0)){i++}if(N<0||(N==0&&U>0)){h++}var z=j+C*(B<<4)-w*(l<<4),v=i+p*(B<<4)-k*(l<<4),u=h+U*(B<<4)-N*(l<<4),M,K,J;for(var D=B,G,H;D0&&K>0&&J>0){H=(G+D*L)<<2;P[H]=I;P[H+1]=O;P[H+2]=Q;P[H+3]=255}M-=A;K-=n;J-=R}z+=E;v+=t;u+=e}}})})(); \ No newline at end of file +(function(b){var a={};if(typeof(exports)==="undefined"){if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){a.exports={};define(function(){return a.exports})}else{a.exports=typeof(window)!=="undefined"?window:b}}else{a.exports=exports}(function(j){if(!o){var o=0.000001}if(!e){var e=(typeof Float32Array!=="undefined")?Float32Array:Array}if(!i){var i=Math.random}var f={};f.setMatrixArrayType=function(p){e=p};if(typeof(j)!=="undefined"){j.glMatrix=f}var m={};m.create=function(){var p=new e(2);p[0]=0;p[1]=0;return p};m.clone=function(p){var q=new e(2);q[0]=p[0];q[1]=p[1];return q};m.fromValues=function(p,r){var q=new e(2);q[0]=p;q[1]=r;return q};m.copy=function(q,p){q[0]=p[0];q[1]=p[1];return q};m.set=function(q,p,r){q[0]=p;q[1]=r;return q};m.add=function(r,q,p){r[0]=q[0]+p[0];r[1]=q[1]+p[1];return r};m.subtract=function(r,q,p){r[0]=q[0]-p[0];r[1]=q[1]-p[1];return r};m.sub=m.subtract;m.multiply=function(r,q,p){r[0]=q[0]*p[0];r[1]=q[1]*p[1];return r};m.mul=m.multiply;m.divide=function(r,q,p){r[0]=q[0]/p[0];r[1]=q[1]/p[1];return r};m.div=m.divide;m.min=function(r,q,p){r[0]=Math.min(q[0],p[0]);r[1]=Math.min(q[1],p[1]);return r};m.max=function(r,q,p){r[0]=Math.max(q[0],p[0]);r[1]=Math.max(q[1],p[1]);return r};m.scale=function(r,q,p){r[0]=q[0]*p;r[1]=q[1]*p;return r};m.scaleAndAdd=function(r,q,p,s){r[0]=q[0]+(p[0]*s);r[1]=q[1]+(p[1]*s);return r};m.distance=function(r,q){var p=q[0]-r[0],s=q[1]-r[1];return Math.sqrt(p*p+s*s)};m.dist=m.distance;m.squaredDistance=function(r,q){var p=q[0]-r[0],s=q[1]-r[1];return p*p+s*s};m.sqrDist=m.squaredDistance;m.length=function(q){var p=q[0],r=q[1];return Math.sqrt(p*p+r*r)};m.len=m.length;m.squaredLength=function(q){var p=q[0],r=q[1];return p*p+r*r};m.sqrLen=m.squaredLength;m.negate=function(q,p){q[0]=-p[0];q[1]=-p[1];return q};m.normalize=function(s,r){var q=r[0],t=r[1];var p=q*q+t*t;if(p>0){p=1/Math.sqrt(p);s[0]=r[0]*p;s[1]=r[1]*p}return s};m.dot=function(q,p){return q[0]*p[0]+q[1]*p[1]};m.cross=function(r,q,p){var s=q[0]*p[1]-q[1]*p[0];r[0]=r[1]=0;r[2]=s;return r};m.lerp=function(r,q,p,s){var v=q[0],u=q[1];r[0]=v+s*(p[0]-v);r[1]=u+s*(p[1]-u);return r};m.random=function(p,s){s=s||1;var q=i()*2*Math.PI;p[0]=Math.cos(q)*s;p[1]=Math.sin(q)*s;return p};m.transformMat2=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[2]*t;s[1]=q[1]*p+q[3]*t;return s};m.transformMat2d=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[2]*t+q[4];s[1]=q[1]*p+q[3]*t+q[5];return s};m.transformMat3=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[3]*t+q[6];s[1]=q[1]*p+q[4]*t+q[7];return s};m.transformMat4=function(s,r,q){var p=r[0],t=r[1];s[0]=q[0]*p+q[4]*t+q[12];s[1]=q[1]*p+q[5]*t+q[13];return s};m.forEach=(function(){var p=m.create();return function(s,w,x,v,u,q){var t,r;if(!w){w=2}if(!x){x=0}if(v){r=Math.min((v*w)+x,s.length)}else{r=s.length}for(t=x;t0){p=1/Math.sqrt(p);s[0]=r[0]*p;s[1]=r[1]*p;s[2]=r[2]*p}return s};l.dot=function(q,p){return q[0]*p[0]+q[1]*p[1]+q[2]*p[2]};l.cross=function(q,v,u){var p=v[0],x=v[1],w=v[2],t=u[0],s=u[1],r=u[2];q[0]=x*r-w*s;q[1]=w*t-p*r;q[2]=p*s-x*t;return q};l.lerp=function(r,q,p,s){var w=q[0],v=q[1],u=q[2];r[0]=w+s*(p[0]-w);r[1]=v+s*(p[1]-v);r[2]=u+s*(p[2]-u);return r};l.random=function(p,u){u=u||1;var s=i()*2*Math.PI;var t=(i()*2)-1;var q=Math.sqrt(1-t*t)*u;p[0]=Math.cos(s)*q;p[1]=Math.sin(s)*q;p[2]=t*u;return p};l.transformMat4=function(s,r,q){var p=r[0],u=r[1],t=r[2];s[0]=q[0]*p+q[4]*u+q[8]*t+q[12];s[1]=q[1]*p+q[5]*u+q[9]*t+q[13];s[2]=q[2]*p+q[6]*u+q[10]*t+q[14];return s};l.transformMat3=function(s,r,q){var p=r[0],u=r[1],t=r[2];s[0]=p*q[0]+u*q[3]+t*q[6];s[1]=p*q[1]+u*q[4]+t*q[7];s[2]=p*q[2]+u*q[5]+t*q[8];return s};l.transformQuat=function(w,F,p){var G=F[0],E=F[1],D=F[2],B=p[0],A=p[1],v=p[2],C=p[3],t=C*G+A*D-v*E,s=C*E+v*G-B*D,r=C*D+B*E-A*G,u=-B*G-A*E-v*D;w[0]=t*C+u*-B+s*-v-r*-A;w[1]=s*C+u*-A+r*-B-t*-v;w[2]=r*C+u*-v+t*-A-s*-B;return w};l.forEach=(function(){var p=l.create();return function(s,w,x,v,u,q){var t,r;if(!w){w=3}if(!x){x=0}if(v){r=Math.min((v*w)+x,s.length)}else{r=s.length}for(t=x;t0){p=1/Math.sqrt(p);t[0]=s[0]*p;t[1]=s[1]*p;t[2]=s[2]*p;t[3]=s[3]*p}return t};k.dot=function(q,p){return q[0]*p[0]+q[1]*p[1]+q[2]*p[2]+q[3]*p[3]};k.lerp=function(r,q,p,s){var w=q[0],v=q[1],u=q[2],x=q[3];r[0]=w+s*(p[0]-w);r[1]=v+s*(p[1]-v);r[2]=u+s*(p[2]-u);r[3]=x+s*(p[3]-x);return r};k.random=function(p,q){q=q||1;p[0]=i();p[1]=i();p[2]=i();p[3]=i();k.normalize(p,p);k.scale(p,p,q);return p};k.transformMat4=function(t,s,q){var p=s[0],v=s[1],u=s[2],r=s[3];t[0]=q[0]*p+q[4]*v+q[8]*u+q[12]*r;t[1]=q[1]*p+q[5]*v+q[9]*u+q[13]*r;t[2]=q[2]*p+q[6]*v+q[10]*u+q[14]*r;t[3]=q[3]*p+q[7]*v+q[11]*u+q[15]*r;return t};k.transformQuat=function(w,F,p){var G=F[0],E=F[1],D=F[2],B=p[0],A=p[1],v=p[2],C=p[3],t=C*G+A*D-v*E,s=C*E+v*G-B*D,r=C*D+B*E-A*G,u=-B*G-A*E-v*D;w[0]=t*C+u*-B+s*-v-r*-A;w[1]=s*C+u*-A+r*-B-t*-v;w[2]=r*C+u*-v+t*-A-s*-B;return w};k.forEach=(function(){var p=k.create();return function(s,w,x,v,u,q){var t,r;if(!w){w=4}if(!x){x=0}if(v){r=Math.min((v*w)+x,s.length)}else{r=s.length}for(t=x;t0.999999){v[0]=0;v[1]=0;v[2]=0;v[3]=1;return v}else{l.cross(p,t,s);v[0]=p[0];v[1]=p[1];v[2]=p[2];v[3]=1+u;return h.normalize(v,v)}}}})();h.setAxes=(function(){var p=d.create();return function(s,r,t,q){p[0]=t[0];p[3]=t[1];p[6]=t[2];p[1]=q[0];p[4]=q[1];p[7]=q[2];p[2]=r[0];p[5]=r[1];p[8]=r[2];return h.normalize(s,h.fromMat3(s,p))}})();h.clone=k.clone;h.fromValues=k.fromValues;h.copy=k.copy;h.set=k.set;h.identity=function(p){p[0]=0;p[1]=0;p[2]=0;p[3]=1;return p};h.setAxisAngle=function(q,t,p){p=p*0.5;var r=Math.sin(p);q[0]=r*t[0];q[1]=r*t[1];q[2]=r*t[2];q[3]=Math.cos(p);return q};h.add=k.add;h.multiply=function(r,x,w){var p=x[0],z=x[1],y=x[2],q=x[3],u=w[0],t=w[1],s=w[2],v=w[3];r[0]=p*v+q*u+z*s-y*t;r[1]=z*v+q*t+y*u-p*s;r[2]=y*v+q*s+p*t-z*u;r[3]=q*v-p*u-z*t-y*s;return r};h.mul=h.multiply;h.scale=k.scale;h.rotateX=function(r,v,t){t*=0.5;var p=v[0],x=v[1],w=v[2],q=v[3],s=Math.sin(t),u=Math.cos(t);r[0]=p*u+q*s;r[1]=x*u+w*s;r[2]=w*u-x*s;r[3]=q*u-p*s;return r};h.rotateY=function(r,v,t){t*=0.5;var p=v[0],x=v[1],w=v[2],q=v[3],s=Math.sin(t),u=Math.cos(t);r[0]=p*u-w*s;r[1]=x*u+q*s;r[2]=w*u+p*s;r[3]=q*u-x*s;return r};h.rotateZ=function(r,v,t){t*=0.5;var p=v[0],x=v[1],w=v[2],q=v[3],s=Math.sin(t),u=Math.cos(t);r[0]=p*u+x*s;r[1]=x*u-p*s;r[2]=w*u+q*s;r[3]=q*u-w*s;return r};h.calculateW=function(r,q){var p=q[0],t=q[1],s=q[2];r[0]=p;r[1]=t;r[2]=s;r[3]=-Math.sqrt(Math.abs(1-p*p-t*t-s*s));return r};h.dot=k.dot;h.lerp=k.lerp;h.slerp=function(u,C,B,F){var p=C[0],G=C[1],E=C[2],r=C[3],z=B[0],y=B[1],x=B[2],A=B[3];var D,q,s,w,v;q=p*z+G*y+E*x+r*A;if(q<0){q=-q;z=-z;y=-y;x=-x;A=-A}if((1-q)>0.000001){D=Math.acos(q);s=Math.sin(D);w=Math.sin((1-F)*D)/s;v=Math.sin(F*D)/s}else{w=1-F;v=F}u[0]=w*p+v*z;u[1]=w*G+v*y;u[2]=w*E+v*x;u[3]=w*r+v*A;return u};h.invert=function(v,r){var t=r[0],q=r[1],p=r[2],w=r[3],s=t*t+q*q+p*p+w*w,u=s?1/s:0;v[0]=-t*u;v[1]=-q*u;v[2]=-p*u;v[3]=w*u;return v};h.conjugate=function(q,p){q[0]=-p[0];q[1]=-p[1];q[2]=-p[2];q[3]=p[3];return q};h.length=k.length;h.len=h.length;h.squaredLength=k.squaredLength;h.sqrLen=h.squaredLength;h.normalize=k.normalize;h.fromMat3=(function(){var p=(typeof(Int8Array)!=="undefined"?new Int8Array([1,2,0]):[1,2,0]);return function(u,q){var r=q[0]+q[4]+q[8];var w;if(r>0){w=Math.sqrt(r+1);u[3]=0.5*w;w=0.5/w;u[0]=(q[7]-q[5])*w;u[1]=(q[2]-q[6])*w;u[2]=(q[3]-q[1])*w}else{var v=0;if(q[4]>q[0]){v=1}if(q[8]>q[v*3+v]){v=2}var t=p[v];var s=p[t];w=Math.sqrt(q[v*3+v]-q[t*3+t]-q[s*3+s]+1);u[v]=0.5*w;w=0.5/w;u[3]=(q[s*3+t]-q[t*3+s])*w;u[t]=(q[t*3+v]+q[v*3+t])*w;u[s]=(q[s*3+v]+q[v*3+s])*w}return u}})();h.str=function(p){return"quat("+p[0]+", "+p[1]+", "+p[2]+", "+p[3]+")"};if(typeof(j)!=="undefined"){j.quat=h}})(a.exports)})(this);glMatrix.setMatrixArrayType(Array);vec3.fromXYZ=function(a){var b=new Array(3);b[0]=a.x;b[1]=a.y;b[2]=a.z;return b};vec3.toXYZ=function(a){return{x:a[0],y:a[1],z:a[2]}};vec4.fromXYZ=function(b,a){var c=new Array(4);c[0]=b.x;c[1]=b.y;c[2]=b.z;c[3]=a;return c};if(typeof Phoria==="undefined"||!Phoria){var Phoria={}}Phoria.RADIANS=Math.PI/180;Phoria.TWOPI=Math.PI*2;Phoria.ONEOPI=1/Math.PI;Phoria.PIO2=Math.PI/2;Phoria.PIO4=Math.PI/4;Phoria.EPSILON=0.000001;(function(){Phoria.Util={};Phoria.Util.extend=function p(w,x,v){var u=function(){},t;u.prototype=x.prototype;w.prototype=new u();w.prototype.constructor=w;w.superclass=x.prototype;if(x.prototype.constructor==Object.prototype.constructor){x.prototype.constructor=x}if(v){for(t in v){if(v.hasOwnProperty(t)){w.prototype[t]=v[t]}}}};Phoria.Util.augment=function n(u,t){for(var v in t.prototype){if(typeof u.prototype[v]==="undefined"){u.prototype[v]=t.prototype[v]}}};Phoria.Util.merge=function f(t,u){var w=Array.isArray(u),v=w&&[]||{};if(w){t=t||[];v=v.concat(t);u.forEach(function(y,x){if(typeof y==="object"){v[x]=Phoria.Util.merge(t[x],y)}else{v[x]=y}})}else{if(t&&typeof t==="object"){Object.keys(t).forEach(function(x){v[x]=t[x]})}Object.keys(u).forEach(function(x){if(typeof u[x]!=="object"||!u[x]){v[x]=u[x]}else{if(!t||!t[x]){v[x]=u[x]}else{v[x]=Phoria.Util.merge(t[x],u[x])}}})}return v};Phoria.Util.combine=function s(t,u){var v=Array.isArray(u)&&Array.isArray(t);if(v){if(t.lengthC){A=x[(C+y)>>1][2];while(z<=B){while(zC&&x[B][2]>A){B--}if(z<=B){w=D[z];D[z]=D[B];D[B]=w;w=x[z];x[z]=x[B];x[B]=w;z++;B--}}if(C>1,y,y,y);t.addColorStop(0,A);t.addColorStop(1,x);u.fillStyle=t;u.fillRect(0,0,z,z);var w=new Image();w.src=v.toDataURL("image/png");return w}})();(function(){Phoria.Preloader=function(){this.images=[];return this};Phoria.Preloader.prototype={images:null,callback:null,counter:0,addImage:function b(c,d){var e=this;c.url=d;c.onload=function(){e.counter++;if(e.counter===e.images.length){e.callback.call(e)}};this.images.push(c)},onLoadCallback:function a(e){this.counter=0;this.callback=e;for(var d=0,c=this.images.length;dB+L||E[0]<-B-L||E[1]>B+L||E[1]<-B-L||E[2]>B||E[2]<-B)?1:0);E[0]/=B;E[1]/=B;E[2]/=B;E[0]=v*E[0]+u+v;E[1]=i*E[1]+s+i}if(y!==I){if(D.style.drawmode==="solid"&&D.polygons.length!==0){var z=mat4.invert(mat4.clone(A),A);mat4.transpose(z,z);switch(D.style.shademode){case"plain":case"lightsource":for(var G=0,N,K;Gd._gravetime){this.children.splice(j,1)}}var q=e-this._lastEmitTime;var n=Math.floor((this.rate/1000)*q);if(n>0){for(var o=0;o1.5||Math.abs(k[1]-u[q[o]][1])>1.5){k[0]=u[q[o]][0];k[1]=u[q[o]][1]}l[o]=k}return l},intersection:function f(j,i,n,m){var h=i.x-j.x,p=n.x-m.x,l=n.x-j.x,g=i.y-j.y,o=n.y-m.y,k=n.y-j.y,q=(p*k-o*l)/(g*p-h*o);return[j.x+q*(i.x-j.x),j.y+q*(i.y-j.y)]}}})();(function(){Phoria.CanvasRenderer=function(e){Phoria.CanvasRenderer.superclass.constructor.call(this);this.canvas=e;this.ctx=e.getContext("2d");return this};Phoria.Util.extend(Phoria.CanvasRenderer,Phoria.Renderer,{canvas:null,ctx:null,render:function c(k,m){this.sortObjects(k);var f=this.ctx;if(!m){f.clearRect(0,0,this.canvas.width,this.canvas.height)}else{m.call(this,f)}for(var l=0,j;l1){f=1}s.fillStyle="rgba("+k+","+(1-f).toFixed(3)+")"}if(l.length===3){F=0,n=0,E=C.width,m=0,B=C.width,h=C.height;if(g.uvs!==undefined){F=C.width*g.uvs[0];n=C.height*g.uvs[1];E=C.width*g.uvs[2];m=C.height*g.uvs[3];B=C.width*g.uvs[4];h=C.height*g.uvs[5]}var q=this.inflatePolygon(l,x,0.5);r.call(this,q,F,n,E,m,B,h);if(k!==null){s.fill()}}else{if(l.length===4){F=0,n=0,E=C.width,m=0,B=C.width,h=C.height;if(g.uvs!==undefined){F=C.width*g.uvs[0];n=C.height*g.uvs[1];E=C.width*g.uvs[2];m=C.height*g.uvs[3];B=C.width*g.uvs[4];h=C.height*g.uvs[5]}s.save();var q=this.inflatePolygon(l.slice(0,3),x,0.5);r.call(this,q,F,n,E,m,B,h);s.restore();F=C.width,n=C.height,E=0,m=C.height,B=0,h=0;if(g.uvs!==undefined){F=C.width*g.uvs[4];n=C.height*g.uvs[5];E=C.width*g.uvs[6];m=C.height*g.uvs[7];B=C.width*g.uvs[0];h=C.height*g.uvs[1]}s.save();var o=new Array(3);o[0]=l[2];o[1]=l[3];o[2]=l[0];q=this.inflatePolygon(o,x,0.5);r.call(this,q,F,n,E,m,B,h);s.restore();if(k!==null){q=this.inflatePolygon(l,x,0.75);s.beginPath();s.moveTo(q[0][0],q[0][1]);for(var y=1,w=q.length;y>4,0),F=Math.min((Math.max(s,q,o)+15)>>4,L),B=Math.max((Math.min(V,T,S)+15)>>4,0),f=Math.min((Math.max(V,T,S)+15)>>4,m);if(F<=l||f<=B){return}var j=w*s-C*V,i=k*q-p*T,h=N*o-U*S;if(w<0||(w==0&&C>0)){j++}if(k<0||(k==0&&p>0)){i++}if(N<0||(N==0&&U>0)){h++}var z=j+C*(B<<4)-w*(l<<4),v=i+p*(B<<4)-k*(l<<4),u=h+U*(B<<4)-N*(l<<4),M,K,J;for(var D=B,G,H;D0&&K>0&&J>0){H=(G+D*L)<<2;P[H]=I;P[H+1]=O;P[H+2]=Q;P[H+3]=255}M-=A;K-=n;J-=R}z+=E;v+=t;u+=e}}})})(); \ No newline at end of file diff --git a/scripts/phoria-renderer.js b/scripts/phoria-renderer.js index ec9b979..56da8fb 100644 --- a/scripts/phoria-renderer.js +++ b/scripts/phoria-renderer.js @@ -74,8 +74,8 @@ if (light instanceof Phoria.DistantLight) { - // Distant lights have no "position" - they simply light the world with parallel rays from an - // infinitely distant location - closest example is light from the sun when overhead + // Distant lights have no "position", just a direction - they light the world with parallel rays + // from an infinitely distant location - closest example is light from the sun when overhead // note that light worlddirection is precalculated as negative. var dotVP = vec3.dot(normal, light.worlddirection); @@ -214,7 +214,7 @@ var x = x2 - x1, y = y2 - y1, det = x * x + y * y, idet; - if (det === 0) det === EPSILON; + if (det === 0) det === Phoria.EPSILON; idet = pixels / Math.sqrt(det); @@ -452,7 +452,7 @@ case "plain": { ctx.beginPath(); - ctx.arc(coord[0], coord[1], w, 0, TWOPI, true); + ctx.arc(coord[0], coord[1], w, 0, Phoria.TWOPI, true); ctx.closePath(); ctx.fill(); break; @@ -485,7 +485,7 @@ Math.min(Math.ceil(rgb[1] * obj.style.color[1]),255) + "," + Math.min(Math.ceil(rgb[2] * obj.style.color[2]),255) + ")"; ctx.beginPath(); - ctx.arc(coord[0], coord[1], w, 0, TWOPI, true); + ctx.arc(coord[0], coord[1], w, 0, Phoria.TWOPI, true); ctx.closePath(); ctx.fill(); break; @@ -554,7 +554,7 @@ { case "plain": { - if (poly.texture === undefined) + if (obj.style.texture === undefined && poly.texture === undefined) { fillStyle = color[0] + "," + color[1] + "," + color[2]; } @@ -578,9 +578,9 @@ // render the polygon - textured or one of the solid fill modes ctx.save(); - if (poly.texture !== undefined) + if (obj.style.texture !== undefined || poly.texture !== undefined) { - var bitmap = obj.textures[ poly.texture ], + var bitmap = obj.textures[ poly.texture !== undefined ? poly.texture : obj.style.texture ], tx0, ty0, tx1, ty1, tx2, ty2; var fRenderTriangle = function(vs, sx0, sy0, sx1, sy1, sx2, sy2) { diff --git a/scripts/phoria-scene.js b/scripts/phoria-scene.js index 12862f2..1fbb82d 100644 --- a/scripts/phoria-scene.js +++ b/scripts/phoria-scene.js @@ -30,7 +30,7 @@ }; this.perspective = { - // vertical field-of-view in degrees NOTE: converted to radians for mat4.perspective() + // vertical field-of-view in degrees NOTE: converted to Phoria.RADIANS for mat4.perspective() fov: 35.0, // aspect ratio of the view plane aspect: 1.0, @@ -174,6 +174,14 @@ { scene.onCamera = scene.onCamera.toString(); }*/ + for (var p in scene) + { + if (scene.hasOwnProperty(p) && p.indexOf("_") === 0) + { + // remove private property/function before serialisation + delete scene[p]; + } + } if (scene.graph) { var fnProcessEntities = function(entities) { @@ -186,14 +194,10 @@ if (e.hasOwnProperty(p)) { // if property name matches "on*Handlers" it is an event handler function list by convention - - // TODO: whoops! the *add* event handler methods are called "on..."! e.g. onCamera on a live scene - rename??? or not serialise??? - // if not serialise, probably still enough for good debug dump... - also could have "debug" flag that *Does* output private props? - - /*if (p.indexOf("on") === 0 && typeof e[p] === "function") + if (p.indexOf("on") === 0 && e[p] instanceof Array) { e[p] = e[p].toString(); - }*/ + } // TODO: modify all Phoria entity classes to correctly mark private vars with "_" @@ -202,14 +206,23 @@ // remove private property/function before serialisation delete e[p]; } - if (p === "children" && e[p] instanceof Array) + switch (p) { - fnProcessEntities(e[p]); + case "textures": + delete e[p]; + break; + + case "children": + if (e[p] instanceof Array) + { + fnProcessEntities(e[p]); + } + break; } } } - // TODO: need to serialise the Entity type into the object structure + // TODO: need to serialise the Entity type into the object structure! } }; fnProcessEntities(scene.graph); @@ -349,7 +362,7 @@ var perspective = mat4.create(); mat4.perspective( perspective, - -this.perspective.fov * RADIANS, + -this.perspective.fov * Phoria.RADIANS, this.perspective.aspect, this.perspective.near, this.perspective.far); @@ -373,7 +386,7 @@ // used to quickly lookup entities in event handlers without walking child lists etc. if (obj.id) entityById[obj.id] = obj; - // multiply local with parent matrix to combine affine transformation + // multiply local with parent matrix to combine affine transformations var matLocal = obj.matrix; if (matParent) { @@ -408,13 +421,13 @@ verts = obj.points[v]; vec = vec4.set(obj._worldcoords[v], verts.x, verts.y, verts.z, 1.0); - // local object transformation -> world + // local object transformation -> world space // skip local transform if matrix not present // else store locally transformed vec4 world points if (matLocal) vec4.transformMat4(vec, vec, matLocal); } - // multiply by camera matrix to generate world coords + // multiply by camera matrix to generate camera space coords for (var v=0; v w+clipOffset || vec[0] < -w-clipOffset || @@ -490,14 +503,12 @@ if (objClip !== len) { // normal lighting transformation - if (obj.polygons.length !== 0) + if (obj.style.drawmode === "solid" && obj.polygons.length !== 0) { - // NOTE: have a flag on scene for "transposedNormalMatrix..."? - i.e. make it optional... - + // TODO: have a flag on scene for "transposedNormalMatrix..." - i.e. make it optional? // invert and transpose the view matrix - for correct normal scaling var matNormals = mat4.invert(mat4.clone(matLocal), matLocal); mat4.transpose(matNormals, matNormals); - //var matNormals = matLocal; switch (obj.style.shademode) { @@ -509,15 +520,17 @@ { if (!obj.polygons[i]._worldnormal) obj.polygons[i]._worldnormal = vec4.create(); - // normal transformation -> world + // normal transformation -> world space normal = obj.polygons[i].normal; wnormal = obj.polygons[i]._worldnormal; - vec4.transformMat4(wnormal, normal, matNormals); - vec4.normalize(wnormal, wnormal); + // use vec3 to ensure normal directional component is not modified + vec3.transformMat4(wnormal, normal, matNormals); + vec3.normalize(wnormal, wnormal); } break; } - /*case "gouraud": + /* + case "gouraud": { // transform each vertex normal for (var i=0, normal, wnormal; i + + + + Phoria - Dev test page 3 + + + + + + + + + + + + + \ No newline at end of file diff --git a/test4.html b/test4.html index 259fac9..d5c52e8 100644 --- a/test4.html +++ b/test4.html @@ -55,7 +55,7 @@ edges: c.edges, polygons: c.polygons, onScene: function(scene) { - this.rotateY(0.5*RADIANS); + this.rotateY(0.5*Phoria.RADIANS); } }); scene.graph.push(cube); diff --git a/test4p.html b/test4p.html index 65078ab..76941f6 100644 --- a/test4p.html +++ b/test4p.html @@ -36,7 +36,7 @@ scene.viewport.height = canvas.height; scene.onCamera(function(position, lookAt, up) { var rotMatrix = mat4.create(); - mat4.rotateY(rotMatrix, rotMatrix, Math.sin(Date.now()/10000)*RADIANS*360); + mat4.rotateY(rotMatrix, rotMatrix, Math.sin(Date.now()/10000)*Phoria.RADIANS*360); vec4.transformMat4(position, position, rotMatrix); }); diff --git a/test5.html b/test5.html index 83c071a..203b3d3 100644 --- a/test5.html +++ b/test5.html @@ -75,13 +75,13 @@ sortmode: "unsorted" } })); - scene.graph.push(new Phoria.DistantLight()); // wall plane object - constructed in-place to avoid rotations of texture coordinates var wall = Phoria.Entity.create({ points: [{x:10, y:0, z:-5},{x:10, y:10, z:-5},{x:10, y:10, z:5},{x:10, y:0, z:5}], polygons: [{vertices:[2,1,0,3]}], style: { + shademode: "plain", doublesided: true } }); @@ -159,13 +159,6 @@ }); cube.children.push(emitter); - // add a light - scene.graph.push(Phoria.DistantLight.create({ - color: [1,1,1], - intensity: 0.5, - direction: {x:2, y:-5, z:5} - })); - var pause = false; var fnAnimate = function() { if (!pause) diff --git a/test9.html b/test9.html index 03fef74..82b1f41 100644 --- a/test9.html +++ b/test9.html @@ -98,7 +98,7 @@ for (var i=0; i<128; i++) { ctx.moveTo(w, w); - ctx.lineTo(Math.cos(Rnd(TWOPI))*ww + w, Math.sin(Rnd(TWOPI))*ww + w); + ctx.lineTo(Math.cos(Rnd(Phoria.TWOPI))*ww + w, Math.sin(Rnd(Phoria.TWOPI))*ww + w); } ctx.closePath(); ctx.stroke(); @@ -121,7 +121,7 @@ // rotate the camera around the scene scene.onCamera(function(position, lookAt, up) { var rotMatrix = mat4.create(); - mat4.rotateY(rotMatrix, rotMatrix, Math.sin(Date.now()/10000)*RADIANS*360); + mat4.rotateY(rotMatrix, rotMatrix, Math.sin(Date.now()/10000)*Phoria.RADIANS*360); vec4.transformMat4(position, position, rotMatrix); }); @@ -154,7 +154,7 @@ // not actually used until the 'callback' sprite mode is set later particle.onRender(function(ctx, x, y, w) { ctx.translate(x, y); - ctx.rotate(Math.random(TWOPI)); + ctx.rotate(Math.random(Phoria.TWOPI)); ctx.drawImage(this.style.sprite, -w, -w, w+w, w+w); }); }