Esempio n. 1
0
//----------------------------------------------------------------------------
void Actor::SetFace(const AVector &dir, const AVector &uping)
{
	AVector right = dir.Cross(uping);
	right.Normalize();
	AVector up = right.Cross(dir);
	up.Normalize();

	Matrix3f matRot(right, dir, up, true);

	LocalTransform.SetRotate(matRot);
}
Esempio n. 2
0
//----------------------------------------------------------------------------
AVector SurfacePatch::Tangent1 (float u, float v) const
{
    AVector tangent0 = PU(u, v);
    AVector tangent1 = PV(u, v);
    tangent0.Normalize();
    AVector normal = tangent0.UnitCross(tangent1);
    tangent1 = normal.Cross(tangent0);
    return tangent1;
}
Esempio n. 3
0
//----------------------------------------------------------------------------
AVector CurveSegment::Binormal (float u) const
{
    AVector velocity = PU(u);
    AVector acceleration = PUU(u);
    float VDotV = velocity.Dot(velocity);
    float VDotA = velocity.Dot(acceleration);
    AVector normal = VDotV*acceleration - VDotA*velocity;
    normal.Normalize();
    velocity.Normalize();
    AVector binormal = velocity.Cross(normal);
    return binormal;
}
Esempio n. 4
0
//----------------------------------------------------------------------------
void CurveSegment::GetFrame (float u, APoint& position, AVector& tangent,
    AVector& normal, AVector& binormal) const
{
    position = P(u);
    AVector velocity = PU(u);
    AVector acceleration = PUU(u);
    float VDotV = velocity.Dot(velocity);
    float VDotA = velocity.Dot(acceleration);
    normal = VDotV*acceleration - VDotA*velocity;
    normal.Normalize();
    tangent = velocity;
    tangent.Normalize();
    binormal = tangent.Cross(normal);
}
Esempio n. 5
0
//----------------------------------------------------------------------------
void SurfacePatch::GetFrame (float u, float v, APoint& position,
    AVector& tangent0, AVector& tangent1, AVector& normal) const
{
    position = P(u, v);

    tangent0 = PU(u, v);
    tangent1 = PV(u, v);
    tangent0.Normalize();
    normal = tangent0.UnitCross(tangent1);

    // The normalized first derivatives are not necessarily orthogonal.
    // Recompute T1 so that {T0,T1,N} is an orthonormal set.
    tangent1 = normal.Cross(tangent0);
}
Esempio n. 6
0
//----------------------------------------------------------------------------
float CurveSegment::Curvature (float u) const
{
    AVector velocity = PU(u);
    float speedSqr = velocity.SquaredLength();

    if (speedSqr >= Mathf::ZERO_TOLERANCE)
    {
        AVector acceleration = PUU(u);
        AVector cross = velocity.Cross(acceleration);
        float numer = cross.Length();
        float denom = Mathf::Pow(speedSqr, 1.5f);
        return numer/denom;
    }
    else
    {
        // Curvature is indeterminate, just return 0.
        return 0.0f;
    }
}
Esempio n. 7
0
//----------------------------------------------------------------------------
float CurveSegment::Torsion (float u) const
{
    AVector velocity = PU(u);
    AVector acceleration = PUU(u);
    AVector cross = velocity.Cross(acceleration);
    float denom = cross.SquaredLength();

    if (denom >= Mathf::ZERO_TOLERANCE)
    {
        AVector jerk = PUUU(u);
        float numer = cross.Dot(jerk);
        return numer/denom;
    }
    else
    {
        // Torsion is indeterminate, just return 0.
        return 0.0f;
    }
}
Esempio n. 8
0
//----------------------------------------------------------------------------
void SurfacePatch::ComputePrincipalCurvatureInfo (float u, float v,
    float& curv0, float& curv1, AVector& dir0, AVector& dir1)
{
    // Tangents:  T0 = dP/du = (x_u,y_u,z_u), T1 = dP/dv = (x_v,y_v,z_v)
    // Normal:    N = Cross(T0,T1)/Length(Cross(T0,T1))
    // Metric Tensor:    G = +-                      -+
    //                       | Dot(T0,T0)  Dot(T0,T1) |
    //                       | Dot(T1,T0)  Dot(T1,T1) |
    //                       +-                      -+
    //
    // Curvature Tensor:  B = +-                          -+
    //                        | -Dot(N,T0_u)  -Dot(N,T0_v) |
    //                        | -Dot(N,T1_u)  -Dot(N,T1_v) |
    //                        +-                          -+
    //
    // Principal curvatures k are the generalized eigenvalues of
    //
    //     Bw = kGw
    //
    // If k is a curvature and w=(a,b) is the corresponding solution to
    // Bw = kGw, then the principal direction as a 3D vector is d = a*U+b*V.
    //
    // Let k1 and k2 be the principal curvatures.  The mean curvature
    // is (k1+k2)/2 and the Gaussian curvature is k1*k2.

    // Compute the derivatives.
    AVector derU = PU(u, v);
    AVector derV = PV(u, v);
    AVector derUU = PUU(u, v);
    AVector derUV = PUV(u, v);
    AVector derVV = PVV(u, v);

    // Compute the metric tensor.
    float metricTensor[2][2];
    metricTensor[0][0] = derU.Dot(derU);
    metricTensor[0][1] = derU.Dot(derV);
    metricTensor[1][0] = metricTensor[0][1];
    metricTensor[1][1] = derV.Dot(derV);

    // Compute the curvature tensor.
    AVector normal = derU.UnitCross(derV);
    float curvatureTensor[2][2];
    curvatureTensor[0][0] = -normal.Dot(derUU);
    curvatureTensor[0][1] = -normal.Dot(derUV);
    curvatureTensor[1][0] = curvatureTensor[0][1];
    curvatureTensor[1][1] = -normal.Dot(derVV);

    // Characteristic polynomial is 0 = det(B-kG) = c2*k^2+c1*k+c0.
    float c0 = curvatureTensor[0][0]*curvatureTensor[1][1] -
        curvatureTensor[0][1]*curvatureTensor[1][0];
    float c1 = 2.0f*curvatureTensor[0][1]* metricTensor[0][1] -
        curvatureTensor[0][0]*metricTensor[1][1] -
        curvatureTensor[1][1]*metricTensor[0][0];
    float c2 = metricTensor[0][0]*metricTensor[1][1] -
        metricTensor[0][1]*metricTensor[1][0];

    // Principal curvatures are roots of characteristic polynomial.
    float temp = Mathf::Sqrt(Mathf::FAbs(c1*c1 - 4.0f*c0*c2));
    curv0 = -0.5f*(c1+temp);
    curv1 = 0.5f*(-c1+temp);

    // Principal directions are solutions to (B-kG)w = 0,
    // w1 = (b12-k1*g12,-(b11-k1*g11)) OR (b22-k1*g22,-(b12-k1*g12))
    float a0 = curvatureTensor[0][1] - curv0*metricTensor[0][1];
    float a1 = curv0*metricTensor[0][0] - curvatureTensor[0][0];
    float length = Mathf::Sqrt(a0*a0 + a1*a1);
    if (length >= Mathf::ZERO_TOLERANCE)
    {
        dir0 = a0*derU + a1*derV;
    }
    else
    {
        a0 = curvatureTensor[1][1] - curv0*metricTensor[1][1];
        a1 = curv0*metricTensor[0][1] - curvatureTensor[0][1];
        length = Mathf::Sqrt(a0*a0 + a1*a1);
        if (length >= Mathf::ZERO_TOLERANCE)
        {
            dir0 = a0*derU + a1*derV;
        }
        else
        {
            // Umbilic (surface is locally sphere, any direction principal).
            dir0 = derU;
        }
    }
    dir0.Normalize();

    // Second tangent is cross product of first tangent and normal.
    dir1 = dir0.Cross(normal);
}
//----------------------------------------------------------------------------
void EditRenderView_PreView::SetObject(PX2::Object *obj)
{
	Texture2D *d2Tex = DynamicCast<Texture2D>(obj);
	Movable *mov = DynamicCast<Movable>(obj);
	if (d2Tex)
	{
		mPreViewType = PVT_TEXTURE;

		const SelectResData &data = PX2_EDIT.GetSelectedResource();
		SelectResData::SelectResType selectResType = data.GetSelectResType();

		std::string texStr = "";

		if (selectResType == SelectResData::RT_NORMAL)
		{
			mUIPicBox->SetTexture(data.ResPathname);

			Texture2D *tex2D = DynamicCast<Texture2D>(PX2_RM.BlockLoad(data.ResPathname));
			if (tex2D)
			{
				texStr = "width:" + StringHelp::IntToString((int)tex2D->GetWidth()) + " "
					+ "height:" + StringHelp::IntToString((int)tex2D->GetHeight()) + " ";
			}
		}
		else if (selectResType == SelectResData::RT_TEXPACKELEMENT)
		{
			PX2_RM.AddTexPack(data.ResPathname);
			const TexPackElement &texPackEle = PX2_RM.GetTexPackElement(
				data.ResPathname, data.EleName);
			if (texPackEle.IsValid())
			{
				mUIPicBox->SetTexture(data.ResPathname, data.EleName);
				mUIPicBox->SetSize((float)texPackEle.W, (float)texPackEle.H);

				texStr = "width: " + StringHelp::IntToString(texPackEle.W) + "  " + "height: " + StringHelp::IntToString(texPackEle.H) + "  ";
			}
		}
		mUIText->SetText(texStr);

		_ReSizeTexture();
	}
	else if (mov)
	{
		mPreViewType = PVT_MODEL;

		mUIText->SetText("");

		EnvirParamPtr beforeParam = PX2_GR.GetCurEnvirParam();
		PX2_GR.SetCurEnvirParam(mModelScene->GetEnvirParam());

		mModeActor->DetachAllChildren();
		mModelMovable = (Movable*)(mov->Copy(""));
		Node::TravelExecute(mModelMovable, _ModePreViewTravelExecuteFun);
		mModeActor->AttachChild(mModelMovable);
		mModelMovable->ResetPlay();
		mModeActor->Update(GetTimeInSeconds(), 0.0f, false);
		mModelCameraActor->ResetPlay();

		const APoint &boundCenter = mModelMovable->WorldBound.GetCenter();
		float boundRadius = mModelMovable->WorldBound.GetRadius();

		APoint camPos = boundCenter + AVector(-boundRadius*2.5f, -boundRadius*2.5f, boundRadius*1.5f);
		AVector dir = boundCenter - camPos;

		if (boundRadius > 0.0f)
		{
			dir.Normalize();
			AVector up = AVector(Float3(0.0f, 0.0f, 1.0f));
			AVector right = dir.Cross(up);
			right.Normalize();
			up = right.Cross(dir);
			up.Normalize();
			AVector::Orthonormalize(dir, up, right);

			mModelCameraActor->GetCameraNode()->LocalTransform.SetRotate(HMatrix(right, dir, up, AVector::ZERO, true));
			mModelCameraActor->GetCameraNode()->LocalTransform.SetTranslate(camPos);
		}

		PX2_GR.SetCurEnvirParam(beforeParam);
	}
	else
	{
		mPreViewType = PVT_NONE;
	}
}
Esempio n. 10
0
//----------------------------------------------------------------------------
void Triangles::UpdateModelTangentsUseGeometry (VertexBufferAccessor& vba)
{
    // Compute the matrix of normal derivatives.
    const int numVertices = vba.GetNumVertices();
    HMatrix* dNormal = new1<HMatrix>(numVertices);
    HMatrix* wwTrn = new1<HMatrix>(numVertices);
    HMatrix* dwTrn = new1<HMatrix>(numVertices);
    memset(wwTrn, 0, numVertices*sizeof(HMatrix));
    memset(dwTrn, 0, numVertices*sizeof(HMatrix));

    const int numTriangles = GetNumTriangles();
    int i, row, col;
    for (i = 0; i < numTriangles; ++i)
    {
        // Get the vertex indices for the triangle.
        int v[3];
        if (!GetTriangle(i, v[0], v[1], v[2]))
        {
            continue;
        }

        for (int j = 0; j < 3; j++)
        {
            // Get the vertex positions and normals.
            int v0 = v[j];
            int v1 = v[(j + 1) % 3];
            int v2 = v[(j + 2) % 3];
            APoint pos0 = vba.Position<Float3>(v0);
            APoint pos1 = vba.Position<Float3>(v1);
            APoint pos2 = vba.Position<Float3>(v2);
            AVector nor0 = vba.Normal<Float3>(v0);
            AVector nor1 = vba.Normal<Float3>(v1);
            AVector nor2 = vba.Normal<Float3>(v2);

            // Compute the edge from pos0 to pos1, project it to the tangent
            // plane of the vertex, and compute the difference of adjacent
            // normals.
            AVector edge = pos1 - pos0;
            AVector proj = edge - edge.Dot(nor0)*nor0;
            AVector diff = nor1 - nor0;
            for (row = 0; row < 3; ++row)
            {
                for (col = 0; col < 3; ++col)
                {
                    wwTrn[v0][row][col] += proj[row]*proj[col];
                    dwTrn[v0][row][col] += diff[row]*proj[col];
                }
            }

            // Compute the edge from pos0 to pos2, project it to the tangent
            // plane of the vertex, and compute the difference of adjacent
            // normals.
            edge = pos2 - pos0;
            proj = edge - edge.Dot(nor0)*nor0;
            diff = nor2 - nor0;
            for (row = 0; row < 3; ++row)
            {
                for (col = 0; col < 3; ++col)
                {
                    wwTrn[v0][row][col] += proj[row]*proj[col];
                    dwTrn[v0][row][col] += diff[row]*proj[col];
                }
            }
        }
    }

    // Add N*N^T to W*W^T for numerical stability.  In theory 0*0^T is added
    // to D*W^T, but of course no update is needed in the implementation.
    // Compute the matrix of normal derivatives.
    for (i = 0; i < numVertices; ++i)
    {
        AVector nor = vba.Normal<Float3>(i);
        for (row = 0; row < 3; ++row)
        {
            for (col = 0; col < 3; ++col)
            {
                wwTrn[i][row][col] =
                    0.5f*wwTrn[i][row][col] + nor[row]*nor[col];
                dwTrn[i][row][col] *= 0.5f;
            }
        }

        wwTrn[i].SetColumn(3, APoint::ORIGIN);
        dNormal[i] = dwTrn[i]*wwTrn[i].Inverse();
    }

    delete1(wwTrn);
    delete1(dwTrn);

    // If N is a unit-length normal at a vertex, let U and V be unit-length
    // tangents so that {U, V, N} is an orthonormal set.  Define the matrix
    // J = [U | V], a 3-by-2 matrix whose columns are U and V.  Define J^T
    // to be the transpose of J, a 2-by-3 matrix.  Let dN/dX denote the
    // matrix of first-order derivatives of the normal vector field.  The
    // shape matrix is
    //   S = (J^T * J)^{-1} * J^T * dN/dX * J = J^T * dN/dX * J
    // where the superscript of -1 denotes the inverse.  (The formula allows
    // for J built from non-perpendicular vectors.) The matrix S is 2-by-2.
    // The principal curvatures are the eigenvalues of S.  If k is a principal
    // curvature and W is the 2-by-1 eigenvector corresponding to it, then
    // S*W = k*W (by definition).  The corresponding 3-by-1 tangent vector at
    // the vertex is called the principal direction for k, and is J*W.  The
    // principal direction for the minimum principal curvature is stored as
    // the mesh tangent.  The principal direction for the maximum principal
    // curvature is stored as the mesh bitangent.
    for (i = 0; i < numVertices; ++i)
    {
        // Compute U and V given N.
        AVector norvec = vba.Normal<Float3>(i);
        AVector uvec, vvec;
        AVector::GenerateComplementBasis(uvec, vvec, norvec);

        // Compute S = J^T * dN/dX * J.  In theory S is symmetric, but
        // because we have estimated dN/dX, we must slightly adjust our
        // calculations to make sure S is symmetric.
        float s01 = uvec.Dot(dNormal[i]*vvec);
        float s10 = vvec.Dot(dNormal[i]*uvec);
        float sAvr = 0.5f*(s01 + s10);
        float smat[2][2] =
        {
            { uvec.Dot(dNormal[i]*uvec), sAvr },
            { sAvr, vvec.Dot(dNormal[i]*vvec) }
        };

        // Compute the eigenvalues of S (min and max curvatures).
        float trace = smat[0][0] + smat[1][1];
        float det = smat[0][0]*smat[1][1] - smat[0][1]*smat[1][0];
        float discr = trace*trace - 4.0f*det;
        float rootDiscr = Mathf::Sqrt(Mathf::FAbs(discr));
        float minCurvature = 0.5f*(trace - rootDiscr);
        // float maxCurvature = 0.5f*(trace + rootDiscr);

        // Compute the eigenvectors of S.
        AVector evec0(smat[0][1], minCurvature - smat[0][0], 0.0f);
        AVector evec1(minCurvature - smat[1][1], smat[1][0], 0.0f);
        AVector tanvec, binvec;
        if (evec0.SquaredLength() >= evec1.SquaredLength())
        {
            evec0.Normalize();
            tanvec = evec0.X()*uvec + evec0.Y()*vvec;
            binvec = norvec.Cross(tanvec);
        }
        else
        {
            evec1.Normalize();
            tanvec = evec1.X()*uvec + evec1.Y()*vvec;
            binvec = norvec.Cross(tanvec);
        }

        if (vba.HasTangent())
        {
            vba.Tangent<Float3>(i) = tanvec;
        }

        if (vba.HasBinormal())
        {
            vba.Binormal<Float3>(i) = binvec;
        }
    }

    delete1(dNormal);
}
//----------------------------------------------------------------------------
void BeamEmitterController::EmitABeam (float ctrlTime)
{
	BeamEmitter *emitter = (BeamEmitter*)mObject;
	ModulesUpdateEffectable(ctrlTime);

	Camera *cam = Renderer::GetDefaultRenderer()->GetCamera();
	const AVector &camD = cam->GetDVector();

	Effectable::FaceType faceType = emitter->GetFaceType();
	BeamEmitter::WaveType waveTypeUp = emitter->GetWaveTypeUp();
	BeamEmitter::WaveType waveTypeExtend = emitter->GetWaveTypeExtend();
	int numLowFre = emitter->GetNumLowFrequency();
	int numHighFre = emitter->GetNumHighFrequency();
	const Float2 &lowFreRangeUp = emitter->GetLowFrequencyRangeUp();
	const Float2 &lowFreRangeExtend = emitter->GetLowFrequencyRangeExtend();
	const Float2 &hightFreRangeUp = emitter->GetHighFrequencyRangeUp();
	const Float2 &hightFreRangeExtend = emitter->GetHighFrequencyRangeExtend();
	APoint emitStartPos = emitter->GetEmitStartPos();
	const APoint &emitEndPos = emitter->GetEmitEndPos();

	if (emitter->IsStartPosUseLocal() && !emitter->IsLocal())
	{
		emitStartPos = emitter->WorldTransform * emitStartPos;
	}

	BeamObject obj;
	obj.StartPos = emitStartPos;
	obj.EndPos = emitEndPos;

	AVector dirVec = emitEndPos - emitStartPos;
	if (dirVec == AVector::ZERO)
	{
		dirVec.X() = 0.01f;
	}
	AVector dir = dirVec;
	dir.Normalize();

	AVector toMeDir;
	if (Effectable::FT_X == faceType)
	{
		toMeDir = AVector::UNIT_X;
	}
	else if (Effectable::FT_NX == faceType)
	{
		toMeDir = -AVector::UNIT_X;
	}
	else if (Effectable::FT_Y == faceType)
	{
		toMeDir = AVector::UNIT_Y;
	}
	else if (Effectable::FT_NY == faceType)
	{
		toMeDir = -AVector::UNIT_Y;
	}
	else if (Effectable::FT_Z == faceType)
	{
		toMeDir = AVector::UNIT_Z;
	}
	else if (Effectable::FT_NZ == faceType)
	{
		toMeDir = -AVector::UNIT_Z;
	}
	else if (Effectable::FT_CAMERA == faceType || 
		Effectable::FT_SPEEDDIR==faceType || 
		Effectable::FT_FREE==faceType)
	{
		toMeDir = -camD;
	}

	AVector upDir = toMeDir.Cross(dir);
	upDir.Normalize();
	AVector toMeExtendDir = dir.Cross(upDir);
	toMeExtendDir.Normalize();

	int numLowFreNumPoints = numLowFre+1;

	std::vector<float> upLFs, toMeLFs;

	if (BeamEmitter::WT_RANDOM==waveTypeUp || BeamEmitter::WT_LINE==waveTypeUp)
	{
		GernerateLFPoints(upLFs, numLowFreNumPoints, waveTypeUp, lowFreRangeUp[0], lowFreRangeUp[1]);
	}
	else
	{
	}

	if (BeamEmitter::WT_RANDOM==waveTypeExtend || BeamEmitter::WT_LINE==waveTypeExtend)
	{
		GernerateLFPoints(toMeLFs, numLowFreNumPoints, waveTypeExtend, lowFreRangeExtend[0], lowFreRangeExtend[1]);
	}
	else
	{
	}

	APoint lastPoint;
	for (int i=0; i<numLowFreNumPoints; i++)
	{
		APoint lPos = emitStartPos + dirVec * (i/(float)(numLowFreNumPoints-1));
		APoint lPoint = lPos + upDir*upLFs[i] + toMeExtendDir * toMeLFs[i];

		if (0 != i)
		{
			for (int k=1; k<numHighFre; k++)
			{
				AVector hVec = lPoint - lastPoint;
				APoint hPoint = lastPoint + hVec * (k/(float)numHighFre);
				hPoint += upDir * Mathf::IntervalRandom(hightFreRangeUp[0], hightFreRangeUp[1]);
				hPoint += toMeExtendDir * Mathf::IntervalRandom(hightFreRangeExtend[0], hightFreRangeExtend[1]);

				obj.Points.push_back(hPoint);
			}
		}

		obj.Points.push_back(lPoint);

		lastPoint = lPoint;
	}

	OnNewAEffectObject(&obj);

	ModulesUpdateEffectObject(&obj);

	mBeamObjects.push_back(obj);
}
Esempio n. 12
0
//----------------------------------------------------------------------------
void SceneNodeCtrl::OnMotion(bool leftDown, RenderStep *renderStep,
	PX2::APoint posNow, PX2::APoint posBefore)
{
	PX2_UNUSED(leftDown);
	PX2_UNUSED(renderStep);

	Renderer *renderer = renderStep->GetRenderer();
	Camera *camera = renderStep->GetCamera();

	// 光标移动更新
	if (DT_NONE == mDragType)
	{
		GeoObjFactory factory;

		DragType dt = GetDragType(renderStep, posNow);
		Movable *ctrlMov = 0;
		Float4 colorYellowAlpha = Float4(1.0f, 1.0f, 0.0f, 0.3f);

		if (DT_X == dt)
		{
			ctrlMov = GetCurrentCtrlX();
			factory.UpdateCtrlColor(renderer, ctrlMov, Float4::YELLOW);
		}
		else if (DT_Y == dt)
		{
			ctrlMov = GetCurrentCtrlY();
			factory.UpdateCtrlColor(renderer, ctrlMov, Float4::YELLOW);
		}
		else if (DT_Z == dt)
		{
			ctrlMov = GetCurrentCtrlZ();
			factory.UpdateCtrlColor(renderer, ctrlMov, Float4::YELLOW);
		}
		else if (DT_XY == dt)
		{
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXY(), colorYellowAlpha);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlYZ(), Float4::ZERO);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXZ(), Float4::ZERO);
		}
		else if (DT_YZ == dt)
		{
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlYZ(), colorYellowAlpha);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXY(), Float4::ZERO);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXZ(), Float4::ZERO);
		}
		else if (DT_XZ == dt)
		{
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXZ(), colorYellowAlpha);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXY(), Float4::ZERO);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlYZ(), Float4::ZERO);
		}
		else if (DT_XYZ == dt)
		{
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXYZ(), Float4::YELLOW);
		}
		else if (DT_NONE == dt)
		{
			factory.UpdateCtrlColor(renderer, GetCurrentCtrlX(), Float4::RED);
			factory.UpdateCtrlColor(renderer, GetCurrentCtrlY(), Float4::GREEN);
			factory.UpdateCtrlColor(renderer, GetCurrentCtrlZ(), Float4::BLUE);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXY(), Float4::ZERO);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlYZ(), Float4::ZERO);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXZ(), Float4::ZERO);
			factory.UpdateCtrlColor1(renderer, GetCurrentCtrlXYZ(), Float4::WHITE);
		}

		if (DT_NONE == dt)
		{
			Event *ent = EditEventSpace::CreateEventX(EditEventSpace::SceneNodeDrag);
			ent->SetData<int>(0);
			EventWorld::GetSingleton().BroadcastingLocalEvent(ent);
		}
		else
		{
			Event *ent = EditEventSpace::CreateEventX(EditEventSpace::SceneNodeDrag);
			ent->SetData<int>(1);
			EventWorld::GetSingleton().BroadcastingLocalEvent(ent);
		}
	}

	if (DT_NONE == mDragType) return;
	else
	{
		Event *ent = EditEventSpace::CreateEventX(EditEventSpace::SceneNodeDrag);
		ent->SetData<int>(1);
		EventWorld::GetSingleton().BroadcastingLocalEvent(ent);
	}

	int numObjs = PX2_SELECTION.GetNumObjects();
	if (0 == numObjs) 
		return;

	// get pickPoint with the plane
	TriMesh *meshHelp = PX2_GR.GetXYPlane();
	if (DT_X == mDragType)
	{
		if (LT_PERSPECTIVE == mLookType || LT_TOP == mLookType)
			meshHelp = PX2_GR.GetXYPlane();
		else if (LT_FRONT == mLookType)
			meshHelp = PX2_GR.GetXZPlane();
	}
	else if (DT_Y == mDragType)
	{
		meshHelp = PX2_GR.GetXYPlane();
	}
	else if (DT_Z == mDragType)
	{
		AVector cameraDir = camera->GetDVector();
		cameraDir.Normalize();
		float dotVal = Mathf::FAbs(cameraDir.Dot(AVector::UNIT_X));
		if (dotVal > 0.7f)
		{
			meshHelp = PX2_GR.GetYZPlane();
		}
		else
		{
			meshHelp = PX2_GR.GetXZPlane();
		}
	}
	else if (DT_XY == mDragType)
	{
		meshHelp = PX2_GR.GetXYPlane();
	}
	else if (DT_YZ == mDragType)
	{
		meshHelp = PX2_GR.GetYZPlane();
	}
	else if (DT_XZ == mDragType)
	{
		meshHelp = PX2_GR.GetXZPlane();
	}
	else if (DT_XYZ == mDragType)
	{
		meshHelp = PX2_GR.GetXYPlane();
	}
	meshHelp->WorldTransform.SetTranslate(GetPosition());

	// get pick ray
	APoint rayOrigin_Now;
	AVector rayDir_Now;
	renderStep->GetPickRay(posNow.X(), posNow.Z(), rayOrigin_Now, rayDir_Now);

	APoint rayOrigin_Before;
	AVector rayDir_Before;
	renderStep->GetPickRay(posBefore.X(), posBefore.Z(), rayOrigin_Before, rayDir_Before);

	// pick
	Picker pickerNow;
	pickerNow.Execute(meshHelp, rayOrigin_Now, rayDir_Now, 0.0f, Mathf::MAX_REAL);
	float lengthNow = pickerNow.GetClosestToZero().T;
	APoint positionNow(rayOrigin_Now + rayDir_Now*lengthNow);

	Picker pickerOrigin;
	pickerOrigin.Execute(meshHelp, rayOrigin_Before, rayDir_Before, 0.0f, Mathf::MAX_REAL);
	float lengthBefore = pickerOrigin.GetClosestToZero().T;
	APoint positionBefore(rayOrigin_Before + rayDir_Before*lengthBefore);

	if (pickerNow.Records.empty() || pickerOrigin.Records.empty()) return;

	AVector transMoved = positionNow - positionBefore;
	AVector transDir = transMoved;
	transDir.Normalize();

	float transValue = 0.0f;
	float transValue1 = 0.0f;
	AVector transVec;
	AVector rolateVec;

	AVector dirX = mDirX;
	AVector dirY = mDirY;
	AVector dirZ = mDirZ;

	if (DT_X == mDragType)
	{
		transValue = transMoved.Dot(dirX);
		transVec = dirX * transValue;

		rolateVec.X() = transMoved.Length() *(1.0f - Mathf::FAbs(transDir.Dot(dirX)));

		AVector vec = transDir.Cross(dirX);
		rolateVec.X() *= Mathf::Sign(vec.Z());
	}
	else if (DT_Y == mDragType)
	{
		transValue = transMoved.Dot(dirY);
		transVec = dirY * transValue;

		rolateVec.Y() = transMoved.Length() *(1.0f - Mathf::FAbs(transDir.Dot(dirY)));

		AVector vec = transDir.Cross(dirY);
		rolateVec.Y() *= Mathf::Sign(vec.Z());
	}
	else if (DT_Z == mDragType)
	{
		transValue = transMoved.Dot(dirZ);
		transVec = dirZ * transValue;

		rolateVec.Z() = transMoved.Length() *(1.0f - Mathf::FAbs(transDir.Dot(dirZ)));

		rolateVec.Z() *= Mathf::Sign(posNow.X() - posBefore.X());
	}
	else if (DT_XY == mDragType)
	{
		transValue = transMoved.Dot(dirX);
		transValue1 = transMoved.Dot(dirY);
		transVec = dirX * transValue + dirY * transValue1;
	}
	else if (DT_YZ == mDragType)
	{
		transValue = transMoved.Dot(dirY);
		transValue1 = transMoved.Dot(dirZ);
		transVec = dirY * transValue + dirZ * transValue1;
	}
	else if (DT_XZ == mDragType)
	{
		transValue = transMoved.Dot(dirX);
		transValue1 = transMoved.Dot(dirZ);
		transVec = dirX * transValue + dirZ * transValue1;
	}
	else if (DT_XYZ == mDragType)
	{
		float transValue0 = Mathf::FAbs(transMoved.Dot(dirX));
		float transValue1 = Mathf::FAbs(transMoved.Dot(dirY));
		float transValue2 = Mathf::FAbs(transMoved.Dot(dirZ));

		float trans = (transValue0 + transValue1 + transValue2) / 3.0f;
		trans *= Mathf::Sign(transMoved.Y());

		transVec = AVector(trans, trans, trans);
	}

	if (CT_SCALE == mCtrlType)
		transVec *= 0.5f;

	HMatrix parentMat = mParentRotateMat.Inverse();
	transVec = parentMat * transVec;

	if (CT_TRANSLATE == mCtrlType)
	{
		PX2_SELECTION.Translate(transVec);

		UpdateCtrlTrans();
	}
	else if (CT_ROLATE == mCtrlType)
	{
		PX2_SELECTION.AddRolate(rolateVec);
	}
	else if (CT_SCALE == mCtrlType)
	{
		if (DT_XYZ == mDragType)
			PX2_SELECTION.AddScale(transVec);
	}

	Object *obj = PX2_SELECTION.GetFirstObject();
	if (obj)
	{
		Event *ent = EditEventSpace::CreateEventX(
			EditEventSpace::ObjectTransformChanged);
		ent->SetData<Object*>(obj);
		EventWorld::GetSingleton().BroadcastingLocalEvent(ent);
	}

	mCtrlsGroup->Update(Time::GetTimeInSeconds(), false);
}