コード例 #1
0
BOOL CRVTrackerDrawPoly::OnRotate()
{
	// Get the brush
	CEditBrush *pBrush = &m_pView->DrawingBrush();

	// Make sure we've got at least three points specified
	if (pBrush->m_Points.GetSize() < 3)
		return FALSE;

	// The origin's point #1
	CVector vOrigin = pBrush->m_Points[0];
	// The original rotation direction's point #2
	CVector vBase = pBrush->m_Points[1];
	// The new rotation's point #3
	CVector vNew = pBrush->m_Points[2];

	// Get the base direction
	CVector vBaseDir = vBase - vOrigin;
	float fBaseMag = vBaseDir.Mag();
	// Don't allow duplicate points
	if (fBaseMag < 0.01f)
		return TRUE;
	vBaseDir *= 1.0f / fBaseMag;

	// Get the rotation direction
	CVector vNewDir = vNew - vOrigin;
	float fNewMag = vNewDir.Mag();
	// Don't allow duplicate points
	if (fNewMag < 0.01f)
		return TRUE;
	vNewDir *= 1.0f / fNewMag;

	// Get the rotation axis
	CVector vRotAxis = vNewDir.Cross(vBaseDir);

	// Get the sin of the angle from the cross product
	float fRotAngle = vRotAxis.Mag();

	// Don't bother if the angle's 0...
	if (fRotAngle == 0.0f)
		return TRUE;

	// Normalize the axis
	vRotAxis *= 1.0f / fRotAngle;

	// Get the actual angle
	fRotAngle = (float)asin(fRotAngle);

	// Handle obtuse angles..
	if (vBaseDir.Dot(vNewDir) < 0.0f)
		fRotAngle = MATH_PI - fRotAngle;

	LTMatrix mRotation;
	// Get the rotation matrix
	mRotation.SetupRot(vRotAxis, fRotAngle);

	// Set up an undo..
	CEditRegion *pRegion = m_pView->GetRegion();
	PreActionList actionList;
	for (uint32 nUndoLoop = 0; nUndoLoop < pRegion->m_Selections; ++nUndoLoop)
		actionList.AddTail(new CPreAction(ACTION_MODIFYNODE, pRegion->m_Selections[nUndoLoop]));
	m_pView->GetRegionDoc()->Modify(&actionList, TRUE);

	// If we're in geometry mode..
	if (m_pView->GetEditMode() == GEOMETRY_EDITMODE)
	{
		// Get the selected vertices
		CVertRefArray vertList;
		m_pView->GetSelectedVerts(vertList);
		// Rotate 'em
		for (uint32 nVertLoop = 0; nVertLoop < vertList.GetSize(); ++nVertLoop)
		{
			CVertRef vert = vertList[nVertLoop];
			if (!vert.IsValid())
				continue;
			vert() -= vOrigin;
			mRotation.Apply(vert());
			vert() += vOrigin;
		}
	}
	else
	{
		// Otherwise, rotate all the selected nodes
		for (uint32 nNodeLoop = 0; nNodeLoop < pRegion->m_Selections.GetSize( ); ++nNodeLoop)
		{
			pRegion->m_Selections[nNodeLoop]->Rotate(mRotation, vOrigin);
		}

		// Update the selection box since stuff rotated...
		m_pView->GetRegionDoc()->UpdateSelectionBox();
	}

	return TRUE;
}
コード例 #2
0
// returns true if intersection happened, plus fills hit dist param with 
// the parametric position of the intersection on the ray dir. 
// the obb must be within ray-origin + ray-dir. So ray-dir isn't normalized.
// source : Real-time rendering moller&haines
inline bool i_OrientedBoundingBoxTest(const ModelOBB &mobb, 
									  const LTransform &tf, 
									  const LTVector &origin, 
									  const LTVector &dir, 
									  float &t)
{
	float tmin = -999999999999.0f;
	float tmax = 999999999999.0f;

	LTVector vObbPos = mobb.m_Pos;

	// Setup our OBB's translated position
	LTMatrix obb_mat;
	obb_mat.Identity();
	obb_mat.SetBasisVectors( &tf.m_Rot.Right(), &tf.m_Rot.Up(), &tf.m_Rot.Forward() );
	obb_mat.SetTranslation( tf.m_Pos );
	obb_mat.Apply(vObbPos);  

	LTVector p = vObbPos - origin;
	float e ;
	float f;
	float hi;
	float t1,t2;
	
	// Setup OBB rotation tranforms
	LTMatrix mObbMat;
	mObbMat.SetBasisVectors(&mobb.m_Basis[0], &mobb.m_Basis[1], &mobb.m_Basis[2]);
	
	// Get matrix of our Node's rotation
	LTMatrix mTrMat;
	tf.m_Rot.ConvertToMatrix(mTrMat);
	
	// Apply our node rotation to our obb rotation
	mTrMat.Apply(mObbMat);
	
	// Get our translated basis vectors
	LTVector axis[3];
	mObbMat.GetBasisVectors(&axis[0], &axis[1], &axis[2]);

	LTVector vSize =  mobb.m_Size * 0.5f ; // we want the 1/2 size of the box.

	for( int i = 0 ; i < 3 ; i++ )
	{
		e = axis[i].Dot(p);  
		f = axis[i].Dot(dir);		
		hi= vSize[i]  ; // 

		if( fabs(f) > 0.00015 )
		{
			t1 = ( e + hi ) / f ;
			t2 = ( e - hi ) / f ;
			if( t1 > t2 ) {float v = t2 ; t2 = t1 ; t1 = v ; }
			if(t1 > tmin ) {tmin = t1 ;}
			if(t2 < tmax ) {tmax = t2 ;}
			if(tmin > tmax ) { 
				 return false ; }
			if(tmax < 0  ) { 
				 return false ; }
		}
		else if( ((-e - hi) > 0 ) || ( (-e + hi) < 0 )) { t = 0 ; return false ; }
	}

	if( tmin > 0 ) { t = tmin ;  return true ; }
	else { t = tmax ;  return true ;}
}
コード例 #3
0
ファイル: PrefabMgr.cpp プロジェクト: Joincheng/lithtech
static void RecurseAndGrowDims(CWorldNode *pNode, LTVector &vMin, LTVector &vMax, LTMatrix& mTransMat)
{
	//sanity check
	if(pNode == NULL)
	{
		return;
	}

	// Grow the dims for this node
	switch (pNode->GetType())
	{
		case Node_Object :
		{
			CBaseEditObj *pObject = pNode->AsObject();
			LTVector vCenter;
			mTransMat.Apply(pObject->GetPos(), vCenter);

			//always include at least the object center
			VEC_MIN(vMin, vMin, vCenter);
			VEC_MAX(vMax, vMax, vCenter);

#ifdef DIRECTEDITOR_BUILD			
			
			//see if there are other dims we need
			for (uint32 nCurDim = pObject->GetNumDims(); nCurDim > 0; --nCurDim)
			{
				LTVector vDims = *pObject->GetDim(nCurDim - 1);
				LTVector vObjMin = vCenter - vDims;
				LTVector vObjMax = vCenter + vDims;
				VEC_MIN(vMin, vMin, vObjMin);
				VEC_MAX(vMax, vMax, vObjMax);
			}
#endif
		}
		break;
		case Node_Brush:
		{
			CEditBrush *pBrush = pNode->AsBrush();
			
			CBoundingBox BBox = pBrush->CalcBoundingBox();

			//transform the bounding box
			LTVector vBoxMin, vBoxMax;
			mTransMat.Apply(BBox.m_Min, vBoxMin);
			mTransMat.Apply(BBox.m_Max, vBoxMax);

			VEC_MIN(vMin, vMin, vBoxMin);
			VEC_MAX(vMax, vMax, vBoxMax);
		}
		break;
		case Node_PrefabRef:
		{
			//create the new transformation matrix
			LTMatrix mRot;
			::gr_SetupMatrixEuler(pNode->GetOr(), mRot.m);

			LTMatrix mTranslate;
			mTranslate.Identity();
			mTranslate.SetTranslation(pNode->GetPos());

			LTMatrix mNewTransMat = mTransMat * mTranslate * mRot;
			RecurseAndGrowDims((CWorldNode*)((CPrefabRef*)pNode)->GetPrefabTree(), vMin, vMax, mNewTransMat);
		}
		break;
	}

	// Go through the children
	GPOS iFinger = pNode->m_Children.GetHeadPosition();
	while (iFinger)
	{
		CWorldNode *pChild = pNode->m_Children.GetNext(iFinger);
		RecurseAndGrowDims(pChild, vMin, vMax, mTransMat);
	}
}