3 Replies Latest reply on May 22, 2008 7:52 PM by Production Monkey

    Crude Perspective Math

    Applied CD Level 1
      My current project has a stock ticker where the stock symbols move left to right but they also move from “back” to “front” in perspective. The ticker symbols are fake, that is they are static bitmaps that never change, just eye candy that loops in the background. I’ve got the letters in the proper perspective for the background and I’ve got a basic motion and scaling tween that looks realistic except for velocity. The problem with a simple tween is that it divides the horizontal sprite movement between frames evenly. For the sprite to appear to be moving at constant velocity it actually needs to move slowly while in the distance and accelerate as it moves to the foreground so obviously it’s going to have to be moved by lingo. I’m going to experiment but I’m wondering if there’s a standard formula that could compute the horizontal increment for each frame (there’s very little vertical movement, so that axis can be ignored). Is it a simple linear or log acceleration? I’ve been working with Director for over 10 years but never seriously messed with the 3D features, I’m assuming creating a 3D sprite would be more effort than this is worth. Here’s what I’ve got to work with:

      I know the start and stop X coordinate for the moving sprite
      I know the number of frames spanned by the tween
      I’ve got the correct start and stop sprite scale
      The background graphic has a sort of grid in perspective so I can compare the number of pixels in a foreground grid box to the number of pixels in a background grid box.
        • 1. Re: Crude Perspective Math
          Production Monkey Level 3
          You don't need any "log acceleration" or anything particularly complicated. By tapping into Director's 3D math capabilities you can apply 3D effects to 2D bitmap sprites. The trick is to manupulate the Quad property of the sprite and to rotate or translate the four points that make up a quad in 3D space.

          Below is a Parent script that handles all the math and a sample behavior to attach to the sprite. I added some rotation to the script for fun, but for your needs just delete that line of code.

          -- 3D quad sample

          Property pMe
          Property p3D_Quad

          on beginsprite me
          pMe = sprite(me.spriteNum)
          p3D_Quad = script("Quad3D").new(pMe.quad, pMe.member.regpoint)

          on exitframe me
          p3D_Quad.rotate(0,2,0) -- for fun we add some rotation

          NewQuad = p3D_Quad.get2DQuad()
          pMe.quad = NewQuad

          Parent Script
          -- Quad3D

          Property pScreenCenter
          Property pQuadTransforms
          Property pRegpoint
          Property pEyeDistance
          Property pClipping
          Property pUnitX
          Property pUnitY
          Property pUnitZ

          on new me, aQuad, regPoint
          pScreenCenter = point((the stage).rect.width/2, (the stage).rect.height/2)
          pQuadTransforms = []
          repeat with aPoint in aQuad
          aPoint = aPoint - pScreenCenter
          aTrans = transform()
          aTrans.translate(aPoint[1], aPoint[2], 0)
          end repeat

          aPoint = aQuad[1] + (aQuad[3] - aQuad[1]) / 2
          aPoint = aPoint - pScreenCenter
          pRegpoint = transform()
          pRegpoint.translate(aPoint[1], aPoint[2], 0)

          pEyeDistance = 500 -- changing this number changes the perspective
          pClipping = -450 -- very very important.

          pUnitX = vector(1,0,0)
          pUnitY = vector(0,1,0)
          pUnitZ = vector(0,0,1)

          return me

          on translate me, x, y, z
          repeat with aTranform in pQuadTransforms
          end repeat
          end translate

          on rotate me, x, y, z
          RegPos = pRegpoint.position
          repeat with aTranform in pQuadTransforms
          aTranform.rotate(RegPos, pUnitX, x)
          aTranform.rotate(RegPos, pUnitY, y)
          aTranform.rotate(RegPos, pUnitZ, z)
          end repeat
          end rotate

          on get2DQuad me
          Quad = []
          repeat with aTranform in pQuadTransforms
          X = aTranform.position.x / ( 1 + (aTranform.position.z / pEyeDistance))
          Y = aTranform.position.y / ( 1 + (aTranform.position.z / pEyeDistance))
          aPoint = point(X,Y) + pScreenCenter
          end repeat
          return Quad
          end get2DQuad
          • 2. Re: Crude Perspective Math
            Applied CD Level 1
            Hey, that’s too cool … thanks. It’s gonna take a few tweaks to get the text to look like it’s projected on the wall surface but I foresee lots of 3D flying sprites in our future.
            • 3. Re: Crude Perspective Math
              Production Monkey Level 3
              Glad I could help.