- Joined
- Aug 1, 2013
- Messages
- 4,658
As I was doing some stuff with selection of units, I ended up making a function that returns the smallest rect of the current camera view.
Aka, all points that you can see are inside the rect without making the rect needlessly large.
Be aware that this does not take terrain height into account.
This also has a slightly larger width than the camera, hence why I set it to 0.8 of the width.
This also assumes that you dont have a bull shit angle of attack... aka, an angle higher than 90 degrees.
Last but not least, it doesnt read in the resolution of the screen, so I have taken a rough estimation of the display resolution.
EDIT:
Dont mind the part where I check what the minX, minY, maxX and maxY are.
I know it doesnt properly work
Aka, all points that you can see are inside the rect without making the rect needlessly large.
JASS:
struct Camera
private static method screenCoordinateToLocation takes Real2D r returns Real2D
local real angleOfAttackEx = (GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK) - 270) * bj_DEGTORAD
local real resolution = 1366. / 676.
local real totalHeight
local real groundOffset
local real totalDistance
local real xOffset
local real rot = GetCameraField(CAMERA_FIELD_ROTATION)
local real cosRotation = Cos(rot * bj_DEGTORAD)
local real sinRotation = Sin(rot * bj_DEGTORAD)
local real oldX
local real fieldOfViewEx = GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW)/2 * bj_DEGTORAD
local real zOffset = GetCameraField(CAMERA_FIELD_ZOFFSET)
local real targetDistance = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
local real roll = GetCameraField(CAMERA_FIELD_ROLL)
call r.setY(r.y/resolution)
call r.rotate(roll * bj_DEGTORAD)
set oldX = r.x
set totalHeight = zOffset + targetDistance*Cos(angleOfAttackEx)
set groundOffset = Tan(angleOfAttackEx + fieldOfViewEx*r.y) * totalHeight
call r.setX(GetCameraEyePositionX() + groundOffset*cosRotation)
call r.setY(GetCameraEyePositionY() + groundOffset*sinRotation)
set totalDistance = SquareRoot(totalHeight*totalHeight + groundOffset*groundOffset)
set xOffset = Tan(fieldOfViewEx*oldX) * totalDistance *0.8
call r.setX(r.x + xOffset*sinRotation)
call r.setY(r.y + xOffset*cosRotation)
return r
endmethod
public static method getViewBounds takes real margin returns rect
local Real2D r1 = .screenCoordinateToLocation(Real2D.create(-1, -1))
local Real2D r2 = .screenCoordinateToLocation(Real2D.create(1, -1))
local Real2D r3 = .screenCoordinateToLocation(Real2D.create(-1, 1))
local Real2D r4 = .screenCoordinateToLocation(Real2D.create(1, 1))
local real minX = r1.x
local real maxX = r4.x
local real minY = r1.y
local real maxY = r4.y
if r2.x < minX then
set minX = r2.x
set maxX = r3.x
endif
if r3.x < minX then
set minX = r3.x
set maxX = r2.x
endif
if r4.x < minX then
set minX = r4.x
set maxX = r1.x
endif
if r2.y < minY then
set minY = r2.y
set maxY = r3.y
endif
if r3.y < minY then
set minY = r3.y
set maxY = r2.y
endif
if r4.y < minY then
set minY = r4.y
set maxY = r1.y
endif
call r1.destroy()
call r2.destroy()
call r3.destroy()
call r4.destroy()
return Rect(minX - margin, minY - margin, maxX + margin, maxY + margin)
endmethod
endstruct
JASS:
struct Real2D
readonly real x
readonly real y
public static method create takes real x, real y returns thistype
local thistype this = .allocate()
set .x = x
set .y = y
return this
endmethod
public static method createEx takes nothing returns thistype
local thistype this = .allocate()
return this
endmethod
public method destroy takes nothing returns nothing
call .deallocate()
endmethod
public method setX takes real x returns nothing
set .x = x
endmethod
public method setY takes real y returns nothing
set .y = y
endmethod
public method rotateAroundCoordinate takes real angle, real pX, real pY returns nothing
local real oldX = .x
local real oldY = .y
local real sin = Sin(angle)
local real cos = Cos(angle)
set .x = (pX + ((oldX - pX) * cos) - ((oldY - pY) * sin))
set .y = (pY + ((oldX - pX) * sin) + ((oldY - pY) * cos))
endmethod
public method rotate takes real angle returns nothing
call .rotateAroundCoordinate(angle, 0, 0)
endmethod
public method toString takes nothing returns string
return "("+R2S(.x)+", "+R2S(.y)+")"
endmethod
endstruct
Be aware that this does not take terrain height into account.
This also has a slightly larger width than the camera, hence why I set it to 0.8 of the width.
This also assumes that you dont have a bull shit angle of attack... aka, an angle higher than 90 degrees.
Last but not least, it doesnt read in the resolution of the screen, so I have taken a rough estimation of the display resolution.
EDIT:
Dont mind the part where I check what the minX, minY, maxX and maxY are.
I know it doesnt properly work
JASS:
public method setPointsRandom takes Real2D r1, Real2D r2, Real2D r3, Real2D r4 returns thistype
set .x = r1.x
if r2.x < .x then
set .x = r2.x
endif
if r3.x < .x then
set .x = r3.x
endif
if r4.x < .x then
set .x = r4.x
endif
set .w = r1.x
if r2.x > .w then
set .w = r2.x
endif
if r3.x > .w then
set .w = r3.x
endif
if r4.x > .w then
set .w = r4.x
endif
set .w = .w-.x
set .y = r1.y
if r2.y < .y then
set .y = r2.y
endif
if r3.y < .y then
set .y = r3.y
endif
if r4.y < .y then
set .y = r4.y
endif
set .h = r1.y
if r2.y > .h then
set .h = r2.y
endif
if r3.y > .h then
set .h = r3.y
endif
if r4.y > .h then
set .h = r4.y
endif
set .h = .h-.y
return this
endmethod
Last edited: