Beispiel #1
0
static
__forceinline
void setLinearAndAngular(const float4& n, const float4& r0, const float4& r1,
                         float4& linear, float4& angular0, float4& angular1)
{
    linear = -n;
    angular0 = -cross3(r0, n);
    angular1 = cross3(r1, n);
}
bool intersect(Point p0, Point p1, Point q0, Point q1) {
  PType c0 = cross3(p0, p1, q0), c1 = cross3(p0, p1, q1);
  PType d0 = cross3(q0, q1, p0), d1 = cross3(q0, q1, p1);
  if(c0 == 0 && c1 == 0) {
    PType e0 = dot3(p0, p1, q0);
    PType e1 = dot3(p0, p1, q1);
    if( !(e0 < e1) ) {
      swap(e0, e1);
    }
    return e0 <= dist2(p0, p1) && 0 <= e1;
  }
  return (c0 ^ c1) <= 0 && (d0 ^ d1) <= 0;
}
Beispiel #3
0
void inertia_triangle(double *v0, double *v1, double *v2,
                      double mass, double *inertia)
{
  double s[3][3] = {{2.0, 1.0, 1.0}, {1.0, 2.0, 1.0}, {1.0, 1.0, 2.0}};
  double v[3][3],sv[3][3],vtsv[3][3];
  double vvv[3],v1mv0[3],v2mv0[3],normal[3];

  v[0][0] = v0[0]; v[0][1] = v0[1]; v[0][2] = v0[2];
  v[1][0] = v1[0]; v[1][1] = v1[1]; v[1][2] = v1[2];
  v[2][0] = v2[0]; v[2][1] = v2[1]; v[2][2] = v2[2];

  times3(s,v,sv);
  transpose_times3(v,sv,vtsv);

  double sum = lensq3(v0) + lensq3(v1) + lensq3(v2);
  vvv[0] = v0[0] + v1[0] + v2[0];
  vvv[1] = v0[1] + v1[1] + v2[1];
  vvv[2] = v0[2] + v1[2] + v2[2];
  sum += lensq3(vvv);

  sub3(v1,v0,v1mv0);
  sub3(v2,v0,v2mv0);
  cross3(v1mv0,v2mv0,normal);
  double a = len3(normal);
  double inv24 = mass/24.0;

  inertia[0] = inv24*a*(sum-vtsv[0][0]);
  inertia[1] = inv24*a*(sum-vtsv[1][1]);
  inertia[2] = inv24*a*(sum-vtsv[2][2]);
  inertia[3] = -inv24*a*vtsv[1][2];
  inertia[4] = -inv24*a*vtsv[0][2];
  inertia[5] = -inv24*a*vtsv[0][1];
}
void calcRigidMotion(const float4* vtx, const float4* vtxPrev, int nVtx, float4& v, float4& w, float4& c)
{
	float4 ang;
	Matrix3x3 inertia;
	c = make_float4(0);
	v = make_float4(0);
	ang = make_float4(0);
	inertia = mtIdentity();
	for(int i=0; i<nVtx; i++)
	{
		c += vtx[i];
		v += vtx[i]-vtxPrev[i];
	}
	c /= (float)nVtx;
	v /= (float)nVtx;
	for(int i=0; i<nVtx; i++)
	{
		const float4& r = vtx[i]-c;
		ang += cross3( r, vtx[i]-vtxPrev[i] );
		Matrix3x3 m;
		m.m_row[0] = make_float4(r.y*r.y + r.z*r.z, -r.x*r.y, -r.x*r.z);
		m.m_row[1] = make_float4(-r.y*r.x, r.x*r.x + r.z*r.z, -r.y*r.z);
		m.m_row[2] = make_float4(-r.z*r.x, -r.z*r.y, r.x*r.x + r.y*r.y);
		inertia = inertia + m;
	}
	Matrix3x3 invInertia = mtInvert( inertia );
	w = mtMul1( invInertia, ang );
}
//-----------------------------------------------------------------------------
void CPUTCamera::LookAt( const float xx, const float yy, const float zz )
{
    float3 pos;
    GetPosition( &pos);

    float3 lookPoint(xx, yy, zz);
    float3 look  = (lookPoint - pos).normalize();
    float3 right = cross3(float3(0.0f,1.0f,0.0f), look).normalize(); // TODO: simplify algebraically
    float3 up    = cross3(look, right);
    
    mParentMatrix = float4x4(
        right.x, right.y, right.z, 0.0f,
           up.x,    up.y,    up.z, 0.0f,
         look.x,  look.y,  look.z, 0.0f,
          pos.x,   pos.y,   pos.z, 1.0f
    );
}
float ClothSimulation::calcVolume( const float4* v, const int4* t, int n )
{
	float vol = 0;
	for(int i=0; i<n; i++)
	{
		const int4& tri = t[i];
		float4 c = cross3(v[tri.y], v[tri.x]);
		vol += dot3F4( c, v[tri.z] );
	}
	return fabs( vol/6.f );
}
Beispiel #7
0
static int luaB_cross (lua_State *L) {
  float x1, y1, z1;
  float x2, y2, z2;
  float ax, ay, az;
  if (lua_gettop(L) != 2) luaL_error(L, "Invalid params, try cross(v,v)");
  lua_checkvector3(L, 1, &x1, &y1, &z1);
  lua_checkvector3(L, 2, &x2, &y2, &z2);
  cross3(x1,y1,z1, x2,y2,z2, &ax, &ay, &az);
  lua_pushvector3(L,ax,ay,az);
  return 1;
}
t_vector3f	rotate3(t_vector3f vec, t_vector3f axis, float angle)
{
    float 		sin_angle;
    float 		cos_angle;
    t_vector3f	tmp;

    sin_angle = (float)sin(-angle);
    cos_angle = (float)cos(-angle);
    tmp = cross3(vec, mul3f(axis, sin_angle));
    tmp = add3v(tmp, mul3f(vec, cos_angle));
    tmp = add3v(tmp, mul3f(vec, dot3(vec, mul3f(axis, 1 - cos_angle))));
    return (tmp);
}
Beispiel #9
0
void lookat(vec3 eye, vec3 center, vec3 up, float* camera) {
	vec3 z = normal3(sub3(eye, center));
	vec3 x = normal3(cross3(up,z));
	vec3 y = normal3(cross3(z,x));
	float Minv[4][4];
	float Tr[4][4];
	mat_identity(&Minv[0][0]);
	mat_identity(&Tr[0][0]);

	Minv[0][0] = x.x;
	Minv[1][0] = y.x;
	Minv[2][0] = z.x;
	Tr[0][3] = -center.x;
	Minv[0][1] = x.y;
	Minv[1][1] = y.y;
	Minv[2][1] = z.y;
	Tr[1][3] = -center.y;
	Minv[0][2] = x.z;
	Minv[1][2] = y.z;
	Minv[2][2] = z.z;
	Tr[2][3] = -center.z;
	matmul(&Minv[0][0], &Tr[0][0], camera);
}
Beispiel #10
0
/* satellite antenna phase center offset ---------------------------------------
* compute satellite antenna phase center offset in ecef
* args   : gtime_t time       I   time (gpst)
*          double *rs         I   satellite position and velocity (ecef)
*                                 {x,y,z,vx,vy,vz} (m|m/s)
*          pcv_t  *pcv        I   satellite antenna parameter
*          double *dant       I   satellite antenna phase center offset (ecef)
*                                 {dx,dy,dz} (m)
* return : none
*-----------------------------------------------------------------------------*/
extern void satantoff(gtime_t time, const double *rs, const pcv_t *pcv,
                      double *dant)
{
    double ex[3],ey[3],ez[3],es[3],r[3],rsun[3],gmst;
    int i;
    
    trace(4,"satantoff: time=%s\n",time_str(time,3));
    
    /* sun position in ecef */
    sunmoonpos(gpst2utc(time),NULL,rsun,NULL,&gmst);
    
    /* unit vectors of satellite fixed coordinates */
    for (i=0;i<3;i++) r[i]=-rs[i];
    if (!normv3(r,ez)) return;
    for (i=0;i<3;i++) r[i]=rsun[i]-rs[i];
    if (!normv3(r,es)) return;
    cross3(ez,es,r);
    if (!normv3(r,ey)) return;
    cross3(ey,ez,ex);
    
    for (i=0;i<3;i++) { /* use L1 value */
        dant[i]=pcv->off[0][0]*ex[i]+pcv->off[0][1]*ey[i]+pcv->off[0][2]*ez[i];
    }
}
void ClothSimulation::volumeConstraint( float4* vtx, float* mass, const int4* tris, int nTris, float initVolume, float coeff )
{
	float vol = calcVolume( vtx, tris, nTris );

	float force = (vol - initVolume)*coeff;

	int nVtx = 0;
	for(int i=0; i<nTris; i++)
	{
		nVtx = max2( nVtx, max2( tris[i].x, max2( tris[i].y, tris[i].z) ) );
	}
	nVtx += 1;

	float4* disp = new float4[nVtx];
	for(int i=0; i<nVtx; i++) disp[i] = make_float4(0,0,0,0);

	for(int i=0; i<nTris; i++)
	{
		const int4& t = tris[i];
		float4& v0 = vtx[t.x];
		float4& v1 = vtx[t.y];
		float4& v2 = vtx[t.z];

		const float4 n = cross3(v1-v0, v2-v0 );
		float nl = length3( n );
		float area = nl/2.f;

//		force = max2( 0.f, force );
		force = min2( 0.f, force );

		float4 f = force/3.f*(n/nl);
		if( mass[t.x] != FLT_MAX )
			disp[t.x] += f;
//			v0 += f;
		if( mass[t.y] != FLT_MAX )
			disp[t.y] += f;
//			v1 += f;
		if( mass[t.z] != FLT_MAX )
			disp[t.z] += f;
//			v2 += f;
	}

	for(int i=0; i<nVtx; i++)
		vtx[i] += disp[i];

	delete [] disp;
}
Beispiel #12
0
void
MeshFaceElementTable::calcNormalVector(int index)
{
  if (normals == NULL)
    return;

  meshElementCode elem_code = getElementCode(index);

  // Pick normal
  Point3& normal = normals[index];
  Point3 *p1, *p2, *p3;

  switch (elem_code) {
  case MEC_303:
  case MEC_304:
  case MEC_306:
  case MEC_307:
    p1 = &meshNodes[nodeIds[index][0]];
    p2 = &meshNodes[nodeIds[index][1]];
    p3 = &meshNodes[nodeIds[index][2]];
    break;
  case MEC_404:
  case MEC_405:
  case MEC_408:
  case MEC_409:
    p1 = &meshNodes[nodeIds[index][0]];
    p2 = &meshNodes[nodeIds[index][1]];
    p3 = &meshNodes[nodeIds[index][2]];
    break;
  default:
    return;
  }

  Point3 a, b;
  diff3(*p3, *p1, a);
  diff3(*p2, *p1, b);
  cross3(b, a, normal);
  normalize(normal);

  for (int i = 0; i < 3; i++) {
    if ( isZero(normal[i]) ) {
      normal[i] = 0.0;
    }
  }
}
Beispiel #13
0
/*
 * multiply the top of the matrix stack by a view-pointing transformation
 * with the eyepoint at e, looking at point l, with u at the top of the screen.
 * The coordinate system is deemed to be right-handed.
 * The generated transformation transforms this view into a view from
 * the origin, looking in the positive y direction, with the z axis pointing up,
 * and x to the right.
 */
void look(Space *t, Point3 e, Point3 l, Point3 u){
	Matrix m, inv;
	Point3 r;
	l=unit3(sub3(l, e));
	u=unit3(vrem3(sub3(u, e), l));
	r=cross3(l, u);
	/* make the matrix to transform from (rlu) space to (xyz) space */
	ident(m);
	m[0][0]=r.x; m[0][1]=r.y; m[0][2]=r.z;
	m[1][0]=l.x; m[1][1]=l.y; m[1][2]=l.z;
	m[2][0]=u.x; m[2][1]=u.y; m[2][2]=u.z;
	ident(inv);
	inv[0][0]=r.x; inv[0][1]=l.x; inv[0][2]=u.x;
	inv[1][0]=r.y; inv[1][1]=l.y; inv[1][2]=u.y;
	inv[2][0]=r.z; inv[2][1]=l.z; inv[2][2]=u.z;
	ixform(t, m, inv);
	move(t, -e.x, -e.y, -e.z);
}
Beispiel #14
0
static int luaB_quat (lua_State *L) {
  if (lua_gettop(L)==4 && lua_isnumber(L,1) && lua_isnumber(L,2) && lua_isnumber(L,3) && lua_isnumber(L,4)) {
    float w,x,y,z;
    w = (float)lua_tonumber(L, 1);
    x = (float)lua_tonumber(L, 2);
    y = (float)lua_tonumber(L, 3);
    z = (float)lua_tonumber(L, 4);
    lua_pushquat(L, w,x,y,z);
    return 1;
  } else if (lua_gettop(L)==2 && lua_isnumber(L,1) && lua_isvector3(L,2)) {
    float angle,x,y,z,ha,s;
    angle = (float)lua_tonumber(L, 1);
    lua_checkvector3(L, 2, &x, &y, &z);
    ha = angle*(0.5f*PI/180.0f);
    s = sinf(ha);
    lua_pushquat(L, cosf(ha),s*x,s*y,s*z);
    return 1;
  } else if (lua_gettop(L)==2 && lua_isvector3(L,1) && lua_isvector3(L,2)) {
    float x1, y1, z1;
    float x2, y2, z2;
    float l1,l2,d;
    lua_checkvector3(L, 1, &x1, &y1, &z1);
    lua_checkvector3(L, 2, &x2, &y2, &z2);

    /* Based on Stan Melax's article in Game Programming Gems */
    l1 = sqrtf(x1*x1 + y1*y1 + z1*z1);
    l2 = sqrtf(x2*x2 + y2*y2 + z2*z2);
    x1/=l1; y1/=l1; z1/=l1; 
    x2/=l2; y2/=l2; z2/=l2; 

    d = dot3(x1,y1,z1, x2,y2,z2);

    /* If dot == 1, vectors are the same */
    if (d >= 1.0f) {
      lua_pushquat(L, 1,0,0,0);
      return 1;
    }

    if (d < (1e-6f - 1.0f)) {

      float ax, ay, az;
      float len2, len;

      cross3(1,0,0, x1,y1,z1, &ax, &ay, &az);
      len2 = ax*ax + ay*ay + az*az;
      if (len2 == 0) {
        cross3(0,1,0, x1,y1,z1, &ax, &ay, &az);
        len2 = ax*ax + ay*ay + az*az;
      }
      len = sqrtf(len2);
      ax/=len; ay/=len; az/=len; 
      lua_pushquat(L, 0,ax,ay,az);
      return 1;

    } else {

      float s = sqrtf((1+d)*2);
      float ax, ay, az;
      float qw, qlen;

      cross3(x1,y1,z1, x2,y2,z2, &ax, &ay, &az);
      ax/=s; ay/=s; az/=s; 
      qw = s*0.5f;
      qlen = sqrtf(qw*qw + ax*ax + ay*ay + az*az);
      lua_pushquat(L, qw/qlen,ax/qlen,ay/qlen,az/qlen);
      return 1;

    }

  } else {
    luaL_error(L, "Invalid params, try quat(n,n,n,n) quat(n,v3) quat(v3,v3)");
    return 0;
  }
}
Beispiel #15
0
 Vector4 Vector4::anotherPerpendicular3(const Vector3& hint, const Vector3& hint2) const
 {
     Vector4 firstPerp = perpendicular3(hint, hint2);
     Vector4 v = cross3(firstPerp);
     return v.normalized3();
 }
Beispiel #16
0
/* satellite position and clock with ssr correction --------------------------*/
static int satpos_ssr(gtime_t time, gtime_t teph, int sat, const nav_t *nav,
                      int opt, double *rs, double *dts, double *var, int *svh)
{
    const ssr_t *ssr;
    eph_t *eph;
    double t1,t2,t3,er[3],ea[3],ec[3],rc[3],deph[3],dclk,dant[3]={0},tk;
    int i,sys;
    
    trace(4,"satpos_ssr: time=%s sat=%2d\n",time_str(time,3),sat);
    
    ssr=nav->ssr+sat-1;
    
    if (!ssr->t0[0].time) {
        trace(2,"no ssr orbit correction: %s sat=%2d\n",time_str(time,0),sat);
        return 0;
    }
    if (!ssr->t0[1].time) {
        trace(2,"no ssr clock correction: %s sat=%2d\n",time_str(time,0),sat);
        return 0;
    }
    /* inconsistency between orbit and clock correction */
    if (ssr->iod[0]!=ssr->iod[1]) {
        trace(2,"inconsist ssr correction: %s sat=%2d iod=%d %d\n",
              time_str(time,0),sat,ssr->iod[0],ssr->iod[1]);
        *svh=-1;
        return 0;
    }
    t1=timediff(time,ssr->t0[0]);
    t2=timediff(time,ssr->t0[1]);
    t3=timediff(time,ssr->t0[2]);
    
    /* ssr orbit and clock correction (ref [4]) */
    if (fabs(t1)>MAXAGESSR||fabs(t2)>MAXAGESSR) {
        trace(2,"age of ssr error: %s sat=%2d t=%.0f %.0f\n",time_str(time,0),
              sat,t1,t2);
        *svh=-1;
        return 0;
    }
    if (ssr->udi[0]>=1.0) t1-=ssr->udi[0]/2.0;
    if (ssr->udi[1]>=1.0) t2-=ssr->udi[0]/2.0;
    
    for (i=0;i<3;i++) deph[i]=ssr->deph[i]+ssr->ddeph[i]*t1;
    dclk=ssr->dclk[0]+ssr->dclk[1]*t2+ssr->dclk[2]*t2*t2;
    
    /* ssr highrate clock correction (ref [4]) */
    if (ssr->iod[0]==ssr->iod[2]&&ssr->t0[2].time&&fabs(t3)<MAXAGESSR_HRCLK) {
        dclk+=ssr->hrclk;
    }
    if (norm(deph,3)>MAXECORSSR||fabs(dclk)>MAXCCORSSR) {
        trace(3,"invalid ssr correction: %s deph=%.1f dclk=%.1f\n",
              time_str(time,0),norm(deph,3),dclk);
        *svh=-1;
        return 0;
    }
    /* satellite postion and clock by broadcast ephemeris */
    if (!ephpos(time,teph,sat,nav,ssr->iode,rs,dts,var,svh)) return 0;
    
    /* satellite clock for gps, galileo and qzss */
    sys=satsys(sat,NULL);
    if (sys==SYS_GPS||sys==SYS_GAL||sys==SYS_QZS||sys==SYS_CMP) {
        if (!(eph=seleph(teph,sat,ssr->iode,nav))) return 0;
        
        /* satellite clock by clock parameters */
        tk=timediff(time,eph->toc);
        dts[0]=eph->f0+eph->f1*tk+eph->f2*tk*tk;
        dts[1]=eph->f1+2.0*eph->f2*tk;
        
        /* relativity correction */
        dts[0]-=2.0*dot(rs,rs+3,3)/CLIGHT/CLIGHT;
    }
    /* radial-along-cross directions in ecef */
    if (!normv3(rs+3,ea)) return 0;
    cross3(rs,rs+3,rc);
    if (!normv3(rc,ec)) {
        *svh=-1;
        return 0;
    }
    cross3(ea,ec,er);
    
    /* satellite antenna offset correction */
    if (opt) {
        satantoff(time,rs,sat,nav,dant);
    }
    for (i=0;i<3;i++) {
        rs[i]+=-(er[i]*deph[0]+ea[i]*deph[1]+ec[i]*deph[2])+dant[i];
    }
    /* t_corr = t_sv - (dts(brdc) + dclk(ssr) / CLIGHT) (ref [10] eq.3.12-7) */
    dts[0]+=dclk/CLIGHT;
    
    /* variance by ssr ura */
    *var=var_urassr(ssr->ura);
    
    trace(5,"satpos_ssr: %s sat=%2d deph=%6.3f %6.3f %6.3f er=%6.3f %6.3f %6.3f dclk=%6.3f var=%6.3f\n",
          time_str(time,2),sat,deph[0],deph[1],deph[2],er[0],er[1],er[2],dclk,*var);
    
    return 1;
}
//-----------------------------------------------------------------------------
void ProjectVerticesOntoTriangles(
	float3 *pSrcPositions,            // Positions of vertices to project
	UINT    srcVertexCount,           // Number of vertices to project
	UINT    triangleCount,            // Number of triangles in mesh projecting onto
	UINT   *pTriangleIndices,         // Vertex indices for each triangle in mesh being projected onto
	float3 *pTriangleVertexPositions, // Position of each vertex in mesh being projected onto
	float3 *pTriangleVertexNormals,   // Normal of each vertex in mesh being projected onto
	MappedVertex *pMapping,           // Output mapping results
    float   frontFacingDistanceThreshold, // Don't map vertices to front-facing triangles further than this distance away
    float   backFacingDistanceThreshold   // Don't map vertices to back-facing triangles further than this distance away
	){
	// Determine which triangle that each vertex projects onto
	for (UINT vIdx = 0; vIdx < srcVertexCount; vIdx++)
	{
		pMapping[vIdx].ClosestDistance = FLT_MAX; // Want to save smallest, so init to largest possible
		float shortestLength = FLT_MAX;
		float3 vv = pSrcPositions[vIdx];

		// Initialize the barycentrics to known bad value so we can later verify they're set to good value
		pMapping[vIdx].BarycentricCoordinates = float3(-1.0f);

		// Find the closest triangle this vertex projects onto (note: actually project the triangles onto the vertex)
		for (UINT tIdx = 0; tIdx < triangleCount; tIdx++)
		{
			// triangle's vertex indices
			UINT i0 = pTriangleIndices[tIdx * 3 + 0];
			UINT i1 = pTriangleIndices[tIdx * 3 + 1];
			UINT i2 = pTriangleIndices[tIdx * 3 + 2];

			// triangle's vertex positions
			float3 v0 = pTriangleVertexPositions[i0];
			float3 v1 = pTriangleVertexPositions[i1];
			float3 v2 = pTriangleVertexPositions[i2];

			// triangle's normal
			float3 normal = cross3(v1 - v0, v2 - v0);
			float rcpArea = 1.0f / normal.length();
			normal *= rcpArea;

			// Vector from triangle (vertex 0) to vertex
			float3 triangleToVertex = vv - v0;
			float dd = dot3(triangleToVertex, normal); // Closest distance from vertex to plane containing the triangle

			// TODO: Assuming vertex normal follows position.  Assert, etc
			float3 n0 = pTriangleVertexNormals[i0];
			float3 n1 = pTriangleVertexNormals[i1];
			float3 n2 = pTriangleVertexNormals[i2];

			// offsetT# is vertex# offset along it's normal so resulting triangle plane contains the vertex
			float3 offsetT0 = v0 + n0 * dd / dot3(n0, normal);
			float3 offsetT1 = v1 + n1 * dd / dot3(n1, normal);
			float3 offsetT2 = v2 + n2 * dd / dot3(n2, normal);

			// Compute area for projected triangle (well, 2X area. Later divide removes factor of 2) 
			float3 crossOffset = cross3(offsetT1 - offsetT0, offsetT2 - offsetT0);
			float  area = crossOffset.length();
			float  rcpOffsetArea = 1.0f / area;

			// Start computing barycentric coordinates.  Each is 2X area of tri formed by one projected triangle edge and the vertex
			float3 aa = cross3(offsetT2 - offsetT1, vv - offsetT1);
			float3 bb = cross3(offsetT0 - offsetT2, vv - offsetT2);
			float3 cc = cross3(offsetT1 - offsetT0, vv - offsetT0);

            // Compute distance to triangle so we can reject intersections with distant triangles.
            // This addresses the issue that hair can extend beyond the mesh (e.g., below the neck)
            float3 barys = float3( aa.length(), bb.length(), cc.length() ) * rcpOffsetArea;
            float barySum = barys.x + barys.y + barys.z;
            if( barySum <= 1.00001f ) // Note slightly > 1.0 to accomodate floating point errors.
            {
                float3 intersection = barys.x*v0 + barys.y*v1 + barys.z*v2;
                float3 ray = vv - intersection;
                float length = ray.length();
                bool frontFacing = dot3(ray, normal) > 0.0f;
                if( ( (  frontFacing && length < frontFacingDistanceThreshold )
                   || ( !frontFacing && length < backFacingDistanceThreshold ) )
                   && (length < shortestLength) )
                {
                    shortestLength = length;
                    pMapping[vIdx].TriangleIndex = tIdx;           // vertex[vIdx] projects onto triangle[hIdx]
                    pMapping[vIdx].ClosestDistance = length;           // and is dd distance away (along the triangle normal)
                    pMapping[vIdx].BarycentricCoordinates = barys; // and intersects at the point with these barycentric coordinates
                }
            }
		}
	}
}
//-----------------------------------------------
void CPUTFrustum::InitializeFrustum
(
    float nearClipDistance,
    float farClipDistance,
    float aspectRatio,
    float fov,
    const float3 &position,
    const float3 &look,
    const float3 &up
)
{
    // ******************************
    // This function computes the position of each of the frustum's eight points.
    // It also computes the normal of each of the frustum's six planes.
    // ******************************

    mNumFrustumVisibleModels = 0;
    mNumFrustumCulledModels  = 0;

    // We have the camera's up and look, but we also need right.
    float3 right = cross3( up, look );

    // Compute the position of the center of the near and far clip planes.
    float3 nearCenter = position + look * nearClipDistance;
    float3 farCenter  = position + look * farClipDistance;

    // Compute the width and height of the near and far clip planes
    float tanHalfFov = gScale2 * tanf(0.5f*fov);
    float halfNearWidth  = nearClipDistance * tanHalfFov;
    float halfNearHeight = halfNearWidth / aspectRatio;
    
    float halfFarWidth   = farClipDistance * tanHalfFov;
    float halfFarHeight  = halfFarWidth / aspectRatio;
    
    // Create two vectors each for the near and far clip planes.
    // These are the scaled up and right vectors.
    float3 upNear      = up    * halfNearHeight;
    float3 rightNear   = right * halfNearWidth;
    float3 upFar       = up    * halfFarHeight;
    float3 rightFar    = right * halfFarWidth;

    // Use the center positions and the up and right vectors
    // to compute the positions for the near and far clip plane vertices (four each)
    mpPosition[0] = nearCenter + upNear - rightNear; // near top left
    mpPosition[1] = nearCenter + upNear + rightNear; // near top right
    mpPosition[2] = nearCenter - upNear + rightNear; // near bottom right
    mpPosition[3] = nearCenter - upNear - rightNear; // near bottom left
    mpPosition[4] = farCenter  + upFar  - rightFar;  // far top left
    mpPosition[5] = farCenter  + upFar  + rightFar;  // far top right
    mpPosition[6] = farCenter  - upFar  + rightFar;  // far bottom right
    mpPosition[7] = farCenter  - upFar  - rightFar;  // far bottom left

    // Compute some of the frustum's edge vectors.  We will cross these
    // to get the normals for each of the six planes.
    float3 nearTop     = mpPosition[1] - mpPosition[0];
    float3 nearLeft    = mpPosition[3] - mpPosition[0];
    float3 topLeft     = mpPosition[4] - mpPosition[0];
    float3 bottomRight = mpPosition[2] - mpPosition[6];
    float3 farRight    = mpPosition[5] - mpPosition[6];
    float3 farBottom   = mpPosition[7] - mpPosition[6];

    mpNormal[0] = cross3(nearTop,     nearLeft).normalize();    // near clip plane
    mpNormal[1] = cross3(nearLeft,    topLeft).normalize();     // left
    mpNormal[2] = cross3(topLeft,     nearTop).normalize();     // top
    mpNormal[3] = cross3(farBottom,   bottomRight).normalize(); // bottom
    mpNormal[4] = cross3(bottomRight, farRight).normalize();    // right
    mpNormal[5] = cross3(farRight,    farBottom).normalize();   // far clip plane
}
int extractManifold(const float4* p, int nPoints, float4& nearNormal, float4& centerOut,
                    int contactIdx[4])
{
    if( nPoints == 0 ) return 0;

    nPoints = min2( nPoints, 64 );

    float4 center = make_float4(0.f);
    {
        float4 v[64];
        memcpy( v, p, nPoints*sizeof(float4) );
        PARALLEL_SUM( v, nPoints );
        center = v[0]/(float)nPoints;
    }

    centerOut = center;

    {   //	sample 4 directions
        if( nPoints < 4 )
        {
            for(int i=0; i<nPoints; i++) contactIdx[i] = i;
            return nPoints;
        }

        float4 aVector = p[0] - center;
        float4 u = cross3( nearNormal, aVector );
        float4 v = cross3( nearNormal, u );
        u = normalize3( u );
        v = normalize3( v );

        int idx[4];

        float2 max00 = make_float2(0,FLT_MAX);
        {
            float4 dir0 = u;
            float4 dir1 = -u;
            float4 dir2 = v;
            float4 dir3 = -v;

            //	idx, distance
            {
                {
                    int4 a[64];
                    for(int ie = 0; ie<nPoints; ie++ )
                    {
                        float4 f;
                        float4 r = p[ie]-center;
                        f.x = dot3F4( dir0, r );
                        f.y = dot3F4( dir1, r );
                        f.z = dot3F4( dir2, r );
                        f.w = dot3F4( dir3, r );

                        a[ie].x = ((*(u32*)&f.x) & 0xffffff00);
                        a[ie].x |= (0xff & ie);

                        a[ie].y = ((*(u32*)&f.y) & 0xffffff00);
                        a[ie].y |= (0xff & ie);

                        a[ie].z = ((*(u32*)&f.z) & 0xffffff00);
                        a[ie].z |= (0xff & ie);

                        a[ie].w = ((*(u32*)&f.w) & 0xffffff00);
                        a[ie].w |= (0xff & ie);
                    }

                    for(int ie=0; ie<nPoints; ie++)
                    {
                        a[0].x = (a[0].x > a[ie].x )? a[0].x: a[ie].x;
                        a[0].y = (a[0].y > a[ie].y )? a[0].y: a[ie].y;
                        a[0].z = (a[0].z > a[ie].z )? a[0].z: a[ie].z;
                        a[0].w = (a[0].w > a[ie].w )? a[0].w: a[ie].w;
                    }

                    idx[0] = (int)a[0].x & 0xff;
                    idx[1] = (int)a[0].y & 0xff;
                    idx[2] = (int)a[0].z & 0xff;
                    idx[3] = (int)a[0].w & 0xff;
                }
            }

            {
                float2 h[64];
                PARALLEL_DO( h[ie] = make_float2((float)ie, p[ie].w), nPoints );
                REDUCE_MIN( h, nPoints );
                max00 = h[0];
            }
        }

        contactIdx[0] = idx[0];
        contactIdx[1] = idx[1];
        contactIdx[2] = idx[2];
        contactIdx[3] = idx[3];

//		if( max00.y < 0.0f )
//			contactIdx[0] = (int)max00.x;

        std::sort( contactIdx, contactIdx+4 );

        return 4;
    }
}
Beispiel #20
0
void basic_gear()
{
char rcsid[] = "junk";
#define NUM_WHEELS 4

// char gear_strings[NUM_WHEELS][12]={"nose","right main", "left main", "tail skid"};
  /*
   * Aircraft specific initializations and data goes here
   */
   

    static int num_wheels = NUM_WHEELS;             /* number of wheels  */
    static DATA d_wheel_rp_body_v[NUM_WHEELS][3] =  /* X, Y, Z locations,full extension */
    {
        { .422,  0.,    .29 },             /*nose*/ /* in feet */
        { 0.026, 0.006, .409 },        /*right main*/
        { 0.026, -.006, .409 },        /*left main*/ 
        { -1.32, 0, .17 }            /*tail skid */
    };
    // static DATA gear_travel[NUM_WHEELS] = /*in Z-axis*/
           // { -0.5, 2.5, 2.5, 0};
    static DATA spring_constant[NUM_WHEELS] =       /* springiness, lbs/ft */
        { 2., .65, .65, 1. };
    static DATA spring_damping[NUM_WHEELS] =        /* damping, lbs/ft/sec */
        { 1.,  .3, .3, .5 };    
    static DATA percent_brake[NUM_WHEELS] =         /* percent applied braking */
        { 0.,  0.,  0., 0. };                       /* 0 = none, 1 = full */
    static DATA caster_angle_rad[NUM_WHEELS] =      /* steerable tires - in */
        { 0., 0., 0., 0};                                   /* radians, +CW */  
  /*
   * End of aircraft specific code
   */
    
  /*
   * Constants & coefficients for tyres on tarmac - ref [1]
   */
   
    /* skid function looks like:
     * 
     *           mu  ^
     *               |
     *       max_mu  |       +          
     *               |      /|          
     *   sliding_mu  |     / +------    
     *               |    /             
     *               |   /              
     *               +--+------------------------> 
     *               |  |    |      sideward V
     *               0 bkout skid
     *                 V     V
     */
  
  
    static int it_rolls[NUM_WHEELS] = { 1,1,1,0};       
        static DATA sliding_mu[NUM_WHEELS] = { 0.5, 0.5, 0.5, 0.3};     
    static DATA rolling_mu[NUM_WHEELS] = { 0.01, 0.01, 0.01, 0.0};      
    static DATA max_brake_mu[NUM_WHEELS] ={ 0.0, 0.6, 0.6, 0.0};        
    static DATA max_mu       = 0.8;     
    static DATA bkout_v      = 0.1;
    static DATA skid_v       = 1.0;
  /*
   * Local data variables
   */
   
    DATA d_wheel_cg_body_v[3];          /* wheel offset from cg,  X-Y-Z */
    DATA d_wheel_cg_local_v[3];         /* wheel offset from cg,  N-E-D */
    DATA d_wheel_rwy_local_v[3];        /* wheel offset from rwy, N-E-U */
        DATA v_wheel_cg_local_v[3];    /*wheel velocity rel to cg N-E-D*/
    // DATA v_wheel_body_v[3];          /* wheel velocity,        X-Y-Z */
    DATA v_wheel_local_v[3];            /* wheel velocity,        N-E-D */
    DATA f_wheel_local_v[3];            /* wheel reaction force,  N-E-D */
    // DATA altitude_local_v[3];       /*altitude vector in local (N-E-D) i.e. (0,0,h)*/
    // DATA altitude_body_v[3];        /*altitude vector in body (X,Y,Z)*/
    DATA temp3a[3];
    // DATA temp3b[3];
    DATA tempF[3];
    DATA tempM[3];      
    DATA reaction_normal_force;         /* wheel normal (to rwy) force  */
    DATA cos_wheel_hdg_angle, sin_wheel_hdg_angle;      /* temp storage */
    DATA v_wheel_forward, v_wheel_sideward,  abs_v_wheel_sideward;
    DATA forward_mu, sideward_mu;       /* friction coefficients        */
    DATA beta_mu;                       /* breakout friction slope      */
    DATA forward_wheel_force, sideward_wheel_force;

    int i;                              /* per wheel loop counter */
  
  /*
   * Execution starts here
   */
   
    beta_mu = max_mu/(skid_v-bkout_v);
    clear3( F_gear_v );         /* Initialize sum of forces...  */
    clear3( M_gear_v );         /* ...and moments               */
    
  /*
   * Put aircraft specific executable code here
   */
   
    percent_brake[1] = Brake_pct[0];
    percent_brake[2] = Brake_pct[1];
    
    caster_angle_rad[0] =
        (0.01 + 0.04 * (1 - V_calibrated_kts / 130)) * Rudder_pedal;
    
    
        for (i=0;i<num_wheels;i++)          /* Loop for each wheel */
    {
                /* printf("%s:\n",gear_strings[i]); */



                /*========================================*/
                /* Calculate wheel position w.r.t. runway */
                /*========================================*/

                
                /* printf("\thgcg: %g, theta: %g,phi: %g\n",D_cg_above_rwy,Theta*RAD_TO_DEG,Phi*RAD_TO_DEG); */

                
                        /* First calculate wheel location w.r.t. cg in body (X-Y-Z) axes... */

                sub3( d_wheel_rp_body_v[i], D_cg_rp_body_v, d_wheel_cg_body_v );

                /* then converting to local (North-East-Down) axes... */

                multtrans3x3by3( T_local_to_body_m,  d_wheel_cg_body_v, d_wheel_cg_local_v );
                

                /* Runway axes correction - third element is Altitude, not (-)Z... */

                d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* since altitude = -Z */

                /* Add wheel offset to cg location in local axes */

                add3( d_wheel_cg_local_v, D_cg_rwy_local_v, d_wheel_rwy_local_v );

                /* remove Runway axes correction so right hand rule applies */

                d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* now Z positive down */

                /*============================*/
                /* Calculate wheel velocities */
                /*============================*/

                /* contribution due to angular rates */

                cross3( Omega_body_v, d_wheel_cg_body_v, temp3a );

                /* transform into local axes */

                multtrans3x3by3( T_local_to_body_m, temp3a,v_wheel_cg_local_v );

                /* plus contribution due to cg velocities */

                add3( v_wheel_cg_local_v, V_local_rel_ground_v, v_wheel_local_v );

                clear3(f_wheel_local_v);
                reaction_normal_force=0;
                if( HEIGHT_AGL_WHEEL < 0. ) 
                        /*the wheel is underground -- which implies ground contact 
                          so calculate reaction forces */ 
                        {
                        /*===========================================*/
                        /* Calculate forces & moments for this wheel */
                        /*===========================================*/

                        /* Add any anticipation, or frame lead/prediction, here... */

                                /* no lead used at present */

                        /* Calculate sideward and forward velocities of the wheel 
                                in the runway plane                                     */

                        cos_wheel_hdg_angle = cos(caster_angle_rad[i] + Psi);
                        sin_wheel_hdg_angle = sin(caster_angle_rad[i] + Psi);

                        v_wheel_forward  = v_wheel_local_v[0]*cos_wheel_hdg_angle
                                         + v_wheel_local_v[1]*sin_wheel_hdg_angle;
                        v_wheel_sideward = v_wheel_local_v[1]*cos_wheel_hdg_angle
                                         - v_wheel_local_v[0]*sin_wheel_hdg_angle;
                        
                    
                /* Calculate normal load force (simple spring constant) */

                reaction_normal_force = 0.;
        
                reaction_normal_force = spring_constant[i]*d_wheel_rwy_local_v[2]
                                          - v_wheel_local_v[2]*spring_damping[i];
                        /* printf("\treaction_normal_force: %g\n",reaction_normal_force); */

                if (reaction_normal_force > 0.) reaction_normal_force = 0.;
                        /* to prevent damping component from swamping spring component */


                /* Calculate friction coefficients */

                        if(it_rolls[i])
                        {
                           forward_mu = (max_brake_mu[i] - rolling_mu[i])*percent_brake[i] + rolling_mu[i];
                           abs_v_wheel_sideward = sqrt(v_wheel_sideward*v_wheel_sideward);
                           sideward_mu = sliding_mu[i];
                           if (abs_v_wheel_sideward < skid_v) 
                           sideward_mu = (abs_v_wheel_sideward - bkout_v)*beta_mu;
                           if (abs_v_wheel_sideward < bkout_v) sideward_mu = 0.;
                        }
                        else
                        {
                                forward_mu=sliding_mu[i];
                                sideward_mu=sliding_mu[i];
                        }          

                        /* Calculate foreward and sideward reaction forces */

                        forward_wheel_force  =   forward_mu*reaction_normal_force;
                        sideward_wheel_force =  sideward_mu*reaction_normal_force;
                        if(v_wheel_forward < 0.) forward_wheel_force = -forward_wheel_force;
                        if(v_wheel_sideward < 0.) sideward_wheel_force = -sideward_wheel_force;
/*                      printf("\tFfwdgear: %g Fsidegear: %g\n",forward_wheel_force,sideward_wheel_force);
 */
                        /* Rotate into local (N-E-D) axes */

                        f_wheel_local_v[0] = forward_wheel_force*cos_wheel_hdg_angle
                                          - sideward_wheel_force*sin_wheel_hdg_angle;
                        f_wheel_local_v[1] = forward_wheel_force*sin_wheel_hdg_angle
                                          + sideward_wheel_force*cos_wheel_hdg_angle;
                        f_wheel_local_v[2] = reaction_normal_force;       

                         /* Convert reaction force from local (N-E-D) axes to body (X-Y-Z) */
                        mult3x3by3( T_local_to_body_m, f_wheel_local_v, tempF );

                        /* Calculate moments from force and offsets in body axes */

                        cross3( d_wheel_cg_body_v, tempF, tempM );

                        /* Sum forces and moments across all wheels */

                        add3( tempF, F_gear_v, F_gear_v );
                        add3( tempM, M_gear_v, M_gear_v );   


                        }


                
/*                  printf("\tN: %g,dZrwy: %g dZdotrwy: %g\n",reaction_normal_force,HEIGHT_AGL_WHEEL,v_wheel_cg_local_v[2]);  */
/*                  printf("\tFxgear: %g Fygear: %g, Fzgear: %g\n",F_X_gear,F_Y_gear,F_Z_gear); */
/*                  printf("\tMgear: %g, Lgear: %g, Ngear: %g\n\n",M_m_gear,M_l_gear,M_n_gear); */
                
                
    }
}
Beispiel #21
0
static
__inline
void solveFriction(Constraint4& cs,
                   const float4& posA, float4& linVelA, float4& angVelA, float invMassA, const Matrix3x3& invInertiaA,
                   const float4& posB, float4& linVelB, float4& angVelB, float invMassB, const Matrix3x3& invInertiaB,
                   float maxRambdaDt[4], float minRambdaDt[4])
{
    if( cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0 ) return;
    const float4& center = cs.m_center;

    float4 n = -cs.m_linear;

    float4 tangent[2];
#if 1
    btPlaneSpace1 (&n, &tangent[0],&tangent[1]);
#else
    float4 r = cs.m_worldPos[0]-center;
    tangent[0] = cross3( n, r );
    tangent[1] = cross3( tangent[0], n );
    tangent[0] = normalize3( tangent[0] );
    tangent[1] = normalize3( tangent[1] );
#endif

    float4 angular0, angular1, linear;
    float4 r0 = center - posA;
    float4 r1 = center - posB;
    for(int i=0; i<2; i++)
    {
        setLinearAndAngular( tangent[i], r0, r1, linear, angular0, angular1 );
        float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,
                                    linVelA, angVelA, linVelB, angVelB );
        rambdaDt *= cs.m_fJacCoeffInv[i];

        {
            float prevSum = cs.m_fAppliedRambdaDt[i];
            float updated = prevSum;
            updated += rambdaDt;
            updated = max2( updated, minRambdaDt[i] );
            updated = min2( updated, maxRambdaDt[i] );
            rambdaDt = updated - prevSum;
            cs.m_fAppliedRambdaDt[i] = updated;
        }

        float4 linImp0 = invMassA*linear*rambdaDt;
        float4 linImp1 = invMassB*(-linear)*rambdaDt;
        float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;
        float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;
#ifdef _WIN32
        btAssert(_finite(linImp0.x));
        btAssert(_finite(linImp1.x));
#endif
        linVelA += linImp0;
        angVelA += angImp0;
        linVelB += linImp1;
        angVelB += angImp1;
    }

    {   //	angular damping for point constraint
        float4 ab = normalize3( posB - posA );
        float4 ac = normalize3( center - posA );
        if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))
        {
            float angNA = dot3F4( n, angVelA );
            float angNB = dot3F4( n, angVelB );

            angVelA -= (angNA*0.1f)*n;
            angVelB -= (angNB*0.1f)*n;
        }
    }
}
Beispiel #22
0
void SimpleDeferredDemo::render()
{
    if( m_firstFrame )
    {
        for(int i=0; i<MAX_BODIES; i++)
        {
            const float4& pos = m_pos[i];
            const Quaternion& quat = qtGetIdentity();

            ShapeBase* boxShape = m_shapes[i];

            const float4* vtx = boxShape->getVertexBuffer();
            const int4* tris = boxShape->getTriangleBuffer();

            float4* v = new float4[boxShape->getNumTris()*3];
            u32* idx = new u32[boxShape->getNumTris()*3];
            float4* n = new float4[boxShape->getNumTris()*3];

            const float4 colors[] = { make_float4(0,1,1,1), make_float4(1,0,1,1), make_float4(1,1,0,1),
                                      make_float4(0,0,1,1), make_float4(0,1,0,1), make_float4(1,0,0,1)
                                    };

            float c = 0.4f;
            float4 color = make_float4(0.8f-c,0.8f-c,0.8f,1.f)*1.8f;
            color = make_float4(0.5f,1,0.5f,1);

            if( i==0 ) color = make_float4(1.f,1.f,1.f, 1.f);

            for(int it=0; it<boxShape->getNumTris(); it++)
            {
                const int4& t = tris[it];

                idx[3*it+0] = it*3;
                idx[3*it+1] = it*3+1;
                idx[3*it+2] = it*3+2;

                v[3*it+0] = vtx[t.x];
                v[3*it+1] = vtx[t.y];
                v[3*it+2] = vtx[t.z];
                if( i==0 ) swap2(v[3*it+1], v[3*it+2]);

                float4 tn = cross3( v[3*it+1] - v[3*it+0], v[3*it+2] - v[3*it+0] );

                tn = normalize3( tn );
                n[3*it+0] = tn;
                n[3*it+1] = tn;
                n[3*it+2] = tn;
            }

            int nTris = boxShape->getNumTris();
            int nVtx = boxShape->getNumVertex();


//		pxReleaseDrawTriangleListTransformed( v, n, idx, nTris*3, nTris*3, color, pos, quat );
            pxDrawTriangleListTransformed( v, n, idx, nTris*3, nTris*3, color, pos, quat );

            delete [] v;
            delete [] idx;
            delete [] n;
        }
//	m_firstFrame = false;
    }
}
Beispiel #23
0
void uiuc_gear()
{

    /*
     * Aircraft specific initializations and data goes here
     */

    static DATA percent_brake[MAX_GEAR] =	    /* percent applied braking */
    {   0.,  0.,  0., 0.,
        0.,  0.,  0., 0.,
        0.,  0.,  0., 0.,
        0.,  0.,  0., 0.
    };			    /* 0 = none, 1 = full */
    static DATA caster_angle_rad[MAX_GEAR] =	    /* steerable tires - in */
    {   0., 0., 0., 0.,
        0., 0., 0., 0.,
        0., 0., 0., 0.,
        0., 0., 0., 0.
    };                         /* radians, +CW */
    /*
     * End of aircraft specific code
     */

    /*
     * Constants & coefficients for tyres on tarmac - ref [1]
     */

    /* skid function looks like:
     *
     *           mu  ^
     *               |
     *       max_mu  |       +
     *               |      /|
     *   sliding_mu  |     / +------
     *               |    /
     *               |   /
     *               +--+------------------------>
     *               |  |    |      sideward V
     *               0 bkout skid
     *	               V     V
     */


    static int it_rolls[MAX_GEAR] =
    {   1, 1, 1, 0,
        0, 0, 0, 0,
        0, 0, 0, 0,
        0, 0, 0, 0
    };
    static DATA sliding_mu[MAX_GEAR] =
    {   0.5, 0.5, 0.5, 0.3,
        0.3, 0.3, 0.3, 0.3,
        0.3, 0.3, 0.3, 0.3,
        0.3, 0.3, 0.3, 0.3
    };
    static DATA max_brake_mu[MAX_GEAR] =
    {   0.0, 0.6, 0.6, 0.0,
        0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.0
    };
    static DATA max_mu	     = 0.8;
    static DATA bkout_v	     = 0.1;
    static DATA skid_v       = 1.0;
    /*
     * Local data variables
     */

    DATA d_wheel_cg_body_v[3];		/* wheel offset from cg,  X-Y-Z	*/
    DATA d_wheel_cg_local_v[3];		/* wheel offset from cg,  N-E-D	*/
    DATA d_wheel_rwy_local_v[3];	/* wheel offset from rwy, N-E-U */
    DATA v_wheel_cg_local_v[3];    /*wheel velocity rel to cg N-E-D*/
    // DATA v_wheel_body_v[3];		/* wheel velocity,	  X-Y-Z	*/
    DATA v_wheel_local_v[3];		/* wheel velocity,	  N-E-D	*/
    DATA f_wheel_local_v[3];		/* wheel reaction force,  N-E-D	*/
    // DATA altitude_local_v[3];       /*altitude vector in local (N-E-D) i.e. (0,0,h)*/
    // DATA altitude_body_v[3];        /*altitude vector in body (X,Y,Z)*/
    DATA temp3a[3];
    // DATA temp3b[3];
    DATA tempF[3];
    DATA tempM[3];
    DATA reaction_normal_force;		/* wheel normal (to rwy) force	*/
    DATA cos_wheel_hdg_angle, sin_wheel_hdg_angle;	/* temp storage */
    DATA v_wheel_forward, v_wheel_sideward,  abs_v_wheel_sideward;
    DATA forward_mu, sideward_mu;	/* friction coefficients	*/
    DATA beta_mu;			/* breakout friction slope	*/
    DATA forward_wheel_force, sideward_wheel_force;

    int i;				/* per wheel loop counter */

    /*
     * Execution starts here
     */

    beta_mu = max_mu/(skid_v-bkout_v);
    clear3( F_gear_v );		/* Initialize sum of forces...	*/
    clear3( M_gear_v );		/* ...and moments		*/

    /*
     * Put aircraft specific executable code here
     */

    percent_brake[1] = Brake_pct[0];
    percent_brake[2] = Brake_pct[1];

    caster_angle_rad[0] =
        (0.01 + 0.04 * (1 - V_calibrated_kts / 130)) * Rudder_pedal;


    for (i=0; i<MAX_GEAR; i++)	  /* Loop for each wheel */
    {
        // Execute only if the gear has been defined
        if (!gear_model[i])
        {
            // do nothing
            continue;
        }
        else
        {

            /*========================================*/
            /* Calculate wheel position w.r.t. runway */
            /*========================================*/

            /* printf("\thgcg: %g, theta: %g,phi: %g\n",D_cg_above_rwy,Theta*RAD_TO_DEG,Phi*RAD_TO_DEG); */

            /* First calculate wheel location w.r.t. cg in body (X-Y-Z) axes... */

            sub3( D_gear_v[i], D_cg_rp_body_v, d_wheel_cg_body_v );

            /* then converting to local (North-East-Down) axes... */

            multtrans3x3by3( T_local_to_body_m,  d_wheel_cg_body_v, d_wheel_cg_local_v );


            /* Runway axes correction - third element is Altitude, not (-)Z... */

            d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* since altitude = -Z */

            /* Add wheel offset to cg location in local axes */

            add3( d_wheel_cg_local_v, D_cg_rwy_local_v, d_wheel_rwy_local_v );

            /* remove Runway axes correction so right hand rule applies */

            d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* now Z positive down */

            /*============================*/
            /* Calculate wheel velocities */
            /*============================*/

            /* contribution due to angular rates */

            cross3( Omega_body_v, d_wheel_cg_body_v, temp3a );

            /* transform into local axes */

            multtrans3x3by3( T_local_to_body_m, temp3a,v_wheel_cg_local_v );

            /* plus contribution due to cg velocities */

            add3( v_wheel_cg_local_v, V_local_rel_ground_v, v_wheel_local_v );

            clear3(f_wheel_local_v);
            reaction_normal_force=0;

            fgSetBool("/gear/gear[0]/wow", false);
            fgSetBool("/gear/gear[1]/wow", false);
            fgSetBool("/gear/gear[2]/wow", false);
            if( HEIGHT_AGL_WHEEL < 0. )
                /*the wheel is underground -- which implies ground contact
                  so calculate reaction forces */
            {
                //set the property - weight on wheels
                //  	  if (i==0)
                //  	    {
                //  	      fgSetBool("/gear/gear[0]/wow", true);
                //  	    }
                //	  if (i==1)
                //	    {
                //	      fgSetBool("/gear/gear[1]/wow", true);
                //	    }
                //  	  if (i==2)
                //  	    {
                //  	      fgSetBool("/gear/gear[2]/wow", true);
                //  	    }

                /*===========================================*/
                /* Calculate forces & moments for this wheel */
                /*===========================================*/

                /* Add any anticipation, or frame lead/prediction, here... */

                /* no lead used at present */

                /* Calculate sideward and forward velocities of the wheel
                in the runway plane					*/

                cos_wheel_hdg_angle = cos(caster_angle_rad[i] + Psi);
                sin_wheel_hdg_angle = sin(caster_angle_rad[i] + Psi);

                v_wheel_forward  = v_wheel_local_v[0]*cos_wheel_hdg_angle
                                   + v_wheel_local_v[1]*sin_wheel_hdg_angle;
                v_wheel_sideward = v_wheel_local_v[1]*cos_wheel_hdg_angle
                                   - v_wheel_local_v[0]*sin_wheel_hdg_angle;


                /* Calculate normal load force (simple spring constant) */

                reaction_normal_force = 0.;

                reaction_normal_force = kgear[i]*d_wheel_rwy_local_v[2]
                                        - v_wheel_local_v[2]*cgear[i];
                /* printf("\treaction_normal_force: %g\n",reaction_normal_force); */

                if (reaction_normal_force > 0.) reaction_normal_force = 0.;
                /* to prevent damping component from swamping spring component */


                /* Calculate friction coefficients */

                if(it_rolls[i])
                {
                    forward_mu = (max_brake_mu[i] - muGear[i])*percent_brake[i] + muGear[i];
                    abs_v_wheel_sideward = sqrt(v_wheel_sideward*v_wheel_sideward);
                    sideward_mu = sliding_mu[i];
                    if (abs_v_wheel_sideward < skid_v)
                        sideward_mu = (abs_v_wheel_sideward - bkout_v)*beta_mu;
                    if (abs_v_wheel_sideward < bkout_v) sideward_mu = 0.;
                }
                else
                {
                    forward_mu=sliding_mu[i];
                    sideward_mu=sliding_mu[i];
                }

                /* Calculate foreward and sideward reaction forces */

                forward_wheel_force  =   forward_mu*reaction_normal_force;
                sideward_wheel_force =  sideward_mu*reaction_normal_force;
                if(v_wheel_forward < 0.) forward_wheel_force = -forward_wheel_force;
                if(v_wheel_sideward < 0.) sideward_wheel_force = -sideward_wheel_force;
                /* printf("\tFfwdgear: %g Fsidegear: %g\n",forward_wheel_force,sideward_wheel_force);
                 */
                /* Rotate into local (N-E-D) axes */

                f_wheel_local_v[0] = forward_wheel_force*cos_wheel_hdg_angle
                                     - sideward_wheel_force*sin_wheel_hdg_angle;
                f_wheel_local_v[1] = forward_wheel_force*sin_wheel_hdg_angle
                                     + sideward_wheel_force*cos_wheel_hdg_angle;
                f_wheel_local_v[2] = reaction_normal_force;

                /* Convert reaction force from local (N-E-D) axes to body (X-Y-Z) */
                mult3x3by3( T_local_to_body_m, f_wheel_local_v, tempF );

                /* Calculate moments from force and offsets in body axes */

                cross3( d_wheel_cg_body_v, tempF, tempM );

                /* Sum forces and moments across all wheels */
                if (tempF[0] != 0.0 || tempF[1] != 0.0 || tempF[2] != 0.0) {
                    fgSetBool("/gear/gear[1]/wow", true);
                }

                add3( tempF, F_gear_v, F_gear_v );
                add3( tempM, M_gear_v, M_gear_v );

            }
        }



        /* printf("\tN: %g,dZrwy: %g dZdotrwy: %g\n",reaction_normal_force,HEIGHT_AGL_WHEEL,v_wheel_cg_local_v[2]); */

        /*printf("\tFxgear: %g Fygear: %g, Fzgear: %g\n",F_X_gear,F_Y_gear,F_Z_gear);
        printf("\tMgear: %g, Lgear: %g, Ngear: %g\n\n",M_m_gear,M_l_gear,M_n_gear); */


    }
}
Beispiel #24
0
static
__inline
void solveFriction(b3GpuConstraint4& cs,
                   const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA,
                   const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB,
                   float maxRambdaDt[4], float minRambdaDt[4])
{

    if( cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0 ) return;
    const b3Vector3& center = (const b3Vector3&)cs.m_center;

    b3Vector3 n = -(const b3Vector3&)cs.m_linear;

    b3Vector3 tangent[2];
#if 1
    b3PlaneSpace1 (n, tangent[0],tangent[1]);
#else
    b3Vector3 r = cs.m_worldPos[0]-center;
    tangent[0] = cross3( n, r );
    tangent[1] = cross3( tangent[0], n );
    tangent[0] = normalize3( tangent[0] );
    tangent[1] = normalize3( tangent[1] );
#endif

    b3Vector3 angular0, angular1, linear;
    b3Vector3 r0 = center - posA;
    b3Vector3 r1 = center - posB;
    for(int i=0; i<2; i++)
    {
        setLinearAndAngular( tangent[i], r0, r1, linear, angular0, angular1 );
        float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,
                                    linVelA, angVelA, linVelB, angVelB );
        rambdaDt *= cs.m_fJacCoeffInv[i];

        {
            float prevSum = cs.m_fAppliedRambdaDt[i];
            float updated = prevSum;
            updated += rambdaDt;
            updated = b3Max( updated, minRambdaDt[i] );
            updated = b3Min( updated, maxRambdaDt[i] );
            rambdaDt = updated - prevSum;
            cs.m_fAppliedRambdaDt[i] = updated;
        }

        b3Vector3 linImp0 = invMassA*linear*rambdaDt;
        b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt;
        b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt;
        b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt;
#ifdef _WIN32
        b3Assert(_finite(linImp0.getX()));
        b3Assert(_finite(linImp1.getX()));
#endif
        linVelA += linImp0;
        angVelA += angImp0;
        linVelB += linImp1;
        angVelB += angImp1;
    }

    {   //	angular damping for point constraint
        b3Vector3 ab = ( posB - posA ).normalized();
        b3Vector3 ac = ( center - posA ).normalized();
        if( b3Dot( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))
        {
            float angNA = b3Dot( n, angVelA );
            float angNB = b3Dot( n, angVelB );

            angVelA -= (angNA*0.1f)*n;
            angVelB -= (angNB*0.1f)*n;
        }
    }

}
Beispiel #25
0
CL_Vec4<Type> &CL_Vec4<Type>::cross3(const CL_Vec4<Type>& v)
{
	*this = cross3(*this, v);
	return *this;
}