feature: Implement display rotation
This commit is contained in:
parent
6911afb6e0
commit
0efaf19b40
3 changed files with 75 additions and 17 deletions
|
@ -9,6 +9,8 @@ type DisplayConfig struct {
|
||||||
Angle *int `yaml:"angle"`
|
Angle *int `yaml:"angle"`
|
||||||
FOV *int `yaml:"fov"`
|
FOV *int `yaml:"fov"`
|
||||||
Spacing *float32 `yaml:"spacing"`
|
Spacing *float32 `yaml:"spacing"`
|
||||||
|
RadiusMultiplier *float32 `yaml:"circle_radius_multiplier"`
|
||||||
|
UseCircularSpacing *bool `yaml:"use_circular_spacing"`
|
||||||
Count *int `yaml:"count"`
|
Count *int `yaml:"count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +43,8 @@ var DefaultConfig = &Config{
|
||||||
Angle: getPtrToInt(45),
|
Angle: getPtrToInt(45),
|
||||||
FOV: getPtrToInt(45),
|
FOV: getPtrToInt(45),
|
||||||
Spacing: getPtrToFloat32(0.5),
|
Spacing: getPtrToFloat32(0.5),
|
||||||
|
RadiusMultiplier: getPtrToFloat32(2),
|
||||||
|
UseCircularSpacing: getPtrToBool(true),
|
||||||
Count: getPtrToInt(3),
|
Count: getPtrToInt(3),
|
||||||
},
|
},
|
||||||
Overrides: AppOverrides{
|
Overrides: AppOverrides{
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
display:
|
display:
|
||||||
angle: 45 # Angle of the virtual displays
|
angle: 45 # Angle of the virtual displays
|
||||||
fov: 45 # FOV of the 3D camera
|
fov: 45 # FOV of the 3D camera
|
||||||
spacing: 0.5 # Spacing between virtual displays
|
spacing: 0.5 # Raw spacing between virtual displays. Does not use circles in the layout. Purely flat plane.
|
||||||
|
circle_radius_multiplier: 2 # Multiplier for the radius of the circle used to calculate the spacing between virtual displays. "Rounded" plane of sorts.
|
||||||
|
use_circular_spacing: true # If true, uses a circular layout for the virtual displays.
|
||||||
count: 3 # Count of virtual displays
|
count: 3 # Count of virtual displays
|
||||||
overrides:
|
overrides:
|
||||||
allow_unsupported_devices: false # If true, allows unsupported devices to be used as long as they're a compatible vendor (Xreal)
|
allow_unsupported_devices: false # If true, allows unsupported devices to be used as long as they're a compatible vendor (Xreal)
|
||||||
|
|
|
@ -35,6 +35,15 @@ func findOptimalHorizontalRes(verticalDisplayRes float32, horizontalDisplayRes f
|
||||||
return horizontalSize
|
return horizontalSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findHfovFromVfov(vfovDeg, w, h float64) float64 {
|
||||||
|
vfovRad := vfovDeg * math.Pi / 180
|
||||||
|
|
||||||
|
ar := w / h
|
||||||
|
hfovRad := 2 * math.Atan(math.Tan(vfovRad/2)*ar)
|
||||||
|
|
||||||
|
return hfovRad * 180 / math.Pi
|
||||||
|
}
|
||||||
|
|
||||||
func EnterRenderLoop(config *libconfig.Config, displayMetadata *edidtools.DisplayMetadata, evdiCards []*EvdiDisplayMetadata) {
|
func EnterRenderLoop(config *libconfig.Config, displayMetadata *edidtools.DisplayMetadata, evdiCards []*EvdiDisplayMetadata) {
|
||||||
log.Info("Initializing AR driver")
|
log.Info("Initializing AR driver")
|
||||||
headset, err := ardriver.GetDevice()
|
headset, err := ardriver.GetDevice()
|
||||||
|
@ -99,7 +108,9 @@ func EnterRenderLoop(config *libconfig.Config, displayMetadata *edidtools.Displa
|
||||||
|
|
||||||
headset.RegisterEventListeners(arEventListner)
|
headset.RegisterEventListeners(arEventListner)
|
||||||
|
|
||||||
fovY := float32(45.0)
|
fovY := float32(*config.DisplayConfig.FOV)
|
||||||
|
fovX := findHfovFromVfov(float64(fovY), float64(displayMetadata.MaxWidth), float64(displayMetadata.MaxHeight))
|
||||||
|
|
||||||
verticalSize := findMaxVerticalSize(fovY, 5.0)
|
verticalSize := findMaxVerticalSize(fovY, 5.0)
|
||||||
|
|
||||||
camera := rl.NewCamera3D(
|
camera := rl.NewCamera3D(
|
||||||
|
@ -125,6 +136,21 @@ func EnterRenderLoop(config *libconfig.Config, displayMetadata *edidtools.Displa
|
||||||
horizontalSize := findOptimalHorizontalRes(float32(displayMetadata.MaxHeight), float32(displayMetadata.MaxWidth), verticalSize)
|
horizontalSize := findOptimalHorizontalRes(float32(displayMetadata.MaxHeight), float32(displayMetadata.MaxWidth), verticalSize)
|
||||||
coreMesh := rl.GenMeshPlane(horizontalSize, verticalSize, 1, 1)
|
coreMesh := rl.GenMeshPlane(horizontalSize, verticalSize, 1, 1)
|
||||||
|
|
||||||
|
var radius float32
|
||||||
|
|
||||||
|
if *config.DisplayConfig.UseCircularSpacing == true {
|
||||||
|
radiusX := (horizontalSize / 2) / float32(math.Tan((float64(fovX)*math.Pi/180.0)/2))
|
||||||
|
radiusY := (verticalSize / 2) / float32(math.Tan((float64(fovY)*math.Pi/180.0)/2))
|
||||||
|
|
||||||
|
if radiusY > radiusX {
|
||||||
|
radius = radiusY
|
||||||
|
} else {
|
||||||
|
radius = radiusX
|
||||||
|
}
|
||||||
|
|
||||||
|
radius *= *config.DisplayConfig.RadiusMultiplier
|
||||||
|
}
|
||||||
|
|
||||||
movementVector := rl.Vector3{
|
movementVector := rl.Vector3{
|
||||||
X: 0.0,
|
X: 0.0,
|
||||||
Y: 0.0,
|
Y: 0.0,
|
||||||
|
@ -171,6 +197,17 @@ func EnterRenderLoop(config *libconfig.Config, displayMetadata *edidtools.Displa
|
||||||
texture := rl.LoadTextureFromImage(image)
|
texture := rl.LoadTextureFromImage(image)
|
||||||
model := rl.LoadModelFromMesh(coreMesh)
|
model := rl.LoadModelFromMesh(coreMesh)
|
||||||
|
|
||||||
|
// spin up/down
|
||||||
|
pitchRad := float32(-90 * rl.Deg2rad)
|
||||||
|
// spin left/right
|
||||||
|
yawRad := currentAngle * rl.Deg2rad
|
||||||
|
|
||||||
|
rotX := rl.MatrixRotateX(pitchRad)
|
||||||
|
rotY := rl.MatrixRotateY(yawRad)
|
||||||
|
|
||||||
|
transform := rl.MatrixMultiply(rotX, rotY)
|
||||||
|
model.Transform = transform
|
||||||
|
|
||||||
rl.SetMaterialTexture(model.Materials, rl.MapAlbedo, texture)
|
rl.SetMaterialTexture(model.Materials, rl.MapAlbedo, texture)
|
||||||
|
|
||||||
rects[i] = &TextureModelPair{
|
rects[i] = &TextureModelPair{
|
||||||
|
@ -235,20 +272,35 @@ func EnterRenderLoop(config *libconfig.Config, displayMetadata *edidtools.Displa
|
||||||
card.EvdiNode.RequestUpdate(card.Buffer)
|
card.EvdiNode.RequestUpdate(card.Buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.DrawModelEx(
|
worldPos := rl.Vector3{
|
||||||
rect.Model,
|
X: 0,
|
||||||
rl.Vector3{
|
|
||||||
X: rect.CurrentDisplaySpacing,
|
|
||||||
Y: verticalSize / 2,
|
Y: verticalSize / 2,
|
||||||
Z: 0,
|
Z: 0,
|
||||||
},
|
}
|
||||||
|
|
||||||
|
if *config.DisplayConfig.UseCircularSpacing == true {
|
||||||
|
yawRad := float32(rl.Deg2rad * rect.CurrentAngle)
|
||||||
|
|
||||||
|
// WTF?
|
||||||
|
posX := float32(math.Sin(float64(yawRad))) * radius
|
||||||
|
posZ := -float32(math.Cos(float64(yawRad))) * radius
|
||||||
|
|
||||||
|
worldPos.X = posX
|
||||||
|
worldPos.Z = posZ + radius
|
||||||
|
} else {
|
||||||
|
worldPos.X = rect.CurrentDisplaySpacing
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.DrawModelEx(
|
||||||
|
rect.Model,
|
||||||
|
worldPos,
|
||||||
// rotate around X to make it vertical
|
// rotate around X to make it vertical
|
||||||
rl.Vector3{
|
rl.Vector3{
|
||||||
X: 1,
|
X: 0,
|
||||||
Y: 0,
|
Y: 0,
|
||||||
Z: 0,
|
Z: 0,
|
||||||
},
|
},
|
||||||
90,
|
0,
|
||||||
rl.Vector3{
|
rl.Vector3{
|
||||||
X: 1,
|
X: 1,
|
||||||
Y: 1,
|
Y: 1,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue