Esempio n. 1
0
	double CalculateWeightsMask(QPointF p, QVector<QPoint> *boundary, double *weights, QImage& mask)
	{
		double sum = 0.;
		int size = boundary->size() - 1;
		CVector3f pointX;
		CVector3f p0, p1, p2;
		CVector3f v1, v2;

		pointX.x = p.x() + EPSILON;
		pointX.y = p.y() + EPSILON;
		pointX.z = .0;

		memset(weights, 0, sizeof(double) * size);

		for (int i = 0; i < size; i++)
		{
			QPoint pt = boundary->at(i);

			if (qGray(mask.pixel(pt)) < 200) // if the boundary point is not marked
			{
				weights[i] = 0;
				continue;
			}			

			p0.x = boundary->at((i - 1 + size) % size).x();
			p0.y = boundary->at((i - 1 + size) % size).y();
			p0.z = .0;

			p1.x = boundary->at(i).x();
			p1.y = boundary->at(i).y();
			p1.z = 0.00001;

			p2.x = boundary->at((i + 1 + size) % size).x();
			p2.y = boundary->at((i + 1 + size) % size).y();
			p2.z = .0;

			v1 = p0 - pointX;
			v2 = p1 - pointX;

			double angle1 = AngleBetweenVectors(v1, v2);
			if (v1.x * v2.y - v1.y * v2.x > 0)
				angle1 = -angle1;

			v1 = v2;
			v2 = p2 - pointX;

			double angle2 = AngleBetweenVectors(v1, v2);
			if (v1.x * v2.y - v1.y * v2.x > 0)
				angle2 = -angle2;

			weights[i] = (tan(angle1 / 2.) + tan(angle2 / 2.)) / (Distance(p1, pointX) + 0.001);
			sum += weights[i];
		}

		return sum;
	}
Esempio n. 2
0
XnBool XnVPushDetector::IsPushDetected(const XnV3DVector& vImmediateVelocity, const XnV3DVector& vPreviousVelocity, XnFloat& fZAngle)
{
	// Check if current motion is too slow
	if (vImmediateVelocity.Magnitude() < m_fPushImmediateMinVelocity)
	{
		return false;
	}

	if (vPreviousVelocity.Magnitude() < m_fPushPreviousMinVelocity)
	{
		fZAngle = AngleBetweenVectors(vImmediateVelocity, XnV3DVector(0,0,-1));

		if (fZAngle < m_fPushMaxAngleFromZ)
		{
			xnLogVerbose(XNV_NITE_MASK_EVENTS,	"Push Detector %s [0x%08x]: "
												"Immediate Velocity %5.3f over threshold %5.3f in the last %d ms (%d ms offset), "
												"Previous  Velocity %5.3f under threshold %5.3f in the last %d ms (%d ms offset), "
												"Angle between Immediate and the Z Axis is %5.3f, under the threshold of %5.3f",
												GetListenerName(), this,
												vImmediateVelocity.Magnitude(), m_fPushImmediateMinVelocity, m_nPushImmediateDuration, m_nPushImmediateOffset,
												vPreviousVelocity.Magnitude(), m_fPushPreviousMinVelocity, m_nPushPreviousDuration, m_nPushPreviousOffset,
												fZAngle, m_fPushMaxAngleFromZ);
			return true;
		}
		return false;
	}

	XnFloat fAngle = AngleBetweenVectors(vPreviousVelocity, vImmediateVelocity);
	if (fAngle > m_fPushMinAngleImmediateAndPrevious)
	{
		fZAngle = AngleBetweenVectors(vImmediateVelocity, XnV3DVector(0,0,-1));
		if (fZAngle < m_fPushMaxAngleFromZ)
		{
			xnLogVerbose(XNV_NITE_MASK_EVENTS,	"Push Detector %s [0x%08x]: "
				"Immediate Velocity %5.3f over threshold %5.3f in the last %d ms (%d ms offset), "
				"Previous  Velocity %5.3f over threshold %5.3f in the last %d ms (%d ms offset), "
				"Angle between Immediate and the Z Axis is %5.3f, under the threshold of %5.3f, "
				"Angle between Immediate and Previous direction is %5.3f, over the threshold of %5.3f",
				GetListenerName(), this,
				vImmediateVelocity.Magnitude(), m_fPushImmediateMinVelocity, m_nPushImmediateDuration, m_nPushImmediateOffset,
				vPreviousVelocity.Magnitude(), m_fPushPreviousMinVelocity, m_nPushPreviousDuration, m_nPushPreviousOffset,
				fZAngle, m_fPushMaxAngleFromZ,
				fAngle, m_fPushMinAngleImmediateAndPrevious);
			return true;
		}
	}

	return false;
} // XnVPushDetector::IsPushDetected
int RenderScene(GameState *State, SDL_Renderer *Renderer)
{
    SDL_RenderClear(Renderer);

    SDL_RenderCopy(Renderer, State->Background, NULL, NULL);

    Entity Player = State->Entities[State->PlayerEntity];
                                    
    SDL_Rect DescRect;
    float Width = Player.Width * State->MeterToPixels;
    float Height = Player.Height * State->MeterToPixels;
    float CenterX = Player.Pos.x - 0.5f * Width;
    float CenterY = Player.Pos.y - 0.5f * Height;
    DescRect.x = CenterX;
    DescRect.y = CenterY;
    DescRect.w = Width;
    DescRect.h = Height;
    SDL_Point Center;
    Center.x = CenterX;
    Center.y = CenterY;


    vec2 NaturalDirection = {0, -1};
    float Angle = AngleBetweenVectors(Player.Direction, NaturalDirection);

    char buffer[128];
    sprintf(buffer, "Angle: %f\n", Angle);
    OutputDebugString(buffer);

    SDL_RenderCopyEx(Renderer, State->Pointer, NULL, &DescRect, Angle, NULL, SDL_FLIP_NONE);

    Angle = AngleBetweenVectors(Player.Vel, NaturalDirection);
    SDL_RenderCopyEx(Renderer, State->Player, NULL, &DescRect, Angle, NULL, SDL_FLIP_NONE);
    SDL_RenderCopyEx(Renderer, State->Circle, NULL, &DescRect, Angle, NULL, SDL_FLIP_NONE);
                    
    SDL_RenderPresent(Renderer);

    return 0;
}
Esempio n. 4
0
float WeightedAngle(vec_t *vec1, vec_t *vec2)
{
	float a = AngleBetweenVectors(vec1, vec2);
	if (a < 11.25f) {
		return 1;
	}
	else if (a < 22.5f) {
		return 0.5f;
	}
	else if (a < 45.0f) {
		return 0.25f;
	}
	else if (a < 90.0f) {
		return 0.125f;
	}

	return 0.05f;
}
Esempio n. 5
0
bool InsidePolygon(Vector3 vIntersection, Vector3 Poly[], long verticeCount)//判断交点是否在多边形内
{
	const double MATCH_FACTOR = 0.99;		// 覆盖不需要的小数位
	double Angle = 0.0;				
	Vector3 vA, vB;					
	for (int i = 0; i < verticeCount; i++)		
	{	
		vA = Poly[i] - vIntersection;		
											
		vB = Poly[(i + 1) % verticeCount] - vIntersection;
												
		Angle += AngleBetweenVectors(vA, vB);	
	}
											
	if(Angle >= (MATCH_FACTOR * (2.0 * PI)) )	// 弧度大于或等于2PI,在多边形内
		return true;							
		
	return false;								
}
bool InsidePolygon(CVector3 vIntersection, CVector3 Poly[], long verticeCount)
{
	const double MATCH_FACTOR = 0.99;		// Used to cover up the error in floating point
	double Angle = 0.0;						// Initialize the angle
	CVector3 vA, vB;						// Create temp vectors
	
	for (int i = 0; i < verticeCount; i++)		// Go in a circle to each vertex and get the angle between
	{	
		vA = Poly[i] - vIntersection;			// Subtract the intersection point from the current vertex
												// Subtract the point from the next vertex
		vB = Poly[(i + 1) % verticeCount] - vIntersection;
												
		Angle += AngleBetweenVectors(vA, vB);	// Find the angle between the 2 vectors and add them all up as we go along
	}
											
	if(Angle >= (MATCH_FACTOR * (2.0 * PI)) )	// If the angle is greater than 2 PI, (360 degrees)
		return true;							// The point is inside of the polygon
		
	return false;								// If you get here, it obviously wasn't inside the polygon, so Return FALSE
}
Esempio n. 7
0
void Projectile::TurnToTarget( float _dt )
{
	// Calculate the vector from this token to the Target's position
	D3DXVECTOR2 vToTarget(0,0);
	D3DXVECTOR2 tDefault(0,-1);

	D3DXVECTOR2 pos = ((BaseEntity*)m_Target)->GetPos() + ((BaseEntity*)m_Target)->GetImgCenter();
	vToTarget.x = pos.x - (this->GetPos().x + this->GetImgCenter().x);
	vToTarget.y = pos.y - (this->GetPos().y + this->GetImgCenter().y);

	// Calculate forward vector
	D3DXVECTOR2 forward = Rotate2D( tDefault, this->GetRot() );
	// calculate the angle between the vectors
	float angle = AngleBetweenVectors( vToTarget, forward );

	if(Steering(forward, vToTarget) < 0.0f)
		this->SetRot(this->GetRot() - 3.0f*_dt);
	else
		this->SetRot(this->GetRot() + 3.0f*_dt);

	forward = Rotate2D( tDefault, this->GetRot() );
	D3DXVec2Normalize(&forward,&forward);
	this->SetDir(forward);
}
Esempio n. 8
0
// Wandering code (based on old ACE movement code)
void ACEMV_Wander(gentity_t * self)
{
	vec3_t          tmp;

	// do not move
	if(self->bs.next_move_time > level.time)
		return;

	// Special check for elevators, stand still until the ride comes to a complete stop.
	/*
	 * FIXME
	 if(self->groundentity != NULL && self->groundentity->use == Use_Plat)
	 if(self->groundentity->moveinfo.state == STATE_UP || self->groundentity->moveinfo.state == STATE_DOWN) // only move when platform not
	 {
	 self->velocity[0] = 0;
	 self->velocity[1] = 0;
	 self->velocity[2] = 0;
	 self->next_move_time = level.time + 500;
	 return;
	 }

	 */

	// touched jumppad last Frame?
	if(self->s.groundEntityNum == ENTITYNUM_NONE)
	{
		if(VectorLength(self->client->ps.velocity) > 120)
		{
			VectorNormalize2(self->client->ps.velocity, tmp);

			if(AngleBetweenVectors(self->bs.moveVector, tmp) >= 120)
			{
				// we might have been knocked back by someone or something ..
				if(!self->bs.moveTarget)
				{
					VectorCopy(tmp, self->bs.moveVector);
					ACEMV_ChangeBotAngle(self);
				}
			}
		}

		//ACEMV_ChangeBotAngle(self);
		//self->client->ps.velocity[0] = self->bs.moveVector[0] * 360;
		//self->client->ps.velocity[1] = self->bs.moveVector[1] * 360;
		//return;
	}

	// is there a target to move to
	if(self->bs.moveTarget)
	{
		ACEMV_MoveToGoal(self);
	}

	// swimming?
	VectorCopy(self->client->ps.origin, tmp);
	tmp[2] += 24;

	if(trap_PointContents(tmp, self->s.number) & MASK_WATER)
	{
		// if drowning and no node, move up
		if(self->client->airOutTime > 0)
		{
			self->client->pers.cmd.upmove = 1;
			self->bs.viewAngles[PITCH] = -45;
		}
		else
			self->client->pers.cmd.upmove = 15;

		self->client->pers.cmd.forwardmove = 100;
	}
	else
	{
		//self->client->airOutTime = 0;    // probably shound not be messing with this, but
	}

	// lava?
	tmp[2] -= 48;
	if(trap_PointContents(tmp, self->s.number) & (CONTENTS_LAVA | CONTENTS_SLIME))
	{
		//  safe_bprintf(PRINT_MEDIUM,"lava jump\n");
		self->bs.viewAngles[YAW] += random() * 360 - 180;
		self->client->pers.cmd.forwardmove = 127;
		self->client->pers.cmd.upmove = 127;
		return;
	}

	// check for special movement if we have a normal move (have to test)
	if(VectorLength(self->client->ps.velocity) < 37)
	{
		//if(random() > 0.1 && ACEMV_SpecialMove(self))
		//  return; //removed this because when wandering, the last thing you want is bots jumping
		//over things and going off ledges.  It's better for them to just bounce around the map.

		self->bs.viewAngles[YAW] += random() * 180 - 90;

		if(ACEMV_CanMove(self, MOVE_FORWARD))
			self->client->pers.cmd.forwardmove = 127;
		else if(ACEMV_CanMove(self, MOVE_BACK))
			self->client->pers.cmd.forwardmove = -127;

		// if there is ground continue otherwise wait for next move
		if( /*!M_CheckBottom || */ self->s.groundEntityNum != ENTITYNUM_NONE)
		{
			if(ACEMV_CanMove(self, MOVE_FORWARD))
				self->client->pers.cmd.forwardmove = 127;
		}

		return;
	}

	if(ACEMV_CheckEyes(self))
		return;

	if(ACEMV_CanMove(self, MOVE_FORWARD))
		self->client->pers.cmd.forwardmove = 127;
}
Esempio n. 9
0
void G_HomingMissile(gentity_t * ent)
{
	gentity_t      *target = NULL;
	gentity_t      *blip = NULL;
	vec3_t          dir, blipdir;
	vec_t           angle;
	qboolean        chaff;

	//qboolean        ignorechaff = qfalse;
	const int       HOMING_THINK_TIME = 60;

	// explode after 15 seconds without a hit
	if(ent->spawnTime + 15000 <= level.time)
	{
		G_ExplodeMissile(ent);
		return;
	}

	/*
	if(ent->parent->health <= 0)
	{
		ent->nextthink = level.time + 15000;
		ent->think = G_ExplodeMissile;
		return;
	}
	*/

	/*
	if(ent->parent && ent->parent->client)
	{
		ignorechaff = (ent->parent->client->ps.powerups[PW_ACCURACY] > 0);
	}
	*/

	while((blip = G_FindRadius(blip, ent->r.currentOrigin, 2000)) != NULL)
	{
#if 0
		if(blip->s.weapon == WP_CHAFF)
		{
			if(ignorechaff)
			{
				continue;
			}

			chaff = qtrue;
		}
		else
#endif
		{
			chaff = qfalse;

			if(blip->client == NULL)
				continue;

			if(blip == ent->parent)
				continue;

			if(blip->health <= 0)
				continue;

			if(blip->client->sess.sessionTeam >= TEAM_SPECTATOR)
				continue;

			if((g_gametype.integer == GT_TEAM || g_gametype.integer == GT_CTF) && OnSameTeam(blip, ent->parent))
				continue;
		}

		if(!G_IsVisible(ent, blip->r.currentOrigin))
			continue;

		VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);

		if(chaff)
		{
			VectorScale(blipdir, 0.5, blipdir);
		}

		if((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
		{
			if(chaff)
			{
				VectorScale(blipdir, 2, blipdir);
			}

			angle = AngleBetweenVectors(ent->r.currentAngles, blipdir);

			if(angle < 120.0f)
			{
				// We add it as our target
				target = blip;
				VectorCopy(blipdir, dir);
			}
		}
	}

	if(target == NULL)
	{
		ent->nextthink = level.time + HOMING_THINK_TIME;	// + 10000;
		ent->think = G_HomingMissile;
	}
	else
	{
		// for exact trajectory calculation, set current point to base.
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);

		VectorNormalize(dir);
		// 0.5 is swing rate.
		VectorScale(dir, 0.5, dir);
		VectorAdd(dir, ent->r.currentAngles, dir);

		// turn nozzle to target angle
		VectorNormalize(dir);
		VectorCopy(dir, ent->r.currentAngles);

		// scale direction, put into trDelta
		if(g_rocketAcceleration.integer)
		{
			// use acceleration instead of linear velocity
			ent->s.pos.trType = TR_ACCELERATION;
			ent->s.pos.trAcceleration = g_rocketAcceleration.value;
			VectorScale(dir, g_rocketVelocity.value, ent->s.pos.trDelta);
		}
		else
		{
			ent->s.pos.trType = TR_LINEAR;
			VectorScale(dir, g_rocketVelocity.value * 0.25, ent->s.pos.trDelta);
		}

		ent->s.pos.trTime = level.time;

		SnapVector(ent->s.pos.trDelta);	// save net bandwidth
		ent->nextthink = level.time + HOMING_THINK_TIME;	// decrease this value also makes fast swing
		ent->think = G_HomingMissile;

		//G_Printf("targeting %s\n", target->classname);
	}
}
Esempio n. 10
0
/*
================
G_HomingMissile

From XREAL r3036
================
*/
void G_HomingMissile(gentity_t * ent)
{
	gentity_t      *target = NULL;
	gentity_t      *blip = NULL;
	vec3_t          dir, blipdir;
	vec_t           angle;
	const int		HOMING_THINK_TIME = 60;

#ifdef TA_WEAPSYS // XREAL: spawnTime
	// explode after 15 seconds without a hit
	if (bg_projectileinfo[ent->s.weapon].timetolive != -1
		&& ent->spawnTime + bg_projectileinfo[ent->s.weapon].timetolive <= level.time)
	{
		G_ExplodeMissile(ent);
		return;
	}
#endif

	/*
	if(ent->parent->health <= 0)
	{
		ent->nextthink = level.time + 15000;
		ent->think = G_ExplodeMissile;
		return;
	}
	*/

	while((blip = G_FindRadius(blip, ent->r.currentOrigin, 2000)) != NULL)
	{
		if(blip->player == NULL)
			continue;

		if(blip == ent->parent)
			continue;

		if(blip->health <= 0)
			continue;

		if(blip->flags & FL_NOTARGET)
			continue;

		if(blip->player->sess.sessionTeam >= TEAM_SPECTATOR)
			continue;

		if(OnSameTeam(blip, ent->parent))
			continue;

		if(!G_IsVisible(ent->s.number, ent->r.currentOrigin, blip->r.currentOrigin))
			continue;

		VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);

		if((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
		{
			angle = AngleBetweenVectors(ent->r.currentAngles, blipdir);

			if(angle < 120.0f)
			{
				// We add it as our target
				target = blip;
				VectorCopy(blipdir, dir);
			}
		}
	}

	if (target == NULL)
	{
		ent->nextthink = level.time + HOMING_THINK_TIME;	// + 10000;
		ent->think = G_HomingMissile;
	}
	else
	{
		// for exact trajectory calculation, set current point to base.
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);

		VectorNormalize(dir);
		// 0.5 is swing rate.
		VectorScale(dir, 0.5, dir);
		VectorAdd(dir, ent->r.currentAngles, dir);

		// turn nozzle to target angle
		VectorNormalize(dir);
		VectorCopy(dir, ent->r.currentAngles);

		ent->s.pos.trTime = level.time;
		G_SetMissileVelocity(ent, dir, ent->s.weapon);

		ent->nextthink = level.time + HOMING_THINK_TIME;	// decrease this value also makes fast swing
		ent->think = G_HomingMissile;

		//G_Printf("targeting %s\n", target->classname);
	}
}
Esempio n. 11
0
	double CalculateWeightsVec(QPointF p, QVector<QPoint> *boundary, double *weights, QVector<int>& mask)
	{
		double sum = 0.;
		int size = boundary->size() - 1;
		CVector3f pointX;
		CVector3f p0, p1, p2;
		CVector3f v1, v2;

		pointX.x = p.x() + EPSILON;
		pointX.y = p.y() + EPSILON;
		pointX.z = .0;

		memset(weights, 0, sizeof(double) * size);

		for (int n = 0; n < mask.size(); ++n)
		{
			int i = mask[n];

			QPoint pt = boundary->at(i);				

			p0.x = boundary->at((i - 1 + size) % size).x();
			p0.y = boundary->at((i - 1 + size) % size).y();
			p0.z = .0;

			p1.x = boundary->at(i).x();
			p1.y = boundary->at(i).y();
			p1.z = 0.00001;

			p2.x = boundary->at((i + 1 + size) % size).x();
			p2.y = boundary->at((i + 1 + size) % size).y();
			p2.z = .0;

			v1 = p0 - pointX;
			v2 = p1 - pointX;

			double angle1 = AngleBetweenVectors(v1, v2);
			if (v1.x * v2.y - v1.y * v2.x > 0)
				angle1 = -angle1;

			v1 = v2;
			v2 = p2 - pointX;

			double angle2 = AngleBetweenVectors(v1, v2);
			if (v1.x * v2.y - v1.y * v2.x > 0)
				angle2 = -angle2;

			weights[i] = (tan(angle1 / 2.) + tan(angle2 / 2.)) / (Distance(p1, pointX) + 0.001);
			sum += weights[i];

		}

// 		for (int i = 0; i < size; i++)
// 		{
// 			QPoint pt = boundary->at(i);
// 
// 			if (!mask.contains(i)) // if the boundary point is not marked
// 			{
// 				weights[i] = 0;
// 				continue;
// 			}			
// 
// 			p0.x = boundary->at((i - 1 + size) % size).x();
// 			p0.y = boundary->at((i - 1 + size) % size).y();
// 			p0.z = .0;
// 
// 			p1.x = boundary->at(i).x();
// 			p1.y = boundary->at(i).y();
// 			p1.z = 0.00001;
// 
// 			p2.x = boundary->at((i + 1 + size) % size).x();
// 			p2.y = boundary->at((i + 1 + size) % size).y();
// 			p2.z = .0;
// 
// 			v1 = p0 - pointX;
// 			v2 = p1 - pointX;
// 
// 			double angle1 = AngleBetweenVectors(v1, v2);
// 			if (v1.x * v2.y - v1.y * v2.x > 0)
// 				angle1 = -angle1;
// 
// 			v1 = v2;
// 			v2 = p2 - pointX;
// 
// 			double angle2 = AngleBetweenVectors(v1, v2);
// 			if (v1.x * v2.y - v1.y * v2.x > 0)
// 				angle2 = -angle2;
// 
// 			weights[i] = (tan(angle1 / 2.) + tan(angle2 / 2.)) / (Distance(p1, pointX) + 0.001);
// 			sum += weights[i];
// 		}

		return sum;
	}
Esempio n. 12
0
void GLViewer::timerEvent (QTimerEvent *event) {
  if (resetTimer) {
   killTimer(event->timerId ());
resetTimer = false;

  if (enableGravity) {
      this->startTimer(200);

    } else {
      this->startTimer (200);
    }
  }

  QPoint point = mapFromGlobal(QCursor::pos ());
  camera()->convertClickToLine(point, orig, dir);

  // Find the selectedPoint coordinates, using camera()->pointUnderPixel().
  bool found;
  selectedPoint = camera()->pointUnderPixel(point, found);
  selectedPoint -= 0.01f*dir; // Small offset to make point clearly visible.

if (enableGravity) {
      if ((qAbs(m_frame.translation ().z) > velocity) && (m_frame.translation ().z < 0)) {
          double liftAmount = fallZOffset(m_frame.translation ().z);
          this->oldZValue = m_frame.translation ().z;
          if (!m_frame.isManipulated ()) {
          if (liftAmount > 0) {
              m_frame.translate (0.0f, 0.0f, (float) gravityForce);
              velocity = 0 - liftAmount + gravityForce;
            }
          if (liftAmount < 0) {
              velocity += gravityForce;
              m_frame.translate (0.0f, 0.0f, (float) velocity);
            }
            }
        } else {

          m_frame.setTranslation ( m_frame.translation ().x,  m_frame.translation ().y, 0.0f);
          this->oldZValue = m_frame.translation ().z;
          velocity = (-1 * (velocity - qAbs(m_frame.translation ().z)));
          if (qAbs(velocity) > gravityForce) {
              m_frame.translate (0.0f, 0.0f, (float) velocity);
            } else {
              m_frame.setTranslation ( m_frame.translation ().x,  m_frame.translation ().y, 0.0f);
              velocity = 0;
              this->oldZValue = m_frame.translation ().z;
            }

        }
  }
QString msg;

msg.append("[OrientAxis->Viewdir, OrientAngle] Angle: ");
msg.append(QString("%1").arg(AngleBetweenVectors (fromVec(camera()->orientation().axis ()), fromVec(camera()->viewDirection ()))));
msg.append(" , ");
msg.append(QString("%1").arg(camera()->orientation ().angle ()));
msg.append(" | [Cam] Orient Axis [View Dir]: ");
msg.append(stringFromVector3d(fromVec(camera()->orientation ().axis ())));
msg.append(QString(" [%1]").arg(stringFromVector3d(fromVec(camera()->viewDirection ()))));
//camera()->setOrientation (Quaternion(camera()->orientation ().axis (),  AngleBetweenVectors (fromVec(selectedPoint), fromVec(orig))));

emit this->sbMsg (msg);
  this->update ();

}
Esempio n. 13
0
/*
==================
V_CalcSpectatorRefdef

==================
*/
void V_CalcSpectatorRefdef ( struct ref_params_s * pparams )
{

	vec3_t					angles;
	static viewinterp_t		ViewInterp;
	static float			bob = 0.0f;
	static vec3_t			velocity ( 0.0f, 0.0f, 0.0f);

	static int lastWeaponModelIndex = 0;
	static int lastViewModelIndex = 0;
		
	cl_entity_t	 * ent = gEngfuncs.GetEntityByIndex( g_iUser2 );
	cl_entity_t	 * gunModel = gEngfuncs.GetViewModel();
	static float lasttime;

	static float lastang[3];
	static float lastorg[3];

	vec3_t delta;
	pparams->onlyClientDraw = false;

	// refresh position
	VectorCopy ( pparams->simorg, v_sim_org );

	// get old values
	VectorCopy ( pparams->cl_viewangles, v_cl_angles );
	VectorCopy ( pparams->viewangles, v_angles );
	VectorCopy ( pparams->vieworg, v_origin );
	v_frametime = pparams->frametime;

	if ( pparams->nextView == 0 )
	{
		// first renderer cycle, full screen

		switch ( g_iUser1 )
		{
			case OBS_CHASE_LOCKED:	V_GetChasePos( g_iUser2, NULL, v_origin, v_angles );
									break;

			case OBS_CHASE_FREE:	V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles );
									break;

			case OBS_ROAMING	:	VectorCopy (v_cl_angles, v_angles);
									VectorCopy (v_sim_org, v_origin);
									break;

			case OBS_IN_EYE		:   V_GetInEyePos( g_iUser2, v_origin, v_angles );
									break;
				
			case OBS_MAP_FREE  :	pparams->onlyClientDraw = true;
									V_GetMapFreePosition( v_cl_angles, v_origin, v_angles );
									break;

			case OBS_MAP_CHASE  :	pparams->onlyClientDraw = true;
									V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles );
									break;
		}

		if ( gHUD.m_Spectator.m_pip->value )
			pparams->nextView = 1;	// force a second renderer view

		gHUD.m_Spectator.m_iDrawCycle = 0;

	}
	else
	{
		// second renderer cycle, inset window

		// set inset parameters
		pparams->viewport[0] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowX);	// change viewport to inset window
		pparams->viewport[1] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowY);
		pparams->viewport[2] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowWidth);
		pparams->viewport[3] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowHeight);
		pparams->nextView	 = 0;	// on further view
		pparams->onlyClientDraw = false;

		// override some settings in certain modes
		switch ( (int)gHUD.m_Spectator.m_pip->value )
		{
			case INSET_CHASE_FREE : V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles );
									break;	

			case INSET_IN_EYE	 :	V_GetInEyePos( g_iUser2, v_origin, v_angles );
									break;

			case INSET_MAP_FREE  :	pparams->onlyClientDraw = true;
									V_GetMapFreePosition( v_cl_angles, v_origin, v_angles );
									break;

			case INSET_MAP_CHASE  :	pparams->onlyClientDraw = true;

									if ( g_iUser1 == OBS_ROAMING )
										V_GetMapChasePosition( 0, v_cl_angles, v_origin, v_angles );
									else
										V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles );

									break;
		}

		gHUD.m_Spectator.m_iDrawCycle = 1;
	}


	// do the smoothing only once per frame, not in roaming or map mode
	if ( (gHUD.m_Spectator.m_iDrawCycle == 0) && (g_iUser1 == OBS_IN_EYE)  )
	{
		// smooth angles

		VectorSubtract( v_angles, lastang, delta );
		if ( Length( delta ) != 0.0f )
		{
			VectorCopy( v_angles, ViewInterp.Angles[ ViewInterp.CurrentAngle & ORIGIN_MASK ] );
			ViewInterp.AngleTime[ ViewInterp.CurrentAngle & ORIGIN_MASK ] = pparams->time;
			ViewInterp.CurrentAngle++;
			VectorCopy( v_angles, lastang );
		}

		if ( cl_vsmoothing && cl_vsmoothing->value )
		{
			int foundidx;
			int i;
			float t;

			t = pparams->time - cl_vsmoothing->value;

			for ( i = 1; i < ORIGIN_MASK; i++ )
			{
				foundidx = ViewInterp.CurrentAngle - 1 - i;
				if ( ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] <= t )
					break;
			}
			
			if ( i < ORIGIN_MASK && ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] != 0.0 )
			{
				// Interpolate
				double dt;
				float  da;
				vec3_t	v1,v2;

				AngleVectors( ViewInterp.Angles[ foundidx & ORIGIN_MASK ], v1, NULL, NULL );
				AngleVectors( ViewInterp.Angles[ (foundidx + 1) & ORIGIN_MASK ], v2, NULL, NULL );
				da = AngleBetweenVectors( v1, v2 );

				dt = ViewInterp.AngleTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ];
					
				if ( dt > 0.0 && ( da < 22.5f) )
				{
					double frac;

					frac = ( t - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK] ) / dt;
					frac = min( 1.0, frac );

					// interpolate angles
					InterpolateAngles( ViewInterp.Angles[ foundidx & ORIGIN_MASK ], ViewInterp.Angles[ (foundidx + 1) & ORIGIN_MASK ], v_angles, frac );
				}
			}
		} 

  		// smooth origin
		
		VectorSubtract( v_origin, lastorg, delta );

		if ( Length( delta ) != 0.0 )
		{
			VectorCopy( v_origin, ViewInterp.Origins[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] );
			ViewInterp.OriginTime[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] = pparams->time;
			ViewInterp.CurrentOrigin++;

			VectorCopy( v_origin, lastorg );
		}

		// don't smooth in roaming (already smoothd), 
		if ( cl_vsmoothing && cl_vsmoothing->value  )
		{
			int foundidx;
			int i;
			float t;

			t = pparams->time - cl_vsmoothing->value;

			for ( i = 1; i < ORIGIN_MASK; i++ )
			{
				foundidx = ViewInterp.CurrentOrigin - 1 - i;
				if ( ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] <= t )
					break;
			}

			if ( i < ORIGIN_MASK &&  ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] != 0.0 )
			{
				// Interpolate
				vec3_t delta;
				double frac;
				double dt;
				vec3_t neworg;

				dt = ViewInterp.OriginTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ];
				if ( dt > 0.0 )
				{
					frac = ( t - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK] ) / dt;
					frac = min( 1.0, frac );
					VectorSubtract( ViewInterp.Origins[ ( foundidx + 1 ) & ORIGIN_MASK ], ViewInterp.Origins[ foundidx & ORIGIN_MASK ], delta );
					VectorMA( ViewInterp.Origins[ foundidx & ORIGIN_MASK ], frac, delta, neworg );

					// Dont interpolate large changes
					if ( Length( delta ) < 64 )
					{
						VectorCopy( neworg, v_origin );
					}
				}
			}
		}
	}	

	// Hack in weapon model:


	if ( (g_iUser1 == OBS_IN_EYE || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE) 
		&& ent && g_iUser2 )
	{
		// get position for weapon model
		VectorCopy( v_origin, gunModel->origin);
		VectorCopy( v_angles, gunModel->angles);

		// add idle tremble
		gunModel->angles[PITCH]*=-1;
		
		// calculate player velocity
		float timeDiff = ent->curstate.msg_time - ent->prevstate.msg_time;

		if ( timeDiff > 0 )
		{
			vec3_t distance;
			VectorSubtract(ent->prevstate.origin, ent->curstate.origin, distance);
			VectorScale(distance, 1/timeDiff, distance );

			velocity[0] = velocity[0]*0.66f + distance[0]*0.33f;
			velocity[1] = velocity[1]*0.66f + distance[1]*0.33f;
			velocity[2] = velocity[2]*0.66f + distance[2]*0.33f;
			
			VectorCopy(velocity, pparams->simvel);
			pparams->onground = 1;

			bob = V_CalcBob( pparams );
		}

		vec3_t forward;
		AngleVectors(v_angles, forward, NULL, NULL );

		for ( int i = 0; i < 3; i++ )
		{
			gunModel->origin[ i ] += bob * 0.4 * forward[ i ];
		}
		
		// throw in a little tilt.
		gunModel->angles[YAW]   -= bob * 0.5;
		gunModel->angles[ROLL]  -= bob * 1;
		gunModel->angles[PITCH] -= bob * 0.3;

		VectorCopy( gunModel->angles, gunModel->curstate.angles );
		VectorCopy( gunModel->angles, gunModel->latched.prevangles );

		if ( lastWeaponModelIndex != ent->curstate.weaponmodel )
		{
			// weapon model changed

			lastWeaponModelIndex = ent->curstate.weaponmodel;
			lastViewModelIndex = V_FindViewModelByWeaponModel( lastWeaponModelIndex );
			if ( lastViewModelIndex )
			{
				gEngfuncs.pfnWeaponAnim(0,0);	// reset weapon animation
			}
			else
			{
				// model not found
				gunModel->model = NULL;	// disable weaopn model
				lastWeaponModelIndex = lastViewModelIndex = 0;
			}
		}

		if ( lastViewModelIndex )
		{
			gunModel->model = IEngineStudio.GetModelByIndex( lastViewModelIndex );
			gunModel->curstate.modelindex = lastViewModelIndex;
			gunModel->curstate.frame = 0;
			gunModel->curstate.colormap = 0; 
			gunModel->index = g_iUser2;
		}
		else
		{
			gunModel->model = NULL;	// disable weaopn model
		}
	}
	else
	{
		gunModel->model = NULL;	// disable weaopn model
		lastWeaponModelIndex = lastViewModelIndex = 0;
	}

	lasttime = pparams->time; 

	// write back new values into pparams

	VectorCopy ( v_angles, pparams->viewangles )
	VectorCopy ( v_origin, pparams->vieworg );

}