Exemple #1
0
/* returns the rotation quat required to match v1 to v2    */
void vects_to_quat(double v1[3], double v2[3], double q[4]){
   double axis[3];
   double phi;
   double denom;
   
   /* first normalise each of em */
   vnormal(v1);
   vnormal(v2);
   
   /* check that someone isn't playing silly buggers */
   if((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2])){
      vcopy(axis, v1);
      phi = 0.0;
      }
   else{
      /* find the axis with a cross product          */
      vcross(axis, v2, v1);

      /* find the angle to rotate around that axis.  */
      /* v1.v2 = ||v1|| ||v2|| cos(angle)            */
      denom = vlength(v1) * vlength(v2);
      if(denom == 0){
         phi = 0.0;
         }
      else{
         phi = acos(vdot(v1, v2) / denom);
         }
      }
   
   /* create the quat */
   axis_to_quat(axis, phi, q);
   }
Exemple #2
0
//perhaps in engine is better? 
void find_best_split_plane( const std::vector <face_t >& faces
							// ,std::vector <face_t >& front
							// ,std::vector <face_t >& back
	) 
{
	//all time low
	score_t low={},s={};
	low.score = 999999;
		
	//along planes, along edges...
	for ( size_t i = faces.size() ; i--; )
	{
		face_t f = faces[i];
		//xplane_t p = { f.a, f.normal() };
		//test_plane(p, faces, s);
		//enum{ABC,AB,BC,CA};
		vec3 N = f.normal();
		plane_t planes[4] = {
			pmake( f.a, N),
			//this should always end up on front/front_on side
			pmake( f.a, vnormal(vcross( N, f.b - f.a ) ) ),
			pmake( f.b, vnormal(vcross( N, f.c - f.b ) ) ),
			pmake( f.c, vnormal(vcross( N, f.a - f.c ) ) )
		};
		//test planes
		for ( int j = 0; j < 4 ; ++j )
		{
			test_plane( planes[j], faces, s);
			if( s.score < low.score )
				low=s,low.face=i;
		}
	}
	//check score
	//use low.p to split front and backm or stop here if bad score
	
	//print
	printf( "\n\nBest plane for all %d\n", faces.size());
	printf( "index %d\n", low.face);
	printf( "score = %d\n", low.score );
	printf( "balance = %d\n", low.balance );
	printf( "splits = %d\n", low.split );
	printf( "coins = %d\n", low.coin );
	printf( "front = %d\n", low.front );
	printf( "back = %d\n", low.back );
	printf( "plane = %f, %f, %f,   %f\n",
			low.p.x,low.p.y,low.p.z,low.p.w );

}
Exemple #3
0
/*
 *  Given an axis and angle, compute quaternion.
 *  This function computes a quaternion based on an axis (defined by
 *  the given vector) and an angle about which to rotate.  The angle is
 *  expressed in radians.  The result is put into the third argument.
 */
void axis_to_quat(float a[3], float phi, float q[4])
{
    vnormal(a);
    vcopy(a,q);
    vscale(q,sin(phi/2.0));
    q[3] = cos(phi/2.0);
}
Exemple #4
0
//save load
vec3 uv_tangent(vec3 v0,vec3 v1,vec3 uv0,vec3 uv1)
{
//	if(vdot(uv0,uv1)==0.f)
	if(uv0.x==uv1.x && uv0.y==uv1.y)
	{
		printf("WARNING!!! Zero area UV.\n");
		//set to face tangent
		return vnormal( vcross( v0, v1 ) );

	}else{

		float coef = 1./(uv0.x * uv1.y - uv1.x * uv0.y);
		vec3 t={
			coef * ((v0.x * uv1.y)  + (v1.x * -uv0.y)),
			coef * ((v0.y * uv1.y)  + (v1.y * -uv0.y)),
			coef * ((v0.z * uv1.y)  + (v1.z * -uv0.y))
		};

		float len=vlen(t);
		if(!len){
			printf("ERROR: zero area UV  @uv_tangent.\n");
			exit(-1);
		}
		t/=len;
		
		return t;
	}
}
/*
 *  Given an axis and angle, compute quaternion.
 */
void axis_to_quat( double a[3], double phi, double q[4] )
{
    vnormal( a );
    vcopy( a, q );
    vscale( q, (double) sin( phi / 2.0) );
    q[3] = (double) cos( phi / 2.0 );
}
void Trackball :: spin ( float friction )
{
    const int RENORMCOUNT = 97 ;
    static int count=0;
    //float * q1, * q2, * dest ;
    float q1[4], * q2, * dest ;
    float t1[4], t2[4], t3[4];
    float tf[4];

    //q1 = m_lastquat ;
    if( friction != 1.0 )
    {
      float temp ;
      temp = vlength(m_lastquat);
      if( temp != 0 )
      {
         vcopy(m_lastquat,q1);
         vnormal(q1) ;
         temp = asin(temp)*friction ;
         q1[0] *= sin(temp) ;
         q1[1] *= sin(temp) ;
         q1[2] *= sin(temp) ;
         q1[3] = cos(temp) ;
      }
      else
      {
         vcopy(m_lastquat,q1);
         q1[3] = m_lastquat[3] ;
      }
    }
    else
    {
        vcopy(m_lastquat,q1);
        q1[3] = m_lastquat[3] ;
    }
    q2 = m_currquat ;
    dest = m_currquat ;

    vcopy(q1,t1);
    vscale(t1,q2[3]);

    vcopy(q2,t2);
    vscale(t2,q1[3]);

    vcross(q2,q1,t3);
    vadd(t1,t2,tf);
    vadd(t3,tf,tf);
    tf[3] = q1[3] * q2[3] - vdot(q1,q2);

    dest[0] = tf[0];
    dest[1] = tf[1];
    dest[2] = tf[2];
    dest[3] = tf[3];

    if (++count > RENORMCOUNT) {
        count = 0;
        normalize_quat(dest);
    }
}
Exemple #7
0
/*

  READ GEO

*/
void get_geometry(TE*root)
{
	printf("_\t_\tGEOMETRIES\t_\t_\t_\t_\n");

	TE*geo = root -> FCE( "library_geometries" )->FCE("geometry");
	while ( geo )
	{
		get_object( geo );
		geo = geo -> NSE ( "geometry" );
	}


	//get transforms, tranform vertices
	TE*node = root -> FCE( "library_visual_scenes" )->
		FCE("visual_scene") -> FCE("node");;
	
	size_t i=0;
	while ( node && i < dae_geo_objects.size() )
	{
	
		dae_geo_t &d = dae_geo_objects[i];
		std::string name = node->Attribute( "name" );
		
		if( name == d.name ){
			
			std::vector< float >mat=str_fv(node->FCE("matrix")->GetText(),16);
			
			//transpose 
			float M[16];
			mtranspose( M, &mat[0] );
			
			//multiply each vertex
			for( size_t k = 0; k < d.pos.size(); k+=3 ){
				vec3 vp={d.pos[k],d.pos[k+1],d.pos[k+2]};
				vp = mmulv( M, vp, 1.f );
				d.pos[k] = vp.x;
				d.pos[k+1] = vp.y;
				d.pos[k+2] = vp.z;
			}
			for( size_t k = 0; k < d.normal.size(); k+=3 ){
				vec3 vp={d.normal[k],d.normal[k+1],d.normal[k+2]};
				vp = vnormal(mmulv( M, vp, 0.f));
				d.normal[k] = vp.x;
				d.normal[k+1] = vp.y;
				d.normal[k+2] = vp.z;
			}
			++i;
		}

		node = node -> NSE( "node" );
	}

	printf("count = %d\n", dae_geo_objects.size());
}
Exemple #8
0
void Ctrl3DRotate::drag(int x, int y){

  // free rotation control
  if(sx0 == x && sy0 == y) {angle_r = 0; return;}
  float x0=sx0-cx, y0=-(sy0-cy), z0=cz;
  float x1=x-cx, y1=-(y-cy), z1=cz;
  float n0=sqrt(x0*x0+y0*y0+z0*z0);
  float n1=sqrt(x1*x1+y1*y1+z1*z1);
  x0/=n0;y0/=n0;z0/=n0;
  x1/=n1;y1/=n1;z1/=n1;
  angle_r=acos(x0*x1+y0*y1+z0*z1)*180/M_PI;
  vnormal(norm_rx, norm_ry, norm_rz, x0, y0, z0, x1, y1, z1);
}
Exemple #9
0
int MouseMoveAndShift::ContinueMOper(int x, int y){    
  
  float cx = 2.*float(x-wndw/2)/wndw;
  float cy = 2.*float(wndh-y-wndh/2)/wndh;
  float cz = 0;
  float cx0 = 2.*float(sx0-wndw/2)/wndw;
  float cy0 = 2.*float(wndh-sy0-wndh/2)/wndh;
  float cz0 = 0;

  Ptn p = {cx, cy, cz};
  Ptn p0 = {cx0, cy0, cz0};  
  switch(oper){
    double w,w0;
  case 1:
	  memcpy(mi,m,sizeof(mi));
	  glInvMat(mi);
	  w =  1.0/(mi[3]*p.x + mi[7]*p.y +
		  mi[11]*p.z + mi[15]);
	  w0 =  1.0/(mi[3]*p0.x + mi[7]*p0.y +
		  mi[11]*p0.z + mi[15]);
	  p = p*w;
	  p0 = p0*w0;
		p = glMulMat(mi,p,w);
		p0 = glMulMat(mi,p0,w0);
	  p=p-p0;
    shift_x = p.x;
    shift_y = p.y;
    shift_z = p.z;
    break;
  case 2:

    // free rotation control
    if(sx0 == x && sy0 == y) {angle_r = 0; break;}
    int windW = wndw/2;
    int windH = wndh/2;
    float x0=sx0-windW, y0=-(sy0-windH), z0=windW/4;
    float x1=x-windW, y1=-(y-windH), z1=windW/4;
    float n0=sqrt(x0*x0+y0*y0+z0*z0);
    float n1=sqrt(x1*x1+y1*y1+z1*z1);
    x0/=n0;y0/=n0;z0/=n0;
    x1/=n1;y1/=n1;z1/=n1;
    angle_r=acos(x0*x1+y0*y1+z0*z1)*180/M_PI;
    vnormal(norm_rx, norm_ry, norm_rz, x0, y0, z0, x1, y1, z1);    
    break;
  }
  return oper;
}
Exemple #10
0
/* Given an quaternion compute an axis and angle */
void quat_to_axis(double vec[3], double *phi, double quat[4]){
   double scale;
   
   scale = quat[0]*quat[0] + quat[1]*quat[1] + quat[2]*quat[2];
   
   if(scale == 0){  /* no rotation, we're stuffed */
      vec[0] = 0;
      vec[1] = 0;
      vec[2] = 1;
      *phi = 0;
      }
   else{
      vcopy(vec, quat);
      vscale(vec, 1.0/scale);
      vnormal(vec);
      
      *phi  = 2.0*acos(quat[3]);
      }
   }
/**
 * \return the id of vertex between two corners.
 *
 * If it wasn't previously computed, does #converge() and adds vertex to process.
 */
static int vertid(PROCESS *process, const CORNER *c1, const CORNER *c2)
{
	float v[3], no[3];
	int vid = getedge(process->edges, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k);

	if (vid != -1) return vid;  /* previously computed */

	converge(process, c1, c2, v);  /* position */

#ifdef USE_ACCUM_NORMAL
	zero_v3(no);
#else
	vnormal(process, v, no);
#endif

	addtovertices(process, v, no);            /* save vertex */
	vid = (int)process->curvertex - 1;
	setedge(process, c1->i, c1->j, c1->k, c2->i, c2->j, c2->k, vid);

	return vid;
}
Exemple #12
0
/* Given an axis and angle, compute quaternion */
void axis_to_quat(double vec[3], double phi, double quat[4]){
   vnormal(vec);
   vcopy(quat, vec);
   vscale(quat, sin(phi/2.0));
   quat[3] = cos(phi/2.0);
   }
Exemple #13
0
	vec3 normal()const{	return vnormal( vcross( b-a, c-a ) );}
Exemple #14
0
//to global verts and faces  (not shorts)
//ALSO, COMBINES EACH DAE OBJECT
void dae_geo_to_polys_and_verts( dae_geo_t dg )
{
	//mtrl string , count
	materials.insert( materials.end(),
					  dg.materials.begin(),dg.materials.end());
	material_counts.insert( material_counts.end(),
							dg.material_counts.begin(),
							dg.material_counts.end());

	printf("_\t_\tDAE -> VERTEX / INDICES\t_\t_\t_\t_\t_\n");
	int II = 0, pi,ui,ni,ci;
	poly_t p={};
	for ( int f = 0; f < dg.poly_count; ++f)
	{
		//vertices / indices
		for ( int j = 0; j < 3; ++j )
		{
			vertex_t v={};
			//get indices, p,normal,
			pi = dg.poly[II++];
			ni = dg.poly[II++];
			ui = dg.poly[II++];
			ci = dg.poly[II++];

			//
			v.pos.x = dg.pos[ pi*3 + 0 ];
			v.pos.y = dg.pos[ pi*3 + 1 ];
			v.pos.z = dg.pos[ pi*3 + 2 ];
			
			v.normal.x = dg.normal[ ni*3 + 0 ];
			v.normal.y = dg.normal[ ni*3 + 1 ];
			v.normal.z = dg.normal[ ni*3 + 2 ];

			v.uv.x = dg.uv[ ui*2 + 0 ];
			v.uv.y = dg.uv[ ui*2 + 1 ];
		
			//vertex hand painted color
			//vset(v.init_rgb,.1,.1,.1);
			v.color.x = dg.rgb[ ci*3 + 0 ];
			v.color.y = dg.rgb[ ci*3 + 1 ];
			v.color.z = dg.rgb[ ci*3 + 2 ];

			int index = vertex_find( v );
			if ( index == (int)verts.size() ){
				verts.push_back( v );
				//debug ( "dupe found\n" );
			}

			 p.index[ j ]=index;
		}

		const vec3 basis[3]={
			{ -.40824829046, -.70710678118,  .57735026919 },//blue
			{ -.40824829046, .70710678118,   .57735026919 },//green
			{ .81649658092,  0.,			 .57735026919 }//red
		};

		//tangent, basis and inset,,, and direction of vertex color light
		for ( int j=0;j<3;++j )
		{
			vertex_t& a = verts[p.index[j]];
			const vertex_t& b =  verts[p.index[(j+1)%3]];
			const vertex_t& c =  verts[p.index[(j+2)%3]];

			//inset ( lighting sample point ) //BAD FOR SMOOTH!!
			a.inset = a.pos + (b.pos-a.pos)*.005f + (c.pos-a.pos)*.005f;

			//tangent
			a.tangent = uv_tangent(
				vnormal(b.pos-a.pos),
				vnormal(c.pos-a.pos), 
				vnormal(b.uv - a.uv),
				vnormal(c.uv - a.uv) 
				);

			//MUST BE CORRECTED FOR SMOOTH SURFACES
			
			// if( vdot ( vnormal( a.normal ), vnormal ( vcross( b.pos-a.pos, c.pos-a.pos ) ) ) < .9 )
			// {
			// 	printf( "SHOULD BE CORRECTED\n");
			 vec3 right = vcross( a.tangent, a.normal );
			 a.tangent = vnormal( vcross( a.normal, right ) );

			// }

			//basis

			//we have normal
			vec3 N = a.normal;//vnormal( vcross(b.pos-a.pos, c.pos-a.pos) );
			vec3 T = a.tangent;
			vec3 B = vcross( T, N );
			
			//rotate basis axes by TBN 
			for( int k=0; k<3;++k)
				a.basis[k] = //exactly like mmulv
					T*vec3f(basis[k].x,basis[k].x,basis[k].x)+
					B*vec3f(basis[k].y,basis[k].y,basis[k].y)+
					N*vec3f(basis[k].z,basis[k].z,basis[k].z)
					;

			//vertex color.. FOR NOW JUST ALL
			// for( int k=0; k<3;++k)
			//  	a.basis_color[k]=a.color;

		}

		polys.push_back(p);
	}
	printf ( "VERTS : %d\n", verts.size() );
	printf ( "POLYS : %d\n", polys.size() );
	printf ( "\n" );
}
Exemple #15
0
void render_vertex_colors()
{
	printf ( "_\t_\tRENDERING VERTEX COLORS_\t_\t_\t_\t_\n");
	
	for(size_t i = 0; i < verts.size(); ++i )// each vertex
	{
		vertex_t&v = verts[i];

		for(size_t j = 0; j < lights.size(); ++j )// each light
		{
			
//			int blocked = 0;
			const light_t&L = lights[j];
			
			
			if( L.dont_bake )
				continue;

			vec3 start, dir;
			if( L.type == light_t::SUN ){
				start = v.pos;//inset;//+L.dir*.000001;
				dir = L.dir*2048.f;
			}else{
				start = L.pos;
				dir = (v.pos - L.pos );
			}
			//early  if ( vdot ( L.pos - v.pos, v.normal ) <= 0.f )continue;
			
			//test triangles (TODO/NOTE : DONT FACE CULL )
			
			int blocked=0;
			//ERROR LAYS HERE!!! NOT IN TANGENT

			for(size_t k = 0; k < polys.size()&& !blocked; ++k )// each polygon
			{
				const poly_t&p = polys[k];
				
				//is this vertex used in the poly?				
				// for (int pi = 0; pi < 3 ; ++pi) // alt, use some margin
				//   	if( (int)i == (int)p.index[pi] )
				//  		continue;
				
				blocked |= ray_triangle( start, dir,
										 verts[p.index[0]].pos,	
										 verts[p.index[1]].pos,
										 verts[p.index[2]].pos);

			}

			if( !blocked )
			{
				//todo inverse linear / square
				vec3 d,dN;
				float f,dp;

				if( L.type == light_t::SUN ){
					dN = L.dir;
					f = 1.f;
				}else {
					d = L.pos - v.pos;
					dN=vnormal( d );
					f = 1.-fmin(1.f, vlen(d) / L.dist );
				}

				for( int k = 0; k<3; ++k )
				{
					dp = fmax(0.f,vdot( v.basis[k], dN ) );
					v.basis_color[k]+=L.rgb*f*dp;
				}
				
				//float f = 1.-fmin(1.f, vlen(d) / L.dist );
				//float f = 1.f/(1.f + vdot( d, d ) );//inv square
				//not as prominent but sphere like
				//float f = 1.f-1.f/(1.f + fmax(0.f,L.dist-vlen( d ) ) );//inv 
			}
		}
		//printf ("C = %.2f,%.2f,%.2f\n", v.init_rgb.x, v.init_rgb.y, v.init_rgb.z);
	}
}