Exemple #1
0
void glopFrustum(GLContext *c,GLParam *p)
{
  GLfloat *r;
  M4 m;
  GLfloat left=p[1].f;
  GLfloat right=p[2].f;
  GLfloat bottom=p[3].f;
  GLfloat top=p[4].f;
  GLfloat near=p[5].f;
  GLfloat farp=p[6].f;
  GLfloat x,y,A,B,C,D,tmp2=int2sll(2);

  x = slldiv(sllmul(tmp2,near), sllsub(right,left));
  y = slldiv(sllmul(tmp2,near), sllsub(top,bottom));
  A = slldiv(slladd(right,left), sllsub(right,left));
  B = slldiv(slladd(top,bottom), sllsub(top,bottom));
  C = slldiv(sllneg(slladd(farp,near)), sllsub(farp,near));
  D = slldiv(sllneg(sllmul(sllmul(tmp2,farp),near)), sllsub(farp,near));

  r=&m.m[0][0];
  r[0]= x; r[1]=int2sll(0);  r[2]=A;            r[3]=int2sll(0);
  r[4]= int2sll(0); r[5]=y;  r[6]=B;            r[7]=int2sll(0);
  r[8]= int2sll(0); r[9]=int2sll(0);  r[10]=C;           r[11]=D;
  r[12]=int2sll(0); r[13]=int2sll(0); r[14]=int2sll(-1); r[15]=int2sll(0);

  gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m);

  gl_matrix_update(c);
}
// http://math.stackexchange.com/questions/1098487/atan2-faster-approximation
// atan2(y,x)
// a := min (|x|, |y|) / max (|x|, |y|)
// s := a * a
// r := ((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a
// if |y| > |x| then r := 1.57079637 - r
// if x < 0 then r := 3.14159274 - r
// if y < 0 then r := -r
sll sllatan2(sll y, sll x) {
  sll abs_x = sllabs(x);
  sll abs_y = sllabs(y);
  sll maxyx = MAX(abs_x, abs_y);
  sll minyx = MIN(abs_x, abs_y);

  sll a = slldiv(minyx, maxyx);
  sll s = sllmul(a, a);
  sll r_1 = sllmul(dbl2sll((-0.0464964749)), s);
  sll r_2 = slladd(r_1, dbl2sll(0.15931422));
  sll r_3 = sllsub(sllmul(r_2, s), dbl2sll(0.327622764));
  sll r = slladd(sllmul(sllmul(r_3, s), a), a);

  if(sllabs(y) > sllabs(x)) {
    r = sllsub(CONST_PI_2, r);
  }
  if(x < CONST_0) {
    r = sllsub(CONST_PI, r);
  }
  if(y < CONST_0) {
    r = sllneg(r);
  }

  return r;
}
sll sllabs(sll x) {
  sll ret = x;
  if (x < CONST_0) {
    ret = sllneg(x);
  }
  return ret;
}
Exemple #4
0
void gl_M4_Rotate(M4 *a,GLfloat t,int u)
{
	GLfloat s,c;
	int v,w;
	if ((v=u+1)>2) v=0;
	if ((w=v+1)>2) w=0;
	s=sllsin(t);
	c=sllcos(t);
	gl_M4_Id(a);
	a->m[v][v]=c;	a->m[v][w]=sllneg(s);
	a->m[w][v]=s;	a->m[w][w]=c;
}
Exemple #5
0
/* inverse of a 3x3 matrix */
void gl_M3_Inv(M3 *a,M3 *m)
{
	 GLfloat det;
	 
	 det =
	     sllsub(
	      slladd(
	       slladd(	
		sllsub(
		 sllsub(sllmul(sllmul(m->m[0][0], m->m[1][1]), m->m[2][2]),
	 		sllmul(sllmul(m->m[0][0], m->m[1][2]), m->m[2][1])), 
		 sllmul(sllmul(m->m[1][0], m->m[0][1]), m->m[2][2])), 
		sllmul(sllmul(m->m[1][0], m->m[0][2]), m->m[2][1])),
	       sllmul(sllmul(m->m[2][0], m->m[0][1]), m->m[1][2])),
	      sllmul(sllmul(m->m[2][0], m->m[0][2]), m->m[1][1]));

	 a->m[0][0] = slldiv(sllsub(sllmul(m->m[1][1],m->m[2][2]), sllmul(m->m[1][2],m->m[2][1])), det);
	 a->m[0][1] = sllneg(slldiv(sllsub(sllmul(m->m[0][1],m->m[2][2]), sllmul(m->m[0][2],m->m[2][1])), det));
	 a->m[0][2] = sllneg(slldiv(slladd(sllmul(sllneg(m->m[0][1]),m->m[1][2]), sllmul(m->m[0][2], m->m[1][1])), det));
	 
	 a->m[1][0] = sllneg(slldiv(sllsub(sllmul(m->m[1][0],m->m[2][2]), sllmul(m->m[1][2],m->m[2][0])), det));
	 a->m[1][1] = slldiv(sllsub(sllmul(m->m[0][0],m->m[2][2]), sllmul(m->m[0][2],m->m[2][0])), det);
	 a->m[1][2] = sllneg(slldiv(sllsub(sllmul(m->m[0][0],m->m[1][2]), sllmul(m->m[0][2],m->m[1][0])), det));

	 a->m[2][0] = slldiv(sllsub(sllmul(m->m[1][0],m->m[2][1]), sllmul(m->m[1][1],m->m[2][0])), det);
	 a->m[2][1] = sllneg(slldiv(sllsub(sllmul(m->m[0][0],m->m[2][1]), sllmul(m->m[0][1],m->m[2][0])), det));
	 a->m[2][2] = slldiv(sllsub(sllmul(m->m[0][0],m->m[1][1]), sllmul(m->m[0][1],m->m[1][0])), det);
}
Exemple #6
0
void glopRotate(GLContext *c,GLParam *p)
{
#define SLL_M_PI dbl2sll(M_PI)
  M4 m;
  GLfloat u[3];
  GLfloat angle;
  int dir_code;

  angle = slldiv(sllmul(p[1].f, SLL_M_PI), int2sll(180));
  u[0]=p[2].f;
  u[1]=p[3].f;
  u[2]=p[4].f;

  /* simple case detection */
  dir_code = ((sllvalue(u[0]) != sllvalue(int2sll(0)))<<2) | ((sllvalue(u[1]) != sllvalue(int2sll(0)))<<1) | (sllvalue(u[2]) != sllvalue(int2sll(0)));

  switch(dir_code) {
  case 0:
    gl_M4_Id(&m);
    break;
  case 4:
    if (sllvalue(u[0]) < sllvalue(int2sll(0))) angle=sllneg(angle);
    gl_M4_Rotate(&m,angle,0);
    break;
  case 2:
    if (sllvalue(u[1]) < sllvalue(int2sll(0))) angle=sllneg(angle);
    gl_M4_Rotate(&m,angle,1);
    break;
  case 1:
    if (sllvalue(u[2]) < sllvalue(int2sll(0))) angle=sllneg(angle);
    gl_M4_Rotate(&m,angle,2);
    break;
  default:
    {
      GLfloat cost, sint;

      /* normalize vector */
      GLfloat len = slladd(
		      slladd(
			      sllmul(u[0],u[0]),
			      sllmul(u[1],u[1])
			),
		     sllmul(u[2],u[2]));
      if (sllvalue(len) == sllvalue(int2sll(0))) return;
      len = slldiv(int2sll(1), sllsqrt(len));
      u[0] = sllmul(u[0], len);
      u[1] = sllmul(u[1], len);
      u[2] = sllmul(u[2], len);

      /* store cos and sin values */
      cost=sllcos(angle);
      sint=sllsin(angle);

      /* fill in the values */
      m.m[3][0]=m.m[3][1]=m.m[3][2]=
        m.m[0][3]=m.m[1][3]=m.m[2][3]=int2sll(0);
      m.m[3][3]=int2sll(1);

      /* do the math */
      m.m[0][0]=slladd(sllmul(u[0],u[0]), sllmul(cost, sllsub(int2sll(1), sllmul(u[0],u[0]))));
      m.m[1][0]=sllsub(sllmul(sllmul(u[0],u[1]), sllsub(int2sll(1), cost)), sllmul(u[2],sint));
      m.m[2][0]=slladd(sllmul(sllmul(u[2],u[0]), sllsub(int2sll(1), cost)), sllmul(u[1],sint));
      m.m[0][1]=slladd(sllmul(sllmul(u[0],u[1]), sllsub(int2sll(1), cost)), sllmul(u[2],sint));
      m.m[1][1]=slladd(sllmul(u[1],u[1]), sllmul(cost, sllsub(int2sll(1), sllmul(u[1],u[1]))));
      m.m[2][1]=sllsub(sllmul(sllmul(u[1],u[2]), sllsub(int2sll(1), cost)), sllmul(u[0],sint));
      m.m[0][2]=sllsub(sllmul(sllmul(u[2],u[0]), sllsub(int2sll(1), cost)), sllmul(u[1],sint));
      m.m[1][2]=slladd(sllmul(sllmul(u[1],u[2]), sllsub(int2sll(1), cost)), sllmul(u[0],sint));
      m.m[2][2]=slladd(sllmul(u[2],u[2]), sllmul(cost, sllsub(int2sll(1), sllmul(u[2],u[2]))));
    }
  }

  gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode],&m);

  gl_matrix_update(c);
}