bool OrE::Math::HitTest( Ellipsoid e1, Ellipsoid e2 )
{
	// Absolute squared distance vector from e2 to e1
	Vec3 vDist = e1.vMiddlePoint - e2.vMiddlePoint;
	vDist *= vDist;
	// Project ray to both ellipsoid surfaces. All what matters is,
	// the the sum of the distances to surface is smaller than the length of
	// the distance vector.
	// Vec3 vRSum = vDist * ( InvSqrt( vDist.Dot( vDist * e1.vRadiiInvSq ) ) + InvSqrt( vDist.Dot( vDist * e2.vRadiiInvSq ) ) );
	// return vRSum.LengthSq() >= vDist.LengthSq();
	return InvSqrt( vDist.Dot( e1.vRadiiInvSq ) ) + InvSqrt( vDist.Dot( e2.vRadiiInvSq ) ) >= 1.0f;
}
void GetEstimatedAttitude(imu_t* imu_ptr)
{
	uint8_t axis;
	int32_t accMag = 0;
	float scale, deltaGyroAngle[3];
	uint8_t validAcc;
	static uint16_t previousT;
	uint16_t currentT = micros();

	scale = (currentT - previousT) * GYRO_SCALE; // GYRO_SCALE unit: radian/microsecond
	previousT = currentT;

	// Initialization
	for (axis = 0; axis < 3; axis++)
	{
		deltaGyroAngle[axis] = imu_ptr->gyroADC[axis]  * scale; // radian

		accLPF32[axis]    -= accLPF32[axis]>>ACC_LPF_FACTOR;
		accLPF32[axis]    += imu_ptr->accADC[axis];
		imu_ptr->accSmooth[axis]    = accLPF32[axis]>>ACC_LPF_FACTOR;

		accMag += (int32_t)imu_ptr->accSmooth[axis]*imu_ptr->accSmooth[axis] ;
	}

	rotateV(&EstG.V,deltaGyroAngle);
	rotateV(&EstM.V,deltaGyroAngle);
	
	accMag = accMag*100/((int32_t)ACC_1G*ACC_1G);
	validAcc = 72 < (uint16_t)accMag && (uint16_t)accMag < 133;
	// Apply complimentary filter (Gyro drift correction)
	// If accel magnitude >1.15G or <0.85G and ACC vector outside of the limit range => we neutralize the effect of accelerometers in the angle estimation.
	// To do that, we just skip filter, as EstV already rotated by Gyro
	for (axis = 0; axis < 3; axis++)
	{
		if ( validAcc )
		EstG.A[axis] = (EstG.A[axis] * GYR_CMPF_FACTOR + imu_ptr->accSmooth[axis]) * INV_GYR_CMPF_FACTOR;
		EstG32.A[axis] = EstG.A[axis]; //int32_t cross calculation is a little bit faster than float
		EstM.A[axis] = (EstM.A[axis] * GYR_CMPFM_FACTOR  + imu_ptr->magADC[axis]) * INV_GYR_CMPFM_FACTOR;
		EstM32.A[axis] = EstM.A[axis];
	}

	// Attitude of the estimated vector
	int32_t sqGX_sqGZ = sq(EstG32.V.X) + sq(EstG32.V.Z);
	invG = InvSqrt(sqGX_sqGZ + sq(EstG32.V.Y));
	att.angle[ROLL]  = _atan2(EstG32.V.X , EstG32.V.Z);
	att.angle[PITCH] = _atan2(EstG32.V.Y , InvSqrt(sqGX_sqGZ)*sqGX_sqGZ);
	
	att.heading = _atan2(
	EstM32.V.Z * EstG32.V.X - EstM32.V.X * EstG32.V.Z,
	(EstM.V.Y * sqGX_sqGZ  - (EstM32.V.X * EstG32.V.X + EstM32.V.Z * EstG32.V.Z) * EstG.V.Y)*invG );
	att.heading /= 10;
}
// pursue behavior
Status PursueBehavior::Execute(void)
{
	// get target
	const TargetData &targetdata = Database::targetdata.Get(mId);

	// get target entity
	Entity *targetEntity = Database::entity.Get(targetdata.mTarget);
	if (!targetEntity)
		return runningTask;

	// get pursue behavior template
	const PursueBehaviorTemplate &pursue = Database::pursuebehaviortemplate.Get(mId);

	// get owner entity
	Entity *entity = Database::entity.Get(mId);

	// direction to target
	Vector2 targetDir(pursue.mOffset.Untransform(TargetDir(pursue.mLeading, entity, targetEntity, targetdata.mOffset)));
	
	// save range
	float distSq = targetDir.LengthSq();

	// normalize direction
	targetDir *= InvSqrt(distSq);

	// move towards target
	mController->mMove += pursue.mStrength * targetDir;

	return runningTask;
}
Beispiel #4
0
void PhyCylinder::interact(Graph *pG2)
{
	nowPos=pG->nowPos;
	nextPos=pG->nextPos;
	pos1=pG2->pTransform->pTOmatrix->mMatrixQueue.back();
	temp=	(nextPos[0]-pos1[12])*(nextPos[0]-pos1[12])+
				(nextPos[2]-pos1[14])*(nextPos[2]-pos1[14]);
	if(temp>r*r*4 )
		return;

	ex=nowPos[0]-pos1[12];
	ey=nowPos[2]-pos1[14];

	templ=ex*ex+ey*ey;

	if( temp > templ )
		return;

	templ=InvSqrt(templ);
	temp=ex*templ;
	ex=ey*templ;
	ey=-temp;

	templ=nextPos[0]-nowPos[0];
	temp=nextPos[2]-nowPos[2];

	templ=ex*templ+ey*temp;

	nextPos[0]= nowPos[0]+templ * ex;
	nextPos[2]= nowPos[2]+templ * ey;
}
bool OrE::Math::HitDetection( Ellipsoid e1, Ellipsoid e2, Vec3& _vFeedbackLocation )
{
	// Absolute squared distance vector from e2 to e1
	Vec3 vDist = e1.vMiddlePoint - e2.vMiddlePoint;
	Vec3 vDistSq = vDist * vDist;
	// Determine the point in the middle between both surfaces.
	// Point on surface from e1, which is nearest to the center of e2 is p1 = r1 * -vDist + e1.m.
	// Point on surface from e2, which is nearest to the center of e1 is p2 = r2 * vDist + e2.m.
	// The point between them is (p1+p2)/2 = ((r2-r1) * vDist + e1.m+e2.m)/2
	float r1 = InvSqrt( vDistSq.Dot( e1.vRadiiInvSq ) );
	float r2 = InvSqrt( vDistSq.Dot( e2.vRadiiInvSq ) );
	_vFeedbackLocation = 0.5f*((r2-r1) * vDist + e1.vMiddlePoint + e2.vMiddlePoint);

	// Same as in HitTest
	return r1+r2 >= 1.0f;
}
Status EvadeBehavior::Execute(void)
{
	// get target
	const TargetData &targetdata = Database::targetdata.Get(mId);

	// get target entity
	Entity *targetEntity = Database::entity.Get(targetdata.mTarget);
	if (!targetEntity)
		return runningTask;

	// get owner entity
	Entity *entity = Database::entity.Get(mId);

	// get evade behavior template
	const EvadeBehaviorTemplate &evade = Database::evadebehaviortemplate.Get(mId);

	// target entity transform
	const Transform2 &targetTransform = targetEntity->GetTransform();

	// evade target's front vector
	Vector2 local(targetTransform.Untransform(entity->GetPosition()));
	if (local.y > 0)
	{
		local *= InvSqrt(local.LengthSq());
		float dir = local.x > 0 ? 1.0f : -1.0f;
		mController->mMove += evade.mStrength * dir * local.y * local.y * local.y * targetTransform.Rotate(Vector2(local.y, -local.x));
	}

	return runningTask;
}
Beispiel #7
0
float4 float4::normalize() const
{
	f32 lsqr = LengthSquared();
	if(NearZero(lsqr)) { return ZERO; };
	f32 recip = InvSqrt(lsqr);
	
	return float4(vec[0]*recip, vec[1]*recip, vec[2]*recip, vec[3]*recip);
};
Beispiel #8
0
void angleCalculate()
{
/// Дальше идет суровая математика, в силу которой мы получаем тангаж, крен, а также курс,
/// ... Причем в расчете курса учавствует магнетометр.
  // Attitude of the estimated vector
  int32_t sqGZ = sq(EstG32.V.Z);
  int32_t sqGX = sq(EstG32.V.X);
  int32_t sqGY = sq(EstG32.V.Y);
  int32_t sqGX_sqGZ = sqGX + sqGZ;
  float invmagXZ  = InvSqrt(sqGX_sqGZ);
  invG = InvSqrt(sqGX_sqGZ + sqGY);
  angle[ROLL]  = _atan2(EstG32.V.X ,EstG32.V.Z);
  angle[PITCH] = - _atan2(EstG32.V.Y , invmagXZ*sqGX_sqGZ);

    heading = _atan2(
      EstM32.V.Z * EstG32.V.X - EstM32.V.X * EstG32.V.Z,
      EstM32.V.Y * invG * sqGX_sqGZ  - (EstM32.V.X * EstG32.V.X + EstM32.V.Z * EstG32.V.Z) * invG * EstG32.V.Y ); 
   heading = heading /10;
 // vectorMultiply(&EstM32,&EstG32,&headvect);
  // heading2=
 // axisDekl=_atan2(EstG32.V.X , EstG32.V.Y);
 // deklination=_atan(EstG32.V.Z * InvSqrt(sqGX+sqGY));
}
Beispiel #9
0
// Return unit length vector in the same direction as given one
CVector3 Normalise( const CVector3& v )
{
	TFloat32 lengthSq = v.x*v.x + v.y*v.y + v.z*v.z;

	// Ensure vector is not zero length (use BaseMath.h float approx. fn with default epsilon)
	if ( gen::IsZero( lengthSq ) )
	{
		return CVector3(0.0f, 0.0f, 0.0f);
	}
	else
	{
		TFloat32 invLength = InvSqrt( lengthSq );
		return CVector3(v.x * invLength, v.y * invLength, v.z * invLength);
	}
}
// Normalise the quaternion - make it unit length as a 4-vector
void CQuaternion::Normalise()
{
	TFloat32 fNormSquared = w*w + x*x + y*y + z*z;

	if ( gen::IsZero( fNormSquared ) )
	{
		w = x = y = z = 0.0f;
	}
	else
	{
		TFloat32 fInvLength = InvSqrt( fNormSquared );
		w *= fInvLength;
		x *= fInvLength;
		y *= fInvLength;
		z *= fInvLength;
	}
}
Beispiel #11
0
// Reduce vector to unit length - member function
void CVector3::Normalise()
{
	TFloat32 lengthSq = x*x + y*y + z*z;

	// Ensure vector is not zero length (use BaseMath.h float approx. fn with default epsilon)
	if ( gen::IsZero( lengthSq ) )
	{
		x = y = z = 0.0f;
	}
	else
	{
		TFloat32 invLength = InvSqrt( lengthSq );
		x *= invLength;
		y *= invLength;
		z *= invLength;
	}
}
// Return a normalised version of a quaternion (unit length as a 4-vector) - non-member version
CQuaternion Normalise
(
	const CQuaternion& quat
)
{
	TFloat32 fNormSquared = quat.w*quat.w + quat.x*quat.x + quat.y*quat.y + quat.z*quat.z;

	if ( gen::IsZero( fNormSquared ) )
	{
		return CQuaternion( 0.0f, 0.0f, 0.0f, 0.0f );
	}
	else
	{
		TFloat32 fInvLength = InvSqrt( fNormSquared );
		return CQuaternion( quat.w*fInvLength, quat.x*fInvLength,
		                    quat.y*fInvLength, quat.z*fInvLength );
	}
}
Beispiel #13
0
Dvoid Vector4::Normalize()
{
    Dfloat lengthsq = x*x + y*y + z*z + w*w;

    if ( ::IsZero( lengthsq ) )
    {
        Zero();
    }
    else
    {
        Dfloat factor = InvSqrt( lengthsq );
        x *= factor;
        y *= factor;
        z *= factor;
        w *= factor;
    }

}  
Beispiel #14
0
void DMP_Covert_Data(void){
	float  qtemp[4],norm ; // 四元数
  
	// 注意,这里的计算原来是错误的,但因为 PID参数原因,暂时不改
	//DMP_DATA.GYROx 即为直接的角度deg; 而非AD。  
	DMP_DATA.dmp_gyrox = ((float)DMP_DATA.GYROx)/16.4f;	    //TOBE FIXED GYROx*M_PI_F/180.0f convert to rad/s
	DMP_DATA.dmp_gyroy = ((float)DMP_DATA.GYROy)/16.4f;
	DMP_DATA.dmp_gyroz = ((float)DMP_DATA.GYROz)/16.4f;
	//acc sensitivity to +/-    4 g
	DMP_DATA.dmp_accx = (((float)DMP_DATA.ACCx)/DMP_ACC_SCALE)*ONE_G;	//加速度 转成单位: m/S^2
	DMP_DATA.dmp_accy = (((float)DMP_DATA.ACCy)/DMP_ACC_SCALE)*ONE_G;
	DMP_DATA.dmp_accz = (((float)DMP_DATA.ACCz)/DMP_ACC_SCALE)*ONE_G;
  
	qtemp[0] = (float)DMP_DATA.qw; 	//提取DMP的四元数
	qtemp[1] = (float)DMP_DATA.qx;
	qtemp[2] = (float)DMP_DATA.qy;
	qtemp[3] = (float)DMP_DATA.qz;
	// 四元数归一化
	norm = InvSqrt(qtemp[0]*qtemp[0] + qtemp[1]*qtemp[1] + qtemp[2]*qtemp[2] + qtemp[3]*qtemp[3]);
	q[0] = qtemp[0] * norm;
	q[1] = qtemp[1] * norm;
	q[2] = qtemp[2] * norm;
	q[3] = qtemp[3] * norm;
	
	DMP_DATA.dmp_roll = (atan2(2.0*(q[0]*q[1] + q[2]*q[3]),
	                       1 - 2.0*(q[1]*q[1] + q[2]*q[2])))* 180/PI;
	 // we let safe_asin() handle the singularities near 90/-90 in pitch
	DMP_DATA.dmp_pitch = asin_s(2.0*(q[0]*q[2] - q[3]*q[1]))* 180/PI;
	//注意:此处计算反了,非右手系。
	DMP_DATA.dmp_yaw = -atan2(2.0*(q[0]*q[3] + q[1]*q[2]),
	                     1 - 2.0*(q[2]*q[2] + q[3]*q[3]))* 180/PI;
  #ifdef YAW_CORRECT
 //纠正
	DMP_DATA.dmp_yaw=-DMP_DATA.dmp_yaw;
	#endif
	
//  gyroxGloble=0.0f*gyrox_val+1.0f*(float)DMP_DATA.GYROx;
//  gyrox_val=gyroxGloble;
//  
//  gyroyGloble=0.0f*gyroy_val+1.0f*(float)DMP_DATA.GYROy;
//  gyroy_val=gyroyGloble;

}
   void Quaternion::ToAngleAxis(float &angle, Vector3 &axis) const
   {
      // The quaternion representing the rotation is
      //   q = cos(A / 2) + sin(A / 2) * (x * i + y * j + z * k)

      float norm = Norm();

      if (norm > EPSILON)
      {
         angle = 2.0f * ACos(w);
         float invMag = InvSqrt(norm);
         axis.x = x * invMag;
         axis.y = y * invMag;
         axis.z = z * invMag;
      }
      else
      {
         // angle is 0 (mod 2 * pi), so use the Z axis so 2D will work
         angle = 0.0;
         axis.x = 0.0;
         axis.y = 0.0;
         axis.z = 1.0;
      }
   }
Beispiel #16
0
int force_calc_bon(t_frame pframe, t_files fpkg)
{
  int     i,j,k,l,N,ci,cj,nqi,id1,id2,id3,id4;
  vector  *x,*v,dx,dy;
  t_vector distx,disty;
  double  dr,r,r2,r6,r12,ir,ir2,ir6,ir12,E=0.0,rc2;
  double  ar21,ar22,air21,air22,air11,air12,ang;
  double  C6ij,C12ij,FORCE,f,df,kc,ddr,fij;
  double  q2,dfq,fq,fe,phi,cosval,cosv2,dV;
  int     ist,isl,ds,m;

  distx=&dx; disty=&dy;
  for(i=0;i<pframe->nr_umols;i++){
    for(j=0;j<pframe->nr_mols[i];j++){
      // BONDED
      for(k=0;k<pframe->mol[pframe->mol_seq[i]]->nr_b;k++){
        id1  = j*pframe->mol[pframe->mol_seq[i]]->nr_t + pframe->mol[pframe->mol_seq[i]]->b_seq[2*k  ]+pframe->n_start[i];
        id2  = j*pframe->mol[pframe->mol_seq[i]]->nr_t + pframe->mol[pframe->mol_seq[i]]->b_seq[2*k+1]+pframe->n_start[i];
        r2   = pbc_dx(pframe,id1,id2,dx);
        dr   = r2*InvSqrt(r2);
        // BEGIN HARMONIC
        kc   = pframe->mol[pframe->mol_seq[i]]->k_bond[2*k];
        ddr  = dr-pframe->mol[pframe->mol_seq[i]]->k_bond[2*k+1];
        df   = kc*ddr;
        dV   = 0.5*df*ddr;
        // END HARMONIC
        E   += dV;
        df  *= InvSqrt(r2);
        for (m=XX; m<=ZZ; m++) {
          fij=-df*dx[m];
          pframe->f[id1][m]+=fij;
          pframe->f[id2][m]-=fij;
        }
      }

      // ANGLES
      for(k=0;k<pframe->mol[pframe->mol_seq[i]]->nr_a;k++){
        id1   = j*pframe->mol[pframe->mol_seq[i]]->nr_t + pframe->mol[pframe->mol_seq[i]]->a_seq[2*k  ]+pframe->n_start[i];
        id2   = j*pframe->mol[pframe->mol_seq[i]]->nr_t + pframe->mol[pframe->mol_seq[i]]->a_seq[2*k+1]+pframe->n_start[i];
        id3   = j*pframe->mol[pframe->mol_seq[i]]->nr_t + pframe->mol[pframe->mol_seq[i]]->a_seq[2*k+2]+pframe->n_start[i];
        ar21  = pbc_dx(pframe,id1,id2,dx);
        ar22  = pbc_dx(pframe,id3,id2,dy);
        phi   = calc_angle(dx,dy,&cosval);
        cosv2 = cosval*cosval;

        // BEGIN HARMONIC
        kc    = pframe->mol[pframe->mol_seq[i]]->k_angle[2*k];
        ddr   = phi-pframe->mol[pframe->mol_seq[i]]->k_angle[2*k+1]*DEG2RAD;
        df    = kc*ddr;
        dV    = 0.5*df*ddr;
        // END HARMONIC
        E    += dV;

        if(cosv2<1){
          double st,sth;
          double cik,cii,ckk;
          double nrkj2,nrij2;
          vector f_i,f_j,f_k;

          st    = -df*InvSqrt(1.0 - cosv2);
          sth   = st*cosval;
          nrkj2 = iprod(dy,dy);
          nrij2 = iprod(dx,dx);
          cik   = st*InvSqrt(nrkj2*nrij2);
          cii   = sth/nrij2;	
          ckk   = sth/nrkj2;	
      
          for (m=XX; (m<=ZZ); m++) {	
	    f_i[m]=-(cik*dy[m]-cii*dx[m]);
	    f_k[m]=-(cik*dx[m]-ckk*dy[m]);
	    f_j[m]=-f_i[m]-f_k[m];
	    pframe->f[id1][m]+=f_i[m];
	    pframe->f[id2][m]+=f_j[m];
	    pframe->f[id3][m]+=f_k[m];
          }
        }
      }
      // PROPER DIHEDRALS
      E += pdihs(pframe,i,j);

      // IMPROPER DIHEDRALS
      E += idihs(pframe,i,j);
    }
  }
  pframe->E[2]  = E;
  pframe->E[0] += E;

  return 0;
}
Beispiel #17
0
int force_calc_nb(t_frame pframe, t_files fpkg)
{
  int     i,j,k,N,ci,cj,nqi;
  vector  *x,*v,distx;
  double   dr,r,r2,r6,r12,ir,ir2,ir6,ir12,E=0.0,rc2;
  double   C6ij,C12ij,FORCE,f,df;
  double   q2,dfq,fq,fe;
  int      ui,uj,mi,mj,ip,jp;

  N   = pframe->nr_parts;
  pframe->virial = 0.0;
  rc2 = pframe->rc2;
  nqi = pframe->nr_unique;

  for(i=0;i<N;i++){
    for(j=i+1;j<N;j++){
      mi   = pframe->resnr [i];
      ui   = pframe->restyp[i];
      mj   = pframe->resnr [j];
      uj   = pframe->restyp[j];
      if( (mi==mj && ui==uj) )
        continue;
      r2   = pbc_dx(pframe,i,j,distx);
      if( r2>rc2  ) //if outside cutoff or same residue
        continue;
      ir2  = 1.0/r2;
      ci   = pframe->partyp_key[pframe->partyp[i]];
      cj   = pframe->partyp_key[pframe->partyp[j]];
      if(pframe->C6 [ci*nqi+cj] > 0 && pframe->C12[ci*nqi+cj]>0){
        ir6   = ir2*ir2*ir2;
        ir12  = ir6*ir6;
        C6ij = pframe->C6 [ci*nqi+cj]*ir6;
        C12ij= pframe->C12[ci*nqi+cj]*ir12;
        E   += C12ij-C6ij;
        df   = (12.0*C12ij - 6.0*C6ij);
        f    = df*ir2;
        for(k=XX;k<=ZZ;k++){
          FORCE             = f * distx[k] ;
          pframe->f[i][k]  += FORCE;
          pframe->f[j][k]  -= FORCE;
        }
      }
      if( pframe->Q [ci*nqi+cj] != 0.0 ){
        ir  = InvSqrt(r2);
        fe  = ELUNIT*pframe->Q[ci*nqi+cj]*ir; 
        E  +=  fe;
        f   = fe*ir2;
        for(k=XX;k<=ZZ;k++){
          FORCE             = f * distx[k] ;
          pframe->f[i][k]  += FORCE;
          pframe->f[j][k]  -= FORCE;
        }
      }
    }
  }

  if(!isfinite(E))
    fatal("NAN ENERGY");
  pframe->E[1]=E;

  return 0;
}
Beispiel #18
0
static boolean RB_IntersectDecalSegment(float x1, float y1, float x2, float y2, line_t *line,
                                        float *x, float *y)
{
    float ax, ay;
    float bx, by;
    float cx, cy;
    float dx, dy;
    float d, c, s, u;
    float newX;
    float ab;

    ax = x1;
    ay = y1;
    bx = x2;
    by = y2;
    cx = line->v1->fx;
    cy = line->v1->fy;
    dx = line->v2->fx;
    dy = line->v2->fy;
    
    if((ax == bx && ay == by) || (cx == dx && cy == dy))
    {
        // zero length
        return false;
    }
    
    if((ax == cx && ay == cy) ||
       (bx == cx && by == cy) ||
       (ax == dx && ay == dy) ||
       (bx == dx && by == dy))
    {
        // shares end point
        return false;
    }
    
    // translate to origin
    bx -= ax; by -= ay;
    cx -= ax; cy -= ay;
    dx -= ax; dy -= ay;

    // normalize
    u = bx * bx + by * by;
    d = InvSqrt(u);
    c = bx * d;
    s = by * d;

    // rotate points c and d so they're on the positive x axis
    newX = cx * c + cy * s;
    cy = cy * c - cx * s;
    cx = newX;
    
    newX = dx * c + dy * s;
    dy = dy * c - dx * s;
    dx = newX;
    
    if((cy < 0 && dy < 0) || (cy >= 0 && dy >= 0))
    {
        // c and d didn't cross
        return false;
    }
    
    ab = dx + (cx - dx) * dy / (dy - cy);
    
    if(ab < 0 || ab > (u * d))
    {
        // c and d crosses but outside of points a and b
        return false;
    }

    // lerp
    *x = ax + ab * c;
    *y = ay + ab * s;

    return true;
}
Beispiel #19
0
void RB_SpawnWallDecal(mobj_t *mobj)
{
    int i;
    line_t *line;
    rbDecal_t *decal;
    rbDecalDef_t *decalDef;
    float dx, dy;
    float cx, cy;
    float fx, fy, fz;
    float nx, ny;
    float s, c;
    float lx1, lx2;
    float ly1, ly2;
    float d;
    float an;
    float offs;
    float cHeight = 0;
    float fHeight = 0;
    float size;

    if(!rbDecals)
    {
        return;
    }

    decalwall = NULL;
    decal_x = mobj->x;
    decal_y = mobj->y;
    decal_z = mobj->z;

    if(P_PathTraverse(decal_x, decal_y,
                      mobj->x + FixedMul(mobj->momx, 10*FRACUNIT),
                      mobj->y + FixedMul(mobj->momy, 10*FRACUNIT),
                      PT_ADDLINES, PIT_DecalCheckLine))
    {
        return;
    }

    line = decalwall;

    if(!line || !(decalDef = RB_GetDecalDef(mobj->type)))
    {
        return;
    }
    
    decal = RB_CreateDecal(decalDef);
    
    decal->x = mobj->x;
    decal->y = mobj->y;
    decal->z = mobj->z;
    decal->type = DCT_WALL;

    // look for a sector to stick to
    if(line->backsector)
    {
        decal->stickSector = line->backsector;
        if(decal->z > line->backsector->ceilingheight)
        {
            decal->type = DCT_UPPERWALL;
            decal->initialStickZ = line->backsector->ceilingheight;
        }
        else if(decal->z < line->backsector->floorheight)
        {
            decal->type = DCT_LOWERWALL;
            decal->initialStickZ = line->backsector->floorheight;
        }
    }

    RB_LinkDecal(decal);
    
    dx = line->fdx;
    dy = line->fdy;
    
    lx1 = line->v1->fx;
    ly1 = line->v1->fy;
    lx2 = line->v2->fx;
    ly2 = line->v2->fy;
    
    // get line angle (direction)
    an = atan2f(dx, dy);
    c = cosf(an);
    s = sinf(an);
    
    // get line distance
    cx = lx1 - FIXED2FLOAT(decal->x);
    cy = ly1 - FIXED2FLOAT(decal->y);
    
    d = (dx * cy - dy * cx) * InvSqrt(dx * dx + dy * dy);
    
    // get nudge direction
    an -= DEG2RAD(90.0f);
    offs = (float)decal->offset / 256.0f;

    nx = (d - 0.8f) * sinf(an);
    ny = (d - 0.8f) * cosf(an);

    /*
  2 ----------- 3
    |         |
    |         |
    |         |
    |         |
    |         |
  1 ----------- 0
    */

    decal->numpoints = 4;
    size = 16 * decal->scale;

    decal->points[0].x = decal->points[3].x =  size * s;
    decal->points[0].y = decal->points[3].y =  size * c;
    decal->points[1].x = decal->points[2].x = -size * s;
    decal->points[1].y = decal->points[2].y = -size * c;
    decal->points[2].z = decal->points[3].z =  size;
    decal->points[0].z = decal->points[1].z = -size;

    fx = FIXED2FLOAT(decal->x);
    fy = FIXED2FLOAT(decal->y);
    fz = FIXED2FLOAT(decal->z);

    decal->points[0].tu = decal->points[3].tu = 0;
    decal->points[0].tv = decal->points[1].tv = 0;
    decal->points[1].tu = decal->points[2].tu = 1;
    decal->points[3].tv = decal->points[2].tv = 1;
    
    if(line->backsector)
    {
        cHeight = FIXED2FLOAT(line->backsector->ceilingheight);
        fHeight = FIXED2FLOAT(line->backsector->floorheight);
    }
    
    for(i = 0; i < decal->numpoints; ++i)
    {
        decal->points[i].x += fx;
        decal->points[i].y += fy;
        decal->points[i].z += fz;
        
        // nudge decal to be closer to the wall
        decal->points[i].x += nx;
        decal->points[i].y += ny;
        
        RB_ClampWallDecalToLine(&decal->points[i], line->backsector != NULL,
                                cHeight, fHeight, fz,
                                lx1, ly1, lx2, ly2);

        // jitter offset a bit
        decal->points[i].x -= (nx * offs);
        decal->points[i].y -= (ny * offs);
    }

    RB_RotateDecalTextureCoords(decal);
    activedecals++;
}
Beispiel #20
0
void Quaternion::Normalize( void )
{
    *this *= InvSqrt(NormSqure());
}
Beispiel #21
0
void MTX_ToQuaternion(matrix m, float *out)
{
    float t, d;
    float mx, my, mz;
    float m21, m20, m10;
    
    mx = m[ 0];
    my = m[ 5];
    mz = m[10];
    
    m21 = (m[ 9] - m[ 6]);
    m20 = (m[ 8] - m[ 2]);
    m10 = (m[ 4] - m[ 1]);
    
    t = 1.0f + mx + my + mz;
    
    if(t > 0)
    {
        d = 0.5f / (t * InvSqrt(t));
        out[0] = m21 * d;
        out[1] = m20 * d;
        out[2] = m10 * d;
        out[3] = 0.25f / d;
    }
    else if(mx > my && mx > mz)
    {
        t = 1.0f + mx - my - mz;
        d = (t * InvSqrt(t)) * 2;
        out[0] = 0.5f / d;
        out[1] = m10 / d;
        out[2] = m20 / d;
        out[3] = m21 / d;
    }
    else if(my > mz)
    {
        t = 1.0f + my - mx - mz;
        d = (t * InvSqrt(t)) * 2;
        out[0] = m10 / d;
        out[1] = 0.5f / d;
        out[2] = m21 / d;
        out[3] = m20 / d;
    }
    else
    {
        t = 1.0f + mz - mx - my;
        d = (t * InvSqrt(t)) * 2;
        out[0] = m20 / d;
        out[1] = m21 / d;
        out[2] = 0.5f / d;
        out[3] = m10 / d;
    }
    
    //
    // normalize quaternion
    // TODO: figure out why InvSqrt produces inaccurate results
    // use sqrtf for now
    //
    d = sqrtf(out[0] * out[0] +
              out[1] * out[1] +
              out[2] * out[2] +
              out[3] * out[3]);
    
    if(d != 0.0f)
    {
        d = 1.0f / d;
        out[0] *= d;
        out[1] *= d;
        out[2] *= d;
        out[3] *= d;
    }
}
// player controller ontrol
void PlayerController::Control(float aStep)
{
	// get parent entity
	Entity *entity = Database::entity.Get(mId);

	// get transform
	const Transform2 &transform = entity->GetTransform();

	// get player controller template
	const PlayerControllerTemplate &controllertemplate = Database::playercontrollertemplate.Get(mId);


	// TO DO: support multiple players
	// TO DO: replace switch statements with behaviors

	// set move input
	switch (controllertemplate.mMove)
	{
	case PlayerControllerTemplate::NONE:
		mMove.x = mMove.y = 0;
		break;

	case PlayerControllerTemplate::MOVELOCAL:
		mMove.x = input[Input::MOVE_HORIZONTAL];
		mMove.y = input[Input::MOVE_VERTICAL];
		break;

	case PlayerControllerTemplate::MOVEWORLD:
		mMove.x = input[Input::MOVE_HORIZONTAL];
		mMove.y = input[Input::MOVE_VERTICAL];
		mMove = transform.Unrotate(mMove);
		break;

	case PlayerControllerTemplate::AIMLOCAL:
		mMove.x = input[Input::AIM_HORIZONTAL];
		mMove.y = input[Input::AIM_VERTICAL];
		break;

	case PlayerControllerTemplate::AIMWORLD:
		mMove.x = input[Input::AIM_HORIZONTAL];
		mMove.y = input[Input::AIM_VERTICAL];
		mMove = transform.Unrotate(mMove);
		break;

	case PlayerControllerTemplate::LEFT:
		mMove = transform.Unrotate(Vector2(1, 0));
		break;

	case PlayerControllerTemplate::RIGHT:
		mMove = transform.Unrotate(Vector2(-1, 0));
		break;

	case PlayerControllerTemplate::UP:
		mMove = transform.Unrotate(Vector2(0, 1));
		break;

	case PlayerControllerTemplate::DOWN:
		mMove = transform.Unrotate(Vector2(0, -1));
		break;
	};

	// set turn input
	switch(controllertemplate.mAim)
	{
	case PlayerControllerTemplate::NONE:
		mAim.x = mAim.y = 0;
		mTurn = 0;
		break;

	case PlayerControllerTemplate::MOVESTEER:
		mAim.x = mAim.y = 0;
		mTurn = -input[Input::MOVE_HORIZONTAL];
		break;

	case PlayerControllerTemplate::MOVELOCAL:
		mAim.x = input[Input::MOVE_HORIZONTAL];
		mAim.y = input[Input::MOVE_VERTICAL];
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::MOVEWORLD:
		mAim.x = input[Input::MOVE_HORIZONTAL];
		mAim.y = input[Input::MOVE_VERTICAL];
		mAim = transform.Unrotate(mAim);
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::MOVECURSOR:
		mAim = transform.Untransform(camerapos[1] + Vector2(input[Input::MOVE_HORIZONTAL], input[Input::MOVE_VERTICAL]) * 120 * VIEW_SIZE / 240);
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::AIMSTEER:
		mAim.x = mAim.y = 0;
		mTurn = -input[Input::AIM_HORIZONTAL];
		break;

	case PlayerControllerTemplate::AIMLOCAL:
		mAim.x = input[Input::AIM_HORIZONTAL];
		mAim.y = input[Input::AIM_VERTICAL];
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::AIMWORLD:
		mAim.x = input[Input::AIM_HORIZONTAL];
		mAim.y = input[Input::AIM_VERTICAL];
		mAim = transform.Unrotate(mAim);
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::AIMCURSOR:
		mAim = transform.Untransform(camerapos[1] + Vector2(input[Input::AIM_HORIZONTAL], input[Input::AIM_VERTICAL]) * 120 * VIEW_SIZE / 240);
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::LEFT:
		mAim = transform.Unrotate(Vector2(1, 0));
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::RIGHT:
		mAim = transform.Unrotate(Vector2(-1, 0));
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::UP:
		mAim = transform.Unrotate(Vector2(0, 1));
		mTurn = TurnLocal(mAim) / aStep;
		break;

	case PlayerControllerTemplate::DOWN:
		mAim = transform.Unrotate(Vector2(0, -1));
		mTurn = TurnLocal(mAim) / aStep;
		break;
	}

	// apply scale and add
	mMove = mMove * controllertemplate.mScale.p + controllertemplate.mAdd.p;
	mTurn = mTurn * controllertemplate.mScale.a + controllertemplate.mAdd.a;

	// clamp to limits
	float moveSq = mMove.LengthSq();
	if (moveSq > 1.0f)
		mMove *= InvSqrt(moveSq);
	mTurn = Clamp(mTurn, -1.0f, 1.0f);

	// set fire input
	mFire[0] = input[Input::FIRE_PRIMARY];
	mFire[1] = input[Input::FIRE_SECONDARY];
	mFire[2] = input[Input::FIRE_CHANNEL3];
	mFire[3] = input[Input::FIRE_CHANNEL4];
}
Beispiel #23
0
float HGE_InvSqrt(float x) {
	return InvSqrt(x);
}
Beispiel #24
0
   Matrix4 &Matrix4::Orthonormalize()
   {
      // Algorithm uses Gram-Schmidt orthogonalization.  If 'this' matrix is
      // M = [m0|m1|m2], then orthonormal output matrix is Q = [q0|q1|q2],
      //
      //   q0 = m0/|m0|
      //   q1 = (m1-(q0*m1)q0)/|m1-(q0*m1)q0|
      //   q2 = (m2-(q0*m2)q0-(q1*m2)q1)/|m2-(q0*m2)q0-(q1*m2)q1|
      //
      // where |V| indicates length of vector V and A*B indicates dot
      // product of vectors A and B.

      // compute q0
      float fInvLength = InvSqrt(
         m[0][0] * m[0][0] + 
         m[1][0] * m[1][0] +
         m[2][0] * m[2][0]);

      m[0][0] *= fInvLength;
      m[1][0] *= fInvLength;
      m[2][0] *= fInvLength;

      // compute q1
      float fDot0 =
         m[0][0] * m[0][1] +
         m[1][0] * m[1][1] +
         m[2][0] * m[2][1];

      m[0][1] -= fDot0 * m[0][0];
      m[1][1] -= fDot0 * m[1][0];
      m[2][1] -= fDot0 * m[2][0];

      fInvLength = InvSqrt(
         m[0][1] * m[0][1] +
         m[1][1] * m[1][1] +
         m[2][1] * m[2][1]);

      m[0][1] *= fInvLength;
      m[1][1] *= fInvLength;
      m[2][1] *= fInvLength;

      // compute q2
      float fDot1 =
         m[0][1] * m[0][2] +
         m[1][1] * m[1][2] +
         m[2][1] * m[2][2];

      fDot0 =
         m[0][0] * m[0][2] +
         m[1][0] * m[1][2] +
         m[2][0] * m[2][2];

      m[0][2] -= fDot0 * m[0][0] + fDot1 * m[0][1];
      m[1][2] -= fDot0 * m[1][0] + fDot1 * m[1][1];
      m[2][2] -= fDot0 * m[2][0] + fDot1 * m[2][1];

      fInvLength = InvSqrt(
         m[0][2] * m[0][2] +
         m[1][2] * m[1][2] +
         m[2][2] * m[2][2]);

      m[0][2] *= fInvLength;
      m[1][2] *= fInvLength;
      m[2][2] *= fInvLength;

      return *this;
   }