function ASHOBJ(x,y,z){
 this.x=x;
 this.y=y;
 this.z=z;
 this.resetx=x;
 this.resety=y;
 this.resetz=z;
 this.fx=0;
 this.fy=0;
 this.fz=0;
 this.show=false;
this.vertexPositionBuffer=gl.createBuffer();;
this.vertices=new Array();
this.vertexColorBuffer=gl.createBuffer();;
 this.colors=new Array();
 this.type=null;
this.operateAwhilelist=new Array();
this.operateAwhilelistSize=0;

 this.timefunctions=new Array(); 
this.timefunctionsSize=0;
this.radius=0, this.rotx=0, this.roty=0, this.rotz=0;
 this.draw=function(){
if(this.show===true){
mat4.identity(mvMat);
 mat4.translate(mvMat, [this.x, this.y, this.z]);

mat4.rotate(mvMat, this.radius, [this.rotx, this.roty, this.rotz]);

mat4.rotate(mvMat, cangle*0.0174532925, [cyaw, cpitch, croll]);
mat4.translate(mvMat, [cx, cy, cz]);

gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, this.vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, this.vertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLE_STRIP, 0, this.vertexPositionBuffer.numItems);
}
 }
this.operateAwhile=function(seconds, what){
this.operateAwhilelist.push(realtime+seconds);
this.operateAwhilelist.push(what);
this.operateAwhilelistSize+=2;
}
//show and update object
this.showup=function(){
this.show=true;
}
//hide and do not update object
this.hideup=function(){
this.show=false;
}
this.rotation=function(degree, rotx, roty, rotz){
this.radius=degree*0.0174532925;
this.rotx=rotx;
this.roty=roty;
this.rotz=rotz;
}
this.reset=function(){
this.x=this.resetx;
this.y=this.resety;
this.z=this.resetz;
this.show=0;
this.fx=0;
this.fy=0;
this.fz=0;
this.radius=0;
this.rotx=0;
this.roty=0;
this.rotz=0;

//CUBE


this.left=this.resetleft;
this.right=this.resetright;
this.up=this.resetup;
this.down=this.resetdown;
this.front=this.resetfront;
this.back=this.resetback;

this.sourceleft=this.resetleft;
this.sourceright=this.resetright;
this.sourceup=this.up;
this.sourcedown=this.down;
this.sourcefront=this.front;
this.sourceback=this.back;
this.destinationleft=this.resetleft;
this.destinationright=this.resetright;
this.destinationup=this.resetup;
this.destinationdown=this.resetdown;
this.destinationfront=this.resetfront;
this.destinationback=this.resetback;

//CUBE
for(i=0; i<this.timefunctionsSize; i+=3)
this.timefunctions[i+0]=false;
this.operateAwhilelist.splice(0,this.operateAwhilelistSize);
}
}
function ASHCUBE(x,y,z,left,right,up,down,front,back,r,g,b){
 ASHOBJ.apply(this, arguments);
 this.left=left;
 this.right=right;
 this.up=up;
 this.down=down;
 this.front=front;
 this.back=back;
 this.r=r;
 this.g=g;
 this.b=b;
this.resetleft=left;
this.resetright=right;
this.resetup=up;
this.resetdown=down;
this.resetfront=front;
this.resetback=back;
this.sourceleft=this.left;
this.sourceright=this.right;
this.sourceup=this.up;
this.sourcedown=this.down;
this.sourcefront=this.front;
this.sourceback=this.back;
this.destinationleft=this.left;
this.destinationright=this.right;
this.destinationup=this.up;
this.destinationdown=this.down;
this.destinationfront=this.front;
this.destinationback=this.back;
this.fdotime=1;
this.sidetime=1;


gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
this.vertices=[
this.left,this.up,this.front,//front
this.right, this.up, this.front,
this.left,this.down,this.front,
this.right, this.down,this.front,
this.left,this.up,this.back,//back
this.right, this.up,this.back,
this.left,this.down,this.back,
this.right, this.down,this.back,
this.left,this.up, this.front, //up
this.right, this.up, this.front,
this.left,this.up,this.back,
this.right, this.up,this.back,
this.left,this.down,this.front, //down
this.right, this.down,this.front,
this.left,this.down,this.back,
this.right, this.down,this.back,
this.left,this.up, this.front, //left
this.left,this.down,this.front,
this.left,this.up,this.back,
this.left,this.down,this.back,
this.right, this.up,this.front, //left
this.right, this.down,this.front,
this.right, this.up,this.back,
this.right, this.down,this.back
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.vertices), gl.STATIC_DRAW);
this.vertexPositionBuffer.itemSize=3;
this.vertexPositionBuffer.numItems=24;

gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexColorBuffer);
for(var i=0; i<24*4; i+=4){
 this.colors[i]=this.r;
 this.colors[i+1]=this.g;
 this.colors[i+2]=this.b;
 this.colors[i+3]=1.0;
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.colors), gl.STATIC_DRAW);
this.vertexColorBuffer.itemSize=4;
this.vertexColorBuffer.numItems=24;
}
ASHCUBE.prototype.setForcedTimeSide=function(time,left,right,up,down,front,back){
this.sourceleft=this.left;
this.sourceright=this.right;
this.sourceup=this.up;
this.sourcedown=this.down;
this.sourcefront=this.front;
this.sourceback=this.back;
this.destinationleft=left;
this.destinationright=right;
this.destinationup=up;
this.destinationdown=down;
this.destinationfront=front;
this.destinationback=back;
this.fdotime=time;
this.sidetime=time+realtime;
}
ASHCUBE.prototype.update=function(time, timeTaken){
var i;
this.x+=this.fx*timeTaken;
this.y+=this.fy*timeTaken;
this.z+=this.fz*timeTaken;

i=1-(this.sidetime-time)/(this.fdotime);
if(i>1) i=1;
this.left=this.sourceleft+(this.destinationleft-this.sourceleft)*i;
this.right=this.sourceright+(this.destinationright-this.sourceright)*i;
this.up=this.sourceup+(this.destinationup-this.sourceup)*i;
this.down=this.sourcedown+(this.destinationdown-this.sourcedown)*i;
this.front=this.sourcefront+(this.destinationfront-this.sourcefront)*i;
this.back=this.sourceback+(this.destinationback-this.sourceback)*i;
if(this.timefunctionsSize>0)
for(i=0; i<this.timefunctionsSize; i+=3)
if(this.timefunctions[i+0]===false &&
this.timefunctions[i+1]<time){
try{
eval(this.timefunctions[i+2]);
}
catch(err){
alert("error in following code: " + this.timefunctions[i+2] + "\n" + err.message);
}
this.timefunctions[i+0]=true;
}

for(i=0; i<this.operateAwhilelistSize; i+=2){
if(this.operateAwhilelist[i+0]>realtime){
try{
eval(this.operateAwhilelist[i+1]);
}
catch(err){
alert("error in following operateAhilecode: " + this.operateAwhilelist[i+2] + "\n" + err.message);
}
}
}

gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexPositionBuffer);
this.vertices=[
this.left,this.up,this.front, //front
this.right, this.up,this.front,
this.left,this.down,this.front,
this.right, this.down,this.front,
this.left,this.up,this.back,//back
this.right, this.up,this.back,
this.left,this.down,this.back,
this.right, this.down,this.back,
this.left,this.up,this.front, //up
this.right, this.up,this.front,
this.left,this.up,this.back,
this.right, this.up,this.back,
this.left,this.down,this.front, //down
this.right, this.down,this.front,
this.left,this.down,this.back,
this.right, this.down,this.back,
this.left,this.up,this.front, //left
this.left,this.down,this.front,
this.left,this.up,this.back,
this.left,this.down,this.back,
this.right, this.up,this.front, //left
this.right, this.down,this.front,
this.right, this.up,this.back,
this.right, this.down,this.back
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.vertices), gl.STATIC_DRAW);
this.vertexPositionBuffer.itemSize=3;
this.vertexPositionBuffer.numItems=24;

gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexColorBuffer);
for(var i=0; i<24*4; i+=4){
this.colors[i]=this.r;
this.colors[i+1]=this.g;
this.colors[i+2]=this.b;
this.colors[i+3]=1.0;
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.colors), gl.STATIC_DRAW);
this.vertexColorBuffer.itemSize=4;
this.vertexColorBuffer.numItems=24;
}