Пример #1
0
//==============================================================================
// プレイヤー判定スキップ
//==============================================================================
void CGame::PushBackBattleArea(void)
{
	// 判定
	CPlayer*	pPlayerCurrent = nullptr;		// 対象オブジェクト
	for (int cntPlayer = 0; cntPlayer < PLAYER_MAX; ++cntPlayer)
	{
		// 対象オブジェクトを取得
		pPlayerCurrent = Player[cntPlayer];

		// 対象のステートを確認
		if (NeedsSkipPlayer(pPlayerCurrent))
		{
			continue;
		}

		// 押し戻し
		VECTOR3	vectorPlayerToCenter = Ground->Pos() - pPlayerCurrent->Pos();
		vectorPlayerToCenter.y = 0.0f;
		float	distanceFromCenter = vectorPlayerToCenter.x * vectorPlayerToCenter.x + vectorPlayerToCenter.y * vectorPlayerToCenter.y + vectorPlayerToCenter.z * vectorPlayerToCenter.z;
		if (distanceFromCenter > (RADIUS_AREA_BATTLE - RADIUS_PUSH_CHARACTER) * (RADIUS_AREA_BATTLE - RADIUS_PUSH_CHARACTER))
		{
			float	distancePushBack = sqrtf(distanceFromCenter) - (RADIUS_AREA_BATTLE - RADIUS_PUSH_CHARACTER);
			vectorPlayerToCenter.Normalize();
   pPlayerCurrent->AddPos(vectorPlayerToCenter * distancePushBack);
   pPlayerCurrent->AddDestPos(vectorPlayerToCenter * distancePushBack);
		}
	}
}
Пример #2
0
/// Computes the angular velocity of a body given the current quaternion orientation and the quaternion velocity
VECTOR3 QUAT::to_omega(const QUAT& q, const QUAT& qd)
{
  VECTOR3 omega;
  omega.x() = 2 * (-q.x * qd.w + q.w * qd.x - q.z * qd.y + q.y * qd.z);
  omega.y() = 2 * (-q.y * qd.w + q.z * qd.x + q.w * qd.y - q.x * qd.z);
  omega.z() = 2 * (-q.z * qd.w - q.y * qd.x + q.x * qd.y + q.w * qd.z);
  return omega;
}
Пример #3
0
//==============================================================================
// 着弾地点判定
//==============================================================================
void CGame::HitBulletToField(void)
{
	VECTOR3		nor;
	float		height;
	CBillboard* mark;
	VECTOR3		markPos;
	CBallistic* ballistic = Player[CManager::netData.charNum]->GetBallistic();
	CPolygon3D* landing = ballistic->GetLanding();

	for(int cnt = 0; cnt < MARK_MAX; ++cnt)
	{
		// 初期化
		nor = VECTOR3(0.0f,0.0f,0.0f);
		height = 0.0f;

		// マーク情報
		mark = ballistic->GetMark(cnt);
		markPos = mark->Pos();

		// 高さ判定
		height = Ground->GetHeight(markPos - VECTOR3(0.0f, BULLET_SIZE * 0.5f, 0.0f), &nor);
		if(height >= markPos.y)
		{
			// 回転を求める
			VECTOR3	vectorUp(0.0f, 1.0f, 0.0f);		// 上方向ベクトル
			VECTOR3	vectorAxisRotation;				// 回転軸
			float	rotation = 0.0f;				// 回転量
			VECTOR3::Cross(&vectorAxisRotation, nor, vectorUp);
			if (vectorAxisRotation.x < FLT_EPSILON && vectorAxisRotation.x > -FLT_EPSILON)
			{
				if (vectorAxisRotation.z < FLT_EPSILON && vectorAxisRotation.z > -FLT_EPSILON)
				{
					if (vectorAxisRotation.y < FLT_EPSILON && vectorAxisRotation.y > -FLT_EPSILON)
					{
						vectorAxisRotation.y = 1.0f;
					}
				}
			}
			vectorAxisRotation.Normalize();
			rotation = VECTOR3::Dot(nor, vectorUp);
			if (rotation <= 1.0f && rotation >= -1.0f)
			{
				rotation = RAD_TO_DEG * acosf(rotation);
			}
			else
			{
				rotation = 0.0f;
			}

			// 着弾マークに設定する
			landing->SetPos(VECTOR3(markPos.x, height + 0.5f, markPos.z));
			landing->SetAxisRotation(vectorAxisRotation);
			landing->SetRotationAxis(rotation);
			break;
		}
	}
}
Пример #4
0
float FieldData::getFieldMag(float point[3])
{
	VECTOR3 pos(point[0],point[1],point[2]);
	VECTOR3 vel;

	int rc = pField->getFieldValue( pos, (float)timeStep, vel);
	if (rc < 0) 
		return -1.f;

	return vel.GetMag();
}
Пример #5
0
/**
 * This matrix is used in the relationships omega' = 2*L*qd and
 * alpha' = 2*L*qdd, where omega'/alpha' are the angular velocity/acceleration
 * of a rigid body in the body's frame and qd/qdd are the first/second time
 * derivatives of the Euler (unit quaternion) parameters.
 * 
 * The matrix L is defined as:
 * -e1  e0  e3 -e2
 * -e2 -e3  e0  e1
 * -e3  e2 -e1  e0
 */
VECTOR3 QUAT::L_mult(REAL qx, REAL qy, REAL qz, REAL qw) const
{
  const double& e0 = w;
  const double& e1 = x;
  const double& e2 = y;
  const double& e3 = z;

  VECTOR3 v;
  v.x() = -e1*qw + e0*qx + e3*qy - e2*qz; 
  v.y() = -e2*qw - e3*qx + e0*qy + e1*qz;
  v.z() = -e3*qw + e2*qx - e1*qy + e0*qz;
  return v;
}
Пример #6
0
/**
 * This matrix is used in the relationships omega = 2*G*qd and
 * alpha = 2*G*qdd, where omega/alpha are the angular velocity/acceleration
 * of a rigid body in the game frame and qd/qdd are the first/second time
 * derivatives of the Euler (unit quaternion) parameters.
 */
VECTOR3 QUAT::G_mult(REAL qx, REAL qy, REAL qz, REAL qw) const
{
  const double e0 = qw;
  const double e1 = qx;
  const double e2 = qy;
  const double e3 = qz;

  VECTOR3 r;
  r.x() = -x*e0 + w*e1 - z*e2 + y*e3;
  r.y() = -y*e0 + z*e1 + w*e2 - x*e3;
  r.z() = -z*e0 - y*e1 + x*e2 + w*e3;
  return r;
}
Пример #7
0
/**
 * The local axis for this joint does not take the orientation of the 
 * inboard link into account; thus, if the orientation of the inboard link 
 * changes, then the local axis remains constant.
 * \param axis a unit vector
 * \sa get_axis_global()
 * \sa set_axis_global()
 */
void PRISMATICJOINT::set_axis(const VECTOR3& axis) 
{
  // check that axis is ok 
  if (std::fabs(axis.norm() - (REAL) 1.0) > EPS)
    throw UndefinedAxisException(); 
 
  // normalize the axis, in case caller did not 
  VECTOR3 naxis = VECTOR3::normalize(axis); 

  // transform axis to joint frame
  _u = POSE3::transform_vector(get_pose(), naxis);

  // setup v1i and v1j 
  VECTOR3::determine_orthonormal_basis(_u, _v1i, _v1j);

  // set _ui
  VECTOR3 outboard_origin(0.0, 0.0, 0.0, _Fb);
  _ui = POSE3::transform_point(_F, outboard_origin);

  // set _uj
  _uj = POSE3::transform_vector(_Fb, _v1i); 

  // set the joint axis in the inner link frame
  update_spatial_axes(); 
}        
Пример #8
0
void get_color_entropy(float& r,float& g,float& b,float& a,VECTOR3 p,int* grid_res)
{
	if(!entropies)
		return;
	int x=p.x(); int y=p.y(); int z=p.z();
	int idx=x+y*grid_res[0]+z*grid_res[0]*grid_res[1];
	float val=entropies[idx];
	r=val;
	if(val<0.5)
		g=2*val;
	else
		g=2-2*val;
	b=1-val;
	a=val;

}
Пример #9
0
//////////////////////////////////////////////////////////////////////////
// get value of node id at time step t
// input
//		id:			node Id
//		t:			time step in check
// output
//		nodeData:	vector value at this node
// return
//		1:			operation successful
//		-1:			invalid id
//////////////////////////////////////////////////////////////////////////
int Solution::GetValue(int id, float t, VECTOR3& nodeData)
{
  float adjusted_t = t - m_MinT;
	if((id < 0) || (id >= m_nNodeNum) || (adjusted_t < 0.0) || (adjusted_t > (float)(m_nTimeSteps-1)))
		return -1;

	if(!isTimeVarying())
		nodeData = m_pDataArray[(int)adjusted_t][id];
	else
	{
		int lowT, highT;
		float ratio;
		lowT = (int)floor(adjusted_t);
		ratio = adjusted_t - (float)floor(adjusted_t);
		highT = lowT + 1;
		if(lowT >= (m_nTimeSteps-1))
		{
			highT = lowT;
			ratio = 0.0;
		}
		nodeData.Set(Lerp(m_pDataArray[lowT][id][0], m_pDataArray[highT][id][0], ratio),
					 Lerp(m_pDataArray[lowT][id][1], m_pDataArray[highT][id][1], ratio),
					 Lerp(m_pDataArray[lowT][id][2], m_pDataArray[highT][id][2], ratio));
	}

	return 1;
}
Пример #10
0
// get the min and max value for all time steps
int Solution::GetMinMaxValueAll(VECTOR3& minVal, VECTOR3& maxVal)
{
	minVal = m_pMinValue[0];
	maxVal = m_pMaxValue[0];

	for(int tFor = 1; tFor < m_nTimeSteps; tFor++)
	{
		if(minVal.GetMag() > m_pMinValue[tFor].GetMag())
			minVal = m_pMinValue[tFor];

		if(maxVal.GetMag() < m_pMaxValue[tFor].GetMag())
			maxVal = m_pMaxValue[tFor];
	}

	return 1;
}
void IMainGame::mFunction_GameOverAnimationInit(BOOL hasPlayerWon)
{
	static std::default_random_engine rndEngine;
	static std::uniform_real_distribution<float> unitDist(-1.0f, 1.0f);

	if (hasPlayerWon)
	{
		mMainGameState = GameState::MainGame::GS_DeathExplode;
		//clear bullets
		mBulletMgr.KillAllBullet();
		//player WIN
		mIsPlayerVictorious = TRUE;
		//set camera to look at chicken
		gCamera.SetLookAt(mChickenBoss.GetPosition());
		//..explode fireworks
		for (int i = 0;i < 2000;++i)
		{
			//shoot direction (add some random offset)
			VECTOR3 dir = { unitDist(rndEngine),unitDist(rndEngine) ,unitDist(rndEngine) };
			//Y direction offset ( a whole column of bullets)
			dir.Normalize();
			mBulletMgr.SpawnBullet(mChickenBoss.GetPosition(), dir, VECTOR3(1, 0,0));
		}
	}
	else
	{
		mMainGameState = GameState::MainGame::GS_DeathExplode;
		//clear bullets
		mBulletMgr.KillAllBullet();
		//player LOSE
		mIsPlayerVictorious = FALSE;
		//..explode fireworks
		for (int i = 0;i < 2000;++i)
		{
			//shoot direction (add some random offset)
			VECTOR3 dir = { unitDist(rndEngine),unitDist(rndEngine) ,unitDist(rndEngine) };
			//Y direction offset ( a whole column of bullets)
			dir.Normalize();
			mBulletMgr.SpawnBullet(mPlayer.GetPosition(), dir, VECTOR3(1, 0, 0));
		}

		//move to another position to watch the explosion
		gCamera.SetPosition(mPlayer.GetPosition() + VECTOR3(300.0f,300.0f,300.0f));
		gCamera.SetLookAt(mPlayer.GetPosition());
	}
}
Пример #12
0
//==============================================================================
// オブジェクトの地形による押し戻し
//==============================================================================
void CGame::PushBackObjectByField(CObject* pObject, float offsetY)
{
	// 地形とのあたり判定
	VECTOR3	NormalGround;		// 地形の法線
	float	HeightGround;		// 地形の高さ
	HeightGround = Ground->GetHeight(pObject->Pos(), &NormalGround) + offsetY;

	//********************************************************
	// 2015_02_12 姿勢制御用の処理を追加 ここから
	//********************************************************
	// 回転を求める
	VECTOR3	vectorUp(0.0f, 1.0f, 0.0f);		// 上方向ベクトル
	VECTOR3	vectorAxisRotation;				// 回転軸
	float	rotation = 0.0f;				// 回転量
	VECTOR3::Cross(&vectorAxisRotation, NormalGround, vectorUp);
	if (vectorAxisRotation.x < FLT_EPSILON && vectorAxisRotation.x > -FLT_EPSILON)
	{
		if (vectorAxisRotation.z < FLT_EPSILON && vectorAxisRotation.z > -FLT_EPSILON)
		{
			if (vectorAxisRotation.y < FLT_EPSILON && vectorAxisRotation.y > -FLT_EPSILON)
			{
				vectorAxisRotation.y = 1.0f;
			}
		}
	}
	vectorAxisRotation.Normalize();
	rotation = VECTOR3::Dot(NormalGround, vectorUp);
	if (rotation <= 1.0f && rotation >= -1.0f)
	{
		rotation = RAD_TO_DEG * acosf(rotation);
	}
	else
	{
		rotation = 0.0f;
	}

	// キャラクターに設定する
 pObject->SetPosY(HeightGround);
 pObject->SetDestPosY(HeightGround);
	pObject->SetAxisRotation(vectorAxisRotation);
	pObject->SetRotationAxis(rotation);
	//********************************************************
	// 2015_02_12 姿勢制御用の処理を追加 ここまで
	//********************************************************
}
Пример #13
0
TRIANGLE::TRIANGLE(VECTOR3 v1, VECTOR3 v2, VECTOR3 v3, VECTOR3 norm, COLOR col)
{
    vertex[0] = v1;
    vertex[1] = v2;
    vertex[2] = v3;

    if(norm.isNull())
        computeNormal();
    else
        normal = norm;

    color = col;
}
Пример #14
0
int GetListOrder()
{
	register int order=0;

	glPushMatrix();
	glLoadIdentity();
	object.trackball.apply_inverse_transform();
	GLdouble m[16];
	glGetDoublev(GL_MODELVIEW_MATRIX, m);
	matrix4f tm(m[0], m[4], m[8],  m[12],
			   m[1], m[5], m[9],  m[13],
			   m[2], m[6], m[10], m[14],
			   m[3], m[7], m[11], m[15]);
	
	tm = tm.inverse();
	tm = tm.transpose();
	
	vec3f splat_normal(0, 0, 1);
	tm.mult_matrix_vec(splat_normal);
	splat_normal.normalize();

	float max = -1;
	float dm;
	for (int i=0; i<SORTED_LIST_NUM; i++){
		VECTOR3 s(splat_normal[0], splat_normal[1], splat_normal[2]);
		VECTOR3 t = viewer.eyes[i];
		t.Normalize();
		dm = dot(t, s);

		if (dm>max){
			order = i;
			max = dm;
		}
	}

	glPopMatrix();
	return order;
}
Пример #15
0
int vtCStreamLine::AdvectOneStep(TIME_DIR time_dir,
                                 INTEG_ORD integ_ord,
                                 TIME_DEP time_dep,
                                 PointInfo& seedInfo,
                                 VECTOR3& finalP)
{
	int istat;
	PointInfo thisParticle;
	VECTOR3 vel;
	float curTime = m_fCurrentTime;
	float dt = m_fInitialStepSize;

	finalP.Set(-1, -1, -1);
	thisParticle = seedInfo;

	// the first point
	istat = m_pField->at_phys(seedInfo.fromCell, seedInfo.phyCoord, 
	                          seedInfo, m_fCurrentTime, vel);
	if(istat == OUT_OF_BOUND)
		return OUT_OF_BOUND;
	if((fabs(vel[0]) < m_fStationaryCutoff) && 
	   (fabs(vel[1]) < m_fStationaryCutoff) && 
	   (fabs(vel[2]) < m_fStationaryCutoff))
		return CRITICAL_POINT;

	float error;
	if(integ_ord == SECOND)
		istat = runge_kutta2(time_dir, time_dep, thisParticle, &curTime, dt);
	else if(integ_ord == FOURTH)
		istat = runge_kutta4(time_dir, time_dep, thisParticle, &curTime, dt);
	else if(integ_ord == RK45)
		istat = runge_kutta45(time_dir, time_dep, thisParticle, &curTime, dt, 
		                      &error);
	else 
		return OUT_OF_BOUND;

	if(istat == OUT_OF_BOUND)			// out of boundary
			return OUT_OF_BOUND;
	m_pField->at_phys(thisParticle.fromCell, thisParticle.phyCoord, 
	                  thisParticle, m_fCurrentTime, vel);
	if((fabs(vel[0]) < m_fStationaryCutoff) && 
	   (fabs(vel[1]) < m_fStationaryCutoff) && 
	   (fabs(vel[2]) < m_fStationaryCutoff))
		return CRITICAL_POINT;
	else
		finalP = thisParticle.phyCoord;

	return OKAY;
}
Пример #16
0
//load seeds
float* get_grid_vec_data(int* grid_res)//get vec data at each grid point
{
	osuflow->GetFlowField()->getDimension(grid_res[0],grid_res[1],grid_res[2]);

	float * vectors=new float[grid_res[0]*grid_res[1]*grid_res[2]*3];
	for(int k=0; k<grid_res[2];k++)
	{
		for(int j=0; j<grid_res[1];j++)
		{
			for(int i=0; i<grid_res[0];i++)
			{
				VECTOR3 data;
				osuflow->GetFlowField()->at_vert(i,j,k,0,data);//t=0, static data
				int idx=i+j*grid_res[0]+k*grid_res[0]*grid_res[1];

				data.Normalize();
				vectors[idx*3+0]=data.x();
				vectors[idx*3+1]=data.y();
				vectors[idx*3+2]=data.z();
			}
		}
	}
	return vectors;
}
Пример #17
0
bool TRIANGLE::intersect(POINT origin, VECTOR3 direction, double &depth) const
{
    //algorithm used:  http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
    //QVector3D d = direction;
    VECTOR3 e1 = vertex[1] - vertex[0];
    VECTOR3 e2 = vertex[2] - vertex[0];
    VECTOR3 p = direction.cross(e2);// QVector3D::crossProduct(d, e2);
    double det = e1.dot(p);// QVector3D::dotProduct(e1, p);
    if(det > -EPSILON && det < EPSILON)
        return false;
    double inv_det = 1.f / det;

    VECTOR3 t = VECTOR3(origin) - vertex[0];

    double u = (t.dot(p) * inv_det); // QVector3D::dotProduct(t, p) * inv_det);
    if(u < 0.f || u > 1.f)
        return false;

    //QVector3D q = QVector3D::crossProduct(t, e1);
    VECTOR3 q = t.cross(e1);

    double v = direction.dot(q) * inv_det; // (QVector3D::dotProduct(d, q) * inv_det);
    if(v < 0.f || (u + v) > 1.f)
        return false;

    double dist = e2.dot(q) * inv_det; // QVector3D::dotProduct(e2, q) * inv_det;
    if(dist > EPSILON)
    {
        //DEBUG PRINT
        //std::cout << "getRayIntersection - Treffer: " << dist << std::endl;
        depth = dist;
        return true;
    }

    return false;
}
Пример #18
0
/**
 * Note that the derivative is not generally a unit quaternion.
 * \param q the current orientation
 * \param w the angular velocity (in the global frame)
 * Uses the matrix:
 *      |  -q.x  +q.w  -q.z  +q.y  |
 * G =  |  -q.y  +q.z  +q.w  -q.x  |
 *      |  -q.z  -q.y  +q.x  +q.w  |
 */
QUAT QUAT::deriv(const QUAT& q, const VECTOR3& w)
{
  QUAT qd;

  qd.w = .5 * (-q.x * w.x() - q.y * w.y() - q.z * w.z());
  qd.x = .5 * (+q.w * w.x() + q.z * w.y() - q.y * w.z());
  qd.y = .5 * (-q.z * w.x() + q.w * w.y() + q.x * w.z());
  qd.z = .5 * (+q.y * w.x() - q.x * w.y() + q.w * w.z());

  return qd;
}
Пример #19
0
//////////////////////////////////////////////////////////////////////////
// get the physical coordinate of the vertex
//
// input:
// verIdx: index of vertex
// output:
// pos: physical coordinate of vertex
//////////////////////////////////////////////////////////////////////////
ReturnStatus CurvilinearGrid::at_vertex(int verIdx, VECTOR3& pos)
{
	int totalVer = xdim() * ydim() * zdim();
	if ((verIdx < 0) || (verIdx >= totalVer))
		return OUT_OF_BOUND;
	/*
	zidx = verIdx / (xdim() * ydim());
	yidx = verIdx % (xdim() * ydim());
	yidx = verIdx / xdim();
	xidx = verIdx - zidx * xdim() * ydim() - yidx * xdim();
	*/
	float xpos = m_pVertex[verIdx][0];
	float ypos = m_pVertex[verIdx][1];
	float zpos = m_pVertex[verIdx][2];

	// pos.set((float)xidx, (float)yidx, (float)zidx);
	pos.set(xpos, ypos, zpos);
	return SUCCESS;
}
Пример #20
0
/**
 * This matrix is used in the relationships qd = 1/2*L^T*omega and
 * qdd = 1/2*L^T*alpha' - 1/4*omega'^2*q, where omega'/alpha' are the angular
 * velocity/acceleration of a rigid body in the body frame and qd/qdd are the
 * first/second time derivatives of the Euler (unit quaternion) parameters.
 * 
 * The matrix L is defined as:
 * -e1  e0  e3 -e2
 * -e2 -e3  e0  e1
 * -e3  e2 -e1  e0
 */
QUAT QUAT::L_transpose_mult(const VECTOR3& v) const
{
  double de0 = -x*v.x() - y*v.y() - z*v.z();
  double de1 = +w*v.x() - z*v.y() + y*v.z();
  double de2 = +z*v.x() + w*v.y() - x*v.z();
  double de3 = -y*v.x() + x*v.y() + w*v.z();

  QUAT q;
  q.w = de0;
  q.x = de1;
  q.y = de2;
  q.z = de3;
  return q;
}
Пример #21
0
// Compute orientation of e with respect to quadrilateral abcd
// by treating abcd as two triangles: abc and acd.
//
// Let there be a viewer who sees abcd counter-clockwise (e.g. from
// a position inside a 3-cell).  Return:
//
//    1 if e on same side of quadrilateral abcd as viewer
//   -1 if e on opposite side of quadrilateral abcd with respect to viewer
//    0 if e is coplanar with abcd
//
// The result is computed by doing two orientation tests, one for e
// with respect to abc, and one for e with respect to acd.
// If these two tests agree, we're done, if they don't, then we
// do more work to figure out what case we're in.
//
int FEL_orient(const VECTOR3& a, const VECTOR3& b,
	const VECTOR3& c, const VECTOR3& d,
	const VECTOR3& e)
{
	const int verbosity = 0;
	VECTOR3 ba = (b - a);
	VECTOR3 ca = (c - a);
	VECTOR3 da = (d - a);
	VECTOR3 ea = (e - a);

	int abc_orient = sign(dot(ea, cross(ba, ca)));
	int acd_orient = sign(dot(ea, cross(ca, da)));

	if (abc_orient == acd_orient)
		return abc_orient;

	// now the fun begins ...


	// find shortest edge in each triangle
	double ba_length = ba.getMag();
	double ca_length = ca.getMag();
	double da_length = da.getMag();
	VECTOR3 bc = b - c;
	VECTOR3 cd = c - d;
	double bc_length = bc.getMag();
	double cd_length = cd.getMag();
	double ea_length = ea.getMag();
	double shortest_abc_edge_length = min(ba_length, min(ca_length, bc_length));
	double shortest_acd_edge_length = min(ca_length, min(da_length, cd_length));

	//
	// If point e is much further from a triangle than the shortest edge
	// of the triangle, assume we cannot compute a meaningful orientation
	// result in floating-point.
	//
	// Note that it is still possible that a triangle is not usable
	// for orientation even if the following tests conclude that it is
	// (the three vertices can be colinear yet not close together).
	// We ignore that case.
	// 
	double relative_distance_threshold = 1e6;
	bool abc_usable_for_orientation =
		(shortest_abc_edge_length > 0.0) &&
		(ea_length / shortest_abc_edge_length < relative_distance_threshold);
	bool acd_usable_for_orientation =
		(shortest_acd_edge_length > 0.0) &&
		(ea_length / shortest_acd_edge_length < relative_distance_threshold);

	//    if (!abc_usable_for_orientation && !acd_usable_for_orientation) {


	if (!abc_usable_for_orientation && !acd_usable_for_orientation)
		return 0;
	if (!abc_usable_for_orientation)
		return acd_orient;
	if (!acd_usable_for_orientation)
		return abc_orient;


	int res;

	//
	// determine whether edge ac of abcd is a ridge or a valley with
	// respect to viewer (who sees abcd counter-clockwise); ridge_valley is:
	//   -1 if ridge, i.e. edge ac protrudes towards viewer
	//    1 if valley, i.e. edge ac protrudes away from viewer
	//    0 abcd is planar
	//
	int ridge_valley = sign(dot(da, cross(ba, ca)));

	// If ridge_valley == 0, abc and acd are coplanar, so
	// abc_orient and acd_orient should have agreed above.
	// In this case choose triangle with the normal with the biggest
	// magnitude as the triangle to use for orientation.
	if (ridge_valley == 0)
	{
		VECTOR3	abc = cross(ba, ca);
		VECTOR3	acd = cross(ca, da);

		double abc_normal_magnitude = abc.getMag();
		double acd_normal_magnitude = acd.getMag();
		if (abc_normal_magnitude > acd_normal_magnitude)
			res = abc_orient;
		else
			res = acd_orient;
		return res;
	}

	// both triangles assumed non-degenerate, quadrilateral is non-planar,
	// do the case analysis
	switch (((abc_orient + 1) << 4) + ((acd_orient + 1) << 2) + (ridge_valley + 1)) {
		//     abc               acd              r_v
	case ((-1 + 1) << 4) + ((0 + 1) << 2) + (-1 + 1) : res = 0; break;
	case ((-1 + 1) << 4) + ((0 + 1) << 2) + (1 + 1) : res = -1; break;
	case ((-1 + 1) << 4) + ((1 + 1) << 2) + (-1 + 1) : res = 1; break;
	case ((-1 + 1) << 4) + ((1 + 1) << 2) + (1 + 1) : res = -1; break;
	case ((0 + 1) << 4) + ((-1 + 1) << 2) + (-1 + 1) : res = 0; break;
	case ((0 + 1) << 4) + ((-1 + 1) << 2) + (1 + 1) : res = -1; break;
	case ((0 + 1) << 4) + ((1 + 1) << 2) + (-1 + 1) : res = 1; break;
	case ((0 + 1) << 4) + ((1 + 1) << 2) + (1 + 1) : res = 0; break;
	case ((1 + 1) << 4) + ((-1 + 1) << 2) + (-1 + 1) : res = 1; break;
	case ((1 + 1) << 4) + ((-1 + 1) << 2) + (1 + 1) : res = -1; break;
	case ((1 + 1) << 4) + ((0 + 1) << 2) + (-1 + 1) : res = 1; break;
	case ((1 + 1) << 4) + ((0 + 1) << 2) + (1 + 1) : res = 0; break;
	default:
		res = 0;
		abort();
	}
	return res;
}
Пример #22
0
int vtCStreamLine::computeFieldLine(TIME_DIR time_dir,
									 TIME_DEP time_dep, 
									 vtListSeedTrace& seedTrace,
									 list<float>& stepList,
									 PointInfo& seedInfo)
{
	int istat;
	PointInfo thisParticle;
	double dt, cell_vol, mag; 
	double curTime;
	VECTOR3 vel;
	float totalStepsize = 0.0;
	bool onAdaptive = true;
	int nSetAdaptiveCount = 0;

	// the first particle
	thisParticle = seedInfo;
	
	seedTrace.push_back(new VECTOR3(seedInfo.phyCoord));
	curTime = (double)m_fCurrentTime;
	istat = m_pField->getFieldValue(seedInfo.phyCoord, m_fCurrentTime, vel);
	if(istat == OUT_OF_BOUND)
		return OUT_OF_BOUND;			// the advection is out of boundary
	if(istat == MISSING_VALUE ||((abs(vel[0]) < m_fStationaryCutoff) && (abs(vel[1]) < m_fStationaryCutoff) && (abs(vel[2]) < m_fStationaryCutoff)))
		return CRITICAL_POINT;			// this is critical point
		
	// get the initial step size
	
	cell_vol = m_pField->GetMinCellVolume();
	mag = vel.GetDMag();
	
	dt = m_fInitStepSize * cell_vol / mag;
	
	//Determine the value of mag*dt to project 10 times init size.  
	double maxMagDt = 10.*dt*mag;

	int rollbackCount = 0;
	// start to advect
	
	while(totalStepsize < (float)((m_nMaxsize-1)*m_fSamplingRate))
	{
		bool doingRetrace = false;
		
		int retrace = true;
		
		
		while(retrace)
		{
			retrace = false;
			
			for(int magTry = 0; magTry < 40; magTry++) {
				
				istat = runge_kutta4(time_dir, time_dep, thisParticle, &curTime, dt, maxMagDt);
			
				if (istat != FIELD_TOO_BIG) break;
				//Shrink dt by factor of 10.
				dt = 0.1*dt;

			}
			assert (istat != FIELD_TOO_BIG);
			
			seedTrace.push_back(new VECTOR3(thisParticle.phyCoord));
			stepList.push_back(dt);

			if(istat == OUT_OF_BOUND)			// out of boundary
				return OUT_OF_BOUND;

			m_pField->getFieldValue(thisParticle.phyCoord, m_fCurrentTime, vel);
			
			if((abs(vel[0]) < m_fStationaryCutoff) && (abs(vel[1]) < m_fStationaryCutoff) && (abs(vel[2]) < m_fStationaryCutoff))
				return CRITICAL_POINT;

			totalStepsize += dt;			// accumulation of step size
			nSetAdaptiveCount++;
			
			if((nSetAdaptiveCount == 2) && (onAdaptive == false))
				onAdaptive = true;

			// just generate valid new point
			if(((int)seedTrace.size() > 2)&&(onAdaptive))
			{
				double minStepsize, maxStepsize;
				VECTOR3 thisPhy, prevPhy, second_prevPhy;
				list<VECTOR3*>::iterator pIter = seedTrace.end();
				pIter--;
				thisPhy = **pIter;
				pIter--;
				prevPhy = **pIter;
				pIter--;
				second_prevPhy = **pIter;

				
				mag = vel.GetDMag();
				minStepsize = m_fInitStepSize * cell_vol / mag;
				maxStepsize = m_fMaxStepSize * cell_vol / mag;
				retrace = adapt_step(second_prevPhy, prevPhy, thisPhy, minStepsize, maxStepsize, &dt, onAdaptive);
				if(onAdaptive == false)
					nSetAdaptiveCount = 0;

				assert (rollbackCount < 10000);//If we got here, it's surely an infinite loop!
					
				// roll back and retrace
				//the doingRetrace flag is to stop double retracing (which results in infinite loop!)
				//Note a slightly different approach is in VTTimeVaryingFieldLine.cpp
				if(retrace && !doingRetrace)			
				{
					seedTrace.pop_back();
					seedTrace.pop_back();
					thisParticle.Set(*(seedTrace.back()));
					totalStepsize -= stepList.back();
					stepList.pop_back();
					totalStepsize -= stepList.back();
					stepList.pop_back();
					rollbackCount++;
					doingRetrace = true;
				} else doingRetrace = false;
			}
		}// end of retrace
		//What was the distance advected?
	}// end of advection
	return (OKAY);
}
Пример #23
0
// streamline advects as far as possible till the boundary or terminates at
// critical points. only two cases will happen: OUT_OF_BOUND & CRITICAL_POINT
int vtCStreamLine::executeInfiniteAdvection(TIME_DIR time_dir,
                                            TIME_DEP time_dep,
                                            vtListSeedTrace& seedTrace,
                                            float& totalStepsize,
                                            vector<float>* vStepsize)
{
	int istat;
	vtParticleInfo* thisSeed;
	PointInfo thisParticle, prevParticle, second_prevParticle, seedInfo;
	vtListParticleIter sIter;
	float dt, dt_estimate, cell_volume, mag, curTime;
	VECTOR3 vel;
	INTEG_ORD integ_ord;

	// initialize
	integ_ord = m_integrationOrder;
	sIter = m_lSeeds.begin();
	thisSeed = *sIter;
	seedInfo = thisSeed->m_pointInfo;
	seedTrace.clear();
	totalStepsize = 0.0;

	// the first point
	seedTrace.push_back(new VECTOR3(seedInfo.phyCoord));
	istat = m_pField->at_phys(seedInfo.fromCell, seedInfo.phyCoord, seedInfo, 
	                          m_fCurrentTime, vel);
	if((fabs(vel[0]) < m_fStationaryCutoff) && 
	   (fabs(vel[1]) < m_fStationaryCutoff) && 
	   (fabs(vel[2]) < m_fStationaryCutoff))
		return CRITICAL_POINT;

	thisParticle = seedInfo;
	curTime = m_fCurrentTime;

	// get the initial stepsize
	cell_volume = m_pField->volume_of_cell(seedInfo.inCell);
	mag = vel.GetMag();
	if(fabs(mag) < 1.0e-6f)
		dt_estimate = 1.0e-5f;
	else
		dt_estimate = pow(cell_volume, (float)0.3333333f) / mag;
	dt = m_fInitialStepSize * dt_estimate;

#ifdef DEBUG
	fprintf(fDebugOut, "****************new particle*****************\n");
	fprintf(fDebugOut, "seed: %f, %f, %f with step size %f\n", 
	        seedInfo.phyCoord[0],seedInfo.phyCoord[1],seedInfo.phyCoord[2],dt);
#endif

	// start to advect
	while(true)
	{
		second_prevParticle = prevParticle;
		prevParticle = thisParticle;

		// take a proper step, also calculates a new step size for the next step
		if(integ_ord == SECOND || integ_ord == FOURTH)
			istat = oneStepGeometric(integ_ord, time_dir, time_dep,
			                         thisParticle, prevParticle, 
			                         second_prevParticle, &curTime, &dt, 
			                         seedTrace.size());
		else if(integ_ord == RK45)
			istat = oneStepEmbedded(integ_ord, time_dir, time_dep,
			                        thisParticle, &curTime, &dt);
		else
			return OUT_OF_BOUND;


		if(istat == OUT_OF_BOUND)			// out of boundary
		{
			// find the boundary intersection point
			VECTOR3 intersectP, startP, endP;
			float oldStepsize, stepSize; 
			oldStepsize = stepSize = dt;
			startP = prevParticle.phyCoord;
			endP = thisParticle.phyCoord;
			m_pField->BoundaryIntersection(intersectP, startP, endP, &stepSize,
			                               oldStepsize);
			totalStepsize += stepSize;
			seedTrace.push_back(new VECTOR3(intersectP));
			if(vStepsize != NULL)
				vStepsize->push_back(stepSize);
			return OUT_OF_BOUND;
		}

		// find the loop
		list<VECTOR3*>::iterator searchIter;
		searchIter = seedTrace.end();
		searchIter--;
		for(; searchIter != seedTrace.begin(); searchIter--)
		{
			if(thisParticle.phyCoord == **searchIter)			// loop
				return CRITICAL_POINT;
		}

		m_pField->at_phys(thisParticle.fromCell, thisParticle.phyCoord, 
		                  thisParticle, m_fCurrentTime, vel);
		seedTrace.push_back(new VECTOR3(thisParticle.phyCoord));
		if(vStepsize != NULL)
			vStepsize->push_back(dt);
		totalStepsize += dt;

#ifdef DEBUG
		fprintf(fDebugOut, "***************advected particle***************\n");
		fprintf(fDebugOut, "pos = (%f, %f, %f), vel = (%f, %f, %f) with step size %f, total step size %f\n", thisParticle.phyCoord[0], thisParticle.phyCoord[1], thisParticle.phyCoord[2], vel[0], vel[1], vel[2], dt, totalStepsize);
#endif

		if(totalStepsize > 4000.0)
		{
			printf("curl\n");
			vel.Set(0.0, 0.0, 0.0);
		}

		if((fabs(vel[0]) < m_fStationaryCutoff) && 
		   (fabs(vel[1]) < m_fStationaryCutoff) && 
		   (fabs(vel[2]) < m_fStationaryCutoff))
			return CRITICAL_POINT;
		if((int)seedTrace.size() > 2)
			adapt_step(second_prevParticle.phyCoord, prevParticle.phyCoord, 
			           thisParticle.phyCoord, &dt);
	}

	return OUT_OF_BOUND;
}
Пример #24
0
int vtCStreamLine::computeFieldLine(TIME_DIR time_dir,
                                    INTEG_ORD integ_ord,
                                    TIME_DEP time_dep, 
                                    vtListSeedTrace& seedTrace,
                                    PointInfo& seedInfo)
{
	int count = 0, istat;
	PointInfo thisParticle, prevParticle, second_prevParticle;
	PointInfo third_prevParticle;
	float dt, dt_estimate, dt_attempt, mag, curTime, prevCurTime;
	VECTOR3 vel;
	float cell_volume;

	// the first point
	istat = m_pField->at_phys(seedInfo.fromCell, seedInfo.phyCoord, seedInfo, 
	                          m_fCurrentTime, vel);
	if(istat == OUT_OF_BOUND)  {
		return OUT_OF_BOUND;
	}
	if((fabs(vel[0]) < m_fStationaryCutoff) && 
	   (fabs(vel[1]) < m_fStationaryCutoff) && 
	   (fabs(vel[2]) < m_fStationaryCutoff)) {
		return CRITICAL_POINT;
	}

	thisParticle = seedInfo;

	seedTrace.push_back(new VECTOR3(seedInfo.phyCoord));
	curTime = m_fCurrentTime;
	count++;

	// get the initial stepsize
	// this method was taken from the paper "Interactive Time-Dependent
	// Particle Tracing Using Tetrahedral Decomposition", by Kenwright and Lane
	dt = m_fInitialStepSize;
	if(m_adaptStepSize)
	{
		cell_volume = m_pField->volume_of_cell(seedInfo.inCell);
		mag = vel.GetMag();
		if(fabs(mag) < 1.0e-6f)
			dt_estimate = 1.0e-5f;
		else
			dt_estimate = pow(cell_volume, (float)0.3333333f) / mag;
		dt = m_fInitialStepSize * dt_estimate;
	}

#ifdef DEBUG
	fprintf(fDebugOut, "****************new particle*****************\n");
	fprintf(fDebugOut, "seed: %f, %f, %f with step size %f\n", 
	        seedInfo.phyCoord[0],seedInfo.phyCoord[1],seedInfo.phyCoord[2],dt);
#endif

	// start to advect
	while(count < m_nMaxsize)
	{
		third_prevParticle = second_prevParticle;
		second_prevParticle = prevParticle;
		prevParticle = thisParticle;
		prevCurTime = curTime;
		dt_attempt = dt;

		// take a proper step, also calculates a new step size for the next step
		if(integ_ord == SECOND || integ_ord == FOURTH)
			istat = oneStepGeometric(integ_ord, time_dir, time_dep,
			                         thisParticle, prevParticle, 
			                         second_prevParticle, &curTime, &dt, count);
		else if(integ_ord == RK45)
			istat = oneStepEmbedded(integ_ord, time_dir, time_dep,
			                        thisParticle, &curTime, &dt);

#ifdef DEBUG
		fprintf(fDebugOut, "point: %f, %f, %f with step size %f\n", 
		        thisParticle.phyCoord[0], thisParticle.phyCoord[1], 
		        thisParticle.phyCoord[2], dt);
#endif

		// check if the step failed
		if(istat == FAIL)
		{
			if(!m_adaptStepSize)
			{
				// can't change the step size, so advection just ends
				return OKAY;
			}
			else if(dt_attempt == m_fMinStepSize)
			{
				// tried to take a step with the min step size, 
				// can't go any further
				return OKAY;
			}
			else
			{
				// try to retake the step with a smaller step size
				dt = dt_attempt*0.1;
				if(dt < m_fMinStepSize)
					dt = m_fMinStepSize;
				thisParticle = prevParticle;
				prevParticle = second_prevParticle;
				second_prevParticle = third_prevParticle;
				curTime = prevCurTime;
				continue;
			}
		}

		seedTrace.push_back(new VECTOR3(thisParticle.phyCoord));
		count++;

		if(!m_adaptStepSize)
		{
			// change step size to prevously used, since the oneStep methods
			// will change the value of dt
			dt = dt_attempt;
		}

		// check if point is outside real bounds 
		// (bounds not counting ghost cells)
		if(!m_pField->IsInRealBoundaries(thisParticle))
		{
			return OUT_OF_BOUND;
		}

		// check if point is at critical point
		m_pField->at_phys(thisParticle.fromCell, thisParticle.phyCoord, 
		                  thisParticle, m_fCurrentTime, vel);
		if((fabs(vel[0]) < m_fStationaryCutoff) && 
		   (fabs(vel[1]) < m_fStationaryCutoff) && 
		   (fabs(vel[2]) < m_fStationaryCutoff))
		{
			return CRITICAL_POINT;
		}
	}

	return OKAY;
}
Пример #25
0
//////////////////////////////////////////////////////////////////////////
// Compute streamlines.
// output
//	listSeedTraces: For each seed, return a list keeping the trace it
//					advects
//////////////////////////////////////////////////////////////////////////
//New version, uses FlowLineData instead of points array to write results of advection.
void vtCStreamLine::computeStreamLine(float curTime, FlowLineData* container){
	m_fCurrentTime = curTime;

	vtListParticleIter sIter;
	int istat;
	int seedNum = 0;
	for(sIter = m_lSeeds.begin(); sIter != m_lSeeds.end(); ++sIter)
	{
		vtParticleInfo* thisSeed = *sIter;
		if(thisSeed->itsValidFlag == 1)			// valid seed
		{
			if(m_itsTraceDir & BACKWARD_DIR)
			{
				vtListSeedTrace* backTrace;
				list<float>* stepList;
				backTrace = new vtListSeedTrace;
				stepList = new list<float>;
				istat = computeFieldLine(BACKWARD, STEADY, *backTrace, *stepList, thisSeed->m_pointInfo);
				SampleFieldline(container, seedNum, BACKWARD, backTrace, stepList, true, istat );
				delete backTrace;
				delete stepList;
			} else {
				//must be pure forward, set start point
				container->setFlowStart(seedNum, 0);
			}
			if(m_itsTraceDir & FORWARD_DIR)
			{
				vtListSeedTrace* forwardTrace;
				list<float>* stepList;
				forwardTrace = new vtListSeedTrace;
				stepList = new list<float>;
				istat = computeFieldLine(FORWARD,STEADY, *forwardTrace, *stepList, thisSeed->m_pointInfo);
				SampleFieldline(container, seedNum, FORWARD, forwardTrace, stepList, true, istat);
				delete forwardTrace;
				delete stepList;
			} else {
				//Must be pure backward, establish end of flowline: 
				container->setFlowEnd(seedNum, 0);
			}
		}
		else                // out of data region.  Just mark seed as end, don't advect.
        {
			float x = thisSeed->m_pointInfo.phyCoord.x();
			float y = thisSeed->m_pointInfo.phyCoord.y();
			float z = thisSeed->m_pointInfo.phyCoord.z();
			container->setFlowPoint(seedNum, 0, x,y,z);
			if(container->getMaxLength(BACKWARD) > 0)
				container->setFlowPoint(seedNum, -1, END_FLOW_FLAG,0.f,0.f);
			if(container->getMaxLength(FORWARD) > 0) 
				container->setFlowPoint(seedNum, 1, END_FLOW_FLAG,0.f,0.f);
			
			if (container->doSpeeds()){
				PointInfo pointInfo;
				VECTOR3 nodeData;
				float t = m_pField->GetStartTime();

				pointInfo.phyCoord.Set(x,y,z);	
				m_pField->getFieldValue(pointInfo.phyCoord, t, nodeData);
				container->setSpeed(seedNum, 0, nodeData.GetMag()/m_pField->getTimeScaleFactor());
			}
			container->setFlowStart(seedNum, 0);
			container->setFlowEnd(seedNum, 0);
        }

		seedNum++;
	}
}
VECTOR4 IRenderPipeline3D::mFunction_VertexLighting(const VECTOR3& vPosW, const VECTOR3& vNormalW)
{
	//---------For Each Vertex, Perform Gouraud Shading------------

	VECTOR4 outColor = { 0.0f,0.0f,0.0f,1.0f };

	//traverse every lights
	for (UINT i = 0;i < c_maxLightCount;++i)
	{
		if (mDirLight[i].mIsEnabled == TRUE)
		{
			//normalized light vector
			VECTOR3 unitIncomingLightVec = mDirLight[i].mDirection;
			unitIncomingLightVec.Normalize();

			//vector from current vertex to Camera(Eye),used when compute specular
			VECTOR3 toEye = mCameraPos - vPosW;
			toEye.Normalize();

			//unit vertex normal
			VECTOR3 unitNormal = vNormalW;
			unitNormal.Normalize();

			//Ambient Color
			VECTOR3 currentAmbient = mMaterial.ambient* mDirLight[i].mAmbientColor * mMaterial.diffuse;

			//diffuse Factor (first make sure that angle <normal,light> is less than PI/2
			VECTOR3 currentDiffuse = { 0,0,0 };
			VECTOR3 currentSpecular = { 0,0,0 };

			float diffuseFactor = mDirLight[i].mDiffuseIntensity*Math::Vec3_Dot((-1)*unitIncomingLightVec, unitNormal);
			if (diffuseFactor > 0.0f)
			{
				//diffuse color (eye pos independent)
				currentDiffuse = diffuseFactor * mDirLight[i].mDiffuseColor;

				//if Texture Mapping is disabled, then use pure diffuse color of material
				if (m_pTexture == nullptr)
				{
					//component-wise
					currentDiffuse = currentDiffuse* mMaterial.diffuse;
				}
				//else the color will be passed down to pixel shader to multiply by 
				//per-pixel sample diffuse color


				//Specular color - eye position dependent
				/*VECTOR3 unitOutgoingLightVec = Vec3_Reflect(unitIncomingLightVec, unitNormal);
				float specFactor =
					mDirLight[i].mSpecularIntensity *
					pow(max(Vec3_Dot(unitOutgoingLightVec, toEye), 0.0f), mMaterial.specularSmoothLevel);

				//Vector3 * vector3 means component-wise mult , return vec3(x1*x2,y1*y2,z1*z2)
				currentSpecular = specFactor* mMaterial.specular * mDirLight[i].mSpecularColor;*/

			}

			VECTOR3 outColor3 = currentAmbient+currentDiffuse+currentSpecular;
			outColor += VECTOR4(outColor3.x, outColor3.y, outColor3.z, 0.0f);
		}
	}

	return outColor;
}
Пример #27
0
/**
 * \note alpha and omega are acceleration and velocity vectors in the global
 *       frame
 */
QUAT QUAT::dderiv(const QUAT& q, const VECTOR3& omega, const VECTOR3& alpha)
{
  QUAT qdd = QUAT::deriv(q, alpha) - (REAL) 0.25 * omega.norm_sq() * q;

  return qdd;
}
Пример #28
0
void ColliderSphereSphere::collide(std::vector<Contact> &vContacts)
{
  const Real contactTolerance = 0.00005;
	VECTOR3 &vel1 = body0_->velocity_;
	VECTOR3 &pos1 = body0_->com_;

	Sphere<Real> *pSphere = dynamic_cast<Sphere<Real>* >(body0_->shape_);
	Real rad1 = pSphere->getRadius();

	VECTOR3 &vel2 = body1_->velocity_;
	VECTOR3 &pos2 = body1_->com_;

	pSphere = dynamic_cast<Sphere<Real>* >(body1_->shape_);
	Real rad2 = pSphere->getRadius();

	Real dist = std::numeric_limits<Real>::max();

	//calc distance and relative orientation
	//we first need to calculate the relative velocity and
	//the velocity along the normal
	VECTOR3 vn = pos1 - pos2;
	vn.Normalize();

	//calculate the relative velocity
	VECTOR3 v12 = vel1 - vel2;
	
  //calculate the velocity along the normal
	Real velalongnormal = vn * v12;

  //calculate the distance
  dist = (pos2-pos1).mag() - rad1 - rad2;
  Real dist1 = fabs(vn*vel1);
  Real dist2 = fabs(vn*vel2);
  Real distpertime = (dist1+dist2)*world_->timeControl_->GetDeltaT();  
  
  if(velalongnormal < -0.005 && distpertime >= dist)
  //if(relativeNormalVelocity < -0.005)
  { 
      Contact contact;
      contact.m_dDistance  = dist;
      contact.m_vNormal    = vn;
      contact.m_vPosition0 = pos1;
      contact.m_vPosition1 = pos2;
      contact.m_pBody0     = body0_;
      contact.m_pBody1     = body1_;
      contact.id0 = contact.m_pBody0->iID_;
      contact.id1 = contact.m_pBody1->iID_;
      contact.vn           = velalongnormal;
      contact.m_dPenetrationDepth = std::min(0.0,dist);
      contact.m_iState     = CollisionInfo::TOUCHING;      
      //std::cout<<"Pre-contact normal velocity: "<<velalongnormal<<" colliding contact"<<std::endl;
      //std::cout<<"Pre-contact angular velocity0: "<<contact.m_pBody0->GetAngVel();
      //std::cout<<"Pre-contact angular velocity1: "<<contact.m_pBody1->GetAngVel();
      //std::cout<<"Pre-contact  velocity0: "<<contact.m_pBody0->m_vVelocity;
      //std::cout<<"Pre-contact  velocity1: "<<contact.m_pBody1->m_vVelocity;
      vContacts.push_back(contact);
  }
  else if(velalongnormal < 0.00001 && dist < contactTolerance)
  {
    Contact contact;
    contact.m_dDistance  = dist;
    contact.m_vNormal    = vn;
    contact.m_vPosition0 = pos1;
    contact.m_vPosition1 = pos2;
    contact.m_pBody0     = body0_;
    contact.m_pBody1     = body1_;    
    contact.id0          = contact.m_pBody0->iID_;
    contact.id1          = contact.m_pBody1->iID_;
    contact.vn           = velalongnormal;
    contact.m_iState     = CollisionInfo::TOUCHING;
    vContacts.push_back(contact);
  }
  else if(dist < 0.1*rad1)
  {
    Contact contact;
    contact.m_dDistance  = dist;
    contact.m_vNormal    = vn;
    contact.m_vPosition0 = pos1;
    contact.m_vPosition1 = pos2;
    contact.m_pBody0     = body0_;
    contact.m_pBody1     = body1_;    
    contact.id0          = contact.m_pBody0->iID_;
    contact.id1          = contact.m_pBody1->iID_;
    contact.vn           = velalongnormal;
    contact.m_iState     = CollisionInfo::TOUCHING;
    vContacts.push_back(contact);
  }
  else
  {
    return;
    Contact contact;
    contact.m_dDistance  = dist;
    contact.m_vNormal    = vn;
    contact.m_vPosition0 = pos1;
    contact.m_vPosition1 = pos2;
    contact.m_pBody0     = body0_;
    contact.m_pBody1     = body1_;
    contact.id0 = contact.m_pBody0->iID_;
    contact.id1 = contact.m_pBody1->iID_;
    contact.vn           = velalongnormal;
    contact.m_iState     = CollisionInfo::VANISHING_CLOSEPROXIMITY;      
    vContacts.push_back(contact);    
  }

}
Пример #29
0
void IPlayer::mFunction_UpdateMovement(float timeElapsed)
{
	//--------------------------keyboard------------------------------
	VECTOR3 moveVector = { 0,0,0 };
	if (IS_KEY_DOWN('A'))
	{
		moveVector.x -= 1.0f;
	}
	if (IS_KEY_DOWN('D'))
	{
		moveVector.x += 1.0f;
	}
	if (IS_KEY_DOWN('W'))
	{
		moveVector.z += 1.0f;
	}
	if (IS_KEY_DOWN('S'))
	{
		moveVector.z -= 1.0f;
	}
	if (IS_KEY_DOWN(VK_LCONTROL))
	{
		moveVector.y -= 1.0f;
	}
	if (IS_KEY_DOWN(VK_SPACE))
	{
		moveVector.y += 1.0f;
	}


	//in case that camera moves faster if 3 directions has projection of speed
	moveVector.Normalize();
	moveVector *= (0.2f*timeElapsed);
	gCamera.fps_MoveRight(moveVector.x);
	gCamera.fps_MoveForward(moveVector.z);
	gCamera.fps_MoveUp(moveVector.y);

	//restrict player movement to a Box
	VECTOR3 camPos = gCamera.GetPosition();
	/*camPos = { Clamp(camPos.x,-c_halfMovementRestrictBoxWidth,c_halfMovementRestrictBoxWidth),
		Clamp(camPos.y,-c_halfMovementRestrictBoxWidth,c_halfMovementRestrictBoxWidth),
		Clamp(camPos.z,-c_halfMovementRestrictBoxWidth,c_halfMovementRestrictBoxWidth) };
	gCamera.SetPosition(camPos);*/

	//update Position
	mLastPos = mCurrentPos;
	mCurrentPos = camPos;


	//-------------------------------cursor movement----------------------------------
	static POINT lastCursorPos = { 0,0 };
	static POINT currentCursorPos = { 0,0 };
	static const int scrWidth = ::GetSystemMetrics(SM_CXSCREEN);
	static const int scrHeight = ::GetSystemMetrics(SM_CYSCREEN);
	lastCursorPos = currentCursorPos;
	::GetCursorPos(&currentCursorPos);

	//if cursor reach the boundary, go to another side
	if (currentCursorPos.x == scrWidth - 1)
	{
		::SetCursorPos(0, currentCursorPos.y);
		lastCursorPos = { 0,currentCursorPos.y };
		currentCursorPos = lastCursorPos;
	}
	else
	{
		if (currentCursorPos.x == 0)
		{
			::SetCursorPos(scrWidth - 1, currentCursorPos.y);
			lastCursorPos = { scrWidth - 1,currentCursorPos.y };
			currentCursorPos = lastCursorPos;
		}
	}

	if (currentCursorPos.y == scrHeight - 1)
	{
		::SetCursorPos(currentCursorPos.x, 0);
		lastCursorPos = { currentCursorPos.x,0 };
		currentCursorPos = lastCursorPos;
	}
	else
	{
		if (currentCursorPos.y == 0)
		{
			::SetCursorPos(currentCursorPos.x, scrHeight - 1);
			lastCursorPos = { currentCursorPos.x,scrHeight - 1 };
			currentCursorPos = lastCursorPos;
		}
	}

	//camera rotation
	int cursorDeltaX = currentCursorPos.x - lastCursorPos.x;
	int cursorDeltaY = (currentCursorPos.y - lastCursorPos.y);
	gCamera.RotateY_Yaw(0.0002f * cursorDeltaX*timeElapsed);
	gCamera.RotateX_Pitch(0.0002f* cursorDeltaY*timeElapsed);

}
Пример #30
0
void
CPointRendererSplat::_TraversePoints_Splat()
{
	printf( "Rendering particles with splatting ... \n" );
	
	// Initialize local variables
	const list<vtListSeedTrace*>* sl_list = (const list<vtListSeedTrace*>*)this->pDataSource;
	int iT=0;
	int bincount = 20;
	float *z = new float[2];
	int *offsetToBins = new int[bincount];
	int *pcountOfBins = new int[bincount];
	for(int i=0; i<bincount; i++)
	{
		offsetToBins[i] = 0;
		pcountOfBins[i] = 0;
	}

	// Get total number of particles to begin
	maxT = 0;
	particlecount = _CountParticles( &maxT, &numT );	
	printf("Total number of particles: %d\n", particlecount); 
	printf("Max Lifetime of a particle: %d\n", maxT ); 

	// Allocate memory for rendering quads
	if( triangleArray != NULL ) delete [] triangleArray;
	if( colorArray != NULL ) delete [] colorArray;
	if( normalArray != NULL ) delete [] normalArray;	

	triangleArray = new float[particlecount * 3 * 3];
	colorArray = new float[particlecount * 3 * 3];
	normalArray = new float[particlecount * 3 * 3];

	int binid = -1;
	float binlength = 0;
	if( sortEnabled == 1 )
	{
		// Get current modelview matrix
		_CurrentModelview();
	
		// Compute min-max z values in world space
		_ZMinMaxEyeSpace( z );
		printf("Z-range: [%f %f]\n", z[0], z[1]); 

		// Compute width of each bin
		binlength = (z[1] - z[0]) / (float)bincount;
	}

	// Scan through all points and asssign bins to them
	iT = 0;
	int offset = 0;	
	for(list<vtListSeedTrace*>::const_iterator
			pIter =  sl_list->begin(); 
		pIter!=sl_list->end(); 
		pIter++, iT++) 
	{
	    // Get next trace
		const vtListSeedTrace *trace = *pIter; 
		int l = trace->size();

		int iP = 0;
		VECTOR3 p, nextp;
		for(list<VECTOR3*>::const_iterator
				pnIter = trace->begin(); 
			pnIter!= trace->end(); 
			pnIter++, iP++) 
		{
			// Get next particle
			p = **pnIter; 

			// If this is not the last point of the trace,
			// Get subsequent particle
			if(iP != (l-1))
			{
				list<VECTOR3*>::const_iterator tmpIter = pnIter;
				tmpIter++;
				nextp = **tmpIter;
			}
			else
			{
				nextp.Set( p(0), p(1), p(2) );
			}

			//printf( "P:%f, %f, %f\n", p(0), p(1), p(2) );
			//printf( "nextP:%f, %f, %f\n", nextp(0), nextp(1), nextp(2) );
						
			// Get World Space Coordinates of the particle
			VECTOR4 p4( p );
			p4 = modelview * p4; 

			if( sortEnabled == 1 )
			{
				// Compute bin id
				binid = (int)floor( p4(2) - z[0]) / binlength;
				if( binid<0 ) binid = 0;
				if( binid>=bincount ) binid = bincount - 1;
	
				// Compute array offset for this particle
				offset = (offsetToBins[binid] + pcountOfBins[binid]);

				// Shift array 
				int nParticlesToShift = 0;
				for(int i=binid+1; i<bincount; i++)
					nParticlesToShift += pcountOfBins[i];			
				memmove( (triangleArray+offset*9+9), (triangleArray+offset*9), nParticlesToShift * 9 * sizeof(float) );
				memmove( (colorArray+offset*9+9), (colorArray+offset*9), nParticlesToShift * 9 * sizeof(float) );
			}
	
			VECTOR3 dir = nextp - p;
			//dir.Normalize();
			
			float frac = 0.5f;
			float highx = p(0) + dir(0)*frac;//*g;
			float highy = p(1) + dir(1)*frac;//*g;
			float highz = p(2) + dir(2)*frac;//*g;
			
			//printf( "P:%f, %f, %f\n", p(0), p(1), p(2) );
			//printf( "nextP:%f, %f, %f\n", nextp(0), nextp(1), nextp(2) );
			//printf( "high:%f, %f, %f\n", highx, highy, highz );

			triangleArray[offset*9] = p(0);		triangleArray[offset*9+1] = p(1)+0.1f;	triangleArray[offset*9+2] = p(2);
			triangleArray[offset*9+3] = p(0);	triangleArray[offset*9+4] = p(1)-0.1f;	triangleArray[offset*9+5] = p(2);
			triangleArray[offset*9+6] = highx;	triangleArray[offset*9+7] = highy;		triangleArray[offset*9+8] = highz;

			// Calculate Normals
			if( lightEnabled == 1 )
			{
				VECTOR3 e1( triangleArray[offset*9+3]-triangleArray[offset*9],
					       triangleArray[offset*9+4]-triangleArray[offset*9+1],
						   triangleArray[offset*9+5]-triangleArray[offset*9+2] );
				VECTOR3 e2( triangleArray[offset*9+6]-triangleArray[offset*9+3],
					       triangleArray[offset*9+7]-triangleArray[offset*9+4],
						   triangleArray[offset*9+8]-triangleArray[offset*9+5] );		
				VECTOR3 e3( triangleArray[offset*9]-triangleArray[offset*9+6],
					       triangleArray[offset*9+1]-triangleArray[offset*9+7],
						   triangleArray[offset*9+2]-triangleArray[offset*9+8] );	
				
				e1.Normalize();
				e2.Normalize();
				e3.Normalize();

				VECTOR3 norm( e3(1)*e1(2) - e3(2)*e1(1), 
							  e3(2)*e1(0) - e3(0)*e1(2),
							  e3(0)*e1(1) - e3(1)*e1(0) );
				norm.Normalize();
				normalArray[offset*9] = norm(0);
				normalArray[offset*9+1] = norm(1);
				normalArray[offset*9+2] = norm(2);

				norm.Set( e1(1)*e2(2) - e1(2)*e2(1), 
							  e1(2)*e2(0) - e1(0)*e2(2),
							  e1(0)*e2(1) - e1(1)*e2(0) );
				norm.Normalize();
				normalArray[offset*9+3] = norm(0);
				normalArray[offset*9+4] = norm(1);
				normalArray[offset*9+5] = norm(2);

				norm.Set( e2(1)*e2(2) - e3(2)*e2(1), 
							  e2(2)*e2(0) - e3(0)*e2(2),
							  e2(0)*e2(1) - e3(1)*e2(0) );
				norm.Normalize();
				normalArray[offset*9+6] = norm(0);
				normalArray[offset*9+7] = norm(1);
				normalArray[offset*9+8] = norm(2);

				//VECTOR3 norm( (e1(0) + e2(0)) / 2.0f, (e1(1) + e2(1)) / 2.0f, (e1(2) + e2(2)) / 2.0f );
				//norm.Normalize();
		

			}

			if( sortEnabled == 1 )
			{
				// Update bin frequency
				pcountOfBins[binid] += 1;
			
				// Update bin offsets
				for(int i=binid+1; i<bincount; i++)
					offsetToBins[i] += 1;
			}

			if( currentColorScheme == 0 )
			{
				// Assign color based on time
				float f = (float)iP / (float)maxT;
				float f1 = (float)(iP+1) / (float)maxT;
				f = 0.2f + 0.8f * f;
				f1 = 0.2f + 0.8f * f1;
				colorArray[offset*9] = f;	colorArray[offset*9+1] = 0.4f; colorArray[offset*9+2] = 1-f;
				colorArray[offset*9+3] = f;	colorArray[offset*9+4] = 0.4f; colorArray[offset*9+5] = 1-f;
				colorArray[offset*9+6] = f1;	colorArray[offset*9+7] = 0.4f; colorArray[offset*9+8] = 1-f1;
			}
			else if( currentColorScheme == 1 )
			{
				// Assign color based on Glyph direction
				dir.Normalize();
				dir[0] = 0.2f + 0.8f * dir(0);
				dir[1] = 0.2f + 0.8f * dir(1);
				dir[2] = 0.2f + 0.8f * dir(2);

				colorArray[offset*9] = dir(0);		colorArray[offset*9+1] = dir(1); colorArray[offset*9+2] = dir(2);
				colorArray[offset*9+3] = dir(0);	colorArray[offset*9+4] = dir(1); colorArray[offset*9+5] = dir(2);
				colorArray[offset*9+6] = dir(0);	colorArray[offset*9+7] = dir(1); colorArray[offset*9+8] = dir(2);
			}

			// Increment offset, if no sorting
			if( sortEnabled == 0 )	offset ++;
		
		}// end inner for: for each trace

	}// end outer for

	delete [] z;
	delete [] offsetToBins;
	delete [] pcountOfBins;
}