Compare commits
13 Commits
7cc9ae15a9
...
8b425898a1
Author | SHA1 | Date | |
---|---|---|---|
8b425898a1 | |||
f3219b8eb1 | |||
1d9b26cd4e | |||
926abae31b | |||
5e8d6b76af | |||
c0445364da | |||
e357e60e5b | |||
d87b8473be | |||
01ea30f5fb | |||
d4fa665b66 | |||
3a197c49fa | |||
5c387be6d4 | |||
c6000e05b3 |
|
@ -137,7 +137,7 @@ describe Vector do
|
||||||
Vector[1, 1].magnitude.should eq(Math.sqrt(2))
|
Vector[1, 1].magnitude.should eq(Math.sqrt(2))
|
||||||
Vector[1, 2].magnitude.should eq(Math.sqrt(1**2 + 2**2))
|
Vector[1, 2].magnitude.should eq(Math.sqrt(1**2 + 2**2))
|
||||||
Vector[2, 2].magnitude.should eq(Math.sqrt(2**2 + 2**2))
|
Vector[2, 2].magnitude.should eq(Math.sqrt(2**2 + 2**2))
|
||||||
Vector[2, 2, 2].magnitude.should eq((2**2 + 2**2 + 2**2)**(1.0/3.0))
|
Vector[2, 2, 2].magnitude.should eq((2**2 + 2**2 + 2**2)**(1.0/2.0))
|
||||||
end
|
end
|
||||||
|
|
||||||
it "normalized vector" do
|
it "normalized vector" do
|
||||||
|
|
|
@ -27,19 +27,19 @@ class Projectable(N)
|
||||||
@gravity_body.speed
|
@gravity_body.speed
|
||||||
end
|
end
|
||||||
|
|
||||||
def sf_shape(coef : Float64 = 1.0, offset : Vector(Float64, N) = Vector(Float64, N).zero)
|
def sf_shape(offset : Vector(Float64, N) = Vector(Float64, N).zero)
|
||||||
shape = SF::CircleShape.new(@size)
|
shape = SF::CircleShape.new(@size)
|
||||||
shape.fill_color = SF.color(@color[0], @color[1], @color[2])
|
shape.fill_color = SF.color(@color[0], @color[1], @color[2])
|
||||||
|
|
||||||
shape.outline_thickness = @outline_size
|
shape.outline_thickness = @outline_size
|
||||||
shape.outline_color = SF.color(@outline_color[0], @outline_color[1], @outline_color[2])
|
shape.outline_color = SF.color(@outline_color[0], @outline_color[1], @outline_color[2])
|
||||||
shape.position = sf_position(coef, offset)
|
shape.position = sf_position(offset)
|
||||||
shape
|
shape
|
||||||
end
|
end
|
||||||
|
|
||||||
# the sf_position is the projected position of the gravity_body on the graphic plan
|
# the sf_position is the projected position of the gravity_body on the graphic plan
|
||||||
def sf_position(coef : Float64 = 1.0, offset : Vector(Float64, N) = Vector(Float64, N).zero)
|
def sf_position(offset : Vector(Float64, N) = Vector(Float64, N).zero)
|
||||||
zoomed_position = @gravity_body.position * coef + offset
|
zoomed_position = @gravity_body.position + offset
|
||||||
SF.vector2(zoomed_position[0], zoomed_position[1])
|
SF.vector2(zoomed_position[0], zoomed_position[1])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -169,13 +169,16 @@ class Vector(T, N) # should be a struct since it's a simple pointer inside, the
|
||||||
T
|
T
|
||||||
end
|
end
|
||||||
|
|
||||||
# I think it's always square root not 1.0/size
|
|
||||||
def magnitude : Number
|
def magnitude : Number
|
||||||
reduce(T.zero) { |base, elem| base + elem**2 } ** (1.0 / size)
|
reduce(T.zero) { |base, elem| base + elem**2 } ** (1.0 / 2.0)
|
||||||
|
end
|
||||||
|
|
||||||
|
# put the vector on a trigonomic circle so sqrt(x**2 + y**2) = 1
|
||||||
|
def normalize
|
||||||
|
self / magnitude
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalize
|
def normalize
|
||||||
magnitude = self.magnitude
|
self.div!(magnitude)
|
||||||
self / magnitude
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -84,6 +84,7 @@ class Vessel(N)
|
||||||
orders.sort!
|
orders.sort!
|
||||||
order = orders.pop # remove last order and execute it
|
order = orders.pop # remove last order and execute it
|
||||||
order.execute
|
order.execute
|
||||||
|
# orders.unshift order if order.keep
|
||||||
order
|
order
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -102,8 +103,9 @@ class Vessel(N)
|
||||||
class Order(N)
|
class Order(N)
|
||||||
setter :station
|
setter :station
|
||||||
getter :priority, :group
|
getter :priority, :group
|
||||||
|
# property :keep
|
||||||
|
|
||||||
def initialize(@priority : Int32 = 0, @group : Symbol = :default, @station : Station(N)? = nil, &@block : Order(N) -> Nil)
|
def initialize(@priority : Int32 = 0, @group : Symbol = :default, @station : Station(N)? = nil, @keep : Bool = false, &@block : Order(N) -> Nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s(io : IO) : Nil
|
def to_s(io : IO) : Nil
|
||||||
|
@ -139,60 +141,112 @@ class Vessel(N)
|
||||||
end
|
end
|
||||||
|
|
||||||
class Pilot(N) < Station(N)
|
class Pilot(N) < Station(N)
|
||||||
property low_thrust_save, low_thrust_pressed, computer_input_thurst
|
# these properties handle manual override of trust (either analogic or exact computed)
|
||||||
property permanent_mode, temporary_mode
|
property low_thrust_save, low_thrust_pressed, computer_input_thrust
|
||||||
|
# on the interface, the pilot can select a body to create relative vectors
|
||||||
|
property current_selected_body : Gravity::Body(N)?
|
||||||
|
# this is a hard limit for thrust so the pilot can avoid killing all the people aboard
|
||||||
|
property max_thrust
|
||||||
|
# permanent mode is the default modes to apply at all time
|
||||||
|
property permanent_modes : Array(Mode)
|
||||||
|
# temporary mode must be set at each tick and will be reset each time it is applied
|
||||||
|
property temporary_modes : Array(Mode)
|
||||||
|
|
||||||
@permanent_mode : Symbol?
|
enum Mode
|
||||||
@temporary_mode : Symbol?
|
Constant
|
||||||
|
Pulse
|
||||||
|
AntiGrav
|
||||||
|
AntiSpeed
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(*p, **o)
|
def initialize(*p, **o)
|
||||||
super
|
super
|
||||||
@permanent_mode = nil
|
@permanent_modes = Array(Mode).new
|
||||||
@temporary_mode = nil
|
@temporary_modes = Array(Mode).new
|
||||||
@low_thrust_save = 0.0
|
@low_thrust_save = 0.0
|
||||||
@low_thrust_pressed = false
|
@low_thrust_pressed = false
|
||||||
@computer_input_thurst = Vector(Float64, N).zero
|
@computer_input_thrust = Vector(Float64, N).zero
|
||||||
|
@max_thrust = 20.0
|
||||||
|
@current_selected_body = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_exact_acceleration_axis!(index : Int32, value : Float64)
|
# Modify immediatly one elemnt of the acceleration vector
|
||||||
|
def set_exact_acceleration_axis(index : Int32, value : Float64)
|
||||||
vessel.gravity_body.acceleration[index] = value
|
vessel.gravity_body.acceleration[index] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_exact_acceleration_axis!(axis : Vector(Float64, N))
|
# Modify immediatly the acceleration vector
|
||||||
|
def set_exact_acceleration_axis(axis : Vector(Float64, N))
|
||||||
axis.each_with_index do |value, index|
|
axis.each_with_index do |value, index|
|
||||||
set_exact_acceleration_axis!(index, value)
|
set_exact_acceleration_axis(index, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# set_exact_acceleration_axis!({0, 23.0}, {1, 11.2}) # to set x;y at once
|
# set_exact_acceleration_axis({0, 23.0}, {1, 11.2}) # to set x;y at once
|
||||||
def set_exact_acceleration_axis!(*tuples : Array(Tuple(Int32, Float64)))
|
def set_exact_acceleration_axis(*tuples : Array(Tuple(Int32, Float64)))
|
||||||
tuples.each do |tuple|
|
tuples.each do |tuple|
|
||||||
set_exact_acceleration_axis!(*tuple)
|
set_exact_acceleration_axis(*tuple)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def immediate_modes : Array(Mode)
|
||||||
|
if !@temporary_modes.empty?
|
||||||
|
@temporary_modes
|
||||||
|
else
|
||||||
|
@permanent_modes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_current_mode
|
def apply_current_mode
|
||||||
if (@permanent_mode == :antigrav && @temporary_mode.nil?) || @temporary_mode == :antigrav
|
new_acceleration_axis = Vector(Float64, N).zero
|
||||||
# somehow it doesn't work as expected... :thinking:
|
must_update_acceleration_axis = false
|
||||||
set_exact_acceleration_axis!(-vessel.gravity)
|
if immediate_modes.includes?(Mode::AntiGrav)
|
||||||
|
must_update_acceleration_axis = true
|
||||||
|
new_acceleration_axis.add!(-vessel.gravity)
|
||||||
end
|
end
|
||||||
|
|
||||||
@temporary_mode = nil # each time we apply the temporary_mode, reset it
|
if immediate_modes.includes?(Mode::AntiSpeed)
|
||||||
|
must_update_acceleration_axis = true
|
||||||
|
reset_acceleration = true
|
||||||
|
if (current_selected_body = @current_selected_body)
|
||||||
|
relative_speed = vessel.gravity_body.speed - current_selected_body.speed
|
||||||
|
new_acceleration_axis.add!(-relative_speed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if new_acceleration_axis.magnitude > @max_thrust
|
||||||
|
new_acceleration_axis.normalize.mult!(@max_thrust)
|
||||||
|
end
|
||||||
|
set_exact_acceleration_axis(new_acceleration_axis) if must_update_acceleration_axis
|
||||||
|
|
||||||
|
@temporary_modes.clear # each time we apply the temporary_mode, reset it
|
||||||
end
|
end
|
||||||
|
|
||||||
def accelerate_current_vector!(coef : Float64)
|
def accelerate_current_vector!(coef : Float64)
|
||||||
set_exact_acceleration_axis!(vessel.gravity_body.speed * coef)
|
set_exact_acceleration_axis(vessel.gravity_body.speed * coef)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Navigation(N) < Station(N)
|
class Navigation(N) < Station(N)
|
||||||
|
class Cadran
|
||||||
|
property radius : Array(Float64)
|
||||||
|
def initialize(default_radius : Float64 = 1000.0)
|
||||||
|
@radius = [] of Float64
|
||||||
|
@radius << default_radius if !default_radius.nil?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
property zoom_select : Int32
|
property zoom_select : Int32
|
||||||
property zoom_position : Vector(Float64, N)
|
property zoom_position : Vector(Float64, N)
|
||||||
|
property cadran : Cadran
|
||||||
|
property zoom_ratio : Float64
|
||||||
|
|
||||||
def initialize(*p, **o)
|
def initialize(*p, **o)
|
||||||
super
|
super
|
||||||
|
@zoom_ratio = 1.0
|
||||||
@zoom_select = 0
|
@zoom_select = 0
|
||||||
@zoom_position = Vector(Float64, N).zero
|
@zoom_position = Vector(Float64, N).zero
|
||||||
|
@cadran = Cadran.new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,8 @@ require "crsfml"
|
||||||
require "imgui"
|
require "imgui"
|
||||||
require "imgui-sfml"
|
require "imgui-sfml"
|
||||||
|
|
||||||
|
require "./physics_sandbox/*"
|
||||||
|
|
||||||
require "log"
|
require "log"
|
||||||
Log.setup(:debug)
|
Log.setup(:debug)
|
||||||
|
|
||||||
|
@ -20,26 +22,58 @@ class Game
|
||||||
@window : SF::RenderWindow
|
@window : SF::RenderWindow
|
||||||
@delta_clock : SF::Clock
|
@delta_clock : SF::Clock
|
||||||
@screen_center_position : Vector(Float64, 2)
|
@screen_center_position : Vector(Float64, 2)
|
||||||
|
@center_position : Vector(Float64, 2)
|
||||||
@joystick_moved : Vector(Float64, 2)
|
@joystick_moved : Vector(Float64, 2)
|
||||||
|
|
||||||
ZOOM = 1/4
|
|
||||||
SECOND_IN_NANO = 1_000_000_000
|
SECOND_IN_NANO = 1_000_000_000
|
||||||
|
DEFAULT_ZOOM = 5/16
|
||||||
|
|
||||||
def accuracy_frequency_nano_rate
|
def accuracy_frequency_nano_rate
|
||||||
((SECOND_IN_NANO * @timescale) // @framerate).to_u64
|
((SECOND_IN_NANO * @timescale) // @framerate).to_u64
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def draw(item : SF::VertexBuffer, transform : SF::Transform? = nil)
|
||||||
|
states = SF::RenderStates.new
|
||||||
|
if transform
|
||||||
|
states.transform = transform
|
||||||
|
end
|
||||||
|
@window.draw(item, states)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw(item : SF::Shape, transform : SF::Transform? = nil)
|
||||||
|
states = SF::RenderStates.new
|
||||||
|
if transform
|
||||||
|
states.transform = transform
|
||||||
|
end
|
||||||
|
@window.draw(item, states)
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_viewport
|
||||||
|
SF.float_rect(0.0, 0.0, 1.0, @width / @height)
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(@framerate : Int32 = 60, @width : Int32 = 800, @height : Int32 = 600)
|
def initialize(@framerate : Int32 = 60, @width : Int32 = 800, @height : Int32 = 600)
|
||||||
@window = SF::RenderWindow.new(
|
@window = SF::RenderWindow.new(
|
||||||
SF::VideoMode.new(width, height),
|
SF::VideoMode.new(width, height),
|
||||||
"Sandbox",
|
"Sandbox",
|
||||||
)
|
)
|
||||||
|
@zoom = 1.0
|
||||||
@joystick_moved = Vector[0.0, 0.0]
|
@joystick_moved = Vector[0.0, 0.0]
|
||||||
@screen_center_position = Vector[width / 2, height / 2]
|
@screen_center_position = Vector[width / 2, height / 2]
|
||||||
|
@center_position = Vector[0.0, 0.0]
|
||||||
|
|
||||||
@delta_clock = SF::Clock.new
|
@delta_clock = SF::Clock.new
|
||||||
|
@time_passed = Time::Span.zero
|
||||||
|
@timescale = 1.0
|
||||||
|
@window_frequency = Time::Span.new(nanoseconds: SECOND_IN_NANO // @framerate)
|
||||||
|
|
||||||
ImGui::SFML.init(@window)
|
ImGui::SFML.init(@window)
|
||||||
@window.framerate_limit = @framerate
|
@window.framerate_limit = @framerate
|
||||||
@time_passed = Time::Span.zero
|
|
||||||
|
@view = SF::View.new
|
||||||
|
@view.viewport = default_viewport # SF.float_rect(0.0, 0.0, 1.0, @width / @height)
|
||||||
|
@view.center = {@center_position[0], @center_position[1]}
|
||||||
|
@window.view = @view
|
||||||
|
|
||||||
# connected = SF::Joystick.connected?(0)
|
# connected = SF::Joystick.connected?(0)
|
||||||
# # How many buttons does joystick #0 support?
|
# # How many buttons does joystick #0 support?
|
||||||
|
@ -51,9 +85,6 @@ class Game
|
||||||
# # What's the current position of the Y axis on joystick #0?
|
# # What's the current position of the Y axis on joystick #0?
|
||||||
# position = SF::Joystick.get_axis_position(0, SF::Joystick::Y)
|
# position = SF::Joystick.get_axis_position(0, SF::Joystick::Y)
|
||||||
|
|
||||||
@timescale = 1.0
|
|
||||||
@window_frequency = Time::Span.new(nanoseconds: SECOND_IN_NANO // @framerate)
|
|
||||||
|
|
||||||
sun_offset = Vector[3*10.0**11, 3*10.0**11]
|
sun_offset = Vector[3*10.0**11, 3*10.0**11]
|
||||||
@bodies = {
|
@bodies = {
|
||||||
vessel: Gravity::MovingBody(2).new(mass: 1.0, g: 0.1, position: Vector[10.0, 10.0]),
|
vessel: Gravity::MovingBody(2).new(mass: 1.0, g: 0.1, position: Vector[10.0, 10.0]),
|
||||||
|
@ -71,33 +102,34 @@ class Game
|
||||||
@vessel_p = Projectable(2).new(
|
@vessel_p = Projectable(2).new(
|
||||||
gravity_body: @bodies[:vessel],
|
gravity_body: @bodies[:vessel],
|
||||||
color: {255, 0, 250},
|
color: {255, 0, 250},
|
||||||
size: 3,
|
size: 5,
|
||||||
)
|
)
|
||||||
@star = Projectable(2).new(
|
@star = Projectable(2).new(
|
||||||
gravity_body: @bodies[:star],
|
gravity_body: @bodies[:star],
|
||||||
color: {200, 200, 50},
|
color: {200, 200, 50},
|
||||||
size: 10,
|
size: 20,
|
||||||
)
|
)
|
||||||
@pla1 = Projectable(2).new(
|
@pla1 = Projectable(2).new(
|
||||||
gravity_body: @bodies[:pla1],
|
gravity_body: @bodies[:pla1],
|
||||||
color: {150, 50, 50},
|
color: {150, 50, 50},
|
||||||
size: 5,
|
size: 10,
|
||||||
)
|
)
|
||||||
@pla2 = Projectable(2).new(
|
@pla2 = Projectable(2).new(
|
||||||
gravity_body: @bodies[:pla2],
|
gravity_body: @bodies[:pla2],
|
||||||
color: {50, 50, 150},
|
color: {50, 50, 150},
|
||||||
size: 5,
|
size: 10,
|
||||||
)
|
)
|
||||||
@pla3 = Projectable(2).new(
|
@pla3 = Projectable(2).new(
|
||||||
gravity_body: @bodies[:pla3],
|
gravity_body: @bodies[:pla3],
|
||||||
color: {50, 150, 50},
|
color: {50, 150, 50},
|
||||||
size: 5,
|
size: 10,
|
||||||
)
|
)
|
||||||
@projectables = {
|
@projectables = {
|
||||||
@star, @pla1, @pla2, @pla3, @star, @vessel_p,
|
@star, @pla1, @pla2, @pla3, @star, @vessel_p,
|
||||||
}
|
}
|
||||||
@g = Gravity::Field(2).new(@gravited)
|
@g = Gravity::Field(2).new(@gravited)
|
||||||
@vessel = Vessel(2).new(name: "Starbird", gravity_body: @bodies[:vessel], gravity_field: @g)
|
@vessel = Vessel(2).new(name: "Starbird", gravity_body: @bodies[:vessel], gravity_field: @g)
|
||||||
|
@vessel.navigation.zoom_ratio = DEFAULT_ZOOM
|
||||||
@timer = Physics::Tick::Timer.new
|
@timer = Physics::Tick::Timer.new
|
||||||
@ui_events_handler = UI::EventHandler.new
|
@ui_events_handler = UI::EventHandler.new
|
||||||
end
|
end
|
||||||
|
@ -113,10 +145,10 @@ class Game
|
||||||
@window.close
|
@window.close
|
||||||
exit
|
exit
|
||||||
when SF::Event::KeyPressed
|
when SF::Event::KeyPressed
|
||||||
puts "KeyPressed #{event}"
|
Log.debug "KeyPressed #{event}"
|
||||||
when SF::Event::MouseMoved
|
when SF::Event::MouseMoved
|
||||||
when SF::Event::MouseButtonEvent
|
when SF::Event::MouseButtonEvent
|
||||||
puts "MouseButtonEvent #{event}"
|
Log.debug "MouseButtonEvent #{event}"
|
||||||
when SF::Event::JoystickButtonPressed
|
when SF::Event::JoystickButtonPressed
|
||||||
@joystick_moved.zero! # reset 0
|
@joystick_moved.zero! # reset 0
|
||||||
joystick_moved_modified = :vector # force exact set
|
joystick_moved_modified = :vector # force exact set
|
||||||
|
@ -143,14 +175,14 @@ class Game
|
||||||
end
|
end
|
||||||
|
|
||||||
if joystick_moved_modified == :vector
|
if joystick_moved_modified == :vector
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(@joystick_moved)
|
@vessel.pilot.set_exact_acceleration_axis(@joystick_moved)
|
||||||
elsif joystick_moved_modified == :accelerate
|
elsif joystick_moved_modified == :accelerate
|
||||||
# can double the vector each second
|
# can double the vector each second
|
||||||
puts "accelerate #{@joystick_moved}"
|
Log.debug "accelerate #{@joystick_moved}"
|
||||||
@vessel.pilot.accelerate_current_vector!(1.0 + (@joystick_moved[0] + 100) / 2 * 0.01)
|
@vessel.pilot.accelerate_current_vector!(1.0 + (@joystick_moved[0] + 100) / 2 * 0.01)
|
||||||
elsif joystick_moved_modified == :slow
|
elsif joystick_moved_modified == :slow
|
||||||
# can slow
|
# can slow
|
||||||
puts "slow down #{@joystick_moved}"
|
Log.debug "slow down #{@joystick_moved}"
|
||||||
@vessel.pilot.accelerate_current_vector!(-1.0 - (@joystick_moved[0] + 100) / 2 * 0.01)
|
@vessel.pilot.accelerate_current_vector!(-1.0 - (@joystick_moved[0] + 100) / 2 * 0.01)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -168,250 +200,15 @@ class Game
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
include ImGui::Helper
|
|
||||||
|
|
||||||
# will yield the value
|
|
||||||
def draw_slider(label : String, data : Float64, max : Float64 = 100.0, min : Float64 = -100.0, flags : ImGui::ImGuiSliderFlags = ImGui::ImGuiSliderFlags::NoRoundToFormat, &)
|
|
||||||
ptr = pointerof(data)
|
|
||||||
if ImGui.slider_scalar(
|
|
||||||
label: label,
|
|
||||||
p_data: ptr,
|
|
||||||
p_min: min,
|
|
||||||
p_max: max,
|
|
||||||
flags: flags,
|
|
||||||
)
|
|
||||||
yield data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# will yield the value
|
|
||||||
def draw_input(label : String, data : Float64, max : Float64 = 100.0, min : Float64 = -100.0, flags : ImGui::ImGuiInputTextFlags = ImGui::ImGuiInputTextFlags::EnterReturnsTrue, &)
|
|
||||||
ptr = pointerof(data)
|
|
||||||
if ImGui.input_scalar(
|
|
||||||
label: label,
|
|
||||||
p_data: ptr,
|
|
||||||
flags: flags,
|
|
||||||
)
|
|
||||||
data = max if data > max
|
|
||||||
data = min if data < min
|
|
||||||
yield data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def accelerate_by_tick(movable_body : Gravity::MovingBody)
|
def accelerate_by_tick(movable_body : Gravity::MovingBody)
|
||||||
gravity_field = @g.acceleration(movable_body.position)
|
gravity_field = @g.acceleration(movable_body.position)
|
||||||
acceleration = movable_body.acceleration + gravity_field
|
acceleration = movable_body.acceleration + gravity_field
|
||||||
Physics.move_by_one_tick!(@timer.tick, movable_body.position, movable_body.speed, acceleration)
|
Physics.move_by_one_tick!(@timer.tick, movable_body.position, movable_body.speed, acceleration)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_captain
|
include PhysicsSandboxDraw
|
||||||
ImGui.text "Time passed: #{@time_passed}"
|
include PhysicsSandboxGrid
|
||||||
draw_slider(
|
include PhysicsSandboxCadran
|
||||||
label: "Set timescale###set_timescale",
|
|
||||||
data: @timescale,
|
|
||||||
min: 0.1,
|
|
||||||
max: 3600 * 24 * 7,
|
|
||||||
flags: (
|
|
||||||
ImGui::ImGuiSliderFlags::Logarithmic
|
|
||||||
),
|
|
||||||
) do |value|
|
|
||||||
@timescale = value
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
def draw_pilot
|
|
||||||
draw_table(title: "Trusters", headers: {"Name", "X", "Y", "unit"}) do
|
|
||||||
draw_table_line(
|
|
||||||
"Analogic acceleration",
|
|
||||||
->{
|
|
||||||
draw_slider(
|
|
||||||
label: "###acceleration_analogue_x",
|
|
||||||
data: @vessel.gravity_body.acceleration[0],
|
|
||||||
flags: (
|
|
||||||
ImGui::ImGuiSliderFlags::Logarithmic
|
|
||||||
),
|
|
||||||
) do |value|
|
|
||||||
@vessel.pilot.order(priority: 10, group: :acceleration_x) do
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(0, value)
|
|
||||||
@vessel.pilot.permanent_mode = :constant
|
|
||||||
@vessel.pilot.low_thrust_pressed = false
|
|
||||||
@vessel.pilot.low_thrust_save = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
->{
|
|
||||||
draw_slider(
|
|
||||||
label: "###acceleration_analogue_y",
|
|
||||||
data: @vessel.gravity_body.acceleration[1],
|
|
||||||
flags: (
|
|
||||||
ImGui::ImGuiSliderFlags::Logarithmic
|
|
||||||
),
|
|
||||||
) do |value|
|
|
||||||
@vessel.pilot.order(priority: 10, group: :acceleration_y) do
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(1, value)
|
|
||||||
@vessel.pilot.permanent_mode = :constant
|
|
||||||
@vessel.pilot.low_thrust_pressed = false
|
|
||||||
@vessel.pilot.low_thrust_save = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
"m/s²",
|
|
||||||
)
|
|
||||||
|
|
||||||
# automatically reset acceleration to 0, used for maneuvers
|
|
||||||
draw_table_line(
|
|
||||||
"Low thrust",
|
|
||||||
->{
|
|
||||||
draw_slider(
|
|
||||||
label: "###acceleration_low_analogic_x",
|
|
||||||
data: @vessel.gravity_body.acceleration[0],
|
|
||||||
) do |value|
|
|
||||||
@vessel.pilot.order(priority: 10, group: :maneuvers) do
|
|
||||||
@vessel.pilot.temporary_mode = :pulse
|
|
||||||
if !@vessel.pilot.low_thrust_pressed
|
|
||||||
@vessel.pilot.low_thrust_save = @vessel.gravity_body.acceleration[0]
|
|
||||||
end
|
|
||||||
@vessel.pilot.low_thrust_pressed = true
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(0, value)
|
|
||||||
lock_callback = @ui_events_handler.add(SF::Event::KeyPressed) do |callback, event|
|
|
||||||
if event.as(SF::Event::KeyPressed).code == SF::Keyboard::Key::L
|
|
||||||
@vessel.pilot.low_thrust_save = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ui_events_handler.add(SF::Event::MouseButtonReleased) do |callback|
|
|
||||||
@ui_events_handler.remove(SF::Event::MouseButtonReleased, callback)
|
|
||||||
@ui_events_handler.remove(SF::Event::MouseButtonReleased, lock_callback)
|
|
||||||
@vessel.pilot.low_thrust_pressed = false
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(0, @vessel.pilot.low_thrust_save)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
->{
|
|
||||||
draw_slider(
|
|
||||||
label: "###acceleration_low_analogic_y",
|
|
||||||
data: @vessel.gravity_body.acceleration[1],
|
|
||||||
) do |value|
|
|
||||||
@vessel.pilot.order(priority: 10, group: :maneuvers) do
|
|
||||||
@vessel.pilot.temporary_mode = :pulse
|
|
||||||
if !@vessel.pilot.low_thrust_pressed
|
|
||||||
@vessel.pilot.low_thrust_save = @vessel.gravity_body.acceleration[1]
|
|
||||||
end
|
|
||||||
@vessel.pilot.low_thrust_pressed = true
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(1, value)
|
|
||||||
lock_callback = @ui_events_handler.add(SF::Event::KeyPressed) do |callback, event|
|
|
||||||
if event.as(SF::Event::KeyPressed).code == SF::Keyboard::Key::L
|
|
||||||
@vessel.pilot.low_thrust_save = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@ui_events_handler.add(SF::Event::MouseButtonReleased) do |callback|
|
|
||||||
@ui_events_handler.remove(SF::Event::MouseButtonReleased, callback)
|
|
||||||
@ui_events_handler.remove(SF::Event::MouseButtonReleased, lock_callback)
|
|
||||||
@vessel.pilot.low_thrust_pressed = false
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(1, @vessel.pilot.low_thrust_save)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
"m/s²",
|
|
||||||
)
|
|
||||||
|
|
||||||
draw_table_line(
|
|
||||||
"Computer acceleration",
|
|
||||||
->{
|
|
||||||
draw_input(
|
|
||||||
label: "###acceleration_digit_x",
|
|
||||||
data: @vessel.pilot.computer_input_thurst[0],
|
|
||||||
) do |value|
|
|
||||||
@vessel.pilot.order(priority: 9, group: :maneuvers) do
|
|
||||||
@vessel.pilot.computer_input_thurst[0] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
->{
|
|
||||||
draw_input(
|
|
||||||
label: "###acceleration_digit_y",
|
|
||||||
data: @vessel.pilot.computer_input_thurst[1],
|
|
||||||
) do |value|
|
|
||||||
@vessel.pilot.order(priority: 9, group: :maneuvers) do
|
|
||||||
@vessel.pilot.computer_input_thurst[1] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
"m/s²",
|
|
||||||
)
|
|
||||||
draw_table_line(
|
|
||||||
"",
|
|
||||||
->{
|
|
||||||
if ImGui.button("Comfirm")
|
|
||||||
@vessel.pilot.order(priority: 100, group: :maneuvers) do
|
|
||||||
@vessel.pilot.permanent_mode = :constant
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(@vessel.pilot.computer_input_thurst)
|
|
||||||
# @vessel.pilot.set_exact_acceleration_axis!(0, @vessel.pilot.computer_input_thurst[0])
|
|
||||||
# @vessel.pilot.set_exact_acceleration_axis!(1, @vessel.pilot.computer_input_thurst[1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if ImGui.button("Reset")
|
|
||||||
@vessel.pilot.order(priority: 100, group: :prepare) do
|
|
||||||
@vessel.pilot.set_exact_acceleration_axis!(@vessel.pilot.computer_input_thurst)
|
|
||||||
# @vessel.pilot.computer_input_thurst[0] = @vessel.gravity_body.acceleration[0]
|
|
||||||
# @vessel.pilot.computer_input_thurst[1] = @vessel.gravity_body.acceleration[1]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
->{
|
|
||||||
if ImGui.button("Zero")
|
|
||||||
@vessel.pilot.order(priority: 10, group: :prepare) do
|
|
||||||
@vessel.pilot.computer_input_thurst[0] = 0.0
|
|
||||||
@vessel.pilot.computer_input_thurst[1] = 0.0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
->{
|
|
||||||
if @vessel.pilot.permanent_mode != :antigrav
|
|
||||||
if ImGui.button("Anti-grav")
|
|
||||||
@vessel.pilot.order(priority: 10, group: :fly_mode) do
|
|
||||||
@vessel.pilot.permanent_mode = :antigrav
|
|
||||||
@vessel.gravity_body.acceleration[0] = @vessel.gravity[0]
|
|
||||||
@vessel.gravity_body.acceleration[1] = @vessel.gravity[1]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if ImGui.button("Disable anti-grav")
|
|
||||||
@vessel.pilot.order(priority: 11, group: :fly_mode) do
|
|
||||||
if @vessel.pilot.permanent_mode == :antigrav
|
|
||||||
@vessel.pilot.permanent_mode = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
},
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def draw_navigation(gravity_field)
|
|
||||||
# ImGui.text "Total Accele is : [#{acceleration[0].round(4)}, #{acceleration[1].round(4)}] m/s²"
|
|
||||||
ImGui.text "Pulse Accele is : [#{@vessel.gravity_body.acceleration[0].round(4)}, #{@vessel.gravity_body.acceleration[1].round(4)}] m/s²"
|
|
||||||
ImGui.text "GraviticBody is : [#{gravity_field[0].round(4)}, #{gravity_field[1].round(4)}] m/s²"
|
|
||||||
ImGui.text "Current speed is : #{@vessel.gravity_body.speed.magnitude.round(4)} m/s"
|
|
||||||
|
|
||||||
draw_table(title: "Actual vectors", headers: {"Name", "X", "Y", "unit"}) do
|
|
||||||
draw_table_line "Position", @vessel.gravity_body.position[0].round(3).to_s, @vessel.gravity_body.position[1].round(3).to_s, "m"
|
|
||||||
draw_table_line "Speed", @vessel.gravity_body.speed[0].round(3).to_s, @vessel.gravity_body.speed[1].round(3).to_s, "m/s"
|
|
||||||
draw_table_line "Acceleration", @vessel.gravity_body.acceleration[0].round(3).to_s, @vessel.gravity_body.acceleration[1].round(3).to_s, "m/s²"
|
|
||||||
end
|
|
||||||
|
|
||||||
ImGui.text "Zoom on"
|
|
||||||
ImGui.radio_button("vessel##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 0)
|
|
||||||
ImGui.same_line
|
|
||||||
ImGui.radio_button("star##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 1)
|
|
||||||
ImGui.same_line
|
|
||||||
ImGui.radio_button("fixed##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 2)
|
|
||||||
ImGui.same_line
|
|
||||||
ImGui.radio_button("zero##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 3)
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute(tick : Int)
|
def execute(tick : Int)
|
||||||
@vessel.execute_orders!
|
@vessel.execute_orders!
|
||||||
|
@ -422,180 +219,68 @@ class Game
|
||||||
gravity_field = @g.acceleration(@bodies[:vessel].position)
|
gravity_field = @g.acceleration(@bodies[:vessel].position)
|
||||||
@graviting.each { |graviting| accelerate_by_tick(graviting) }
|
@graviting.each { |graviting| accelerate_by_tick(graviting) }
|
||||||
|
|
||||||
if ImGui.begin("Bridge")
|
draw_bridge(gravity_field)
|
||||||
if ImGui.tree_node_ex("Captain", ImGui::ImGuiTreeNodeFlags.new(ImGui::ImGuiTreeNodeFlags::DefaultOpen))
|
|
||||||
draw_captain
|
|
||||||
ImGui.tree_pop
|
|
||||||
end
|
|
||||||
|
|
||||||
if ImGui.tree_node_ex("Navigation", ImGui::ImGuiTreeNodeFlags.new(ImGui::ImGuiTreeNodeFlags::DefaultOpen))
|
object_position =
|
||||||
draw_navigation(gravity_field)
|
|
||||||
ImGui.tree_pop
|
|
||||||
end
|
|
||||||
|
|
||||||
if ImGui.tree_node_ex("Pilot", ImGui::ImGuiTreeNodeFlags.new(ImGui::ImGuiTreeNodeFlags::DefaultOpen))
|
|
||||||
draw_pilot
|
|
||||||
ImGui.tree_pop
|
|
||||||
end
|
|
||||||
|
|
||||||
ImGui.end
|
|
||||||
end
|
|
||||||
|
|
||||||
zoom_object_position =
|
|
||||||
if @vessel.navigation.zoom_select == 0
|
if @vessel.navigation.zoom_select == 0
|
||||||
@vessel.navigation.zoom_position = @vessel.gravity_body.position * ZOOM
|
@vessel.navigation.zoom_position = @vessel.gravity_body.position
|
||||||
elsif @vessel.navigation.zoom_select == 1
|
elsif @vessel.navigation.zoom_select == 1
|
||||||
@vessel.navigation.zoom_position = @star.gravity_body.position * ZOOM
|
@vessel.navigation.zoom_position = @star.gravity_body.position
|
||||||
elsif @vessel.navigation.zoom_select == 2
|
elsif @vessel.navigation.zoom_select == 2
|
||||||
@vessel.navigation.zoom_position
|
@vessel.navigation.zoom_position
|
||||||
else
|
else
|
||||||
@vessel.navigation.zoom_position = @screen_center_position
|
@vessel.navigation.zoom_position = @screen_center_position
|
||||||
end
|
end
|
||||||
zoom_offset = @screen_center_position - zoom_object_position
|
@center_position = object_position
|
||||||
@projectables.each { |projectable| @window.draw(projectable.sf_shape(ZOOM, zoom_offset)) }
|
@view.set_center(
|
||||||
draw_all_trajectories(ZOOM, zoom_offset)
|
@center_position[0],
|
||||||
|
@center_position[1],
|
||||||
|
)
|
||||||
|
if @zoom != @vessel.navigation.zoom_ratio
|
||||||
|
@view.zoom @zoom / @vessel.navigation.zoom_ratio
|
||||||
|
@zoom = @vessel.navigation.zoom_ratio
|
||||||
|
if @zoom == 1.0
|
||||||
|
@view.viewport = default_viewport
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@window.view = @view
|
||||||
|
|
||||||
draw_grid(ZOOM, zoom_object_position)
|
@projectables.each { |projectable| draw(projectable.sf_shape) }
|
||||||
# draw_grid(ZOOM, Vector[0.0, 0.0])
|
draw_all_trajectories
|
||||||
|
# draw_grid
|
||||||
|
@vessel.navigation.cadran.radius.each do |radius|
|
||||||
|
draw_cadran(center: @vessel.gravity_body.position, radius: radius)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_all_trajectories(coef, offset)
|
def draw_all_trajectories
|
||||||
t = Trajectory.new(body: @vessel_p.gravity_body, gravity_field: @g)
|
t = Trajectory.new(body: @vessel_p.gravity_body, gravity_field: @g)
|
||||||
t_with_gravity = t.compute(steps: 1000, accuracy: 500.millisecond * @timescale)
|
t_with_gravity = t.compute(steps: 1000, accuracy: 500.millisecond * @timescale)
|
||||||
draw_trajectory({255, 0, 0}, t_with_gravity, coef, offset)
|
draw_trajectory({255, 0, 0}, t_with_gravity)
|
||||||
|
|
||||||
t = Trajectory.new(body: @vessel_p.gravity_body, gravity_field: Gravity::Field(2).zero)
|
t = Trajectory.new(body: @vessel_p.gravity_body, gravity_field: Gravity::Field(2).zero)
|
||||||
t_without_gravity = t.compute(steps: 20, accuracy: 5.second * @timescale)
|
t_without_gravity = t.compute(steps: 20, accuracy: 5.second * @timescale)
|
||||||
draw_trajectory({255, 255, 0}, t_without_gravity, coef, offset)
|
draw_trajectory({255, 255, 0}, t_without_gravity)
|
||||||
|
|
||||||
t = Trajectory.new(body: @pla1.gravity_body, gravity_field: @g)
|
t = Trajectory.new(body: @pla1.gravity_body, gravity_field: @g)
|
||||||
t_without_gravity = t.compute(steps: 100, accuracy: 10.second * @timescale)
|
t_without_gravity = t.compute(steps: 100, accuracy: 10.second * @timescale)
|
||||||
draw_trajectory({255, 0, 0}, t_without_gravity, coef, offset)
|
draw_trajectory({255, 0, 0}, t_without_gravity)
|
||||||
|
|
||||||
t = Trajectory.new(body: @pla2.gravity_body, gravity_field: @g)
|
t = Trajectory.new(body: @pla2.gravity_body, gravity_field: @g)
|
||||||
t_without_gravity = t.compute(steps: 100, accuracy: 10.second * @timescale)
|
t_without_gravity = t.compute(steps: 100, accuracy: 10.second * @timescale)
|
||||||
draw_trajectory({0, 0, 255}, t_without_gravity, coef, offset)
|
draw_trajectory({0, 0, 255}, t_without_gravity)
|
||||||
|
|
||||||
t = Trajectory.new(body: @pla3.gravity_body, gravity_field: @g)
|
t = Trajectory.new(body: @pla3.gravity_body, gravity_field: @g)
|
||||||
t_without_gravity = t.compute(steps: 100, accuracy: 10.second * @timescale)
|
t_without_gravity = t.compute(steps: 100, accuracy: 10.second * @timescale)
|
||||||
draw_trajectory({0, 255, 0}, t_without_gravity, coef, offset)
|
draw_trajectory({0, 255, 0}, t_without_gravity)
|
||||||
end
|
end
|
||||||
|
|
||||||
def draw_trajectory(color : Tuple(Int32, Int32, Int32), trajectory, coef = 1.0, offset = Vector(Float64, 2).zero)
|
def draw_trajectory(color : Tuple(Int32, Int32, Int32), trajectory)
|
||||||
trajectory.each do |point|
|
trajectory.each do |point|
|
||||||
sf_point = SF::CircleShape.new(1)
|
sf_point = SF::CircleShape.new(2)
|
||||||
sf_point.fill_color = SF.color(*color)
|
sf_point.fill_color = SF.color(*color)
|
||||||
point = point * coef + offset
|
|
||||||
sf_point.position = SF.vector2(point[0], point[1])
|
sf_point.position = SF.vector2(point[0], point[1])
|
||||||
@window.draw(sf_point)
|
draw(sf_point)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def absolute_coordinates(x, y, coef, offset)
|
|
||||||
v = SF.vector2f(
|
|
||||||
(x - (offset[0] % MAIN_LINES_REAL_SPACE)) * coef,
|
|
||||||
(y - (offset[1] % MAIN_LINES_REAL_SPACE)) * coef,
|
|
||||||
)
|
|
||||||
# pp v
|
|
||||||
# v
|
|
||||||
end
|
|
||||||
|
|
||||||
def relative_coordinates(x, y, coef, offset)
|
|
||||||
SF.vector2f(x * coef, y * coef)
|
|
||||||
end
|
|
||||||
|
|
||||||
MAIN_LINES_REAL_SPACE = 1000
|
|
||||||
SECONDARY_LINES_AMOUNT = 3
|
|
||||||
SECONDARY_LINES_SPACE = MAIN_LINES_REAL_SPACE / SECONDARY_LINES_AMOUNT
|
|
||||||
SECONDARY_LINES_COLOR = SF::Color.new(255, 255, 255, 20)
|
|
||||||
|
|
||||||
# this one will be dynamic to evaluate distances
|
|
||||||
def draw_grid(coef, zoom_offset)
|
|
||||||
main_lines = Array(SF::VertexBuffer).new
|
|
||||||
secondary_lines = Array(SF::VertexBuffer).new
|
|
||||||
max_size = {@width, @height}.max
|
|
||||||
|
|
||||||
# puts "------------------"
|
|
||||||
main_lines_amount = (MAIN_LINES_REAL_SPACE / max_size / coef).ceil.to_i32 + 2
|
|
||||||
main_lines_amount.times do |index|
|
|
||||||
main_line_v = SF::VertexBuffer.new(SF::LineStrip)
|
|
||||||
main_line_h = SF::VertexBuffer.new(SF::LineStrip)
|
|
||||||
main_lines << main_line_v
|
|
||||||
main_lines << main_line_h
|
|
||||||
main_line_v.create(2)
|
|
||||||
main_line_h.create(2)
|
|
||||||
v_start = MAIN_LINES_REAL_SPACE * index
|
|
||||||
v_end = @width / coef + zoom_offset[0] % MAIN_LINES_REAL_SPACE
|
|
||||||
h_start = MAIN_LINES_REAL_SPACE * index
|
|
||||||
h_end = @height / coef + zoom_offset[1] % MAIN_LINES_REAL_SPACE
|
|
||||||
# pp({
|
|
||||||
# index: index,
|
|
||||||
# v_start: v_start,
|
|
||||||
# v_end: v_end,
|
|
||||||
# h_start: h_start,
|
|
||||||
# h_end: h_end,
|
|
||||||
# offset: zoom_offset,
|
|
||||||
# coef: coef,
|
|
||||||
# })
|
|
||||||
main_line_v_buffer_0 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(v_start, 0, coef, zoom_offset),
|
|
||||||
)
|
|
||||||
main_line_v_buffer_1 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(v_start, h_end, coef, zoom_offset),
|
|
||||||
)
|
|
||||||
main_line_h_buffer_0 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(0, h_start, coef, zoom_offset),
|
|
||||||
)
|
|
||||||
main_line_h_buffer_1 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(v_end, h_start, coef, zoom_offset),
|
|
||||||
)
|
|
||||||
main_line_v_buffer = Slice[main_line_v_buffer_0, main_line_v_buffer_1]
|
|
||||||
main_line_h_buffer = Slice[main_line_h_buffer_0, main_line_h_buffer_1]
|
|
||||||
main_line_v.update(main_line_v_buffer, 0)
|
|
||||||
main_line_h.update(main_line_h_buffer, 0)
|
|
||||||
|
|
||||||
SECONDARY_LINES_AMOUNT.times do |subindex|
|
|
||||||
secondary_line_v = SF::VertexBuffer.new(SF::LineStrip)
|
|
||||||
secondary_line_h = SF::VertexBuffer.new(SF::LineStrip)
|
|
||||||
secondary_lines << secondary_line_v
|
|
||||||
secondary_lines << secondary_line_h
|
|
||||||
secondary_line_v.create(2)
|
|
||||||
secondary_line_h.create(2)
|
|
||||||
secondary_v_start = SECONDARY_LINES_SPACE * subindex
|
|
||||||
secondary_h_start = SECONDARY_LINES_SPACE * subindex
|
|
||||||
secondary_line_v_buffer_0 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(v_start + secondary_v_start, 0, coef, zoom_offset),
|
|
||||||
color: SECONDARY_LINES_COLOR,
|
|
||||||
)
|
|
||||||
secondary_line_v_buffer_1 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(v_start + secondary_v_start, h_end, coef, zoom_offset),
|
|
||||||
color: SECONDARY_LINES_COLOR,
|
|
||||||
)
|
|
||||||
secondary_line_h_buffer_0 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(0, h_start + secondary_h_start, coef, zoom_offset),
|
|
||||||
color: SECONDARY_LINES_COLOR,
|
|
||||||
)
|
|
||||||
secondary_line_h_buffer_1 = SF::Vertex.new(
|
|
||||||
absolute_coordinates(v_end, h_start + secondary_h_start, coef, zoom_offset),
|
|
||||||
color: SECONDARY_LINES_COLOR,
|
|
||||||
)
|
|
||||||
secondary_line_v_buffer = Slice[secondary_line_v_buffer_0, secondary_line_v_buffer_1]
|
|
||||||
secondary_line_h_buffer = Slice[secondary_line_h_buffer_0, secondary_line_h_buffer_1]
|
|
||||||
secondary_line_v.update(secondary_line_v_buffer, 0)
|
|
||||||
secondary_line_h.update(secondary_line_h_buffer, 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
main_lines.each do |line|
|
|
||||||
# line[0].color = SF::Color.new(255, 255, 255)
|
|
||||||
# line[1].color = SF::Color.new(255, 255, 255)
|
|
||||||
@window.draw(line)
|
|
||||||
end
|
|
||||||
secondary_lines.each do |line|
|
|
||||||
# line[0].color = SF::Color.new(255, 255, 255)
|
|
||||||
# line[1].color = SF::Color.new(255, 255, 255)
|
|
||||||
@window.draw(line)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
56
src/tests/physics_sandbox/cadran.cr
Normal file
56
src/tests/physics_sandbox/cadran.cr
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
module PhysicsSandboxCadran
|
||||||
|
|
||||||
|
def add_line(lines, p1 : SF::Vector2f, p2 : SF::Vector2f, color : SF::Color = SF::Color::White)
|
||||||
|
line1 = SF::VertexBuffer.new(SF::LineStrip)
|
||||||
|
line1.create(2)
|
||||||
|
line1.update(
|
||||||
|
Slice[
|
||||||
|
SF::Vertex.new(position: p1, color: color),
|
||||||
|
SF::Vertex.new(position: p2, color: color),
|
||||||
|
], 0)
|
||||||
|
lines << line1
|
||||||
|
end
|
||||||
|
|
||||||
|
CADRAN_COLOR = SF::Color.new(230, 230, 230, 120)
|
||||||
|
def draw_cadran(center : Vector(Float64, 2), radius : Number)
|
||||||
|
circle = SF::CircleShape.new(radius: radius, point_count: 100)
|
||||||
|
circle.outline_color = CADRAN_COLOR
|
||||||
|
circle.outline_thickness = 1
|
||||||
|
center_position_offset = {
|
||||||
|
center[0] - radius,
|
||||||
|
center[1] - radius,
|
||||||
|
}
|
||||||
|
circle.position = center_position_offset
|
||||||
|
circle.fill_color = SF::Color::Transparent
|
||||||
|
draw(circle)
|
||||||
|
|
||||||
|
lines = Array(SF::VertexBuffer).new
|
||||||
|
add_line(
|
||||||
|
lines: lines,
|
||||||
|
p1: SF.vector2f(center[0] - 2**(1/2)/2 * radius, center[1] - 2**(1/2)/2 * radius),
|
||||||
|
p2: SF.vector2f(center[0] + 2**(1/2)/2 * radius, center[1] + 2**(1/2)/2 * radius),
|
||||||
|
color: CADRAN_COLOR,
|
||||||
|
)
|
||||||
|
add_line(
|
||||||
|
lines: lines,
|
||||||
|
p1: SF.vector2f(center[0] + 2**(1/2)/2 * radius, center[1] - 2**(1/2)/2 * radius),
|
||||||
|
p2: SF.vector2f(center[0] - 2**(1/2)/2 * radius, center[1] + 2**(1/2)/2 * radius),
|
||||||
|
color: CADRAN_COLOR,
|
||||||
|
)
|
||||||
|
add_line(
|
||||||
|
lines: lines,
|
||||||
|
p1: SF.vector2f(center[0] + radius, center[1]),
|
||||||
|
p2: SF.vector2f(center[0] - radius, center[1]),
|
||||||
|
color: CADRAN_COLOR,
|
||||||
|
)
|
||||||
|
add_line(
|
||||||
|
lines: lines,
|
||||||
|
p1: SF.vector2f(center[0], center[1] - radius),
|
||||||
|
p2: SF.vector2f(center[0], center[1] + radius),
|
||||||
|
color: CADRAN_COLOR,
|
||||||
|
)
|
||||||
|
|
||||||
|
lines.each { |line| draw(line) }
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
360
src/tests/physics_sandbox/draw.cr
Normal file
360
src/tests/physics_sandbox/draw.cr
Normal file
|
@ -0,0 +1,360 @@
|
||||||
|
module PhysicsSandboxDraw
|
||||||
|
|
||||||
|
include ImGui::Helper
|
||||||
|
|
||||||
|
# will yield the value
|
||||||
|
def draw_slider(label : String, data : Float64, max : Float64 = 100.0, min : Float64 = -100.0, flags : ImGui::ImGuiSliderFlags = ImGui::ImGuiSliderFlags::NoRoundToFormat, &)
|
||||||
|
ptr = pointerof(data)
|
||||||
|
if ImGui.slider_scalar(
|
||||||
|
label: label,
|
||||||
|
p_data: ptr,
|
||||||
|
p_min: min,
|
||||||
|
p_max: max,
|
||||||
|
flags: flags,
|
||||||
|
)
|
||||||
|
yield data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# will yield the value
|
||||||
|
def draw_input(label : String, data : Float64, max : Float64 = 100.0, min : Float64 = -100.0, flags : ImGui::ImGuiInputTextFlags = ImGui::ImGuiInputTextFlags::EnterReturnsTrue, &)
|
||||||
|
ptr = pointerof(data)
|
||||||
|
if ImGui.input_scalar(
|
||||||
|
label: label,
|
||||||
|
p_data: ptr,
|
||||||
|
flags: flags,
|
||||||
|
)
|
||||||
|
data = max if data > max
|
||||||
|
data = min if data < min
|
||||||
|
yield data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_captain
|
||||||
|
ImGui.text "Time passed: #{@time_passed}"
|
||||||
|
draw_slider(
|
||||||
|
label: "Set timescale###set_timescale",
|
||||||
|
data: @timescale,
|
||||||
|
min: 0.1,
|
||||||
|
max: 3600 * 24 * 7,
|
||||||
|
flags: (
|
||||||
|
ImGui::ImGuiSliderFlags::Logarithmic
|
||||||
|
),
|
||||||
|
) do |value|
|
||||||
|
@timescale = value
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_pilot
|
||||||
|
draw_table(title: "Trusters", headers: {"Name", "X", "Y", "unit"}) do
|
||||||
|
draw_table_line(
|
||||||
|
"Analogic acceleration",
|
||||||
|
->{
|
||||||
|
draw_slider(
|
||||||
|
label: "###acceleration_analogue_x",
|
||||||
|
data: @vessel.gravity_body.acceleration[0],
|
||||||
|
min: -@vessel.pilot.max_thrust,
|
||||||
|
max: @vessel.pilot.max_thrust,
|
||||||
|
flags: (
|
||||||
|
ImGui::ImGuiSliderFlags::Logarithmic
|
||||||
|
),
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.order(priority: 10, group: :acceleration_x) do
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(0, value)
|
||||||
|
@vessel.pilot.permanent_modes.clear
|
||||||
|
@vessel.pilot.permanent_modes << Vessel::Pilot::Mode::Constant
|
||||||
|
@vessel.pilot.low_thrust_pressed = false
|
||||||
|
@vessel.pilot.low_thrust_save = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
->{
|
||||||
|
draw_slider(
|
||||||
|
label: "###acceleration_analogue_y",
|
||||||
|
data: @vessel.gravity_body.acceleration[1],
|
||||||
|
min: -@vessel.pilot.max_thrust,
|
||||||
|
max: @vessel.pilot.max_thrust,
|
||||||
|
flags: (
|
||||||
|
ImGui::ImGuiSliderFlags::Logarithmic
|
||||||
|
),
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.order(priority: 10, group: :acceleration_y) do
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(1, value)
|
||||||
|
@vessel.pilot.permanent_modes.clear
|
||||||
|
@vessel.pilot.permanent_modes << Vessel::Pilot::Mode::Constant
|
||||||
|
@vessel.pilot.low_thrust_pressed = false
|
||||||
|
@vessel.pilot.low_thrust_save = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
"m/s²",
|
||||||
|
)
|
||||||
|
|
||||||
|
# automatically reset acceleration to 0, used for maneuvers
|
||||||
|
draw_table_line(
|
||||||
|
"Low thrust",
|
||||||
|
->{
|
||||||
|
draw_slider(
|
||||||
|
label: "###acceleration_low_analogic_x",
|
||||||
|
data: @vessel.gravity_body.acceleration[0],
|
||||||
|
min: -@vessel.pilot.max_thrust,
|
||||||
|
max: @vessel.pilot.max_thrust,
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.order(priority: 10, group: :maneuvers) do
|
||||||
|
@vessel.pilot.temporary_modes << Vessel::Pilot::Mode::Pulse
|
||||||
|
if !@vessel.pilot.low_thrust_pressed
|
||||||
|
@vessel.pilot.low_thrust_save = @vessel.gravity_body.acceleration[0]
|
||||||
|
end
|
||||||
|
@vessel.pilot.low_thrust_pressed = true
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(0, value)
|
||||||
|
lock_callback = @ui_events_handler.add(SF::Event::KeyPressed) do |callback, event|
|
||||||
|
if event.as(SF::Event::KeyPressed).code == SF::Keyboard::Key::L
|
||||||
|
@vessel.pilot.low_thrust_save = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ui_events_handler.add(SF::Event::MouseButtonReleased) do |callback|
|
||||||
|
@ui_events_handler.remove(SF::Event::MouseButtonReleased, callback)
|
||||||
|
@ui_events_handler.remove(SF::Event::MouseButtonReleased, lock_callback)
|
||||||
|
@vessel.pilot.low_thrust_pressed = false
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(0, @vessel.pilot.low_thrust_save)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
->{
|
||||||
|
draw_slider(
|
||||||
|
label: "###acceleration_low_analogic_y",
|
||||||
|
data: @vessel.gravity_body.acceleration[1],
|
||||||
|
min: -@vessel.pilot.max_thrust,
|
||||||
|
max: @vessel.pilot.max_thrust,
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.order(priority: 10, group: :maneuvers) do
|
||||||
|
@vessel.pilot.temporary_modes << Vessel::Pilot::Mode::Pulse
|
||||||
|
if !@vessel.pilot.low_thrust_pressed
|
||||||
|
@vessel.pilot.low_thrust_save = @vessel.gravity_body.acceleration[1]
|
||||||
|
end
|
||||||
|
@vessel.pilot.low_thrust_pressed = true
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(1, value)
|
||||||
|
lock_callback = @ui_events_handler.add(SF::Event::KeyPressed) do |callback, event|
|
||||||
|
if event.as(SF::Event::KeyPressed).code == SF::Keyboard::Key::L
|
||||||
|
@vessel.pilot.low_thrust_save = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ui_events_handler.add(SF::Event::MouseButtonReleased) do |callback|
|
||||||
|
@ui_events_handler.remove(SF::Event::MouseButtonReleased, callback)
|
||||||
|
@ui_events_handler.remove(SF::Event::MouseButtonReleased, lock_callback)
|
||||||
|
@vessel.pilot.low_thrust_pressed = false
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(1, @vessel.pilot.low_thrust_save)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
"m/s²",
|
||||||
|
)
|
||||||
|
|
||||||
|
draw_table_line(
|
||||||
|
"Computer acceleration",
|
||||||
|
->{
|
||||||
|
draw_input(
|
||||||
|
label: "###acceleration_digit_x",
|
||||||
|
data: @vessel.pilot.computer_input_thrust[0],
|
||||||
|
min: -@vessel.pilot.max_thrust,
|
||||||
|
max: @vessel.pilot.max_thrust,
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.order(priority: 9, group: :maneuvers) do
|
||||||
|
@vessel.pilot.computer_input_thrust[0] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
->{
|
||||||
|
draw_input(
|
||||||
|
label: "###acceleration_digit_y",
|
||||||
|
data: @vessel.pilot.computer_input_thrust[1],
|
||||||
|
min: -@vessel.pilot.max_thrust,
|
||||||
|
max: @vessel.pilot.max_thrust,
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.order(priority: 9, group: :maneuvers) do
|
||||||
|
@vessel.pilot.computer_input_thrust[1] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
"m/s²",
|
||||||
|
)
|
||||||
|
|
||||||
|
draw_table_line(
|
||||||
|
"[Security] Max thurst",
|
||||||
|
->{
|
||||||
|
draw_input(
|
||||||
|
label: "###pilot_input_max_thurst",
|
||||||
|
data: @vessel.pilot.max_thrust,
|
||||||
|
min: 9,
|
||||||
|
max: 900,
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.max_thrust = value
|
||||||
|
end
|
||||||
|
},
|
||||||
|
->{
|
||||||
|
draw_slider(
|
||||||
|
label: "###pilot_slider_max_thurst",
|
||||||
|
data: @vessel.pilot.max_thrust,
|
||||||
|
min: 9,
|
||||||
|
max: 900,
|
||||||
|
) do |value|
|
||||||
|
@vessel.pilot.max_thrust = value
|
||||||
|
end
|
||||||
|
},
|
||||||
|
->{
|
||||||
|
ImGui.text @vessel.pilot.max_thrust > 20 ? "Inertia Dampers needed" : "No danger"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Manual reset
|
||||||
|
draw_table_line(
|
||||||
|
"",
|
||||||
|
->{
|
||||||
|
if ImGui.button("Comfirm")
|
||||||
|
@vessel.pilot.order(priority: 100, group: :maneuvers) do
|
||||||
|
@vessel.pilot.permanent_modes.clear
|
||||||
|
@vessel.pilot.permanent_modes << Vessel::Pilot::Mode::Constant
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(@vessel.pilot.computer_input_thrust)
|
||||||
|
# @vessel.pilot.set_exact_acceleration_axis(0, @vessel.pilot.computer_input_thrust[0])
|
||||||
|
# @vessel.pilot.set_exact_acceleration_axis(1, @vessel.pilot.computer_input_thrust[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
->{
|
||||||
|
if ImGui.button("Reset")
|
||||||
|
@vessel.pilot.order(priority: 100, group: :prepare) do
|
||||||
|
@vessel.pilot.permanent_modes.clear
|
||||||
|
@vessel.pilot.permanent_modes << Vessel::Pilot::Mode::Constant
|
||||||
|
@vessel.pilot.set_exact_acceleration_axis(@vessel.pilot.computer_input_thrust)
|
||||||
|
# @vessel.pilot.computer_input_thrust[0] = @vessel.gravity_body.acceleration[0]
|
||||||
|
# @vessel.pilot.computer_input_thrust[1] = @vessel.gravity_body.acceleration[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
->{
|
||||||
|
if ImGui.button("Zero")
|
||||||
|
@vessel.pilot.order(priority: 10, group: :prepare) do
|
||||||
|
@vessel.pilot.computer_input_thrust[0] = 0.0
|
||||||
|
@vessel.pilot.computer_input_thrust[1] = 0.0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
draw_table_line(
|
||||||
|
"",
|
||||||
|
# AntiGrav
|
||||||
|
->{
|
||||||
|
if !@vessel.pilot.permanent_modes.includes?(Vessel::Pilot::Mode::AntiGrav)
|
||||||
|
if ImGui.button("Anti-grav")
|
||||||
|
@vessel.pilot.order(priority: 10, group: :fly_mode) do
|
||||||
|
@vessel.pilot.permanent_modes << Vessel::Pilot::Mode::AntiGrav
|
||||||
|
# @vessel.gravity_body.acceleration[0] = @vessel.gravity[0]
|
||||||
|
# @vessel.gravity_body.acceleration[1] = @vessel.gravity[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ImGui.button("Disable anti-grav")
|
||||||
|
@vessel.pilot.order(priority: 11, group: :fly_mode) do
|
||||||
|
if @vessel.pilot.permanent_modes.includes?(Vessel::Pilot::Mode::AntiGrav)
|
||||||
|
@vessel.pilot.permanent_modes.delete Vessel::Pilot::Mode::AntiGrav
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
|
||||||
|
# AntiSpeed
|
||||||
|
->{
|
||||||
|
if !@vessel.pilot.permanent_modes.includes?(Vessel::Pilot::Mode::AntiSpeed)
|
||||||
|
if ImGui.button("Anti-speed")
|
||||||
|
@vessel.pilot.order(priority: 10, group: :fly_mode) do
|
||||||
|
@vessel.pilot.permanent_modes << Vessel::Pilot::Mode::AntiSpeed
|
||||||
|
@vessel.pilot.current_selected_body = @star.gravity_body
|
||||||
|
# @vessel.antispeed[0] = @vessel.speed[0]
|
||||||
|
# @vessel.antispeed[1] = @vessel.speed[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if ImGui.button("Disable anti-speed")
|
||||||
|
@vessel.pilot.order(priority: 11, group: :fly_mode) do
|
||||||
|
if @vessel.pilot.permanent_modes << Vessel::Pilot::Mode::AntiSpeed
|
||||||
|
@vessel.pilot.permanent_modes.delete Vessel::Pilot::Mode::AntiSpeed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_navigation(gravity_field)
|
||||||
|
# ImGui.text "Total Accele is : [#{acceleration[0].round(4)}, #{acceleration[1].round(4)}] m/s²"
|
||||||
|
ImGui.text "Pulse Accele is : [#{@vessel.gravity_body.acceleration[0].round(4)}, #{@vessel.gravity_body.acceleration[1].round(4)}] m/s²"
|
||||||
|
ImGui.text "GraviticBody is : [#{gravity_field[0].round(4)}, #{gravity_field[1].round(4)}] m/s²"
|
||||||
|
ImGui.text "Current speed is : #{@vessel.gravity_body.speed.magnitude.round(4)} m/s"
|
||||||
|
|
||||||
|
draw_table(title: "Actual vectors", headers: {"Name", "X", "Y", "unit"}) do
|
||||||
|
draw_table_line "Position", @vessel.gravity_body.position[0].round(3).to_s, @vessel.gravity_body.position[1].round(3).to_s, "m"
|
||||||
|
draw_table_line "Speed", @vessel.gravity_body.speed[0].round(3).to_s, @vessel.gravity_body.speed[1].round(3).to_s, "m/s"
|
||||||
|
draw_table_line "Acceleration", @vessel.gravity_body.acceleration[0].round(3).to_s, @vessel.gravity_body.acceleration[1].round(3).to_s, "m/s²"
|
||||||
|
end
|
||||||
|
|
||||||
|
ImGui.text "Zoom on"
|
||||||
|
ImGui.radio_button("vessel##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 0)
|
||||||
|
ImGui.same_line
|
||||||
|
ImGui.radio_button("star##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 1)
|
||||||
|
ImGui.same_line
|
||||||
|
ImGui.radio_button("fixed##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 2)
|
||||||
|
ImGui.same_line
|
||||||
|
ImGui.radio_button("zero##navigation_zoom", pointerof(@vessel.navigation.zoom_select), 3)
|
||||||
|
draw_slider(
|
||||||
|
label: "###cadran_slide_zoom_ratio",
|
||||||
|
data: @vessel.navigation.zoom_ratio,
|
||||||
|
max: 10,
|
||||||
|
min: 0.001,
|
||||||
|
flags: ImGui::ImGuiSliderFlags::Logarithmic,
|
||||||
|
) do |value|
|
||||||
|
@vessel.navigation.zoom_ratio = value
|
||||||
|
end
|
||||||
|
|
||||||
|
ImGui.text "Cadran"
|
||||||
|
draw_slider(
|
||||||
|
label: "###cadran_slide_radius",
|
||||||
|
data: @vessel.navigation.cadran.radius[0],
|
||||||
|
max: 10.0**10,
|
||||||
|
min: 0.0,
|
||||||
|
flags: ImGui::ImGuiSliderFlags::Logarithmic,
|
||||||
|
) do |value|
|
||||||
|
@vessel.navigation.cadran.radius[0] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_bridge(gravity_field)
|
||||||
|
|
||||||
|
if ImGui.begin("Bridge")
|
||||||
|
if ImGui.tree_node_ex("Captain", ImGui::ImGuiTreeNodeFlags.new(ImGui::ImGuiTreeNodeFlags::DefaultOpen))
|
||||||
|
draw_captain
|
||||||
|
ImGui.tree_pop
|
||||||
|
end
|
||||||
|
|
||||||
|
if ImGui.tree_node_ex("Navigation", ImGui::ImGuiTreeNodeFlags.new(ImGui::ImGuiTreeNodeFlags::DefaultOpen))
|
||||||
|
draw_navigation(gravity_field)
|
||||||
|
ImGui.tree_pop
|
||||||
|
end
|
||||||
|
|
||||||
|
if ImGui.tree_node_ex("Pilot", ImGui::ImGuiTreeNodeFlags.new(ImGui::ImGuiTreeNodeFlags::DefaultOpen))
|
||||||
|
draw_pilot
|
||||||
|
ImGui.tree_pop
|
||||||
|
end
|
||||||
|
|
||||||
|
ImGui.end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
115
src/tests/physics_sandbox/grid.cr
Normal file
115
src/tests/physics_sandbox/grid.cr
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
module PhysicsSandboxGrid
|
||||||
|
|
||||||
|
MAIN_LINES_REAL_SPACE = 1000
|
||||||
|
SECONDARY_LINES_AMOUNT = 3
|
||||||
|
SECONDARY_LINES_SPACE = MAIN_LINES_REAL_SPACE / SECONDARY_LINES_AMOUNT
|
||||||
|
SECONDARY_LINES_COLOR = SF::Color.new(255, 255, 255, 30)
|
||||||
|
|
||||||
|
def absolute_coordinates(pos, offset)
|
||||||
|
SF.vector2f(pos[0] + offset[0], pos[1] + offset[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
# this one will be dynamic to evaluate distances
|
||||||
|
def draw_grid
|
||||||
|
main_lines = Array(SF::VertexBuffer).new
|
||||||
|
secondary_lines = Array(SF::VertexBuffer).new
|
||||||
|
width = @width
|
||||||
|
height = @height
|
||||||
|
max_size = {width, height}.max
|
||||||
|
offset = {
|
||||||
|
-@center_position[0] + (@center_position[0] // MAIN_LINES_REAL_SPACE) * MAIN_LINES_REAL_SPACE,
|
||||||
|
-@center_position[1] + (@center_position[1] // MAIN_LINES_REAL_SPACE) * MAIN_LINES_REAL_SPACE,
|
||||||
|
}
|
||||||
|
|
||||||
|
main_lines_amount = (max_size / MAIN_LINES_REAL_SPACE).ceil.to_i32 + 1
|
||||||
|
start = -main_lines_amount // 2
|
||||||
|
stop = start + main_lines_amount
|
||||||
|
pp({
|
||||||
|
center_position: @center_position,
|
||||||
|
offset: offset,
|
||||||
|
max_size: max_size,
|
||||||
|
start: start,
|
||||||
|
stop: stop,
|
||||||
|
main_lines_amount: main_lines_amount,
|
||||||
|
})
|
||||||
|
|
||||||
|
(start..stop).each do |index|
|
||||||
|
main_line_v = SF::VertexBuffer.new(SF::LineStrip)
|
||||||
|
main_line_h = SF::VertexBuffer.new(SF::LineStrip)
|
||||||
|
main_lines << main_line_v
|
||||||
|
main_lines << main_line_h
|
||||||
|
main_line_v.create(2)
|
||||||
|
main_line_h.create(2)
|
||||||
|
x_start = MAIN_LINES_REAL_SPACE * index
|
||||||
|
x_end = width
|
||||||
|
y_start = MAIN_LINES_REAL_SPACE * index
|
||||||
|
y_end = height
|
||||||
|
# pp({
|
||||||
|
# center_position: @center_position,
|
||||||
|
# index: index,
|
||||||
|
# v_start: v_start,
|
||||||
|
# x_end: x_end,
|
||||||
|
# y_start: y_start,
|
||||||
|
# h_end: h_end,
|
||||||
|
# x_start: x_start,
|
||||||
|
# y_start: y_start,
|
||||||
|
# })
|
||||||
|
main_line_v_buffer_0 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({x_start, start * MAIN_LINES_REAL_SPACE}, offset),
|
||||||
|
)
|
||||||
|
main_line_v_buffer_1 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({x_start, y_end}, offset),
|
||||||
|
)
|
||||||
|
main_line_h_buffer_0 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({start * MAIN_LINES_REAL_SPACE, y_start}, offset),
|
||||||
|
)
|
||||||
|
main_line_h_buffer_1 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({x_end, y_start}, offset),
|
||||||
|
)
|
||||||
|
main_line_v_buffer = Slice[main_line_v_buffer_0, main_line_v_buffer_1]
|
||||||
|
main_line_h_buffer = Slice[main_line_h_buffer_0, main_line_h_buffer_1]
|
||||||
|
main_line_v.update(main_line_v_buffer, 0)
|
||||||
|
main_line_h.update(main_line_h_buffer, 0)
|
||||||
|
|
||||||
|
SECONDARY_LINES_AMOUNT.times do |subindex|
|
||||||
|
secondary_line_v = SF::VertexBuffer.new(SF::LineStrip)
|
||||||
|
secondary_line_h = SF::VertexBuffer.new(SF::LineStrip)
|
||||||
|
secondary_lines << secondary_line_v
|
||||||
|
secondary_lines << secondary_line_h
|
||||||
|
secondary_line_v.create(2)
|
||||||
|
secondary_line_h.create(2)
|
||||||
|
secondary_x_start = SECONDARY_LINES_SPACE * subindex
|
||||||
|
secondary_y_start = SECONDARY_LINES_SPACE * subindex
|
||||||
|
secondary_line_v_buffer_0 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({x_start + secondary_x_start, start * MAIN_LINES_REAL_SPACE}, offset),
|
||||||
|
color: SECONDARY_LINES_COLOR,
|
||||||
|
)
|
||||||
|
secondary_line_v_buffer_1 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({x_start + secondary_x_start, y_end}, offset),
|
||||||
|
color: SECONDARY_LINES_COLOR,
|
||||||
|
)
|
||||||
|
secondary_line_h_buffer_0 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({start * MAIN_LINES_REAL_SPACE, y_start + secondary_y_start}, offset),
|
||||||
|
color: SECONDARY_LINES_COLOR,
|
||||||
|
)
|
||||||
|
secondary_line_h_buffer_1 = SF::Vertex.new(
|
||||||
|
absolute_coordinates({x_end, y_start + secondary_y_start}, offset),
|
||||||
|
color: SECONDARY_LINES_COLOR,
|
||||||
|
)
|
||||||
|
secondary_line_v_buffer = Slice[secondary_line_v_buffer_0, secondary_line_v_buffer_1]
|
||||||
|
secondary_line_h_buffer = Slice[secondary_line_h_buffer_0, secondary_line_h_buffer_1]
|
||||||
|
secondary_line_v.update(secondary_line_v_buffer, 0)
|
||||||
|
secondary_line_h.update(secondary_line_h_buffer, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
main_lines.each do |line|
|
||||||
|
draw(line)
|
||||||
|
end
|
||||||
|
secondary_lines.each do |line|
|
||||||
|
draw(line)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user