1 Reply Latest reply on Jun 27, 2006 9:45 PM by Roofy

    Using ModelsUnderRay Collision detection

    Roofy Level 1
      Ok first things first. I know you guys who have been reading my other post is going to get confused after reading this post so let me make myself clear. First yes I was previously trying to Havok, but I could not get my car to work with it. So This is why I am now asking stuff about ModelsUnderRay collision detection.

      Second, I found this tutorial at http://www.fbe.unsw.edu.au/learning/director/, and all things seem to go pretty good with using the max File the tutorial uses. Meaning I have not tried this on my car as of yet. In addition, considering that things seem to work with the tutorial, I now came up with a new question. Basically, if I am correct, I think by using the code below, this is not going to work with my car when the car is going up a hill. I conclude this by knowing that the tutorial just uses a character, meaning it is not like a using something like a car that has a chassis and 4 wheels. So my question is this... How can I get the chassis to follow the angle of the hill if I am using a behaviour that looks something like this...

      on collisionDetect me

      -- create a list to store collision data created by modelsUnderRay
      -- cast ray to left
      collisionList = p3Dmember.modelsUnderRay(pCharacter.worldPosition, \
      -pCharacter.transform.yAxis,#detailed)

      -- if models picked up by ray, then activate checkForCollion
      -- handler and send the collisionList as a parameter
      if (collisionList.count) then me.checkForCollision(collisionList[1])

      -- cast ray to right
      collisionList = p3Dmember.modelsUnderRay(pCharacter.worldPosition, \
      pCharacter.transform.yAxis,#detailed)

      -- if models picked up by ray, then check for collision
      if (collisionList.count) then me.checkForCollision(collisionList[1])

      -- cast ray forward
      collisionList = p3Dmember.modelsUnderRay(pCharacter.worldPosition, \
      pCharacter.transform.xAxis,#detailed)

      -- if models picked up by ray, then check for collision
      if (collisionList.count) then me.checkForCollision(collisionList[1])

      -- cast ray backward
      collisionList = p3Dmember.modelsUnderRay(pCharacter.worldPosition, \
      -pCharacter.transform.xAxis,#detailed)

      -- if models picked up by ray, then check for collision
      if (collisionList.count) then me.checkForCollision(collisionList[1])

      end


      on checkForCollision me, collisData

      -- grab the #distance value from the CollisionList
      dist = collisData.distance

      -- check if distance is less than width of bounding box
      if (dist < pCharBoundingBox.resource.width ) then

      -- get distance of penetration
      diff = pCharBoundingBox.resource.width - dist

      -- calculate vector perpendicular to the wall's surface to move the character
      -- using the #isectNormal property
      tVector = collisData.isectNormal * diff

      -- move the character in order to resolve the collision
      pCharacter.translate(tVector,#world)

      end if

      end


      on keyDown

      -- check to see which key has been pressed
      -- and set the property relating to that key to TRUE
      if keypressed(123) then pLeftArrow = TRUE -- 123 = left arrow key
      if keypressed(124) then pRightArrow = TRUE -- 124 = right arrow key
      if keypressed(125) then pDownArrow = TRUE -- 125 = down arrow key
      if keypressed(126) then pUpArrow = TRUE -- 125 = up arrow key

      -- if 'r' key pressed, return character to starting position
      if keypressed("r") then resetCharacter

      -- if 'c' key is pressed, then switch camera
      if keypressed("c") then changeCamera

      end


      on keyUp
      -- when the arrow keys are released, set the properties to FALSE
      pLeftArrow = FALSE
      pRightArrow = FALSE
      pUpArrow = FALSE
      pDownArrow = FALSE
      end


      on exitFrame
      characterMove
      end


      on characterMove

      -- if the right arrow is pressed,
      -- rotate the character 5 degrees about the z-axis
      if pRightArrow then pCharacter.rotate(0,0,-5)

      --if the right arrow is pressed,
      -- rotate character -5 degrees about the z-axis
      if pLeftArrow then pCharacter.rotate(0,0,5)

      -- if the up arrow is pressed,
      -- move the character 5 pixels along the y-axis
      if pUpArrow then pCharacter.translate(0,5,0)

      -- if the down arrow is pressed,
      -- move the character -5 pixels along the y-axis
      if pDownArrow then pCharacter.translate(0,-5,0)


      -- move along terrain
      -- create reference for terrain (ground)
      terrain = p3Dmember.model("Terrain")

      -- store character's position
      charPos = pCharacter.worldPosition
      charPos.y = charPos.y - 20

      -- cast a ray down
      collisData = p3Dmember.modelsUnderRay(charPos,vector(0,0,-1),#detailed)

      -- if model is picked up on ray.
      if collisData.count then

      -- store total no of models detected by the ray
      totalCount = collisData.count

      repeat with modelNo = 1 to totalCount

      -- check if over the terrain model
      if (collisData[modelNo].model = terrain) then

      terrainPos = collisData[modelNo].isectPosition

      -- find out the distance the character should move up or down
      diff = (terrainPos.z - pCharacter.worldPosition.z)+45

      -- move the character
      pCharacter.translate(0,0,diff,#world)


      end if

      end repeat

      end if

      end
        • 1. Re: Using ModelsUnderRay Collision detection
          Roofy Level 1
          ok,
          I have been trying to work this out for ahwile and I got pretty close on getting this correct but there are still some glitches. So far I did a little research in the help files to see what the dot product does and this is how I got my calculations going so far

          --the code
          on beginSprite me
          I created 2 spheres and a box. Next, I then positioned them so that the first sphere is alligned with the front end of the box and then I aligned the second sphere to back of the box. I will not show you the code of beginSprite because all this does is for creating the models and there are no calculations going inside this handler. In addition, with these 3 models, my purpose is to say lets prtend that the box is the chasis of the car and the sphere that is placed at the frent end of the chassis are to represemt the 2 front wheels and the othere sphere is to represent the 2 back wheels of the car. Also, I initlalised a timer to the following below
          pTimer = (the milliseconds)
          end beginSprite
          ... note The timere is just for purposes of simulating a pretend upward movement for the wheels. See below which should explain it better then I can say it in words.

          --the code below is the calculations. The translations is for saying that I am pretending that the wheels are inclining up a hill. However, the wheels in the true game will be getting calculated by finding the distance of collion by using the modelsUnderRay function just like you normally would. By the way, all models and the camera are set to y is the up vector

          on exitFrame
          if ((the milliseconds) - pTimer) > 1000 then -- increment the calculations every one second
          pBall1.translate(0, 0.125, 0) -- This is for saying that this is the calculations that I am calculating the front wheels need to move up when they incline up the hill.
          pBall2.translate(0, -0.125, 0) -- Just like the front wheel pretend calulations but for the back wheels, and use a negative translate.
          pos1 = pBall1.transform.position -- get the calculated position for the front wheels
          pos2 = pBall2.transform.position -- get the calculated position for the back wheels
          norm1 = pos1.getnormalized() -- not sure I understand this, but in the help files, it says that when you calculate the dot product of 2 vectors that have been normalized, you then get their cosine
          norm2 = pos2.getNormalized() -- normalize the back wheels position
          dotProduct = norm1.dot(norm2) -- calculate the dot product of the 2 vectors
          pBox.rotate(dotAngle, 0, 0) -- I took a guess and thought that using the dotProduct will allow me to correctly rotate the chassis but the chassis is quite not rotating correctlly
          pTimer = (the milliseconds) -- update the timer so that we can recyle the above code again
          end if
          end exitFrame

          ... Ok, now like I said previously, the chassis is rotating almost correctlly, but if you continue to do this, and by after the third cycle, the front end wheels start to collide with the chassis. So in other words, the rotations look correct untill exitFrame is called for the third time and after which then the front wheels start to collide with the chassis.

          So I am wondering if anyone could help me out to fix this and explain what I am doing wrong?