示例#1
0
HRESULT CVector3DClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
{
	CVector3D* pObj;
	HRESULT hr;
	*ppvObj = NULL;
	hr = E_OUTOFMEMORY;

	// Агрегация не поддерживается!!!
	if(NULL != pUnkOuter)
		return CLASS_E_NOAGGREGATION;

	pObj = new CVector3D();

	if(NULL == pObj)
		return hr;

	hr = pObj->QueryInterface(riid, ppvObj);

	if (FAILED(hr))
		delete pObj;
	else
	{
		g_cObj++;
	}
	return hr;
}
示例#2
0
文件: NUSpline.cpp 项目: 2asoft/0ad
// called after all nodes added. This function calculates the node velocities
void RNSpline::BuildSpline()
{
	if (NodeCount == 2)
	{
		Node[0].Velocity = GetStartVelocity(0);
		Node[NodeCount-1].Velocity = GetEndVelocity(NodeCount-1);
		return;
	}
	else if (NodeCount < 2)
		return;

	for (int i = 1; i < NodeCount-1; ++i)
	{
		CVector3D Next = Node[i+1].Position - Node[i].Position;
		CVector3D Previous = Node[i-1].Position - Node[i].Position;
		Next.Normalize();
		Previous.Normalize();

		// split the angle (figure 4)
		Node[i].Velocity = Next - Previous;
		Node[i].Velocity.Normalize();
	}
	// calculate start and end velocities
	Node[0].Velocity = GetStartVelocity(0);
	Node[NodeCount-1].Velocity = GetEndVelocity(NodeCount-1);
}
示例#3
0
//! perpendicular connecting line between two lines
bool
CMathGeom3D::
LineBetweenLines(const CLine3D &line1, const CLine3D &line2, CLine3D &linei)
{
  const CVector3D &v1 = line1.vector();
  const CVector3D &v2 = line2.vector();

  const CVector3D vd(line2.start(), line1.start());

  double v22 = v2.dotProduct(v2);

  if (fabs(v22) < CMathGen::EPSILON_E6)
    return false;

  double v11 = v1.dotProduct(v1);
  double v21 = v2.dotProduct(v1);

  double d = v11*v22 - v21*v21;

  if (fabs(d) < CMathGen::EPSILON_E6)
    return false;

  double vd1 = vd.dotProduct(v1);
  double vd2 = vd.dotProduct(v2);

  double mu1 = (vd2*v21 - vd1*v22)/d;

  double mu2 = (vd2 + mu1*v21)/v22;

  linei = CLine3D(line1.point(mu1), line2.point(mu2));

  return true;
}
示例#4
0
void TerrainOverlay::RenderTileOutline(const CColor& colour, int line_width, bool draw_hidden, ssize_t i, ssize_t j)
{
	if (draw_hidden)
	{
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_CULL_FACE);
	}
	else
	{
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_CULL_FACE);
	}

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

	if (line_width != 1)
		glLineWidth((float)line_width);

	CVector3D pos;
	glBegin(GL_QUADS);
		glColor4fv(colour.FloatArray());
		m_Terrain->CalcPosition(i,   j,   pos); glVertex3fv(pos.GetFloatArray());
		m_Terrain->CalcPosition(i+1, j,   pos); glVertex3fv(pos.GetFloatArray());
		m_Terrain->CalcPosition(i+1, j+1, pos); glVertex3fv(pos.GetFloatArray());
		m_Terrain->CalcPosition(i,   j+1, pos); glVertex3fv(pos.GetFloatArray());
	glEnd();

	if (line_width != 1)
		glLineWidth(1.0f);
}
示例#5
0
void CMatrix::RotateVector(const CVector3D *a, const CVector3D *b, const CVector3D *axis) {
    CVector3D c;
    if (axis == NULL) {
        c.CrossProduct(a, b);
    } else {
        c = *axis;
    }
    
    float fCos = a->DotProduct(b) / (a->Length() * b->Length());
    float fSin = sqrtf(1 - (fCos * fCos));
    float nCos = 1.0f - fCos;
    
    m[0][0] = ((c.x*c.x) * nCos) + fCos;
    m[1][0] = ((c.y*c.x) * nCos) - (c.z * fSin);
    m[2][0] = ((c.z*c.x) * nCos) + (c.y * fSin);
    m[3][0] = 0;
    m[0][1] = ((c.x*c.y) * nCos) + (c.z * fSin);
    m[1][1] = ((c.y*c.y) * nCos) + fCos;
    m[2][1] = ((c.z*c.y) * nCos) - (c.x * fSin);
    m[3][1] = 0;
    m[0][2] = ((c.x*c.z) * nCos) - (c.y * fSin);
    m[1][2] = ((c.y*c.z) * nCos) + (c.x * fSin);
    m[2][2] = ((c.z*c.z) * nCos) + fCos;
    m[3][2] = 0;
    m[0][3] = 0; m[1][3] = 0; m[2][3] = 0; m[3][3] = 1;
}
示例#6
0
bool CCollision::CollisionOBBShpere(const COBB &A,const CVector3D &center , float radius){
	CVector3D V = center-A.m_center;
	CVector3D VL;
	for(int i=0;i<3;i++) {
		VL.v[i] = abs(CVector3D::Dot(A.m_axis[i],V)) - A.m_length[i];
		if(VL.v[i]<0) VL.v[i]=0;
	}
	return (VL.Length()<radius);
	

}
示例#7
0
文件: Camera.cpp 项目: Gallaecio/0ad
void CCamera::LookAlong(CVector3D camera, CVector3D orientation, CVector3D up)
{
	orientation.Normalize();
	up.Normalize();
	CVector3D s = orientation.Cross(up);

	m_Orientation._11 = -s.X;	m_Orientation._12 = up.X;	m_Orientation._13 = orientation.X;	m_Orientation._14 = camera.X;
	m_Orientation._21 = -s.Y;	m_Orientation._22 = up.Y;	m_Orientation._23 = orientation.Y;	m_Orientation._24 = camera.Y;
	m_Orientation._31 = -s.Z;	m_Orientation._32 = up.Z;	m_Orientation._33 = orientation.Z;	m_Orientation._34 = camera.Z;
	m_Orientation._41 = 0.0f;	m_Orientation._42 = 0.0f;	m_Orientation._43 = 0.0f;			m_Orientation._44 = 1.0f;
}
示例#8
0
CVector3D CThinLens::Ray_Direction(CPoint2D _sp, CPoint2D _lp) const {
    CVector3D direction;
    CPoint2D p;
    p.x = _sp.x * m_f / m_d;
    p.y = _sp.y * m_f / m_d;

    direction = (p.x - _lp.x) * m_u + (p.y - _lp.y) * m_v - m_f * m_w;
    direction.Normalize();

    return direction;
}
//----------------------------------------------------------------------------------------
CVector3D CParallelProjectionGeometry2D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex /* = 0 */)
{
	CVector3D vOutput;

	float32 fProjectionAngle = getProjectionAngle(_iProjectionIndex);

	vOutput.setX(cosf(fProjectionAngle));
	vOutput.setY(sinf(fProjectionAngle));
	vOutput.setZ(0.0f);

	return vOutput;
}
示例#10
0
 CQuaternion::CQuaternion(const CEulerRotation & oRot) {
    CLog("math","CQuaternion::Constructor (CEulerRotation)",LL_OBJECT);
    CEulerType::EEulerAxis NextAngle[] = {CEulerType::EU_Y_AXIS, 
                                          CEulerType::EU_Z_AXIS, 
                                          CEulerType::EU_X_AXIS, 
                                          CEulerType::EU_Y_AXIS};
    CVector3D oEulerAngles = oRot.Angles();
    CEulerType oType = oRot.Type();
    int iFirstAxis = oType.InnerAxis();	
    int iSecondAxis = NextAngle[iFirstAxis + (oType.OddParity() ? 1 : 0)];
    int iThirdAxis = NextAngle[iFirstAxis + 1 - (oType.OddParity() ? 1 : 0)];
    if (oType.RotatingFrame()) {
       double dTemp = oEulerAngles.X();
       oEulerAngles.X() = oEulerAngles.Z();
       oEulerAngles.Z() = dTemp;
    }
    if (oType.OddParity()) {
       oEulerAngles.Y() = -oEulerAngles.Y();
    }	
    double dHF = oEulerAngles.X() * 0.5;
    double dHS = oEulerAngles.Y() * 0.5;
    double dHT = oEulerAngles.Z() * 0.5;
    double dCHF = cos(dHF);
    double dCHS = cos(dHS);
    double dCHT = cos(dHT);
    double dSHF = sin(dHF);
    double dSHS = sin(dHS);
    double dSHT = sin(dHT);
    double dCHFxCHT = dCHF * dCHT;
    double dCHFxSHT = dCHF * dSHT;
    double dSHFxCHT = dSHF * dCHT;
    double dSHFxSHT = dSHF * dSHT;
    double a[3];
    if (oType.Repetition()) {
       a[iFirstAxis]  = dCHS * (dCHFxSHT + dSHFxCHT);
       a[iSecondAxis] = dSHS * (dCHFxCHT + dSHFxSHT);
       a[iThirdAxis]  = dSHS * (dCHFxSHT - dSHFxCHT);
       m_dScalar      = dCHS * (dCHFxCHT - dSHFxSHT);
    }
    else {
       a[iFirstAxis]  = dCHS * dSHFxCHT - dSHS * dCHFxSHT;
       a[iSecondAxis] = dCHS * dSHFxSHT + dSHS * dCHFxCHT;
       a[iThirdAxis]  = dCHS * dCHFxSHT - dSHS * dSHFxCHT;
       m_dScalar      = dCHS * dCHFxCHT + dSHS * dSHFxSHT;
    }
    if (oType.OddParity()) {
       a[iSecondAxis] = -a[iSecondAxis];
    }	
    m_oVector.FromDouble(a[0], a[1], a[2]);
    Normalise();
    return;
 } //CQuaternion(const CEulerRotation & oRot)
示例#11
0
float CMatrix3D::GetYRotation() const
{
	// Project the X axis vector onto the XZ plane
	CVector3D axis = -GetLeft();
	axis.Y = 0;

	// Normalise projected vector

	float len = axis.Length();
	if (len < 0.0001f)
		return 0.f;
	axis *= 1.0f/len;

	// Negate the return angle to match the SetYRotation convention
	return -atan2(axis.Z, axis.X);
示例#12
0
void	CalcNormal(CPoint3D v[3], CVector3D &out)
{
	CVector3D v1,v2;
	//static const int x = 0;
	//static const int y = 1;
	//static const int z = 2;

	// Calculate two vectors from the three points
	//v1.dx = v[0].x - v[1].x;
	//v1.dy = v[0].y - v[1].y;
	//v1.dz = v[0].z - v[1].z;
	v1=v[0]-v[1];

	//v2.dx = v[1].x - v[2].x;
	//v2.dy = v[1].y - v[2].y;
	//v2.dz = v[1].z - v[2].z;
	v2=v[1]-v[2];

	// Take the cross product of the two vectors to get
	// the normal vector which will be stored in out
	//out.dx = v1.dy*v2.dz - v1.dz*v2.dy;
	//out.dy = v1.dz*v2.dx - v1.dx*v2.dz;
	//out.dz= v1.dx*v2.dy - v1.dy*v2.dx;
	out = v1*v2;

	// Normalize the vector (shorten length to one)
	out.Normalize();
}
示例#13
0
void CGameView::ResetCameraAngleZoom()
{
	CCamera targetCam = m->ViewCamera;
	SetupCameraMatrixNonSmooth(m, &targetCam.m_Orientation);

	// Compute the zoom adjustment to get us back to the default
	CVector3D forwards = targetCam.m_Orientation.GetIn();

	CVector3D pivot = GetSmoothPivot(targetCam);
	CVector3D delta = pivot - targetCam.m_Orientation.GetTranslation();
	float dist = delta.Dot(forwards);
	m->Zoom.AddSmoothly(m->ViewZoomDefault - dist);

	// Reset orientations to default
	m->RotateX.SetValueSmoothly(DEGTORAD(m->ViewRotateXDefault));
	m->RotateY.SetValueSmoothly(DEGTORAD(m->ViewRotateYDefault));
}
示例#14
0
void TerrainOverlay::RenderTile(const CColor& colour, bool draw_hidden, ssize_t i, ssize_t j)
{
	// TODO: if this is unpleasantly slow, make it much more efficient
	// (e.g. buffering data and making a single draw call? or at least
	// far fewer calls than it makes now)

	if (draw_hidden)
	{
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_CULL_FACE);
	}
	else
	{
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_CULL_FACE);
	}
	
#if CONFIG2_GLES
#warning TODO: implement TerrainOverlay::RenderTile for GLES
#else

	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	CVector3D pos;
	glBegin(GL_TRIANGLES);
		glColor4fv(colour.FloatArray());
		if (m_Terrain->GetTriangulationDir(i, j))
		{
			m_Terrain->CalcPosition(i,   j,   pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i+1, j,   pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i,   j+1, pos); glVertex3fv(pos.GetFloatArray());

			m_Terrain->CalcPosition(i+1, j,   pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i+1, j+1, pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i,   j+1, pos); glVertex3fv(pos.GetFloatArray());
		}
		else
		{
			m_Terrain->CalcPosition(i,   j,   pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i+1, j,   pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i+1, j+1, pos); glVertex3fv(pos.GetFloatArray());

			m_Terrain->CalcPosition(i+1, j+1, pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i,   j+1, pos); glVertex3fv(pos.GetFloatArray());
			m_Terrain->CalcPosition(i,   j,   pos); glVertex3fv(pos.GetFloatArray());
		}
	glEnd();

#endif
}
示例#15
0
文件: CSoundBase.cpp 项目: 2asoft/0ad
void CSoundBase::SetDirection(const CVector3D& direction)
{
	if ( m_ALSource )
	{
		CScopeLock lock(m_ItemMutex);
		alSourcefv(m_ALSource, AL_DIRECTION, direction.GetFloatArray());
		AL_CHECK;
	}
}
示例#16
0
文件: CSoundBase.cpp 项目: 2asoft/0ad
void CSoundBase::SetLocation (const CVector3D& position)
{
	if ( m_ALSource != 0 )
	{
		CScopeLock lock(m_ItemMutex);
		alSourcefv(m_ALSource,AL_POSITION, position.GetFloatArray());
		AL_CHECK;
	}
}
示例#17
0
CVector3D CModelDef::SkinNormal(const SModelVertex& vtx,
								const CMatrix3D newPoseMatrices[])
{
	// To be correct, the normal vectors apparently need to be multiplied by the
	// inverse of the transpose. Unfortunately inverses are slow.
	// If a matrix is orthogonal, M * M^T = I and so the inverse of the transpose
	// is the original matrix. But that's not entirely relevant here, because
	// the bone matrices include translation components and so they're not
	// orthogonal.
	// But that's okay because we have
	//   M = T * R
	// and want to find
	//   n' = (M^T^-1) * n
	//      = (T * R)^T^-1 * n
	//      = (R^T * T^T)^-1 * n
	//      = (T^T^-1 * R^T^-1) * n
	// R is indeed orthogonal so R^T^-1 = R. T isn't orthogonal at all.
	// But n is only a 3-vector, and from the forms of T and R (which have
	// lots of zeroes) I can convince myself that replacing T with T^T^-1 has no
	// effect on anything but the fourth component of M^T^-1 - and the fourth
	// component is discarded since it has no effect on n', and so we can happily
	// use n' = M*n.
	//
	// (This isn't very good as a proof, but it's better than assuming M is
	// orthogonal when it's clearly not.)

	CVector3D result (0, 0, 0);

	for (int i = 0; i < SVertexBlend::SIZE && vtx.m_Blend.m_Bone[i] != 0xff; ++i)
	{
		result += newPoseMatrices[vtx.m_Blend.m_Bone[i]].Rotate(vtx.m_Norm) * vtx.m_Blend.m_Weight[i];
	}
	
	// If there was more than one influence, the result is probably not going
	// to be of unit length (since it's a weighted sum of several independent
	// unit vectors), so we need to normalise it.
	// (It's fairly common to only have one influence, so it seems sensible to
	// optimise that case a bit.)
	if (vtx.m_Blend.m_Bone[1] != 0xff) // if more than one influence
		result.Normalize();

	return result;
}
示例#18
0
void CBoundingBoxAligned::Transform(const CMatrix3D& transform, CBoundingBoxOriented& result) const
{
	// The idea is this: compute the corners of this bounding box, transform them according to the specified matrix,
	// then derive the box center, orientation vectors, and half-sizes.
	// TODO: this implementation can be further optimized; see Philip's comments on http://trac.wildfiregames.com/ticket/914
	const CVector3D& pMin = m_Data[0];
	const CVector3D& pMax = m_Data[1];

	// Find the corners of these bounds. We only need some of the corners to derive the information we need, so let's 
	// not actually compute all of them. The corners are numbered starting from the minimum position (m_Data[0]), going
	// counter-clockwise in the bottom plane, and then in the same order for the top plane (starting from the corner
	// that's directly above the minimum position). Hence, corner0 is pMin and corner6 is pMax, so we don't need to
	// custom-create those.
	
	CVector3D corner0; // corner0 is pMin, no need to copy it
	CVector3D corner1(pMax.X, pMin.Y, pMin.Z);
	CVector3D corner3(pMin.X, pMin.Y, pMax.Z);
	CVector3D corner4(pMin.X, pMax.Y, pMin.Z);
	CVector3D corner6; // corner6 is pMax, no need to copy it

	// transform corners to world space
	corner0 = transform.Transform(pMin); // = corner0
	corner1 = transform.Transform(corner1);
	corner3 = transform.Transform(corner3);
	corner4 = transform.Transform(corner4);
	corner6 = transform.Transform(pMax); // = corner6

	// Compute orientation vectors, half-size vector, and box center. We can get the orientation vectors by just taking
	// the directional vectors from a specific corner point (corner0) to the other corners, once in each direction. The
	// half-sizes are similarly computed by taking the distances of those sides and dividing them by 2. Finally, the 
	// center is simply the middle between the transformed pMin and pMax corners.

	const CVector3D sideU(corner1 - corner0);
	const CVector3D sideV(corner4 - corner0);
	const CVector3D sideW(corner3 - corner0);

	result.m_Basis[0] = sideU.Normalized();
	result.m_Basis[1] = sideV.Normalized();
	result.m_Basis[2] = sideW.Normalized();

	result.m_HalfSizes = CVector3D(
		sideU.Length()/2.f,
		sideV.Length()/2.f,
		sideW.Length()/2.f
	);

	result.m_Center = (corner0 + corner6) * 0.5f;
}
示例#19
0
//! intersection of line and plane
bool
CMathGeom3D::
LinePlaneIntersect(const CVector3D &vector1, const CVector3D &vector2,
                   const CVector3D &normal, double normalc, CVector3D &ipoint, double &iparam)
{
  CVector3D direction = vector2 - vector1;

  double d1 = direction.dotProduct(normal);

  if (fabs(d1) < CMathGen::EPSILON_E6)
    return false;

  double d2 = vector1.dotProduct(normal);

  iparam = (normalc - d2)/d1;
  ipoint = vector1 + direction*iparam;

  return true;
}
void CClassifyGrid::GetNeighbor( PointData & point, int dis, CClassifyChunk * chunk, int x, int y )
{
	m_vecPointData.clear();
	double distance = m_dbGridLength * dis;
	double distance2 = distance * distance;

	for ( int xx = x - dis; xx <= x + dis; xx++ )
		for ( int yy = y - dis; yy <= y + dis; yy++ ) {
			int i = xx;
			int j = yy;
			CClassifyChunk * data_chunk = chunk;
			while ( i < 0 && data_chunk != NULL ) {
				i += m_nUnitNumber[ 0 ];
				data_chunk = InBound( data_chunk->m_iX - 1, data_chunk->m_iY ) ? m_vecPointer[ Index( data_chunk->m_iX - 1, data_chunk->m_iY ) ] : NULL;
			}
			while ( i > m_nUnitNumber[ 0 ] - 1 && data_chunk != NULL ) {
				i -= m_nUnitNumber[ 0 ];
				data_chunk = InBound( data_chunk->m_iX + 1, data_chunk->m_iY ) ? m_vecPointer[ Index( data_chunk->m_iX + 1, data_chunk->m_iY ) ] : NULL;
			}
			while ( j < 0 && data_chunk != NULL ) {
				j += m_nUnitNumber[ 1 ];
				data_chunk = InBound( data_chunk->m_iX, data_chunk->m_iY - 1 ) ? m_vecPointer[ Index( data_chunk->m_iX, data_chunk->m_iY - 1 ) ] : NULL;
			}
			while ( j > m_nUnitNumber[ 1 ] - 1 && data_chunk != NULL ) {
				j -= m_nUnitNumber[ 1 ];
				data_chunk = InBound( data_chunk->m_iX, data_chunk->m_iY + 1 ) ? m_vecPointer[ Index( data_chunk->m_iX, data_chunk->m_iY + 1 ) ] : NULL;
			}

			if ( data_chunk != NULL ) {
				PointDataVector & cell_vector = data_chunk->m_vecGridIndex[ data_chunk->Index( i, j ) ];
				for ( int k = 0; k < ( int )cell_vector.size(); k++ ) {
					CVector3D diff = point.v - ( cell_vector[ k ] )->v;
					if ( diff.length2() < distance2 ) {
						m_vecPointData.push_back( cell_vector[ k ] );
					}
				}
			}
		}
}
示例#21
0
文件: GeomCalc.cpp 项目: vujn/chenan
 // if the point is on the left of the triangle, then it is in the triangle
BOOL CPoint3D::IsInTheTriangle(CPoint3D p1, CPoint3D p2, CPoint3D p3) const
{
	CVector3D normal = (p2-p1)*(p3-p2);
	normal.Normalize();
	if (	this->IsAtTheLeftOf(p1, p2, normal)==0 ||
			this->IsAtTheLeftOf(p2, p3, normal)==0 ||
			this->IsAtTheLeftOf(p3, p1, normal)==0)
	{
		return 0;				//one the triangle's side
	}
	else
	{
		if (	this->IsAtTheLeftOf(p1, p2, normal)==1 &&
				this->IsAtTheLeftOf(p2, p3, normal)==1 &&
				this->IsAtTheLeftOf(p3, p1, normal)==1	)
		{
			return 1;			//in the triangle
		}
		else
			return -1;			//out the triangle
	}
}
//rotate the camera angleInc radians around a unit vector
void CGraphicsCamera::Rotate( CVector3D axis, double angleInc )
{
	CQuaternion quat( angleInc, axis.normalize() );
	double m[4][4] = {0.};
	quat.QuatToMat( m );
	CVector3D v1( m_pos, m_focalPt );
	//multiply our view vector by the rotation matrix
	v1 = v1*m;
	//update our position
	m_pos = CPoint3D( v1.x + m_focalPt.x, v1.y + m_focalPt.y, v1.z + m_focalPt.z );
	//update our camera's up vector
	m_up = m_up*m;
}
示例#23
0
Noise3D::Noise3D(int f, int v) : freq(f), vfreq(v) 
{
	grads = new CVector3D**[freq];
	for(int i=0; i<freq; i++) 
	{
		grads[i] = new CVector3D*[freq];
		for(int j=0; j<freq; j++) 
		{
			grads[i][j] = new CVector3D[vfreq];
			for(int k=0; k<vfreq; k++) 
			{
				CVector3D vec;
				do {
					vec = CVector3D(2*randFloat()-1, 2*randFloat()-1, 2*randFloat()-1);
				}
				while(vec.LengthSquared() > 1 || vec.LengthSquared() < 0.1);
				vec.Normalize();
				grads[i][j][k] = CVector3D(vec.X, vec.Y, vec.Z);
			}
		}
	}
}
示例#24
0
文件: GeomCalc.cpp 项目: vujn/chenan
//modified by wangxin 
CMatrix3D CMatrix3D::CreateRotateMatrix( double da, CVector3D bv )
{
	bv.Normalize();
	CMatrix3D matrix;
	matrix.a[0] = bv.dx*bv.dx*(1-cos(da))+cos(da);
	matrix.a[5] = bv.dy*bv.dy*(1-cos(da))+cos(da);
	matrix.a[10] = bv.dz*bv.dz*(1-cos(da))+cos(da);
	matrix.a[1] = bv.dx*bv.dy*(1-cos(da))+bv.dz*sin(da);
	matrix.a[4] = bv.dx*bv.dy*(1-cos(da))-bv.dz*sin(da);
	matrix.a[2] = bv.dx*bv.dz*(1-cos(da))-bv.dy*sin(da);
	matrix.a[8] = bv.dx*bv.dz*(1-cos(da))+bv.dy*sin(da);
	matrix.a[6] = bv.dy*bv.dz*(1-cos(da))+bv.dx*sin(da);
	matrix.a[9] = bv.dy*bv.dz*(1-cos(da))-bv.dx*sin(da); 
	matrix.a[3] = matrix.a[7] = matrix.a[11] = matrix.a[12] = matrix.a[13] = matrix.a[14] = 0;
	matrix.a[15] = 1;
	return matrix;
}
示例#25
0
///////////////////////////////////////////////////////////////////////////////
// CalcNormal: calculate the world space normal of the vertex at (i,j)
void CTerrain::CalcNormal(ssize_t i, ssize_t j, CVector3D& normal) const
{
	CVector3D left, right, up, down;

	// Calculate normals of the four half-tile triangles surrounding this vertex:

	// get position of vertex where normal is being evaluated
	CVector3D basepos;
	CalcPosition(i, j, basepos);

	if (i > 0) {
		CalcPosition(i-1, j, left);
		left -= basepos;
		left.Normalize();
	}

	if (i < m_MapSize-1) {
		CalcPosition(i+1, j, right);
		right -= basepos;
		right.Normalize();
	}

	if (j > 0) {
		CalcPosition(i, j-1, up);
		up -= basepos;
		up.Normalize();
	}

	if (j < m_MapSize-1) {
		CalcPosition(i, j+1, down);
		down -= basepos;
		down.Normalize();
	}

	CVector3D n0 = up.Cross(left);
	CVector3D n1 = left.Cross(down);
	CVector3D n2 = down.Cross(right);
	CVector3D n3 = right.Cross(up);

	// Compute the mean of the normals
	normal = n0 + n1 + n2 + n3;
	float nlen=normal.Length();
	if (nlen>0.00001f) normal*=1.0f/nlen;
}
示例#26
0
//! intersection of line and plane
bool
CMathGeom3D::
LinePlaneIntersect(const CPoint3D &point, const CVector3D &direction,
                   const CNPlane3D &normal, CPoint3D &ipoint, double &iparam)
{
  double d1 = direction.dotProduct(normal.getDirection());

  if (fabs(d1) < CMathGen::EPSILON_E6)
    return false;

  CVector3D vector1(point);

  double d2 = vector1.dotProduct(normal.getDirection());

  iparam = (normal.getScalar() - d2)/d1;
  ipoint = point + direction*iparam;

  return true;
}
bool CGraphicsCamera::MouseMove( const CPoint& delta )
{
	float dx = float( delta.x );
	float dy = float( delta.y );
	CVector3D v1( m_pos, m_focalPt );
	CVector3D right = v1.normalize().cross( m_up );
	CVector3D up = m_up;
	right *= dx;
	up *= dy;
	m_pos = m_pos + up.asPoint3D() + right.asPoint3D();
	m_focalPt = m_focalPt + up.asPoint3D() + right.asPoint3D();

	return true;
}
示例#28
0
文件: Camera.cpp 项目: Gallaecio/0ad
void CCamera::BuildCameraRay(int px, int py, CVector3D& origin, CVector3D& dir) const
{
	CVector3D cPts[4];
	GetCameraPlanePoints(m_FarPlane, cPts);

	// transform to world space
	CVector3D wPts[4];
	for (int i = 0; i < 4; i++)
		wPts[i] = m_Orientation.Transform(cPts[i]);

	// get world space position of mouse point
	float dx = (float)px / (float)g_Renderer.GetWidth();
	float dz = 1 - (float)py / (float)g_Renderer.GetHeight();

	CVector3D vdx = wPts[1] - wPts[0];
	CVector3D vdz = wPts[3] - wPts[0];
	CVector3D pt = wPts[0] + (vdx * dx) + (vdz * dz);

	// copy origin
	origin = m_Orientation.GetTranslation();
	// build direction
	dir = pt - origin;
	dir.Normalize();
}
示例#29
0
//////////////////////////////////////////////////////////////////////////////
// SetupFrame: camera and light direction for this frame
void ShadowMap::SetupFrame(const CCamera& camera, const CVector3D& lightdir)
{
	if (!m->Texture)
		m->CreateTexture();

	CVector3D z = lightdir;
	CVector3D y;
	CVector3D x = camera.m_Orientation.GetIn();
	CVector3D eyepos = camera.m_Orientation.GetTranslation();

	z.Normalize();
	x -= z * z.Dot(x);
	if (x.Length() < 0.001)
	{
		// this is invoked if the camera and light directions almost coincide
		// assumption: light direction has a significant Z component
		x = CVector3D(1.0, 0.0, 0.0);
		x -= z * z.Dot(x);
	}
	x.Normalize();
	y = z.Cross(x);

	// X axis perpendicular to light direction, flowing along with view direction
	m->LightTransform._11 = x.X;
	m->LightTransform._12 = x.Y;
	m->LightTransform._13 = x.Z;

	// Y axis perpendicular to light and view direction
	m->LightTransform._21 = y.X;
	m->LightTransform._22 = y.Y;
	m->LightTransform._23 = y.Z;

	// Z axis is in direction of light
	m->LightTransform._31 = z.X;
	m->LightTransform._32 = z.Y;
	m->LightTransform._33 = z.Z;

	// eye is at the origin of the coordinate system
	m->LightTransform._14 = -x.Dot(eyepos);
	m->LightTransform._24 = -y.Dot(eyepos);
	m->LightTransform._34 = -z.Dot(eyepos);

	m->LightTransform._41 = 0.0;
	m->LightTransform._42 = 0.0;
	m->LightTransform._43 = 0.0;
	m->LightTransform._44 = 1.0;

	m->LightTransform.GetInverse(m->InvLightTransform);
	m->ShadowBound.SetEmpty();

	//
	m->LightspaceCamera = camera;
	m->LightspaceCamera.m_Orientation = m->LightTransform * camera.m_Orientation;
	m->LightspaceCamera.UpdateFrustum();
}
CVector3D CGraphicsCamera::GetRightVector()
{
	CVector3D forward = GetForwardVector();
	return forward.cross( m_up ).normalize();
}