Ejemplo n.º 1
0
//----------------------------------------------------------------------------
bool TriggerActor::IsPointIn(const PX2::APoint &point) const
{
	Transform trans = WorldTransform;
	APoint localPoint = trans.Inverse() * point;

	if (mAreaType == AT_SPHERE)
	{
		Sphere3f sphere;
		sphere.Radius = mAreaParam[0];

		if (InSphere<float>(localPoint, sphere))
			return true;
	}
	else if (mAreaType == AT_BOX)
	{
		Box3f box;
		box.Extent[0] = mAreaParam[0];
		box.Extent[1] = mAreaParam[1];
		box.Extent[2] = mAreaParam[2];

		if (localPoint.X() >= -box.Extent[0] &&
			localPoint.Y() >= -box.Extent[1] &&
			localPoint.Z() >= -box.Extent[2] &&
			localPoint.X() <= box.Extent[0] &&
			localPoint.Y() <= box.Extent[1] &&
			localPoint.Z() <= box.Extent[2])
			return true;
	}

	return false;
}
Ejemplo n.º 2
0
//----------------------------------------------------------------------------
Vector2f RenderStep::PointWorldToViewPort(const APoint &point,
	bool *isInBack)
{
	Rectf viewPort = mViewPort;
	if (viewPort.IsEmpty())
		viewPort = Rectf(0.0f, 0.0f, mSize.Width, mSize.Height);

	HMatrix matProjView = mCamera->GetProjectionMatrix() * mCamera->GetViewMatrix();
	HPoint hPoint(point.X(), point.Y(), point.Z(), point.W());
	HPoint tempPoint = matProjView * hPoint;

	if (isInBack)
	{
		if (tempPoint.Z() <= 0)
			*isInBack = true;
		else
			*isInBack = false;
	}

	float wInv = 1.0f / tempPoint.W();

	//投影坐标范围为[-1,1]要变成[0,1]
	Vector2f screenPoint;
	screenPoint.X() = (1.0f + tempPoint.X()*wInv) / 2.0f;
	screenPoint.Y() = (1.0f + tempPoint.Y()*wInv) / 2.0f;

	//投影坐标范围为[0,1]要变成视口内坐标
	screenPoint.X() = viewPort.Left + screenPoint.X()*viewPort.Width();
	screenPoint.Y() = viewPort.Bottom + screenPoint.Y()*viewPort.Height();

	return screenPoint;
}
//----------------------------------------------------------------------------
void ApplicationBase::OnProjectSize (int width, int height)
{
	mUIManager->GetDefaultView()->SetSize((float)width, (float)height);
	APoint curPos = mUIManager->GetDefaultView()->GetCamera()->GetPosition();
	mUIManager->GetDefaultView()->GetCamera()->SetPosition(APoint((float)width/2.0f, 
		curPos.Y(), (float)height/2.0f));
}
Ejemplo n.º 4
0
//----------------------------------------------------------------------------
Vector2f Renderer::PointWorldToViewPort (const  APoint &point, bool *isInBack)
{
	HMatrix matProjView = GetProjectionMatrix() * GetViewMatrix();
	HPoint hPoint(point.X(), point.Y(), point.Z(), point.W());
	HPoint tempPoint = matProjView * hPoint;

	if (isInBack)
	{
		if (tempPoint.Z() <= 0)
			*isInBack = true;
		else
			*isInBack = false;
	}

	float wInv = 1.0f / tempPoint.W();

	//投影坐标范围为[-1,1]要变成[0,1]
	Vector2f screenPoint;
	screenPoint.X() = (1.0f + tempPoint.X()*wInv)/2.0f;
	screenPoint.Y() = (1.0f + tempPoint.Y()*wInv)/2.0f;

	//投影坐标范围为[0,1]要变成视口内坐标
	int viewX, viewY, viewW, viewH;
	GetViewport(viewX, viewY, viewW, viewH);

	screenPoint.X() = viewX + screenPoint.X()*viewW;
	screenPoint.Y() = viewY + screenPoint.Y()*viewH;

	return screenPoint;
}
//----------------------------------------------------------------------------
bool InputPushTransformController::TransScope(APoint &pos)
{
	if (mMinPos.X() > mMaxPos.X() || mMinPos.Y() > mMaxPos.Y() ||
		mMinPos.Z() > mMaxPos.Z() || mMinPos == mMaxPos)
	{
		return false;
	}

	if (mMinPos.X() > pos.X())
	{
		pos.X() = mMinPos.X();
		mVelocity.X() = 0.0f;
	}

	if (mMinPos.Y() > pos.Y())
	{
		pos.Y() = mMinPos.Y();
		mVelocity.Y() = 0.0f;
	}

	if (mMinPos.Z() > pos.Z())
	{
		pos.Z() = mMinPos.Z();
		mVelocity.Z() = 0.0f;
	}

	if (pos.X() > mMaxPos.X())
	{
		pos.X() = mMaxPos.X();
		mVelocity.X() = 0.0f;
	}

	if (pos.Y() > mMaxPos.Y())
	{
		pos.Y() = mMaxPos.Y();
		mVelocity.Y() = 0.0f;
	}

	if (pos.Z() > mMaxPos.Z())
	{
		pos.Z() = mMaxPos.Z();
		mVelocity.Z() = 0.0f;
	}

	return true;
}
Ejemplo n.º 6
0
//----------------------------------------------------------------------------
void Transform::SetScale (const APoint& scale)
{
	if (scale.X()==scale.Y() && scale.Y()==scale.Z())
	{
		SetUniformScale(scale.X());
	}
	else
	{
		assertion(mIsRSMatrix, "Matrix is not a rotation\n");
		assertion(scale[0] != 0.0f && scale[1] != 0.0f && scale[2] != 0.0f,
			"Scales must be nonzero\n");

		mScale = scale;
		mIsIdentity = false;
		mIsUniformScale = false;
		UpdateHMatrix();
	}
}
Ejemplo n.º 7
0
//-----------------------------------------------------------------------------
wxAPoint3Property::wxAPoint3Property (const wxString &label, const wxString &name,
									  const APoint &value)
									  :
wxPGProperty(label, name)
{
	SetValue(APointToVariant(value));
	AddPrivateChild(new wxFloatProperty(wxT("X"),wxPG_LABEL,value.X()));
	AddPrivateChild(new wxFloatProperty(wxT("Y"),wxPG_LABEL,value.Y()));
	AddPrivateChild(new wxFloatProperty(wxT("Z"),wxPG_LABEL,value.Z()));
}
Ejemplo n.º 8
0
//----------------------------------------------------------------------------
void EU_CanvasStage::_MoveCamera(float horz, float vert)
{
	if (!Project::GetSingletonPtr()) return;

	Scene *scene = PX2_PROJ.GetScene();
	if (!scene) return;

	if (mStageCameraNode)
	{
		APoint position = mStageCameraNode->LocalTransform.GetTranslate();
		AVector rVector;
		AVector dVector;
		AVector uVector;
		mStageCameraNode->LocalTransform.GetRDUVector(rVector, dVector, uVector);

		if (mViewType == VT_PERSPECTIVE)
		{
			dVector.Z() = 0.0f;
			dVector.Normalize();
			rVector.Z() = 0.0f;
			rVector.Normalize();
			position += dVector * vert;
			position -= rVector * horz;
		}
		else if (mViewType == VT_TOP)
		{
			position.Y() += vert * 1.0f;
			position.X() -= horz * 1.0f;
		}
		else if (mViewType == VT_LEFT)
		{
			position.Z() += vert * 1.0f;
			position.Y() += horz * 1.0f;
		}
		else if (mViewType == VT_FRONT)
		{
			position.Z() += vert * 1.0f;
			position.X() -= horz * 1.0f;
		}

		mStageCameraNode->LocalTransform.SetTranslate(position);
	}
}
Ejemplo n.º 9
0
//----------------------------------------------------------------------------
void Actor::SetRotation (APoint &rolate)
{
	mRotation = rolate;

	if (mMovable)
	{
		mMovable->LocalTransform.SetRotate(Matrix3f().MakeEulerXYZ(
			rolate.X(), rolate.Y(), rolate.Z()));
	}
}
//----------------------------------------------------------------------------
void Actor::SetRotation (const APoint &rolate)
{
	if (rolate == mRotation)
		return;

	mRotation = rolate;

	if (mMovable)
	{
		mMovable->LocalTransform.SetRotate(Matrix3f().MakeEulerXYZ(
			rolate.X(), rolate.Y(), rolate.Z()));
	}

	if (mHelpMovable)
	{
		mHelpMovable->LocalTransform.SetRotate(Matrix3f().MakeEulerXYZ(
			rolate.X(), rolate.Y(), rolate.Z()));
	}
}
Ejemplo n.º 11
0
//----------------------------------------------------------------------------
void EditRenderView_Scene::_MoveCamera(float horz, float vert)
{
	Scene *scene = PX2_PROJ.GetScene();
	if (!scene) return;

	CameraActor *camActor = scene->GetUseCameraActor();

	if (camActor)
	{
		APoint position = camActor->LocalTransform.GetTranslate();
		AVector rVector;
		AVector dVector;
		AVector uVector;
		camActor->GetRDUVector(rVector, dVector, uVector);

		if (mViewType == VT_PERSPECTIVE)
		{
			dVector.Z() = 0.0f;
			dVector.Normalize();
			rVector.Z() = 0.0f;
			rVector.Normalize();
			position += dVector * vert;
			position -= rVector * horz;
		}
		else if (mViewType == VT_TOP)
		{
			position.Y() += vert * 1.0f;
			position.X() -= horz * 1.0f;
		}
		else if (mViewType == VT_LEFT)
		{
			position.Z() += vert * 1.0f;
			position.Y() += horz * 1.0f;
		}
		else if (mViewType == VT_FRONT)
		{
			position.Z() += vert * 1.0f;
			position.X() -= horz * 1.0f;
		}

		camActor->LocalTransform.SetTranslate(position);
	}
}
Ejemplo n.º 12
0
//----------------------------------------------------------------------------
void FMODSound::SetPosition (const APoint &position)
{
    FMOD_VECTOR pos;
    pos.x = position.X();
    pos.y = position.Y();
    pos.z = position.Z();

    if (mChannel)
        mChannel->set3DAttributes(&pos, 0);
}
//-----------------------------------------------------------------------------
void MovableTransProperty::OnChange (wxPropertyGridEvent &event)
{
	if (!mProperty)
		return;

	wxPGProperty *id = event.GetProperty();
	const wxString &name = event.GetPropertyName();
	std::string stdName = std::string(name);
	wxVariant variant = id->GetValue();

	if (0 == id)
		return;

	if (variant.IsNull())
		return;

	APoint value;

	if (mPropertyTranslate == id)
	{
		value = APointRefFromVariant(variant);
		mTrans->SetTranslate(value);
	}
	else if (mPropertyRotation == id)
	{
		value = APointRefFromVariant(variant);
		mTrans->SetRotate(Matrix3f().MakeEulerXYZ(
			value.X(), value.Y(), value.Z()));
	}
	else if (mPropertyScale == id)
	{
		value = APointRefFromVariant(variant);
		if (value.X()!=0.0f && value.Y()!=0.0f && value.Z()!=0.0f)
		{
			mTrans->SetScale(value);
		}
	}

	Event *ent = 0;
	ent = EditEventSpace::CreateEventX(EditEventSpace::ObjectTransformChanged);
	ent->SetData<Object*>(mObject);
	EventWorld::GetSingleton().BroadcastingLocalEvent(ent);
}
//----------------------------------------------------------------------------
AVector InputPushTransformController::GetSmallTransDir()
{
	Movable *movable = DynamicCast<Movable>(mObject);
	if (!movable)
		AVector::ZERO;

	APoint curPos = movable->LocalTransform.GetTranslate();

	AVector moveDir = AVector::ZERO;
	if (curPos.X() < mMinPosSmall.X())
	{
		moveDir.X() = mMinPosSmall.X() - curPos.X();
	}

	if (curPos.Y() < mMinPosSmall.Y())
	{
		moveDir.Y() = mMinPosSmall.Y() - curPos.Y();
	}

	if (curPos.Z() < mMinPosSmall.Z())
	{
		moveDir.Z() = mMinPosSmall.Z() - curPos.Z();
	}

	if (curPos.X()>mMaxPosSmall.X())
	{
		moveDir.X() = mMaxPosSmall.X() - curPos.X();
	}

	if (curPos.Y() > mMaxPosSmall.Y())
	{
		moveDir.Y() = mMaxPosSmall.Y() - curPos.Y();
	}

	if (curPos.Z() > mMaxPosSmall.Z())
	{
		moveDir.Z() = mMaxPosSmall.Z() - curPos.Z();
	}

	return moveDir;
}
MovableTransProperty::MovableTransProperty (PropertyPage *parent, 
	const std::string &name, const std::string &tag,
	Transform *trans, Object *obj)
	:
Property(parent, name, tag, Property::PT_TRANSFORM, 0),
	mIsRSMatrix(0),
	mPropertyTranslate(0),
	mPropertyRotation(0),
	mPropertyScale(0),
	mPropertyIsUniformScale(0),
	mTrans(trans),
	mObject(obj)
{
	APoint position;
	APoint rotation;
	APoint scale(1.0f, 1.0f, 1.0f);

	bool isRSMatrix = mTrans->IsRSMatrix();
	if (isRSMatrix)
	{
		position = mTrans->GetTranslate();
		Matrix3f mat = mTrans->GetRotate();
		mat.ExtractEulerXYZ(rotation.X(), rotation.Y(), rotation.Z());
		scale = mTrans->GetScale();
		bool isUniformScale = mTrans->IsUniformScale();

		mProperty = parent->mPage->Append(new wxStringProperty(
			name, tag, wxT("<composed>")) );

		mPropertyTranslate = parent->mPage->AppendIn(mProperty, 
			new wxAPoint3Property("Translate", tag+"Translate",
			position));
		mPropertyRotation = parent->mPage->AppendIn(mProperty, 
			new wxAPoint3Property("Rotate", tag+"Rotate", rotation));
		mPropertyScale = parent->mPage->AppendIn(mProperty, 
			new wxAPoint3Property("Scale", tag+"Scale", scale));

		mPropertyIsUniformScale = parent->mPage->AppendIn(mProperty, 
			new wxBoolProperty("IsUniformScale", tag+"IsUniformScale", isUniformScale));
		mPropertyIsUniformScale->Enable(false);
	}
	else
	{
		mProperty = parent->mPage->Append(new wxStringProperty(
			name, tag, wxT("<composed>")) );

		mIsRSMatrix = parent->mPage->AppendIn(mProperty, 
			new wxBoolProperty("IsRSMatrix", tag+"IsRSMatrix", false));
		mIsRSMatrix->Enable(false);
	}
}
Ejemplo n.º 16
0
//----------------------------------------------------------------------------
void Terrain::AddJunglers (Texture2D *tex, APoint center, float radius,
	int num, float width, float height, float lower)
{
	if (!tex)
		return;

	for (int i=0; i<mNumRows; i++)
	{
		for (int j=0; j<mNumCols; j++)
		{
			GetPage(i, j)->mAddingJObjs.clear();
		}
	}

	for (int i=0; i<num; i++)
	{
		float unitRadius = Mathf::UnitRandom();
		float fX0 = Mathf::SymmetricRandom();
		float fY0 = Mathf::SymmetricRandom();
		AVector normal0(fX0, fY0, 0.0f);
		normal0.Normalize();

		float fX1 = Mathf::SymmetricRandom();
		float fY1 = Mathf::SymmetricRandom();
		AVector normal1(fX1, fY1, 0.0f);
		normal1.Normalize();

		APoint pos = center + normal0*unitRadius*radius;
		pos.Z() = GetHeight(pos.X(), pos.Y()) - lower;

		JObj obj;
		obj.Pos = pos;
		obj.Normal = normal1;
		obj.Width = width;
		obj.Height = height;

		TerrainPage *page = GetCurrentPage(obj.Pos.X(), obj.Pos.Y());
		page->mAddingJObjs.push_back(obj);
	}

	for (int i=0; i<mNumRows; i++)
	{
		for (int j=0; j<mNumCols; j++)
		{
			TerrainPage *page = GetPage(i, j);
			page->AddJunglers(tex, page->mAddingJObjs);
		}
	}
}
Ejemplo n.º 17
0
//-----------------------------------------------------------------------------
int CellSpace::PositionToIndex(const APoint &pos) const
{
	float posA = pos.X();
	float posB = pos.Y();

	int index = (int)(posA / mCellLength) +
		((int)(posB / mCellWidth) * mNumCellsLength);

	if (index > (int)mCells.size() - 1)
		index = (int)mCells.size() - 1;

	if (index < 0)
		index = 0;

	return index;
}
Ejemplo n.º 18
0
//----------------------------------------------------------------------------
void Selection::AddRolate(AVector vec)
{
	for (int i = 0; i < (int)mObjects.size(); i++)
	{
		Movable *mov = DynamicCast<Movable>(mObjects[i]);
		if (mov)
		{
			APoint rotation;
			Matrix3f mat = mov->LocalTransform.GetRotate();
			mat.ExtractEulerZYX(rotation.Z(), rotation.Y(), rotation.X());
			rotation += vec;
			Matrix3f matTrans;
			matTrans.MakeEulerZYX(rotation[2], rotation[1], rotation[0]);
			mov->LocalTransform.SetRotate(matTrans);
			mov->Update(Time::GetTimeInSeconds(), false);
		}
	}

	_UpdateSelect();
}
Ejemplo n.º 19
0
//----------------------------------------------------------------------------
void CurveCtrl::SetCtrlsScale (float xScale, float zScale)
{
    mXScale = xScale;
    mZScale = zScale;

    if (mDragBox)
    {
        APoint scale = mDragBox->LocalTransform.GetScale();
        mDragBox->LocalTransform.SetScale(Float3(xScale, scale.Y(), zScale));
    }

    if (mDragBoxArrive)
    {
        mDragBoxArrive->LocalTransform.SetScale(Float3(xScale, 1.0f, zScale));
    }

    if (mDragBoxLeave)
    {
        mDragBoxLeave->LocalTransform.SetScale(Float3(xScale, 1.0f, zScale));
    }

    OnCtrlChanged(false);
}
Ejemplo n.º 20
0
//----------------------------------------------------------------------------
void RawTerrain::OnCameraMotion ()
{
	assertion(mCamera != 0, "Camera must exist\n");
	if (!mCamera)
	{
		return;
	}

	// 获得地形模型坐标系下相继的方位
	APoint worldEye = mCamera->GetPosition();
	AVector worldDir = mCamera->GetDVector();
	APoint modelEye = WorldTransform.Inverse()*worldEye;
	AVector modelDir = WorldTransform.Inverse()*worldDir;

	// Update the model-space origins of the terrain pages.  Start the
	// process by locating the page that contains the camera.
	float length = mSpacing*(float)(mSize - 1);
	float invLength = 1.0f/length;
	int newCameraCol = (int)Mathf::Floor(modelEye.X()*invLength);
	int newCameraRow = (int)Mathf::Floor(modelEye.Y()*invLength);
	if (newCameraCol != mCameraCol || newCameraRow != mCameraRow)
	{
		mCameraCol = newCameraCol;
		mCameraRow = newCameraRow;

		// Translate page origins for toroidal wraparound.
		int cminO = mCameraCol - mNumCols/2;
		int cminP = cminO % mNumCols;
		if (cminP < 0)
		{
			cminP += mNumCols;
		}

		int rminO = mCameraRow - mNumRows/2;
		int rminP = rminO % mNumRows;
		if (rminP < 0)
		{
			rminP += mNumRows;
		}

		int rO = rminO, rP = rminP;
		for (int row = 0; row < mNumRows; ++row)
		{
			int cO = cminO, cP = cminP;
			for (int col = 0; col < mNumCols; ++col)
			{
				RawTerrainPage* page = mPages[rP][cP];
				Float2 oldOrigin = page->GetOrigin();
				Float2 newOrigin(cO*length, rO*length);
				APoint pageTrn(
					newOrigin[0] - oldOrigin[0],
					newOrigin[1] - oldOrigin[1],
					page->LocalTransform.GetTranslate().Z());
				page->LocalTransform.SetTranslate(pageTrn);

				++cO;
				if (++cP == mNumCols)
				{
					cP = 0;
				}
			}

			++rO;
			if (++rP == mNumRows)
			{
				rP = 0;
			}
		}
		Update();
	}
}
Ejemplo n.º 21
0
//----------------------------------------------------------------------------
bool PlanarShadows::OnKeyDown (unsigned char key, int x, int y)
{
	if (WindowApplication3::OnKeyDown(key, x, y))
	{
		return true;
	}

	switch (key)
	{
	case 'w':
	case 'W':
		mWireState->Enabled = !mWireState->Enabled;
		return true;

	case 'g':
		mUpdateTime += 0.01;
		mBiped->Update(mUpdateTime);
		return true;
	case 'G':
		mUpdateTime = 0.0;
		mBiped->Update(mUpdateTime);
		return true;
	}

	const float delta = 1.0f;
	APoint translate;

	switch (key)
	{
	case 'x':
		translate = mProjectorNode->LocalTransform.GetTranslate();
		translate.X() -= delta;
		mProjectorNode->LocalTransform.SetTranslate(translate);
		mProjectorNode->Update();
		break;
	case 'X':
		translate = mProjectorNode->LocalTransform.GetTranslate();
		translate.X() += delta;
		mProjectorNode->LocalTransform.SetTranslate(translate);
		mProjectorNode->Update();
		break;
	case 'y':
		translate = mProjectorNode->LocalTransform.GetTranslate();
		translate.Y() -= delta;
		mProjectorNode->LocalTransform.SetTranslate(translate);
		mProjectorNode->Update();
		break;
	case 'Y':
		translate = mProjectorNode->LocalTransform.GetTranslate();
		translate.Y() += delta;
		mProjectorNode->LocalTransform.SetTranslate(translate);
		mProjectorNode->Update();
		break;
	case 'z':
		translate = mProjectorNode->LocalTransform.GetTranslate();
		translate.Z() -= delta;
		mProjectorNode->LocalTransform.SetTranslate(translate);
		mProjectorNode->Update();
		break;
	case 'Z':
		translate = mProjectorNode->LocalTransform.GetTranslate();
		translate.Z() += delta;
		mProjectorNode->LocalTransform.SetTranslate(translate);
		mProjectorNode->Update();
		break;
	case 's':
	case 'S':
		// TODO:  Test streaming.
		return true;
	default:
		return false;
	}

	return true;
}
//----------------------------------------------------------------------------
void EditRenderView_TimeLine::OnMotion(const APoint &pos)
{
	AVector diff = pos - mLastMousePoint;
	if (AVector::ZERO == diff) return;

	float movedX = -diff.X() / mPixelOverCamIn;
	float movedZ = -diff.Z() / mPixelOverCamOut;
	Rectf rect(0, 0, mLeftWidth, mSize.Height);
	bool leftContain = rect.IsInsize(Float2(pos.X(), pos.Z()));

	bool isCtrlDown = PX2_EDIT.IsCtrlDown;
	CurveCtrl *selectedCtrl = PX2_EDIT.GetTimeLineEdit()->GetSelectedCurveCtrl();

	if (isCtrlDown && !leftContain && selectedCtrl && mIsLeftDown)
	{
		Camera *camera = mRenderStep->GetCamera();

		const APoint &outVal = selectedCtrl->GetOutVal();
		Vector2f posInViewPort = mUIViewGrid->PointWorldToViewPort(outVal);

		float xDiss = pos.X() - posInViewPort.X();
		float zDiss = pos.Z() - posInViewPort.Y();
		float xDissReal = xDiss / mPixelOverCamIn;
		float zDissReal = zDiss / mPixelOverCamOut;

		AVector arrive = AVector(-xDissReal, 0.0f, -zDissReal);
		arrive.Normalize();
		AVector leave = AVector(xDissReal, 0.0f, zDissReal);
		leave.Normalize();

		if (CurveCtrl::SM_ARRIVE == selectedCtrl->GetSelectMode())
		{
			if (xDiss < 0.0f)
			{
				selectedCtrl->SetArriveTangent(arrive);

				InterpCurveMode mode = selectedCtrl->GetInterpCurveMode();
				if (ICM_CURVE_AUTO == mode || ICM_CURVE_AUTOCLAMPED == mode)
				{
					selectedCtrl->SetInterpCurveMode(ICM_CURVE_USER);
					//UnToggleAllInterps();
					//ToggleInterp(ICM_CURVE_USER);
				}
			}
		}
		else if (CurveCtrl::SM_LEAVE == selectedCtrl->GetSelectMode())
		{
			if (xDiss > 0.0f)
			{
				selectedCtrl->SetLeaveTangent(leave);

				InterpCurveMode mode = selectedCtrl->GetInterpCurveMode();
				if (ICM_CURVE_AUTO == mode || ICM_CURVE_AUTOCLAMPED == mode)
				{
					selectedCtrl->SetInterpCurveMode(ICM_CURVE_USER);
					//UnToggleAllInterps();
					//ToggleInterp(ICM_CURVE_USER);
				}
			}
		}
		else if (CurveCtrl::SM_CENTER == selectedCtrl->GetSelectMode())
		{
			APoint camPos = camera->GetPosition();
			Vector2f camScreenPos = mUIViewGrid->PointWorldToViewPort(camPos);
			float xDissCam = pos.X() - camScreenPos.X();
			float zDissCam = pos.Z() - camScreenPos.Y();
			float xDissCamReal = xDissCam / mPixelOverCamIn;
			float zDissCamReal = zDissCam / mPixelOverCamOut;
			APoint pointPos = camPos + AVector(xDissCamReal, 0.0f, zDissCamReal);
			pointPos.Y() = 0.0f;

			selectedCtrl->SetInVal(pointPos.X()); // ctrl may changed

			selectedCtrl = PX2_EDIT.GetTimeLineEdit()->GetSelectedCurveCtrl(); // ctrl may changed, can it again
			if (selectedCtrl) selectedCtrl->SetOutVal(pointPos);
		}
	}

	bool doMovCal = false;

	if (mIsMiddleDown && !leftContain)
		doMovCal = true;

	if (mIsRightDown && !leftContain)
		doMovCal = true;

	if (doMovCal)
	{
		if (MM_PAN == mMoveMode)
		{
			APoint pos = mUIViewGrid->GetCameraNode()->LocalTransform.GetTranslate();
			pos += AVector(movedX, 0.0f, movedZ);
			mUIViewGrid->GetCameraNode()->LocalTransform.SetTranslate(pos);
			mUIViewGrid->GetCameraNode()->Update(GetTimeInSeconds(), 0.0f);

			_RefreshGrid(false);
		}
		else if (MM_ZOOM == mMoveMode)
		{
		}
	}

	mLastMousePoint = pos;
}
//----------------------------------------------------------------------------
void SceneBuilder::ProcessSkin(INode *node, Modifier *skinMod)
{
	// 构造皮肤控制器。如果Max的网格被按照材质细分,每一个网格都需要自己的蒙皮
	// 信息控制器。蒙皮信息中的offset,在动画起始时被计算,是骨骼的世界变换。
	//
	// node:
	//		指向蒙皮修改器指向的Max中的节点。
	// skinMod:
	//		指向蒙皮修改器

	// 1. 获得max蒙皮信息中的骨骼,对应的在Phoenix的骨骼节点列表
	// 2. 获得maxNode影响的Phoenix网格
	// 3. 获得max中每个骨骼所影响的Phoenix网格中的顶点的数量,忽略不受蒙皮信息
	//	  影响的网格
	// 4. 计算Phoenix mesh的蒙皮信息,生成SkinControl,AttachController到
	//    Phoenix mesh上。
	
	// 1

	bool needDel;
	TriObject *triObj = GetTriObject(node, &needDel);
	Mesh *maxMesh = &triObj->GetMesh();

	// Max皮肤控制器接口
	ISkin *skin = (ISkin*)skinMod->GetInterface(I_SKIN);
	ISkinContextData *skinData = skin->GetContextInterface(node);

	// max Skin Bones -> Phoenix2 Skin Bones
	int b, numSkinBone = skin->GetNumBones();
	PX2::Node **bones = new1<PX2::Node*>(numSkinBone);
	for (b=0; b<numSkinBone; b++)
	{
		INode *boneNode = skin->GetBone(b);
		const std::string &boneName = boneNode->GetName();
		PX2::Node *node = PX2::StaticCast<PX2::Node>(mScene->GetObjectByName(boneName));
		bones[b] = node;
	}

	// 1

	// 获得maxNode相关联的Phoenix mesh
	std::vector<PX2::TriMesh*> meshes;
	PX2::Object *object = mScene->GetObjectByName(node->GetName());
	if (object->IsExactly(PX2::TriMesh::TYPE))
	{
		meshes.push_back(PX2::StaticCast<PX2::TriMesh>(object));
	}
	else
	{
		PX2::Node *node = PX2::StaticCast<PX2::Node>(object);
		const char *nName = node->GetName().c_str();
		for (int c=0; c<node->GetNumChildren(); c++)
		{
			PX2::Movable *child = node->GetChild(c);
			const char *cName = child->GetName().c_str();
			if (strncmp(cName, nName, strlen(nName)) == 0) // 这里必须是strlen(nName),因为子节点有_1,_2
			{
				meshes.push_back(PX2::StaticCast<PX2::TriMesh>(child));
			}
		}
	}

	// 为Phoenix2的每个网格建立相关的皮肤控制器

	int *boneInfuseNumVert = new1<int>(numSkinBone);
	for (int m=0; m<(int)meshes.size(); m++)
	{
		PX2::TriMesh *mesh = meshes[m];

		// Phoenix顶点在max顶点中的索引
		PX2::VertexBuffer *vb = mesh->GetVertexBuffer();
		int px2MeshVertexNum = vb->GetNumElements();
		std::vector<int> MaxVertexIndex; // i->max索引
		int v, i, j, k;

		PX2::VertexBufferAccessor vba(mesh->GetVertexFormat(), vb);

		// 3

		for (int v=0; v<px2MeshVertexNum; ++v)
		{
			Float3 &position = vba.Position<Float3>(v);
			for (i=0; i<maxMesh->getNumVerts(); i++)
			{
				if (position[0] == maxMesh->verts[i].x
					&& position[1] == maxMesh->verts[i].y 
					&& position[2] == maxMesh->verts[i].z)
				{
					MaxVertexIndex.push_back(i);
					break;
				}
			}
		}

		// 确定每个骨骼所影响的顶点数量
		int maxVertexSize = (int)MaxVertexIndex.size();
		memset(boneInfuseNumVert, 0, sizeof(int)*numSkinBone);
		for (i=0; i<maxVertexSize; i++)
		{
			v = MaxVertexIndex[i];
			for (j=0; j<skinData->GetNumAssignedBones(v); j++)
			{ // 这个max中的顶点受到几个骨骼影响啊?!
				b = skinData->GetAssignedBone(v, j); // 获得这个影响的骨骼索引(这个j是第几个)
				boneInfuseNumVert[b]++; // 这个骨骼影响的顶点数量++
			}
		}

		// (通过PX2中的顶点找到Max中的顶点,找到Max中影响该顶点的骨骼)

		// 如果Max的网格是被按照材质分割的,可能一些骨骼对当前Phoenix2网格没有
		// 影响
		int bQuantity = 0; // 影响当前Phoenix2网格的骨骼数量
		for (b=0; b<numSkinBone; b++)
		{
			if (boneInfuseNumVert[b] > 0)
				bQuantity++;
		}

		if (bQuantity == 0)
		{
			// Phoenix网格不被任何骨骼影响,进入下一个网格
			continue;
		}

		// 4

		PX2::Node **theBones = new1<PX2::Node*>(bQuantity);
		float **weight = new2<float>(bQuantity, maxVertexSize);
		memset(weight[0],0,bQuantity*maxVertexSize*sizeof(float));
		PX2::APoint **offset = new2<PX2::APoint>(bQuantity, maxVertexSize);
		memset(offset[0],0,bQuantity*maxVertexSize*sizeof(PX2::APoint));
		PX2::HMatrix *mats = new1<PX2::HMatrix>(bQuantity);

		// 计算max骨骼到Phoenix骨骼对应的索引(k)
		std::vector<int> bIArray(numSkinBone);
		for (b=0, k=0; b<numSkinBone; b++)
		{
			if (boneInfuseNumVert[b] > 0)
			{
				theBones[k] = bones[b]; // 获取对Mesh有影响的骨骼
				bIArray[b] = k; // max bone index -> px2 可用bone index
				
				HMatrix boneWorldMat = theBones[k]->WorldTransform.Matrix();
				HMatrix meshWorldMat =  mesh->WorldTransform.Matrix();

				mats[k] = boneWorldMat.Inverse() * meshWorldMat;
				
				k++;
			}
		}

		// 遍历顶点,计算顶点权重和offset
		for (i=0; i<maxVertexSize; i++)
		{
			v = MaxVertexIndex[i];
			for (j=0; j<skinData->GetNumAssignedBones(v); j++)
			{ // 遍历影响该Max顶点的骨骼
				b = skinData->GetAssignedBone(v, j);
				k = bIArray[b];
				float wit = skinData->GetBoneWeight(v, j); // 第j个骨骼的影响权重
				weight[i][k] = wit;

				Float3 &position = vba.Position<Float3>(i);

				APoint point = theBones[k]->WorldTransform.Inverse() 
					* (mesh->WorldTransform * APoint(position));
				offset[i][k] = Float3(point.X(), point.Y(), point.Z()); // 在所受影响骨骼中的位置
			}
		}

		PX2::SkinController *skinCtrl = new0 PX2::SkinController
			(maxVertexSize, bQuantity);
		skinCtrl->SetName("SkinController");
		for (int i=0; i<bQuantity; i++)
		{
			skinCtrl->GetBones()[i] = theBones[i];
			skinCtrl->GetTMMatrixs()[i] = mats[i];
		}

		// offset
		for (int i=0; i<maxVertexSize; i++)
		{
			for (int j=0; j<bQuantity; j++)
			{
				skinCtrl->GetWeights()[i][j] = weight[i][j];
				skinCtrl->GetOffsets()[i][j] = offset[i][j]; 
			}
		}

		// index weights
		for (int i=0; i<maxVertexSize; i++)
		{
			Float4 inds = Float4(0.0f, 0.0f, 0.0f, 0.0f);
			Float4 wights = Float4(0.0f, 0.0f, 0.0f, 0.0f);

			In *pSortBone = new In[bQuantity];
			for (int j=0; j<bQuantity; j++)
			{
				pSortBone[j].index = j;
				pSortBone[j].data = weight[i][j];
			}
			qsort(pSortBone, bQuantity, sizeof(pSortBone[0]), cmp);

			int useBoneNum = bQuantity;
			if (useBoneNum > 4)
				useBoneNum = 4;

			float allWeight = 0.0f;
			for (int useBoneIndex=0; useBoneIndex<useBoneNum; useBoneIndex++)
			{
				allWeight += pSortBone[useBoneIndex].data;
			}
			if (allWeight <= 0.0f)
				allWeight = 1.0f;

			for (int useBoneIndex=0; useBoneIndex<useBoneNum; useBoneIndex++)
			{
				inds[useBoneIndex] = (float)(pSortBone[useBoneIndex].index);
				wights[useBoneIndex] = pSortBone[useBoneIndex].data/allWeight;
			}

			vba.TCoord<Float4>(1, i) = inds;
			vba.TCoord<Float4>(2, i) = wights;

			delete [] pSortBone;
		}
		
		skinCtrl->Repeat = Controller::RT_WRAP;
		skinCtrl->MinTime = 0.0f;
		skinCtrl->MaxTime = TicksToSec(mTimeEnd - mTimeStart);

		mesh->AttachController(skinCtrl);

		delete1(theBones);
		delete2(weight);
		delete2(offset);
		delete1(mats);
	}

	if (needDel)
	{
		delete0(triObj);
	}

	delete1(bones);
	delete1(boneInfuseNumVert);
}
Ejemplo n.º 24
0
//----------------------------------------------------------------------------
void SizeNode::UpdateLayout(Movable *parent)
{
	Movable *par = parent;
	if (!par) return;

	SizeNode *parNode = DynamicCast<SizeNode>(par);

	// parent pvoit决定了从那一点作为原点,计算当前Frame原点位置
	// 例如
	// (0.0f, 0.0f)是左下角
	// (0.5f, 0.5f)是中心点	
	Sizef parentSize;
	AVector parentLeftBottomOffset;
	if (parNode)
	{
		parentSize = parNode->GetSize();
		parentLeftBottomOffset = parNode->LeftBottomCornerOffset;
	}

	APoint localPos = LocalTransform.GetTranslate();
	Sizef localSize = GetSize();

	APoint newPos;
	Sizef newSize = localSize;
	if (parNode)
	{
		float width = 0.0f;
		float height = 0.0f;

		bool isHEqual = (mAnchorHor[0] == mAnchorHor[1]);
		bool isVEqual = (mAnchorVer[0] == mAnchorVer[1]);

		if (isHEqual)
		{
			width = localSize.Width;
			newPos.X() = parentLeftBottomOffset.X() +
				parentSize.Width * mAnchorHor[0] + mAnchorParamHor[0];
		}
		else
		{
			// 如果是范围,直接取中心点,作为原点
			width = parentSize.Width * (mAnchorHor[1] - mAnchorHor[0]) - mAnchorParamHor[0] + mAnchorParamHor[1];
			newPos.X() = parentLeftBottomOffset.X() + parentSize.Width*mAnchorHor[0] + mAnchorParamHor[0] + width / 2.0f;
		}

		if (isVEqual)
		{
			height = localSize.Height;
			newPos.Z() = parentLeftBottomOffset.Z() +
				parentSize.Height * mAnchorVer[0] + mAnchorParamVer[0];
		}
		else
		{
			// 如果是范围,直接取中心点,作为原点
			height = parentSize.Height * (mAnchorVer[1] - mAnchorVer[0]) - mAnchorParamVer[0] + mAnchorParamVer[1];
			newPos.Z() = parentLeftBottomOffset.Z() + parentSize.Height*mAnchorVer[0] + mAnchorParamVer[0] + height / 2.0f;
		}

		newSize = Sizef(width, height);
	}

	newPos.Y() = localPos.Y();
	LocalTransform.SetTranslate(newPos);

	if (newSize != localSize)
	{
		SetSize(newSize);
	}
}
Ejemplo n.º 25
0
//----------------------------------------------------------------------------
bool PolyhedronDistance::ApplyTransform (unsigned char key)
{
    APoint trn;
    HMatrix rot, incr;
    float trnSpeed = 0.1f;
    float rotSpeed = 0.1f;

    switch (key)
    {
        case 'x':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.X() -= trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'X':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.X() += trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'y':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Y() -= trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'Y':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Y() += trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'z':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Z() -= trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 'Z':
            trn = mTetras[0]->LocalTransform.GetTranslate();
            trn.Z() += trnSpeed;
            mTetras[0]->LocalTransform.SetTranslate(trn);
            break;
        case 's':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.X() -= trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'S':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.X() += trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 't':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Y() -= trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'T':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Y() += trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'u':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Z() -= trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'U':
            trn = mTetras[1]->LocalTransform.GetTranslate();
            trn.Z() += trnSpeed;
            mTetras[1]->LocalTransform.SetTranslate(trn);
            break;
        case 'a':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Y, rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'A':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Y, -rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'b':
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'B':
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, -rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'c':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_X, 1.3f*rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, -rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        case 'C':
            rot = mTetras[0]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_X, -1.3f*rotSpeed);
            mTetras[0]->LocalTransform.SetRotate(incr*rot);
            rot = mTetras[1]->LocalTransform.GetRotate();
            incr.MakeRotation(AVector::UNIT_Z, rotSpeed);
            mTetras[1]->LocalTransform.SetRotate(incr*rot);
            break;
        default:
            return false;
    }

    // Prevent solution point coordinates from being negative.  The polyhedron
    // distance calculator expects solution points to be in the first octant.
    // Vertices are offset by mOffsetMagnitude*Vector3f(1,1,1) in
    // UpdateSegments() before the call to the distance routine.  Here we make
    // sure that no translation of a polyhedron takes it so far into one of the
    // other 7 octants that the offset will not be sufficient to guarantee that
    // the solution points lie in the first octant.
    VertexBufferAccessor vba;
    float threshold = -mOffsetMagnitude + trnSpeed;
    for (int j = 0; j < 2; ++j)
    {
        const APoint& wTrn = mTetras[j]->WorldTransform.GetTranslate();
        const HMatrix& wRot = mTetras[j]->WorldTransform.GetRotate();
        vba.ApplyTo(mTetras[j]);
        for (int i = 0; i < 4; i++)
        {
            AVector relPosition = vba.Position<Float3>(i);
            APoint position = wTrn + wRot*relPosition;
            APoint trn = mTetras[j]->LocalTransform.GetTranslate();
            for (int k = 0; k < 3; ++k)
            {
                if (position[k] < threshold)
                {
                    trn[k] += trnSpeed;
                }
            }
            mTetras[j]->LocalTransform.SetTranslate(trn);
        }
    }

    mScene->Update();
    UpdateSegments();
    return true;
}