Saturday, November 9, 2013

Blender3D GameKit Lua Plane Top Bottom Constraint



The top bottom constraint is a bit tricky. As camera keeps moving with plane. I used camera as a reference to calcuate the top and bottom screen edge.
1. Get camera position
2. Calculate current top edge Y location
3. Calculate current bottom edge Y location
4. Compare with current plane location, and return signals, -1 as plane too low, 1 as plane too high, 0 for plane inside the screen
5. feed the signal and mouse movement to function edgeMoveFilter, which only permit plane move toward centre if it is on edge
The code is below and red marks are comments.
******Oninit.lua****************
    --Global variable
    --set touch move parameters
    Sensitivity = 0.005
    --invert = -1 -> is inverted
    Invert = 1
    Threshold=3.5
 -- Plane Contrain
    Xmin = -0.87
    Xmax = 0.87
 -- Plane Top Bottom Constrain
    Ymin = -1.50
    Ymax = 1.30
--filter movement so plane will only move towards center if touchs edge
function edgeMoveFilter(limitSignal,oldX)
    if limitSignal == -1 and oldX > 0 then
        return oldX
    elseif limitSignal == -1 and oldX < 0 then
        return 0
    elseif limitSignal == 1 and oldX >0 then
        return 0
    elseif limitSignal ==1 and oldX <0 then
        return oldX
    end
        return 0
end   

--check if over boundary on Y axis
function YoverLimit(obj,cameraObj)
    local vec3 = obj:getPosition()
    local cameraV = cameraObj:getLinearVelocity()
    --get camero position
    local cameraP = cameraObj:getPosition()
    --calculate bottom edge ;ocation
    local nextYmin = cameraP.y+Ymin
    --calculate top edge location
    local nextYmax = cameraP.y+Ymax
    --check whether plane is on edge and return signals
    if vec3.y < nextYmin then
        return -1
    elseif vec3.y > nextYmax then
        return 1
    else 
        return 0
    end
end

--endNew-----------
function XoverLimit(obj)
    local vec3 = obj:getPosition()
    if vec3.x < Xmin then
        return -1
    elseif vec3.x > Xmax then
        return 1
    else
        return 0
    end
end
function printPosition(obj)
    local vec3 = obj:getPosition()
    dPrintf("position x: " .. vec3.x)
    dPrintf("position y: " .. vec3.y)
    dPrintf("position z: " .. vec3.z)
    
end    
function velocityCap(v,vmax)
    if (v>vmax) then
        return vmax
    elseif (v < -vmax) then
        return -vmax
    else return v
    end
end

******planeTouchMove.lua****************  

mouse=OgreKit.Mouse()
scene = OgreKit.getActiveScene()
play = scene:getObject("plane")
--new--get camera objcet
camera = scene:getObject("Camera")
--end new---------------------------
logicM = OgreKit.LogicManager()
myLogicObject = logicM:getObject("plane")
mySensor = myLogicObject:getSensor("Collision")
maxVelocity=0.08


mouse:capture()
--print current plane posistion on screen
--printPosition(play)
--using threshold to filter out unwanted small touch movement

if ((mouse.xrel>Threshold or mouse.xrel<-Threshold)or(mouse.yrel>Threshold or mouse.yrel<-Threshold)and (not(play.touchBoundary))) then
      velocityY=velocityCap((mouse.yrel) * Sensitivity, maxVelocity)
      velocityX=velocityCap((mouse.xrel) * Sensitivity, maxVelocity) 
      --new----------------------
      --check if plane over screen boundary 
      limitSignalX = XoverLimit(play)
      limitSignalY = YoverLimit(play,camera)
      --the X Y directions are swap as the screen is in landscape
      if limitSignalX==0  and limitSignalY == 0 then
      --when plane is inside boundary
        play:translate(-velocityY* Invert,-velocityX * Invert,0)
      else
      --when plane touches boundary it can only move away from boundrary
        newY = edgeMoveFilter(limitSignalX,-velocityY * Invert)
        newX = edgeMoveFilter(limitSignalY,-velocityX * Invert)
        play:translate(newY,newX,0)
      end
      --end new---------------------
end


  


    

No comments:

Post a Comment