//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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; } }
//---------------------------------------------------------------------------- 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; } }
//---------------------------------------------------------------------------- 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; } }
//---------------------------------------------------------------------------- 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); }
//---------------------------------------------------------------------------- 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); }