const lowp vec3 CUBE[8] = vec3[8](
    //Front set of points
	vec3(-1.0, -1.0, -1.0), //TL
	vec3(1.0, -1.0, -1.0), //TR
	vec3(1.0, 1.0, -1.0), //BR
	vec3(-1.0, 1.0, -1.0), //BL
	//Back set of points
	vec3(-1.0, -1.0, 1.0),//TL
	vec3(1.0, -1.0, 1.0), //TR
	vec3(1.0, 1.0, 1.0), //BR
	vec3(-1.0, 1.0, 1.0) //BL
);

vec3 rotateMat(vec3 vpos, float rotx, float roty, float rotz){
	mat3 rx = mat3(1.,0.,0.,
                                 0.,cos(rotx),-sin(rotx),
                                 0.,sin(rotx), cos(rotx));
    mat3 ry = mat3(cos(roty),0.,sin(roty),
                                 0.,1.,0.,
                                 -sin(roty),0.,cos(roty));
 /*   mat3 rz= mat3(cos(rotz),-sin(rotz),0.,
                                 sin(rotz),cos(rotz),0.,
                                 0.,0.,1.);*/
    vec3 res = ry*vpos;
             res = rx*res;
           //  res = rz*res;
    return res;
}

vec2 projPoint(vec3 opos){
	float dts = 1./(4.-opos.z);
	//float dts = 1.;
	mat2x3 p = mat2x3(dts,0.,0.,
                                        0.,dts,0.);
    return vec2(
        (p[0][0]*opos.x)+(p[0][1]*opos.y)+(p[0][2]*opos.z),
        (p[1][0]*opos.x)+(p[1][1]*opos.y)+(p[1][2]*opos.z)
    );
//    projd/=map(opos.z+1.5, 1., 2., 1., 1.75);

	//return projd;
	//return opos.xy/opos.z;
}


#define CCW(A, B, C) ((C.y-A.y) * (B.x-A.x) > (B.y-A.y) * (C.x-A.x))
#define INTERSECT(A,B,C,D) ((CCW(A,C,D) != CCW(B,C,D) && CCW(A,B,C) != CCW(A,B,D)) ? 1. : 0.)

float intersectionTest(vec2 a, vec2 b, vec2 c[8]){
    return (INTERSECT(a, b, c[0], c[1] ))+
	(INTERSECT(a, b, c[2], c[3] ))+
	(INTERSECT(a, b, c[4], c[5] ))+
	(INTERSECT(a, b, c[6], c[7] ))+
	
	(INTERSECT(a, b, c[0], c[3] ))+
	(INTERSECT(a, b, c[1], c[2] ))+
	(INTERSECT(a, b, c[4], c[7] ))+
	(INTERSECT(a, b, c[5], c[6] ))+
	
	(INTERSECT(a, b, c[0], c[4] ))+
	(INTERSECT(a, b, c[1], c[5] ))+
	(INTERSECT(a, b, c[2], c[6] ))+
	(INTERSECT(a, b, c[3], c[7] ));
}

#define PROJECTPOINT(j) {\
        verts[j]+=o;\
		verts[j]*=s;\
		vec3 rot = rotateMat(verts[j], rotam.x,rotam.y,rotam.z);\
		rot+=po;\
		projdp[j] = projPoint(rot)*1.5;\
}

float incube(vec2 p, vec3 rotam, vec3 o, vec3 s, vec3 po){
	lowp vec3 verts[8] = CUBE;
	
	vec2 projdp[8];
	lowp float intersects1 = 0.;
	lowp float intersects2 = 0.;
	/*
	for(int j = 0; j < 8; j++){
		verts[j]+=o;
		verts[j]*=s;
		vec3 rot = rotateMat(verts[j], rotam.x,rotam.y,rotam.z);
		rot+=po;
		projdp[j] = projPoint(rot)*1.5;
	}
	*/
    PROJECTPOINT(0);
    PROJECTPOINT(1);
    PROJECTPOINT(2);
    PROJECTPOINT(3);
    PROJECTPOINT(4);
    PROJECTPOINT(5);
    PROJECTPOINT(6);
    PROJECTPOINT(7);
	intersects1 = intersectionTest(p, vec2(p.x+100., p.y), projdp);
	//if(intersects1 == 0.) return 0.;
    intersects2 = intersectionTest(p, vec2(p.x-100., p.y), projdp);

	return min(min(intersects1, intersects2), 1.);
}

float sfloor(float n){
	return floor(n) + max(mod(8.0 * n, 8.0)-7.0, 0.0);
}

const lowp float qPi = 0.78539;
float playerShadow3d(in vec3 shPos, in vec2 pRot, in vec3 chpos, in vec3 wrldpos){
	//float shCol = 0.;
	/*if(shPos.z > -0.125 && shPos.z < 0.125 && shPos.x > 0.75 && shPos.x < 1.5){
    	  return 1.;
    }*/
	      if(wrldpos.x < 0.0) return 0.0;
		  //float an=radians(sin(((position.x-wpos.x)*2.+(position.z-wpos.z)*2.)))*45.);
		  float an=sin(2.*(qPi*(chpos.x-wrldpos.x))+2.*(qPi*(chpos.z-wrldpos.z)))*qPi;
    
	     // pr.y-=qPi*.75;*/
	    // vec2 pr = playRot;
	  //    pr.x+=.5*qPi;
    
	      lowp float cpr = (sfloor(pRot.x*2.)*.5)+(2.5*qPi);
   
         //TORSO
	     lowp float torso = incube(vec2(shPos.x-1.5, shPos.z), vec3(cpr, 0., 0.), vec3(-1.,0.,0.), vec3(0.93, 0.6, 0.31), vec3(0.));
	     //if(torso == 1.) return 1.;
   
	     //LEGS
	     lowp float lleg = incube(vec2(shPos.x-1.5, shPos.z), vec3(cpr, an, 0.), vec3(-1.,1,0.), vec3(0.92, 0.31, 0.31), vec3(-1.8,0.,0.));
	     lowp float rleg = incube(vec2(shPos.x-1.5, shPos.z), vec3(cpr, -an, 0.), vec3(-1.,-1.,0.), vec3(0.92, 0.31, 0.31), vec3(-1.8,0.,0.));
	     //if(min(rleg, lleg) == 1.) return 1.;
	     //ARMS
	     lowp float larm = incube(vec2(shPos.x-1.5, shPos.z), vec3(cpr, an, 0.), vec3(-1.,3.,0.), vec3(0.92, 0.31, 0.31), vec3(0.));
	     lowp float rarm = incube(vec2(shPos.x-1.5, shPos.z), vec3(cpr, -an, 0.), vec3(-1.,-3.,0.), vec3(0.92, 0.31, 0.31), vec3(0.));
	  //   if(min(rarm, larm) == 1.) return 1.;
	     
 	    //HEAD
	     lowp float head = incube(vec2(shPos.x-1.5, shPos.z), vec3(pRot.x+(2.*qPi), -(pRot.y+qPi), 0.), vec3(1.,0.,0.), vec3(0.56, 0.56, 0.56), vec3(0.));
	     //diffuse.rgb -= (max(max(max(max(max(lleg,rleg), larm), rarm), torso), head)*.25)*max(map(wordShadow, 0.50, 0.05, 0., 1.), uv1.x);
	     return min(lleg+rleg+larm+rarm+torso+head,1.);
	    // diffuse.rgb = head;

}
