XNA Creators Club Online
Page 1 of 1 (3 items)
Sort Posts: Previous Next

Making Two Models Swap Positions

Last post 11/21/2009 2:23 PM by Kibokun. 2 replies.
  • 11/20/2009 12:44 PM

    Making Two Models Swap Positions

    So I've got a grid of cubes and I'd like to allow the player to swap positions with the cubes that are adjacent to it. Right now I have a 2d array of world matrices available to my game board class and I'm using Matrix.Lerp to animate between the two positions. However, when I originally created these matrices, I used Matrix.CreateTranslation to a vector scaled by the size of my cubes. However, I don't apply this when I swap positions, so the new positions of the cubes don't line up with the grid anymore because their movement hasn't been scaled. Is there any way to do this if I"m calculating the matrices this way? Code below:

    My first alignment on the grid:

    1             float sphereScale = Math.Max(pieceTransforms[0].M11, pieceTransforms[0].M22); 
    2             blockSize = blocks[0].Model.Meshes[0].BoundingSphere.Radius * sphereScale * 1.9f; 
    3  
    4             for (int y = 0; y < Height; y++) 
    5             { 
    6                 for (int x = 0; x < Width; x++) 
    7                 { 
    8                     Vector3 blockPos = new Vector3( 
    9                         (Width - 1) * -0.5f, (Height - 1) * -0.5f, 0.0f); 
    10                     blockPos += new Vector3(x, y, 0.0f); 
    11                     blockPos *= blockSize; 
    12  
    13                     Matrix transform = Matrix.CreateTranslation(blockPos); 
    14  
    15                     boardPositionMatrices[x, y] = transform; 
    16                     layout[x, y].World = transform; 
    17                 } 
    18             } 



    My swap position code:
    1                 Matrix toTransform, fromTransform; 
    2  
    3                 // Linearly interpolate between the world matrcies of the to and from blocks 
    4                 // to eventually end up with them both in the other's original positioning. 
    5                 Matrix.Lerp(ref boardPositionMatrices[shiftingBlocks[0].XLayoutPosition, 
    6                                                       shiftingBlocks[0].YLayoutPosition], 
    7                             ref boardPositionMatrices[shiftingBlocks[1].XLayoutPosition, 
    8                                                       shiftingBlocks[1].YLayoutPosition], 
    9                             currentShiftTime / shiftDuration, 
    10                             out fromTransform); 
    11                  
    12                 Matrix.Lerp(ref boardPositionMatrices[shiftingBlocks[1].XLayoutPosition, 
    13                                                       shiftingBlocks[1].YLayoutPosition], 
    14                             ref boardPositionMatrices[shiftingBlocks[0].XLayoutPosition, 
    15                                                       shiftingBlocks[0].YLayoutPosition], 
    16                             currentShiftTime / shiftDuration, 
    17                             out toTransform);  
    18  
    19  
    20                 shiftingBlocks[0].World = fromTransform; 
    21                 shiftingBlocks[1].World = toTransform; 


    Here is a picture showing the results of the swap of a cube with its left neighbor: http://imgur.com/uXRz6.jpg
  • 11/20/2009 1:18 PM In reply to

    Re: Making Two Models Swap Positions

    Since all of the blocks use the same offsets and scale, I think the easiest way to accomplish this would be to change how you're transitioning blocks. I would add an "in-between" state so you don't have to change the actual destination world transforms:
    class Block 
        Matrix Destination, PrevLocatation; 
        float TransitionAmount = 1.0f; 
        Matrix CurrentWorld 
        { 
            get 
            { 
                return Matrix.Lerp(PrevLocatation, Destination, TransitionAmount 
            } 
        } 
        ... 
     
        public static void SwapPositions(Block block1, Block block2) 
        { 
            block1.PrevLocatation = block1.CurrentWorld; 
            block2.PrevLocatation = block2.CurrentWorld; 
             
            block1.Destination = block2.CurrentWorld 
            block2.Destination = block1.CurrentWorld; 
     
            block1.TransitionAmount = 0.0f; 
            block2.TransitionAmount = 0.0f; 
        } 
     
        public void Update() 
        { 
            if(TransitionAmount < 1.0f) 
                TransitionAmount += 0.05f; 
            if(TransitionAmount > 1.0f) 
                TransitionAmount = 1.0f; 
        } 

    Then initialize Destination and PrevLocatation to what you're initializing the World matrix to in the code you posted, and use CurrentWorld instead of World everywhere else.
    "Software is never finished, it is in varying states of 'less broken'" because "If it ain't broke, it doesn't have enough features yet"

    In Playtest: Avatar Land | The MANLY Game for MANLY Men

    The signature that was too big for the 512 char limit
  • 11/21/2009 2:23 PM In reply to

    Re: Making Two Models Swap Positions

    This worked, but it needed one minor fix. Between setting the previous locations to CurrentWorld and setting the destinations, the return value of CurrentWorld changes. In fact, it flipped the sign of one of the matrix entries as it prepared to transform in the opposite direction (I presume.). So I just stored CurrentWorld for both blocks before setting it so the linear interpolation wouldn't start between those calls and cause one block not to move.

    Thanks again!
Page 1 of 1 (3 items) Previous Next