Advertisement Jump to content
Sign in to follow this  
MARS_999

How to stop camera from moving past an confined area

This topic is 1799 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have my camera confined to a aabb and now need to get the logic right for when the user moves the camera to the edge it will stop and just stay there vs, now I am testing when they move if the camera position isn't inside the box it just resets the camera back to the starting position. 

 

How can I just stop the camera at that position and not move it anymore until they move back into the aabb area?

 

Thanks!

Share this post


Link to post
Share on other sites
Advertisement

Rather than resetting the camera position when it's outside, do not let it move outside the box at all.

if ( Not_Inside_Box( requestedPosition ) ) return; // no change in position
cameraPos = requestedPosition; return;

If you want the camera to move as close as possible to the new position but remain in the box or on the edge of the box, find the intersection of the vector < requestedPosition-cameraPos > with the AABB, and that's your new camera position.

function GetCameraPosition()
{
     if (Not_Inside_Box( requestedPosition ) ) return Intersection_With_Box( vector( requestedPosition - cameraPos ) );
     return requestedPosition;
}
Edited by Buckeye

Share this post


Link to post
Share on other sites

Camera.position = getCameraPosition(Player.position);

if (camera.position.x<minX) camera.position.x=minX else if (camera.position.x>maxX) camera.position.x=maxX;

if (camera.position.y<minY) camera.position.y=minY else if (camera.position.y>maxY) camera.position.y=maxY;

 

-or-

A lot of Math libraries have a Clamp function... Clamp(value, minValue, maxValue)

tempCamPos = getCameraPosition(Player.position)

camera.position.x=Clamp(tempCamPos.x,minX,maxX)

camera.position.y=Clamp(tempCamPos.y,minY,maxY)

 

 

Share this post


Link to post
Share on other sites

Depending upon which SDK you are using, you might be able to put a collision mesh around your camera and do a collision test on the camera entity to stop it from passing through walls, IF that is what you are trying to do.

Share this post


Link to post
Share on other sites

Agreed, it's just a collision problem (either point vs. AABB or AABB vs. AABB). You wouldn't ask how to stop your main character passing through walls, what makes the camera any different?

Share this post


Link to post
Share on other sites

I am thinking that your guys solutions are what I am looking for... 

 

I am posting the code that is for the update of the camera, and let you look through it.

 

I am using Irrlicht, and this is someone else's RTS code base. Problem is I did try to do a if() return; and that messes up the camera position for some reason...

 

{ 
NX::App& app = NX::App::Get();
irr::core::aabbox3df aabb(-50.0f, -.5f, -50.0f,
 app.GetMapData().GetMapCenter().X * 2, 
 125.0f,
 app.GetMapData().GetMapCenter().Z * 2);
//static irr::core::vector3df prevCamPos(app.GetCamera()->getPosition());
 
if(!aabb.isPointInside(app.GetCamera()->getPosition()))
{
Target.set(0.0f, 0.0f, 0.0f);
oldTarget.set(0.0f, 0.0f, 0.0f);
rotX = 0;
rotY = 0;
NX::App::Get().GetCamera()->setPosition(NX::CAMERA_START_POS);
//irr::core::vector3df pos = app.GetCamera()->getPosition() - prevCamPos;
//NX::App::Get().GetCamera()->setPosition(app.GetCamera()->getPosition() - pos);
//prevCamPos = app.GetCamera()->getPosition();
}
 
irr::f32 nRotX = rotX;
irr::f32 nRotY = rotY;
irr::f32 nZoom = currentZoom;
 
irr::core::vector3df translate(oldTarget);
irr::core::vector3df tvectX = Pos - Target;
 
tvectX = tvectX.crossProduct(UpVector); 
tvectX.normalize(); 
 
   //Zoom 
   if (isMouseButtonDown(MOUSE_BUTTON_RIGHT) && isMouseButtonDown(MOUSE_BUTTON_LEFT)) 
   { 
      if (!zooming) 
      { 
         zoomStartX = MousePos.X; 
         zoomStartY = MousePos.Y; 
         zooming = true; 
         nZoom = currentZoom; 
      } 
      else 
      { 
 irr::f32 old = nZoom;
          nZoom += (zoomStartX - MousePos.X) * zoomSpeed * 100; 
 
//         f32 targetMinDistance = 0.1f; 
//         if (nZoom < targetMinDistance) 
//            nZoom = targetMinDistance; 
 
         if (nZoom < targetMinDistance) 
            nZoom = targetMinDistance; 
         else if (nZoom > targetMaxDistance) 
            nZoom = targetMaxDistance; 
 
 
         if (nZoom < 0) 
            nZoom = old; 
      } 
   } 
   else 
   { 
      if (zooming) 
      { 
 irr::f32 old = currentZoom;
         currentZoom = currentZoom + (zoomStartX - MousePos.X ) * zoomSpeed; 
         nZoom = currentZoom; 
 
         if (nZoom < 0) 
            nZoom = currentZoom = old; 
      } 
      zooming = false; 
   } 
 
   //Rotate 
   if(isMouseButtonDown(MOUSE_BUTTON_LEFT) && !zooming) 
   { 
      if (!rotating) 
      { 
         rotateStartX = MousePos.X; 
         rotateStartY = MousePos.Y; 
         rotating = true; 
         nRotX = rotX; 
         nRotY = rotY; 
      } 
      else 
      { 
         nRotX += (rotateStartX - MousePos.X) * rotateSpeed; 
         nRotY += (rotateStartY - MousePos.Y) * rotateSpeed; 
      } 
   } 
   else 
   { 
      if (rotating) 
      { 
         rotX = rotX + (rotateStartX - MousePos.X) * rotateSpeed; 
         rotY = rotY + (rotateStartY - MousePos.Y) * rotateSpeed; 
         nRotX = rotX; 
         nRotY = rotY; 
      } 
 
      rotating = false; 
   } 
 
   //Translate 
   if(isMouseButtonDown(MOUSE_BUTTON_RIGHT) && !zooming) 
   { 
      if (!translating) 
      { 
         translateStartX = MousePos.X; 
         translateStartY = MousePos.Y; 
         translating = true; 
      } 
      else 
      { 
         translate += tvectX * (translateStartX - MousePos.X) * translateSpeed; 
         translate.X += tvectX.Z * (translateStartY - MousePos.Y) * translateSpeed; 
         translate.Z -= tvectX.X * (translateStartY - MousePos.Y) * translateSpeed; 
 
         oldTarget = translate; 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_S)  || isKeyDown(irr::KEY_UP)    && !zooming) 
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0; 
         movevector.normalize(); 
 
         setPosition(getPosition() - movevector * translateSpeed); 
         setTarget(getTarget() - movevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_W)  || isKeyDown(irr::KEY_DOWN)  && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df movevector = getPosition() - getTarget();
         movevector.Y = 0; 
         movevector.normalize(); 
 
         setPosition(getPosition() + movevector * translateSpeed); 
         setTarget(getTarget() + movevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_A)  || isKeyDown(irr::KEY_LEFT)  && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
         setPosition(getPosition() - strafevector * translateSpeed); 
         setTarget(getTarget() - strafevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else if(isKeyDown(irr::KEY_KEY_D)  || isKeyDown(irr::KEY_RIGHT) && !zooming)
   { 
      if (!translating) 
         translating = true; 
      else 
      { 
 irr::core::vector3df totargetvector = getPosition() - getTarget();
         totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
         setPosition(getPosition() + strafevector * translateSpeed); 
         setTarget(getTarget() + strafevector * translateSpeed); 
         updateAbsolutePosition(); 
      } 
   } 
   else 
   { 
      translating = false; 
 
      if (!translating && !zooming && !rotating) 
      { 
         //Mouse Coordinates go from 0 to 1 on both axes 
         if (MousePos.X < 0.05)   //Up 
         { 
irr::core::vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
            setPosition(getPosition() - strafevector * translateSpeed); 
            setTarget(getTarget() - strafevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.X > 0.95) //Down 
         { 
irr::core::vector3df totargetvector = getPosition() - getTarget();
            totargetvector.normalize(); 
irr::core::vector3df crossvector = totargetvector.crossProduct(getUpVector());
irr::core::vector3df strafevector = crossvector.normalize();
 
            setPosition(getPosition() + strafevector * translateSpeed); 
            setTarget(getTarget() + strafevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.Y < 0.05)   //Up 
         { 
irr::core::vector3df movevector = getPosition() - getTarget();
            movevector.Y = 0; 
            movevector.normalize(); 
 
            setPosition(getPosition() - movevector * translateSpeed); 
            setTarget(getTarget() - movevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
         else if (MousePos.Y > 0.95) //Down 
         { 
irr::core::vector3df movevector = getPosition() - getTarget();
            movevector.Y = 0; 
            movevector.normalize(); 
 
            setPosition(getPosition() + movevector * translateSpeed); 
            setTarget(getTarget() + movevector * translateSpeed); 
            updateAbsolutePosition(); 
         } 
      } 
   } 
 
   //Set Position 
   Target = translate;
   
   Pos.X = nZoom + Target.X; 
   Pos.Y = Target.Y; 
   Pos.Z = Target.Z; 
 
//i added these if() statements
   if(nRotY > 180.0f)
nRotY = 180.0f;
   if(nRotY < 20.0f)
nRotY = 20.0f;
 
   Pos.rotateXYBy( nRotY, Target); 
   Pos.rotateXZBy(-nRotX, Target); 
 
   //Correct Rotation Error 
   UpVector.set(0,1,0); 
   UpVector.rotateXYBy(-nRotY, irr::core::vector3df(0,0,0)); 
   UpVector.rotateXZBy(-nRotX+180.f, irr::core::vector3df(0,0,0));
 
   //prevCamPos = app.GetCamera()->getPosition();
} 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!