Advertisement
Guest User

ddd

a guest
Aug 22nd, 2014
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.87 KB | None | 0 0
  1. local Player = game.Players.LocalPlayer
  2. local Screen = script.Parent
  3. local Camera = workspace.CurrentCamera
  4.     local FieldOfView   = Camera.FieldOfView --//will be abbreviated as FOV when paired with other words (e.g. MyFOV)
  5.     local XY_FOV_RATIO  = .7 --//The X and Y axis do not both cover 70 degrees, so this scales it down  
  6.  
  7.  
  8. --//returns four vectors in a table such that:
  9. --//table.x = [x lower bound lookvector, x upper bound lookvector]
  10. --//table.y = [y lower bound lookvector, y upper bound lookvector]
  11. --//input cameraDirection is the camera CFrame, fieldOfView is the Field of View in radians
  12.  
  13. local function GetCameraBoundsInCameraSpace(fieldOfView)
  14.     local RadianHalfFOV = math.rad(fieldOfView*.5)
  15.  
  16.     --//Finds all the lookVector camera bounds via rotation
  17.     local LowerCameraBoundY = CFrame.Angles( RadianHalfFOV,0,0).lookVector
  18.     local UpperCameraBoundY = CFrame.Angles(-RadianHalfFOV,0,0).lookVector
  19.    
  20.     --//Y is straight foreward because FOV is based off of it, we have to
  21.     --//do some modifications for X though
  22.    
  23.     local ScaleFromYtoX = Screen.AbsoluteSize.X/Screen.AbsoluteSize.Y  
  24.    
  25.     local UpperCameraBoundYHeight = UpperCameraBoundY.Y
  26.     local UpperCameraBoundYDepth  = UpperCameraBoundY.Z
  27.    
  28.     local UpperCameraBoundXSize   = UpperCameraBoundYHeight*ScaleFromYtoX
  29.    
  30.    
  31.     local LowerCameraBoundX = Vector3.new(-UpperCameraBoundXSize,0,UpperCameraBoundYDepth).unit
  32.     local UpperCameraBoundX = Vector3.new( UpperCameraBoundXSize,0,UpperCameraBoundYDepth).unit
  33.  
  34.     local X_FOVAngle = math.deg(2*math.atan(UpperCameraBoundXSize/UpperCameraBoundYDepth)) --simply 2tan^-1(y/x)
  35.  
  36.     return {
  37.         X = {["Lower"] = LowerCameraBoundX, ["Upper"] = UpperCameraBoundX};
  38.         Y = {["Lower"] = LowerCameraBoundY, ["Upper"] = UpperCameraBoundY};
  39.        
  40.         X_FOV = X_FOVAngle;
  41.         Y_FOV = fieldOfView; --//Also returns field of view for math purposes
  42.     }
  43. end
  44.  
  45.  
  46. --//returns a normalised vector projected onto an object-space plane on the camera
  47. local function ProjectVectorOntoCameraPlane(cameraDirection, vectorPointingToPart, plane)
  48.     local ProjectedVector --//vectorPointingToPart projected onto plane
  49.  
  50.     local CameraObjectSpaceVector;
  51.     --//essentially the X component on the screen
  52.     if plane == "XZ" then
  53.         CameraObjectSpaceVector = cameraDirection:vectorToObjectSpace(vectorPointingToPart)
  54.         ProjectedVector         = Vector3.new(CameraObjectSpaceVector.x,0,CameraObjectSpaceVector.z) --//removes Y component so the vector becomes 2D on XZ
  55.  
  56.     --//essentially the Y component on the sreen
  57.     elseif plane == "YZ" then
  58.         CameraObjectSpaceVector = cameraDirection:vectorToObjectSpace(vectorPointingToPart)
  59.         ProjectedVector         = Vector3.new(0,CameraObjectSpaceVector.y,CameraObjectSpaceVector.z) --//removes Z component so the vector becomes 2D on XY
  60.     end
  61.  
  62.     return ProjectedVector.unit
  63. end
  64.  
  65.  
  66. --//returns a normalized vector pointing from from to to (heh)
  67. local function PointToVector3(from, to)
  68.     return (to-from).unit
  69. end
  70.  
  71. --//returns angles between vectors in degrees
  72. local function FindDegreesBetweenVectors(vector1, vector2)
  73.     return math.deg(math.acos(vector1.unit:Dot(vector2.unit)))
  74. end
  75.  
  76. --//returns Absolute X and Absolute Y positions of a 3D position
  77. local function ObtainScreenPositionFrom3DPosition(position, camera, fieldOfView)
  78.     local ObjectIsOutsideOfScreenBounds = false
  79.     local AbsoluteXPosition;
  80.     local AbsoluteYPosition;
  81.  
  82.     --//General X and Y position stuff
  83.         local DirectionToPartFromCamera  = PointToVector3(camera.CoordinateFrame.p,position)
  84.         local CameraBounds = GetCameraBoundsInCameraSpace(fieldOfView) --//this can be moved outside the function and achieve the same effect
  85.  
  86.         local FieldOfViewAlongXAxis = CameraBounds.X_FOV
  87.         local FieldOfViewAlongYAxis = CameraBounds.Y_FOV --//the same as fieldOfView ALWAYS
  88.  
  89.     --//Finding the approximate X pixel value
  90.         local PartDirectionInCameraSpaceXZ = ProjectVectorOntoCameraPlane(camera.CoordinateFrame, DirectionToPartFromCamera, "XZ")
  91.    
  92.         local AngleFromLowerBoundX = FindDegreesBetweenVectors(CameraBounds.X.Lower, PartDirectionInCameraSpaceXZ)
  93.         local AngleFromUpperBoundX = FindDegreesBetweenVectors(CameraBounds.X.Upper, PartDirectionInCameraSpaceXZ)
  94.  
  95.         if AngleFromLowerBoundX <= FieldOfViewAlongXAxis and AngleFromUpperBoundX <= FieldOfViewAlongXAxis then --//if it doesn't extends beyond the degrees in the FOV
  96.             AbsoluteXPosition = (AngleFromUpperBoundX / FieldOfViewAlongXAxis) * Screen.AbsoluteSize.X --//basically ratio of way across screen (yes, scale!) * #pixels
  97.         else
  98.             ObjectIsOutsideOfScreenBounds = true
  99.         end
  100.  
  101.     --//Finding the approximate Y pixel value
  102.         local PartDirectionInCameraSpaceXY = ProjectVectorOntoCameraPlane(camera.CoordinateFrame, DirectionToPartFromCamera, "YZ")
  103.    
  104.    
  105.         local AngleFromLowerBoundY = FindDegreesBetweenVectors(CameraBounds.Y.Lower, PartDirectionInCameraSpaceXY)
  106.         local AngleFromUpperBoundY = FindDegreesBetweenVectors(CameraBounds.Y.Upper, PartDirectionInCameraSpaceXY)
  107.  
  108.         if AngleFromLowerBoundY <= FieldOfViewAlongYAxis and AngleFromUpperBoundY <= FieldOfViewAlongYAxis then --//if it doesn't extends beyond the degrees in the FOV
  109.             AbsoluteYPosition = (AngleFromLowerBoundY / FieldOfViewAlongYAxis) * Screen.AbsoluteSize.Y --//basically ratio of way across screen (yes, scale!) * #pixels
  110.         else
  111.             ObjectIsOutsideOfScreenBounds = true
  112.         end
  113.  
  114.     return ObjectIsOutsideOfScreenBounds and Vector2.new(0,0) or Vector2.new(AbsoluteXPosition, AbsoluteYPosition)
  115. end
  116.  
  117.  
  118. --//main body ok
  119.  
  120.  
  121. local function main()
  122.     local GUIThing = Instance.new("Frame",Screen)  
  123.         GUIThing.Size = UDim2.new(0,5,0,5)
  124.    
  125.  
  126.     while wait() do
  127.  
  128.         local cameraBounds = GetCameraBoundsInCameraSpace(FieldOfView)
  129.    
  130.         --//moves a GUI around to cover 0,0
  131.         local XYPos = ObtainScreenPositionFrom3DPosition(Vector3.new(0,0,0),Camera,FieldOfView)
  132.         if XYPos ~= Vector2.new(0,0) then
  133.             GUIThing.Visible  = true
  134.             GUIThing.Position = UDim2.new(0,XYPos.X,0,XYPos.Y)
  135.         else
  136.             GUIThing.Visible  = false
  137.         end
  138.     end
  139. end
  140.  
  141. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement