Changeset 693

Show
Ignore:
Timestamp:
07/05/07 19:41:49 (17 months ago)
Author:
leo
Message:

Allow fixed orientation for control points.

Location:
trunk/common
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/common/lc_flexpiece.cpp

    r692 r693  
    2424        lcFlexiblePiecePoint* Point = new lcFlexiblePiecePoint(this); 
    2525        Point->SetPosition(1, true, Vector3(0.0f, 0.0f, 1.0f * i)); 
     26 
     27        if (i == 1 || i == 2) 
     28            Point->SetFlag(LC_FLEXPIECE_POINT_TANGENT); 
    2629 
    2730        if (Last) 
     
    5356        NewPoint->m_ParentPosition = Point->m_ParentPosition; 
    5457 
     58        NewPoint->m_Flags = Point->m_Flags; 
     59 
    5560        if (Last) 
    5661            Last->m_Next = NewPoint; 
     
    184189    delete m_Mesh; 
    185190    m_Mesh = NULL; 
    186  
    187     ObjArray<Vector3> ControlPoints(16); 
    188     for (lcObject* Point = m_Children; Point; Point = Point->m_Next) 
    189         ControlPoints.Add(Point->m_ParentPosition); 
    190191 
    191192    int NumSections = 3; 
     
    203204 
    204205    // Calculate the initial rotation matrix for the curve points. 
    205     Vector3 Z = Normalize(Vector3(ControlPoints[1]) - Vector3(ControlPoints[0])); 
     206    Vector3 Z = Normalize(m_Children->m_Next->m_ParentPosition - m_Children->m_ParentPosition); 
    206207 
    207208    // Build the Y vector of the matrix. 
     
    221222    Matrix33 LastMat = Matrix33(Normalize(X), Normalize(Y), Normalize(Z)); 
    222223 
    223     for (int i = 0; i < ControlPoints.GetSize() - 1; i++) 
    224     { 
    225         Vector3 p0, p1, p2, p3; 
    226  
    227         if (i == 0) 
    228         { 
    229             p0 = Vector3(ControlPoints[0]); 
    230             p1 = Vector3(ControlPoints[0]); 
    231             p2 = Vector3(ControlPoints[1]); 
    232             p3 = Vector3(ControlPoints[2]); 
    233         } 
    234         else if (i == ControlPoints.GetSize() - 2) 
    235         { 
    236             p0 = Vector3(ControlPoints[i-1]); 
    237             p1 = Vector3(ControlPoints[i]); 
    238             p2 = Vector3(ControlPoints[i+1]); 
    239             p3 = Vector3(ControlPoints[i+1]); 
    240         } 
     224    lcFlexiblePiecePoint* PrevPoint = (lcFlexiblePiecePoint*)m_Children; 
     225    lcFlexiblePiecePoint* Point = (lcFlexiblePiecePoint*)m_Children; 
     226    lcFlexiblePiecePoint* NextPoint = (lcFlexiblePiecePoint*)m_Children->m_Next; 
     227    int Segment = 0; 
     228 
     229    while (NextPoint) 
     230    { 
     231        Matrix33 StartMat, EndMat; 
     232 
     233        Vector3 p0 = PrevPoint->m_ParentPosition; 
     234        Vector3 p1 = Point->m_ParentPosition; 
     235        Vector3 p2 = NextPoint->m_ParentPosition; 
     236        Vector3 p3 = NextPoint->m_Next ? NextPoint->m_Next->m_ParentPosition : NextPoint->m_ParentPosition; 
     237 
     238        // Calculate the start and end orientation for this curve segment. 
     239        if (Point->IsFlagged(LC_FLEXPIECE_POINT_TANGENT)) 
     240            StartMat = LastMat; 
    241241        else 
    242         { 
    243             p0 = Vector3(ControlPoints[i-1]); 
    244             p1 = Vector3(ControlPoints[i]); 
    245             p2 = Vector3(ControlPoints[i+1]); 
    246             p3 = Vector3(ControlPoints[i+2]); 
    247         } 
     242            StartMat = Point->m_ModelParent; 
     243 
     244        if (NextPoint->IsFlagged(LC_FLEXPIECE_POINT_TANGENT)) 
     245        { 
     246            // Make the tangent at this point be parallel to a vector between the point before and after it. 
     247            Vector3 Tan = p3 - p1; 
     248 
     249            Tan.Normalize(); 
     250            float Dot = Dot3(StartMat[2], Tan); 
     251 
     252            if (Dot < 0.999f) 
     253            { 
     254                Vector3 Axis = Cross3(StartMat[2], Tan); 
     255                float Angle = acosf(Dot); 
     256 
     257                Matrix33 Rot = MatrixFromAxisAngle(Axis, Angle); 
     258                EndMat = Mul(StartMat, Rot); 
     259            } 
     260            else 
     261                EndMat = StartMat; 
     262        } 
     263        else 
     264            EndMat = NextPoint->m_ModelParent; 
     265 
     266        float Dot = Dot3(StartMat[2], EndMat[2]); 
     267        Vector3 Axis; 
     268        float Angle; 
     269 
     270        if (Dot < 0.999f) 
     271        { 
     272            Axis = Cross3(StartMat[2], EndMat[2]); 
     273            Angle = acosf(Dot); 
     274        } 
     275        else 
     276        { 
     277            Axis = Vector3(0, 0, 1); 
     278            Angle = 0; 
     279        } 
     280 
     281        // Calculate the coefficients of a bezier curve that passes through the 2 end points 
     282        // for this segment and has the tangent vectors calculated above. 
     283        p0 = p1; 
     284        p3 = p2; 
     285 
     286        float Len = Length(p1-p2) * 0.5f; 
     287        p1 = p1 + StartMat[2] * Len; 
     288        p2 = p2 - EndMat[2] * Len; 
     289 
     290        Matrix44 Points = Matrix44(Vector4(p0, 1), Vector4(p1, 1), Vector4(p2, 1), Vector4(p3, 1)); 
    248291 
    249292        for (int j = 0; j < NumSegments; j++) 
    250293        { 
     294            static Matrix44 Blend(Vector4(-1, 3, -3, 1), Vector4(3, -6, 3, 0), Vector4(-3, 3, 0, 0), Vector4(1, 0, 0, 0));   
     295            static Matrix44 Tangent(Vector4(0, 0, 0, 0), Vector4(-3, 9, -9, 3), Vector4(6,-12, 6, 0), Vector4(-3, 3, 0, 0));   
     296 
    251297            float t = (float)j/(NumSegments-1); 
    252             float t2 = t * t; 
    253             float t3 = t2 * t; 
    254  
    255             Vector3 Pos = 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); 
    256             Vector3 Tan = 0.5f * ((-p0 + p2) + 2 * (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t + 3 * (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t2); 
     298 
     299            Vector3 Pos = Vector3(Mul4(Mul4(Vector4(t*t*t,t*t,t,1), Blend), Points));   
     300            Vector3 Tan = Vector3(Mul4(Mul4(Vector4(0,t*t,t,1), Tangent), Points));   
    257301 
    258302            Tan.Normalize(); 
     
    267311                LastMat = Mul(LastMat, Rot); 
    268312            } 
     313 
     314            int IndexOffset = NumSlices * NumSegments * Segment; 
    269315 
    270316            for (int k = 0; k < NumSlices; k++) 
     
    279325                    if (k != NumSlices-1) 
    280326                    { 
    281                         MeshEdit.AddIndex(j * NumSlices + k); 
    282                         MeshEdit.AddIndex(j * NumSlices + k + 1); 
    283                         MeshEdit.AddIndex((j+1) * NumSlices + k); 
    284                         MeshEdit.AddIndex(j * NumSlices + k + 1); 
    285                         MeshEdit.AddIndex((j+1) * NumSlices + k + 1); 
    286                         MeshEdit.AddIndex((j+1) * NumSlices + k); 
     327                        MeshEdit.AddIndex(IndexOffset +    j * NumSlices + k); 
     328                        MeshEdit.AddIndex(IndexOffset +    j * NumSlices + k + 1); 
     329                        MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); 
     330                        MeshEdit.AddIndex(IndexOffset +    j * NumSlices + k + 1); 
     331                        MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k + 1); 
     332                        MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); 
    287333                    } 
    288334                    else 
    289335                    { 
    290                         MeshEdit.AddIndex(j * NumSlices + k); 
    291                         MeshEdit.AddIndex(j * NumSlices); 
    292                         MeshEdit.AddIndex((j+1) * NumSlices + k); 
    293                         MeshEdit.AddIndex(j * NumSlices); 
    294                         MeshEdit.AddIndex((j+1) * NumSlices); 
    295                         MeshEdit.AddIndex((j+1) * NumSlices + k); 
     336                        MeshEdit.AddIndex(IndexOffset +    j * NumSlices + k); 
     337                        MeshEdit.AddIndex(IndexOffset +    j * NumSlices); 
     338                        MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); 
     339                        MeshEdit.AddIndex(IndexOffset +    j * NumSlices); 
     340                        MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices); 
     341                        MeshEdit.AddIndex(IndexOffset + (j+1) * NumSlices + k); 
    296342                    } 
    297343                } 
     
    299345        } 
    300346 
    301         MeshEdit.OffsetIndices(6 * (NumSlices) * (NumSegments-1) * i, 6 * (NumSlices) * (NumSegments-1), NumSlices * NumSegments * i); 
     347        LastMat = EndMat; 
     348 
     349        PrevPoint = Point; 
     350        Point = NextPoint; 
     351        NextPoint = (lcFlexiblePiecePoint*)Point->m_Next; 
     352 
     353        Segment++; 
    302354    } 
    303355 
     
    317369{ 
    318370    m_Parent = Parent; 
     371 
     372    ChangeKey(0, false, LC_PIECEOBJ_ROTATION, Vector4(0, 0, 1, 0)); 
    319373} 
    320374 
     
    325379void lcFlexiblePiecePoint::Update(u32 Time) 
    326380{ 
     381    Vector4 AxisAngle; 
     382 
    327383    CalculateKey(Time, LC_FLEXPIECE_POINT_POSITION, &m_ParentPosition); 
    328     m_WorldPosition = Mul31(m_ParentPosition, ((lcPieceObject*)m_Parent)->m_ModelWorld); 
     384    CalculateKey(Time, LC_PIECEOBJ_ROTATION, &AxisAngle); 
     385 
     386    m_ModelParent = MatrixFromAxisAngle(AxisAngle); 
     387    m_ModelParent.SetTranslation(m_ParentPosition); 
     388 
     389    m_ModelWorld = Mul(m_ModelParent, ((lcPieceObject*)m_Parent)->m_ModelWorld); 
     390    m_WorldPosition = Vector3(m_ModelWorld[3]); 
    329391} 
    330392 
     
    341403 
    342404    RenderSection.Owner = (lcPieceObject*)this; 
    343     RenderSection.ModelWorld = Mul(ScaleMatrix, ModelWorld);; 
     405    RenderSection.ModelWorld = Mul(ScaleMatrix, ModelWorld); 
    344406    RenderSection.Mesh = lcSphereMesh; 
    345407    RenderSection.Section = &lcSphereMesh->m_Sections[0]; 
  • trunk/common/lc_flexpiece.h

    r691 r693  
    3535{ 
    3636    LC_FLEXPIECE_POINT_POSITION, 
     37    LC_FLEXPIECE_POINT_ROTATION, 
    3738    LC_FLEXPIECE_POINT_NUMKEYS 
    3839}; 
     40 
     41// Flexible piece point flags. 
     42#define LC_FLEXPIECE_POINT_TANGENT  0x0100 
    3943 
    4044class lcFlexiblePiecePoint : public lcObject 
     
    4953    virtual void Update(u32 Time); 
    5054    virtual void AddToScene(lcScene* Scene, int Color); 
     55 
     56public: 
     57    Matrix44 m_ModelParent; 
     58    Matrix44 m_ModelWorld; 
    5159}; 
    5260