Start implementing radar data backend
This commit is contained in:
parent
2ea249b948
commit
52b6e96f83
6 changed files with 330 additions and 197 deletions
11
.vscode/tasks.json
vendored
11
.vscode/tasks.json
vendored
|
@ -9,6 +9,15 @@
|
||||||
],
|
],
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"label": "rust: cargo build"
|
"label": "rust: cargo build"
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
"type": "shell",
|
||||||
|
"command": "steam steam://rungameid/365960",
|
||||||
|
"group": "build",
|
||||||
|
"label": "Run rFactor2",
|
||||||
|
"dependsOn": [
|
||||||
|
"rust: cargo build"
|
||||||
|
]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -64,8 +64,6 @@ create_functions_enum!(
|
||||||
[CreateDevice, create_device],
|
[CreateDevice, create_device],
|
||||||
[DestroyDevice, destroy_device],
|
[DestroyDevice, destroy_device],
|
||||||
[CreateSwapchainKHR, create_swapchain],
|
[CreateSwapchainKHR, create_swapchain],
|
||||||
[QueueSubmit, submit_queue],
|
|
||||||
[GetDeviceQueue, get_device_queue],
|
|
||||||
[AcquireNextImageKHR, acquire_next_image],
|
[AcquireNextImageKHR, acquire_next_image],
|
||||||
[QueuePresentKHR, present_queue],
|
[QueuePresentKHR, present_queue],
|
||||||
);
|
);
|
||||||
|
|
210
src/lib.rs
210
src/lib.rs
|
@ -19,19 +19,43 @@ use structs::*;
|
||||||
use vk_handles::*;
|
use vk_handles::*;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
|
static mut LOG_ENABLED: bool = true;
|
||||||
static mut LOG_FILE: String = String::new();
|
static mut LOG_FILE: String = String::new();
|
||||||
|
|
||||||
static mut OVERLAY: Overlay = Overlay::new();
|
static mut OVERLAY: Overlay = Overlay::new();
|
||||||
static mut QUEUE_SUBMIT: PFN_vkQueueSubmit =
|
|
||||||
unsafe { mem::transmute(vkVoidFunction as *const c_void) };
|
|
||||||
static mut ACQUIRE_NEXT_IMAGE: PFN_vkAcquireNextImageKHR =
|
static mut ACQUIRE_NEXT_IMAGE: PFN_vkAcquireNextImageKHR =
|
||||||
unsafe { mem::transmute(vkVoidFunction as *const c_void) };
|
unsafe { mem::transmute(vkVoidFunction as *const c_void) };
|
||||||
|
|
||||||
|
pub(crate) fn logging() -> bool {
|
||||||
|
unsafe { LOG_ENABLED }
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! write_log {
|
||||||
|
($msg:expr) => {
|
||||||
|
if crate::logging() {
|
||||||
|
crate::log($msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use write_log;
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub(crate) extern "C" fn vkNegotiateLoaderLayerInterfaceVersion(
|
pub(crate) extern "C" fn vkNegotiateLoaderLayerInterfaceVersion(
|
||||||
pVersionStruct: *mut VkNegotiateLayerInterface,
|
pVersionStruct: *mut VkNegotiateLayerInterface,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
|
let log_enabled = match std::env::var("RFACTOR_HUD_LOG") {
|
||||||
|
Ok(var) => {
|
||||||
|
let i: u32 = var.parse().unwrap_or(0);
|
||||||
|
|
||||||
|
i == 1
|
||||||
|
}
|
||||||
|
Err(_) => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe { LOG_ENABLED = log_enabled };
|
||||||
|
|
||||||
|
if logging() {
|
||||||
let home = std::env::var("HOME").unwrap();
|
let home = std::env::var("HOME").unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
LOG_FILE = format!("{}/rf2_vk_hud.log", home);
|
LOG_FILE = format!("{}/rf2_vk_hud.log", home);
|
||||||
|
@ -39,9 +63,10 @@ pub(crate) extern "C" fn vkNegotiateLoaderLayerInterfaceVersion(
|
||||||
|
|
||||||
if let Err(_) = File::create(unsafe { &LOG_FILE }) {}
|
if let Err(_) = File::create(unsafe { &LOG_FILE }) {}
|
||||||
|
|
||||||
write_log(" ==================================================================");
|
write_log!(" ==================================================================");
|
||||||
write_log(" ======================= New Negotiation ==========================");
|
write_log!(" ======================= New Negotiation ==========================");
|
||||||
write_log(" ==================================================================");
|
write_log!(" ==================================================================");
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
*pVersionStruct = VkNegotiateLayerInterface {
|
*pVersionStruct = VkNegotiateLayerInterface {
|
||||||
|
@ -57,7 +82,7 @@ pub(crate) extern "C" fn vkNegotiateLoaderLayerInterfaceVersion(
|
||||||
set_vk_handles(match VkTypedefHandles::new() {
|
set_vk_handles(match VkTypedefHandles::new() {
|
||||||
Ok(handles) => handles,
|
Ok(handles) => handles,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("failed to load typedef handles {:?}", err));
|
write_log!(format!("failed to load typedef handles {:?}", err));
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -73,7 +98,7 @@ extern "system" fn get_device_proc_addr(
|
||||||
let func_string = match VkString::try_from(function_name) {
|
let func_string = match VkString::try_from(function_name) {
|
||||||
Ok(func) => func,
|
Ok(func) => func,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
write_log("Err: failed creating string");
|
write_log!("Err: failed creating string");
|
||||||
return Functions::Null.convert();
|
return Functions::Null.convert();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -99,7 +124,7 @@ extern "system" fn get_instance_proc_addr(
|
||||||
let func_string = match VkString::try_from(function_name) {
|
let func_string = match VkString::try_from(function_name) {
|
||||||
Ok(func) => func,
|
Ok(func) => func,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
write_log("Err: failed creating string");
|
write_log!("Err: failed creating string");
|
||||||
return Functions::Null.convert();
|
return Functions::Null.convert();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -122,7 +147,7 @@ pub(crate) extern "system" fn create_instance(
|
||||||
allocator: *const VkAllocationCallbacks,
|
allocator: *const VkAllocationCallbacks,
|
||||||
instance: *mut VkInstance,
|
instance: *mut VkInstance,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
write_log(" ================== vulkan layer create instance ==================");
|
write_log!(" ================== vulkan layer create instance ==================");
|
||||||
|
|
||||||
let chain_info = match VkLayerInstanceCreateInfo::get_chain_info(
|
let chain_info = match VkLayerInstanceCreateInfo::get_chain_info(
|
||||||
unsafe { &*create_info },
|
unsafe { &*create_info },
|
||||||
|
@ -130,7 +155,7 @@ pub(crate) extern "system" fn create_instance(
|
||||||
) {
|
) {
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
None => {
|
None => {
|
||||||
write_log("instance chain info not found.");
|
write_log!("instance chain info not found.");
|
||||||
return VK_ERROR_LAYER_NOT_PRESENT;
|
return VK_ERROR_LAYER_NOT_PRESENT;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -151,11 +176,11 @@ pub(crate) extern "system" fn create_instance(
|
||||||
|
|
||||||
vk_handles_mut().load_instance_functions(unsafe { *instance }, proc_addr);
|
vk_handles_mut().load_instance_functions(unsafe { *instance }, proc_addr);
|
||||||
|
|
||||||
write_log("-> successfully created instance.");
|
write_log!("-> successfully created instance.");
|
||||||
|
|
||||||
let ext_names = unsafe { (*create_info).extension_names() };
|
let ext_names = unsafe { (*create_info).extension_names() };
|
||||||
|
|
||||||
write_log(format!("{:?}", ext_names));
|
write_log!(format!("{:?}", ext_names));
|
||||||
|
|
||||||
// DXVK workaround, it creates the instance twice with different properties
|
// DXVK workaround, it creates the instance twice with different properties
|
||||||
if ext_names.contains(&VkString::new("VK_KHR_surface")) {
|
if ext_names.contains(&VkString::new("VK_KHR_surface")) {
|
||||||
|
@ -168,7 +193,7 @@ pub(crate) extern "system" fn create_instance(
|
||||||
) {
|
) {
|
||||||
Ok(ins) => ins,
|
Ok(ins) => ins,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("-> local instance creation failed: {:?}", err));
|
write_log!(format!("-> local instance creation failed: {:?}", err));
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -176,7 +201,7 @@ pub(crate) extern "system" fn create_instance(
|
||||||
OVERLAY.set_instance(ins);
|
OVERLAY.set_instance(ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_log("-> created local instance handle");
|
write_log!("-> created local instance handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
VK_SUCCESS
|
VK_SUCCESS
|
||||||
|
@ -186,7 +211,7 @@ pub(crate) extern "system" fn destroy_instance(
|
||||||
instance: VkInstance,
|
instance: VkInstance,
|
||||||
allocator: *const VkAllocationCallbacks,
|
allocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
write_log(" ================== vulkan layer destroy instance ==================");
|
write_log!(" ================== vulkan layer destroy instance ==================");
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(vk_fn) = vk_handles().handle("vkDestroyInstance") {
|
if let Some(vk_fn) = vk_handles().handle("vkDestroyInstance") {
|
||||||
|
@ -203,14 +228,14 @@ pub(crate) extern "system" fn create_device(
|
||||||
allocator: *const VkAllocationCallbacks,
|
allocator: *const VkAllocationCallbacks,
|
||||||
device: *mut VkDevice,
|
device: *mut VkDevice,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
write_log(" ================== vulkan layer create device ==================");
|
write_log!(" ================== vulkan layer create device ==================");
|
||||||
|
|
||||||
let chain_info =
|
let chain_info =
|
||||||
match VkLayerDeviceCreateInfo::get_chain_info(unsafe { &*create_info }, VK_LAYER_LINK_INFO)
|
match VkLayerDeviceCreateInfo::get_chain_info(unsafe { &*create_info }, VK_LAYER_LINK_INFO)
|
||||||
{
|
{
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
None => {
|
None => {
|
||||||
write_log("device chain info not found.");
|
write_log!("device chain info not found.");
|
||||||
return VK_ERROR_LAYER_NOT_PRESENT;
|
return VK_ERROR_LAYER_NOT_PRESENT;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -226,7 +251,7 @@ pub(crate) extern "system" fn create_device(
|
||||||
create_device(physical_device, create_info, allocator, device)
|
create_device(physical_device, create_info, allocator, device)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
write_log("failed creating device");
|
write_log!("failed creating device");
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,18 +263,10 @@ pub(crate) extern "system" fn create_device(
|
||||||
|
|
||||||
vk_handles_mut().load_device_functions(unsafe { *device }, proc_addr);
|
vk_handles_mut().load_device_functions(unsafe { *device }, proc_addr);
|
||||||
unsafe {
|
unsafe {
|
||||||
QUEUE_SUBMIT = match vk_handles().handle("vkQueueSubmit") {
|
|
||||||
Some(submit) => mem::transmute(submit),
|
|
||||||
None => {
|
|
||||||
write_log("failed querying vkQueueSubmit");
|
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ACQUIRE_NEXT_IMAGE = match vk_handles().handle("vkAcquireNextImageKHR") {
|
ACQUIRE_NEXT_IMAGE = match vk_handles().handle("vkAcquireNextImageKHR") {
|
||||||
Some(acquire_next_image) => mem::transmute(acquire_next_image),
|
Some(acquire_next_image) => mem::transmute(acquire_next_image),
|
||||||
None => {
|
None => {
|
||||||
write_log("failed querying vkAcquireNextImageKHR");
|
write_log!("failed querying vkAcquireNextImageKHR");
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -258,7 +275,7 @@ pub(crate) extern "system" fn create_device(
|
||||||
let pdev = match PhysicalDevice::from_raw(unsafe { OVERLAY.instance() }, physical_device) {
|
let pdev = match PhysicalDevice::from_raw(unsafe { OVERLAY.instance() }, physical_device) {
|
||||||
Ok(pdev) => pdev,
|
Ok(pdev) => pdev,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("failed creating physical device: {:?}", err));
|
write_log!(format!("failed creating physical device: {:?}", err));
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -267,7 +284,7 @@ pub(crate) extern "system" fn create_device(
|
||||||
{
|
{
|
||||||
Ok(qi) => qi,
|
Ok(qi) => qi,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("failed getting queue info: {:?}", err));
|
write_log!(format!("failed getting queue info: {:?}", err));
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -279,13 +296,13 @@ pub(crate) extern "system" fn create_device(
|
||||||
);
|
);
|
||||||
|
|
||||||
for info in create_queue_info {
|
for info in create_queue_info {
|
||||||
write_log(format!(
|
write_log!(format!(
|
||||||
"pCreateDeviceInfo; queue fam: {}, queue count: {}",
|
"pCreateDeviceInfo; queue fam: {}, queue count: {}",
|
||||||
info.queueFamilyIndex, info.queueCount
|
info.queueFamilyIndex, info.queueCount
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
write_log(format!(
|
write_log!(format!(
|
||||||
"Queue: queue fam: {}, queue count: {}",
|
"Queue: queue fam: {}, queue count: {}",
|
||||||
queue_info.queue_create_info.queueFamilyIndex, queue_info.queue_create_info.queueCount
|
queue_info.queue_create_info.queueFamilyIndex, queue_info.queue_create_info.queueCount
|
||||||
));
|
));
|
||||||
|
@ -293,21 +310,21 @@ pub(crate) extern "system" fn create_device(
|
||||||
|
|
||||||
let ext_names = unsafe { (*create_info).extension_names() };
|
let ext_names = unsafe { (*create_info).extension_names() };
|
||||||
|
|
||||||
write_log(format!("{:?}", ext_names));
|
write_log!(format!("{:?}", ext_names));
|
||||||
|
|
||||||
let device = match Device::preinitialized(unsafe { *device }, proc_addr, pdev, &ext_names) {
|
let device = match Device::preinitialized(unsafe { *device }, proc_addr, pdev, &ext_names) {
|
||||||
Ok(dev) => dev,
|
Ok(dev) => dev,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("-> local device creation failed: {:?}", err));
|
write_log!(format!("-> local device creation failed: {:?}", err));
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
write_log("created device");
|
write_log!("created device");
|
||||||
|
|
||||||
let queue = device.get_queue(queue_info.queue_family_index, queue_info.queue_index);
|
let queue = device.get_queue(queue_info.queue_family_index, queue_info.queue_index);
|
||||||
|
|
||||||
write_log("got queue from device");
|
write_log!("got queue from device");
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
OVERLAY.set_device(device);
|
OVERLAY.set_device(device);
|
||||||
|
@ -321,7 +338,7 @@ pub(crate) extern "system" fn destroy_device(
|
||||||
device: VkDevice,
|
device: VkDevice,
|
||||||
allocator: *const VkAllocationCallbacks,
|
allocator: *const VkAllocationCallbacks,
|
||||||
) {
|
) {
|
||||||
write_log(" ================== vulkan layer destroy device ==================");
|
write_log!(" ================== vulkan layer destroy device ==================");
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(vk_fn) = vk_handles().handle("vkDestroyDevice") {
|
if let Some(vk_fn) = vk_handles().handle("vkDestroyDevice") {
|
||||||
|
@ -338,20 +355,20 @@ pub(crate) extern "system" fn create_swapchain(
|
||||||
_allocator: *const VkAllocationCallbacks,
|
_allocator: *const VkAllocationCallbacks,
|
||||||
p_swapchain: *mut VkSwapchainKHR,
|
p_swapchain: *mut VkSwapchainKHR,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
write_log(" ================== vulkan layer create swapchain ==================");
|
write_log!(" ================== vulkan layer create swapchain ==================");
|
||||||
|
|
||||||
let create_swapchain: PFN_vkCreateSwapchainKHR =
|
let create_swapchain: PFN_vkCreateSwapchainKHR =
|
||||||
match vk_handles().handle("vkCreateSwapchainKHR") {
|
match vk_handles().handle("vkCreateSwapchainKHR") {
|
||||||
Some(create_swapchain) => unsafe { mem::transmute(create_swapchain) },
|
Some(create_swapchain) => unsafe { mem::transmute(create_swapchain) },
|
||||||
None => {
|
None => {
|
||||||
write_log("failed querying vkCreateSwapchainKHR");
|
write_log!("failed querying vkCreateSwapchainKHR");
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
create_swapchain(_device, create_info, _allocator, p_swapchain);
|
create_swapchain(_device, create_info, _allocator, p_swapchain);
|
||||||
|
|
||||||
write_log(format!("-> created swapchain vk handle {:?}", unsafe {
|
write_log!(format!("-> created swapchain vk handle {:?}", unsafe {
|
||||||
*p_swapchain
|
*p_swapchain
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -359,99 +376,23 @@ pub(crate) extern "system" fn create_swapchain(
|
||||||
match unsafe { Swapchain::from_raw(OVERLAY.device(), &*create_info, *p_swapchain) } {
|
match unsafe { Swapchain::from_raw(OVERLAY.device(), &*create_info, *p_swapchain) } {
|
||||||
Ok(swapchain) => swapchain,
|
Ok(swapchain) => swapchain,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("create swapchain failed: {:?}", err));
|
write_log!(format!("create swapchain failed: {:?}", err));
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
write_log("-> created Arc<Swapchain>");
|
write_log!("-> created Arc<Swapchain>");
|
||||||
|
|
||||||
if let Err(err) = unsafe { OVERLAY.create_rendering(swapchain) } {
|
if let Err(err) = unsafe { OVERLAY.create_rendering(swapchain) } {
|
||||||
write_log(format!("create overlay rendering struct failed: {:?}", err));
|
write_log!(format!("create overlay rendering struct failed: {:?}", err));
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
return VK_ERROR_INITIALIZATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_log("-> created renderer");
|
write_log!("-> created renderer");
|
||||||
|
|
||||||
VK_SUCCESS
|
VK_SUCCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) extern "system" fn submit_queue(
|
|
||||||
queue: VkQueue,
|
|
||||||
submit_count: u32,
|
|
||||||
submits: *const VkSubmitInfo,
|
|
||||||
fence: VkFence,
|
|
||||||
) -> VkResult {
|
|
||||||
write_log(" ================== vulkan layer submit queue ==================");
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
write_log(format!(
|
|
||||||
"submit queue ({:?}), internal queue: ({:?})",
|
|
||||||
queue,
|
|
||||||
OVERLAY.queue().lock().unwrap().vk_handle()
|
|
||||||
));
|
|
||||||
|
|
||||||
// let command_buffers = slice::from_raw_parts(
|
|
||||||
// (*submits).pCommandBuffers,
|
|
||||||
// (*submits).commandBufferCount as usize,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let cb = match OVERLAY.render() {
|
|
||||||
// Ok(cb) => cb,
|
|
||||||
// Err(err) => {
|
|
||||||
// write_log(format!("overlay rendering failed: {:?}", err));
|
|
||||||
// return VK_ERROR_DEVICE_LOST;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let cb = [command_buffers, &[cb]].concat();
|
|
||||||
|
|
||||||
// let mut_ptr = submits as *mut VkSubmitInfo;
|
|
||||||
|
|
||||||
// (*mut_ptr).commandBufferCount = cb.len() as u32;
|
|
||||||
// (*mut_ptr).pCommandBuffers = cb.as_ptr();
|
|
||||||
|
|
||||||
QUEUE_SUBMIT(queue, submit_count, submits, fence)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) extern "system" fn get_device_queue(
|
|
||||||
device: VkDevice,
|
|
||||||
queue_family_index: u32,
|
|
||||||
queue_index: u32,
|
|
||||||
p_queue: *mut VkQueue,
|
|
||||||
) {
|
|
||||||
write_log(" ================== vulkan layer get device queue ==================");
|
|
||||||
|
|
||||||
let get_device_queue: PFN_vkGetDeviceQueue = match vk_handles().handle("vkGetDeviceQueue") {
|
|
||||||
Some(get_queue) => unsafe { mem::transmute(get_queue) },
|
|
||||||
None => {
|
|
||||||
write_log("failed querying vkGetDeviceQueue");
|
|
||||||
panic!("failed querying vkGetDeviceQueue");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
get_device_queue(device, queue_family_index, queue_index, p_queue);
|
|
||||||
write_log(format!("new queue: {:?}", unsafe { *p_queue }));
|
|
||||||
unsafe {
|
|
||||||
write_log(format!(
|
|
||||||
"internal queue: ({:?})",
|
|
||||||
OVERLAY.queue().lock().unwrap().vk_handle()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsafe {
|
|
||||||
// let arc_device = OVERLAY.device();
|
|
||||||
|
|
||||||
// arc_device.physical_device().OVERLAY.add_queue(Queue::new(
|
|
||||||
// arc_device,
|
|
||||||
// *p_queue,
|
|
||||||
// queue_family_index,
|
|
||||||
// queue_index,
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) extern "system" fn acquire_next_image(
|
pub(crate) extern "system" fn acquire_next_image(
|
||||||
device: VkDevice,
|
device: VkDevice,
|
||||||
swapchain: VkSwapchainKHR,
|
swapchain: VkSwapchainKHR,
|
||||||
|
@ -472,7 +413,7 @@ pub(crate) extern "system" fn acquire_next_image(
|
||||||
Some(fence),
|
Some(fence),
|
||||||
);
|
);
|
||||||
|
|
||||||
write_log(format!(
|
write_log!(format!(
|
||||||
"acquire (swapchain: {:?}) res: {:?}",
|
"acquire (swapchain: {:?}) res: {:?}",
|
||||||
sc.vk_handle(),
|
sc.vk_handle(),
|
||||||
res
|
res
|
||||||
|
@ -488,13 +429,13 @@ pub(crate) extern "system" fn acquire_next_image(
|
||||||
OutOfDate::TimeOut => VK_TIMEOUT,
|
OutOfDate::TimeOut => VK_TIMEOUT,
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("failed acquiring next image {:?}", err));
|
write_log!(format!("failed acquiring next image {:?}", err));
|
||||||
VK_ERROR_DEVICE_LOST
|
VK_ERROR_DEVICE_LOST
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
write_log("acquired other swapchain image");
|
write_log!("acquired other swapchain image");
|
||||||
ACQUIRE_NEXT_IMAGE(device, swapchain, timeout, semaphore, fence, image_index)
|
ACQUIRE_NEXT_IMAGE(device, swapchain, timeout, semaphore, fence, image_index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,8 +446,9 @@ pub(crate) extern "system" fn present_queue(
|
||||||
queue: VkQueue,
|
queue: VkQueue,
|
||||||
present_info: *const VkPresentInfoKHR,
|
present_info: *const VkPresentInfoKHR,
|
||||||
) -> VkResult {
|
) -> VkResult {
|
||||||
write_log(" ================== vulkan layer queue present ==================");
|
if logging() {
|
||||||
write_log(format!("iq: {:?}, cq: {:?}", queue, unsafe {
|
write_log!(" ================== vulkan layer queue present ==================");
|
||||||
|
write_log!(format!("iq: {:?}, cq: {:?}", queue, unsafe {
|
||||||
OVERLAY.queue().lock().unwrap().vk_handle()
|
OVERLAY.queue().lock().unwrap().vk_handle()
|
||||||
}));
|
}));
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -515,13 +457,17 @@ pub(crate) extern "system" fn present_queue(
|
||||||
(*present_info).swapchainCount as usize,
|
(*present_info).swapchainCount as usize,
|
||||||
);
|
);
|
||||||
|
|
||||||
write_log(format!("present {} swapchain(s)", swapchains.len()));
|
write_log!(format!("present {} swapchain(s)", swapchains.len()));
|
||||||
|
|
||||||
for swapchain in swapchains {
|
for swapchain in swapchains {
|
||||||
write_log(format!("present swapchain: {:?}", swapchain));
|
write_log!(format!("present swapchain: {:?}", swapchain));
|
||||||
|
|
||||||
if let Some(swch) = OVERLAY.swapchain(*swapchain) {
|
if let Some(swch) = OVERLAY.swapchain(*swapchain) {
|
||||||
write_log(" -> internal swapchain found!");
|
write_log!(format!(
|
||||||
|
" -> internal swapchain found! ({:?})",
|
||||||
|
swch.vk_handle()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,7 +475,7 @@ pub(crate) extern "system" fn present_queue(
|
||||||
match unsafe { OVERLAY.render() } {
|
match unsafe { OVERLAY.render() } {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("overlay rendering failed: {:?}", err));
|
write_log!(format!("overlay rendering failed: {:?}", err));
|
||||||
return VK_ERROR_DEVICE_LOST;
|
return VK_ERROR_DEVICE_LOST;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -537,7 +483,7 @@ pub(crate) extern "system" fn present_queue(
|
||||||
let pfn: PFN_vkQueuePresentKHR = match vk_handles().handle("vkQueuePresentKHR") {
|
let pfn: PFN_vkQueuePresentKHR = match vk_handles().handle("vkQueuePresentKHR") {
|
||||||
Some(pfn) => unsafe { mem::transmute(pfn) },
|
Some(pfn) => unsafe { mem::transmute(pfn) },
|
||||||
None => {
|
None => {
|
||||||
write_log("failed querying vkQueuePresentKHR");
|
write_log!("failed querying vkQueuePresentKHR");
|
||||||
return VK_ERROR_DEVICE_LOST;
|
return VK_ERROR_DEVICE_LOST;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -545,7 +491,9 @@ pub(crate) extern "system" fn present_queue(
|
||||||
pfn(queue, present_info)
|
pfn(queue, present_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_log(msg: impl ToString) {
|
pub fn log(msg: impl ToString) {
|
||||||
|
assert!(logging());
|
||||||
|
|
||||||
if let Ok(mut file) = OpenOptions::new()
|
if let Ok(mut file) = OpenOptions::new()
|
||||||
.append(true)
|
.append(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
use crate::write_log;
|
use crate::write_log;
|
||||||
|
|
||||||
use self::{rendering::Rendering, rfactor_data::RFactorData};
|
use self::{
|
||||||
|
rendering::Rendering,
|
||||||
|
rfactor_data::{DataConfig, RFactorData},
|
||||||
|
};
|
||||||
|
|
||||||
mod pipeline;
|
mod pipeline;
|
||||||
mod rendering;
|
mod rendering;
|
||||||
mod rfactor_data;
|
mod rfactor_data;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use cgmath::vec3;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
|
@ -66,30 +70,40 @@ impl Overlay {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> {
|
pub fn create_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> {
|
||||||
write_log("-> create rendering: start");
|
write_log!("-> create rendering: start");
|
||||||
|
|
||||||
self.rendering = None;
|
self.rendering = None;
|
||||||
|
|
||||||
write_log("-> create rendering: old cleared");
|
write_log!("-> create rendering: old cleared");
|
||||||
|
|
||||||
self.rendering = Some(Rendering::new(self.device(), self.queue(), swapchain)?);
|
self.rendering = Some(Rendering::new(self.device(), self.queue(), swapchain)?);
|
||||||
|
|
||||||
write_log("-> create rendering: new created");
|
write_log!("-> create rendering: new created");
|
||||||
|
|
||||||
write_log("-> create rendering: end");
|
write_log!("-> create rendering: end");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) -> Result<()> {
|
pub fn render(&mut self) -> Result<()> {
|
||||||
|
let swapchain = self.rendering.as_ref().unwrap().swapchain().clone();
|
||||||
|
|
||||||
if self.rfactor_data.is_none() {
|
if self.rfactor_data.is_none() {
|
||||||
self.rfactor_data = RFactorData::new(
|
self.rfactor_data = RFactorData::new(
|
||||||
|
DataConfig {
|
||||||
|
radar_scale: 1.0,
|
||||||
|
radar_car_distance: 20.0,
|
||||||
|
safe_color: vec3(0.0, 0.75, 0.0),
|
||||||
|
danger_color: vec3(0.75, 0.0, 0.0),
|
||||||
|
},
|
||||||
self.device(),
|
self.device(),
|
||||||
self.rendering
|
self.rendering
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.single_color_pipeline()
|
.single_color_pipeline()
|
||||||
.descriptor_layout(),
|
.descriptor_layout(),
|
||||||
|
swapchain.width(),
|
||||||
|
swapchain.height(),
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
@ -104,8 +118,6 @@ impl Overlay {
|
||||||
None => Vec::new(),
|
None => Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let swapchain = self.rendering.as_ref().unwrap().swapchain().clone();
|
|
||||||
|
|
||||||
self.rendering.as_mut().unwrap().render(swapchain, &objects)
|
self.rendering.as_mut().unwrap().render(swapchain, &objects)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cgmath::{Vector2, Vector4};
|
use cgmath::{Matrix4, Vector2, Vector4};
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -22,25 +22,25 @@ impl PositionOnlyVertex {
|
||||||
/// corners[2] - top right
|
/// corners[2] - top right
|
||||||
/// corners[3] - bottom right
|
/// corners[3] - bottom right
|
||||||
///
|
///
|
||||||
pub fn from_2d_corners(corners: [Vector2<f32>; 4]) -> [Self; 6] {
|
pub fn from_2d_corners(ortho: Matrix4<f32>, corners: [Vector2<f32>; 4]) -> [Self; 6] {
|
||||||
[
|
[
|
||||||
Self {
|
Self {
|
||||||
position: corners[0].extend(0.0).extend(1.0),
|
position: ortho * corners[0].extend(0.0).extend(1.0),
|
||||||
},
|
},
|
||||||
Self {
|
Self {
|
||||||
position: corners[1].extend(0.0).extend(1.0),
|
position: ortho * corners[1].extend(0.0).extend(1.0),
|
||||||
},
|
},
|
||||||
Self {
|
Self {
|
||||||
position: corners[2].extend(0.0).extend(1.0),
|
position: ortho * corners[2].extend(0.0).extend(1.0),
|
||||||
},
|
},
|
||||||
Self {
|
Self {
|
||||||
position: corners[2].extend(0.0).extend(1.0),
|
position: ortho * corners[2].extend(0.0).extend(1.0),
|
||||||
},
|
},
|
||||||
Self {
|
Self {
|
||||||
position: corners[3].extend(0.0).extend(1.0),
|
position: ortho * corners[3].extend(0.0).extend(1.0),
|
||||||
},
|
},
|
||||||
Self {
|
Self {
|
||||||
position: corners[0].extend(0.0).extend(1.0),
|
position: ortho * corners[0].extend(0.0).extend(1.0),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -62,20 +62,20 @@ impl Rendering {
|
||||||
queue: Arc<Mutex<Queue>>,
|
queue: Arc<Mutex<Queue>>,
|
||||||
swapchain: Arc<Swapchain>,
|
swapchain: Arc<Swapchain>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
write_log("-> Rendering ctor: begin");
|
crate::write_log!("-> Rendering ctor: begin");
|
||||||
let vk_images = swapchain.vk_images()?;
|
let vk_images = swapchain.vk_images()?;
|
||||||
write_log(format!(
|
write_log!(format!(
|
||||||
"-> Rendering ctor: vk images ({})",
|
"-> Rendering ctor: vk images ({})",
|
||||||
vk_images.len()
|
vk_images.len()
|
||||||
));
|
));
|
||||||
let images = match swapchain.wrap_images(&vk_images, &queue, true) {
|
let images = match swapchain.wrap_images(&vk_images, &queue, true) {
|
||||||
Ok(images) => images,
|
Ok(images) => images,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
write_log(format!("-> Rendering ctor: failed wrapper: {:?}", err));
|
write_log!(format!("-> Rendering ctor: failed wrapper: {:?}", err));
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
write_log("-> Rendering ctor: wrapped images");
|
write_log!("-> Rendering ctor: wrapped images");
|
||||||
|
|
||||||
let render_target = RenderTarget::builder()
|
let render_target = RenderTarget::builder()
|
||||||
.add_sub_pass(
|
.add_sub_pass(
|
||||||
|
@ -85,9 +85,9 @@ impl Rendering {
|
||||||
)
|
)
|
||||||
.build(&device)?;
|
.build(&device)?;
|
||||||
|
|
||||||
write_log("-> Rendering ctor: created render_target");
|
write_log!("-> Rendering ctor: created render_target");
|
||||||
|
|
||||||
write_log(format!(
|
write_log!(format!(
|
||||||
"-> Rendering swapchain extents ({}, {})",
|
"-> Rendering swapchain extents ({}, {})",
|
||||||
swapchain.width(),
|
swapchain.width(),
|
||||||
swapchain.height(),
|
swapchain.height(),
|
||||||
|
@ -149,7 +149,7 @@ impl Rendering {
|
||||||
recorder.set_scissor(&scissor);
|
recorder.set_scissor(&scissor);
|
||||||
recorder.set_viewport(&viewport);
|
recorder.set_viewport(&viewport);
|
||||||
|
|
||||||
write_log(format!("-> Rendering {} objects", objects.len()));
|
write_log!(format!("-> Rendering {} objects", objects.len()));
|
||||||
|
|
||||||
for object in objects {
|
for object in objects {
|
||||||
let buffer = object.buffer();
|
let buffer = object.buffer();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cgmath::vec2;
|
use cgmath::{ortho, vec2, vec3, InnerSpace, Matrix4, Vector2, Vector3, VectorSpace};
|
||||||
use rfactor_sm_reader::*;
|
use rfactor_sm_reader::*;
|
||||||
use vulkan_rs::prelude::*;
|
use vulkan_rs::prelude::*;
|
||||||
|
|
||||||
|
@ -7,64 +7,214 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use super::rendering::PositionOnlyVertex;
|
use super::rendering::PositionOnlyVertex;
|
||||||
|
|
||||||
|
fn convert_vec(v: rF2Vec3) -> Vector3<f32> {
|
||||||
|
vec3(v.x as f32, v.y as f32, v.z as f32)
|
||||||
|
}
|
||||||
|
|
||||||
pub trait RenderObject {
|
pub trait RenderObject {
|
||||||
fn descriptor(&self) -> &Arc<DescriptorSet>;
|
fn descriptor(&self) -> &Arc<DescriptorSet>;
|
||||||
fn buffer(&self) -> &Arc<Buffer<PositionOnlyVertex>>;
|
fn buffer(&self) -> &Arc<Buffer<PositionOnlyVertex>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DataConfig {
|
||||||
|
pub radar_scale: f32,
|
||||||
|
pub radar_car_distance: f32,
|
||||||
|
pub safe_color: Vector3<f32>,
|
||||||
|
pub danger_color: Vector3<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct RFactorData {
|
pub struct RFactorData {
|
||||||
|
// config
|
||||||
|
config: DataConfig,
|
||||||
|
|
||||||
// rf2 memory mapped data
|
// rf2 memory mapped data
|
||||||
// telemetry_reader: TelemetryReader,
|
telemetry_reader: TelemetryReader,
|
||||||
// scoring_reader: ScoringReader,
|
scoring_reader: ScoringReader,
|
||||||
|
|
||||||
// radar objects
|
// radar objects
|
||||||
background: RadarObject,
|
background: RadarObject,
|
||||||
player_car: RadarObject,
|
player_car: RadarObject,
|
||||||
cars: Vec<RadarObject>,
|
cars: Vec<RadarObject>,
|
||||||
|
|
||||||
|
// game info
|
||||||
|
player_id: Option<i32>,
|
||||||
|
|
||||||
|
// math objects
|
||||||
|
radar_center: Vector2<f32>,
|
||||||
|
ortho: Matrix4<f32>,
|
||||||
|
window_width: u32,
|
||||||
|
window_height: u32,
|
||||||
|
car_width: f32,
|
||||||
|
car_height: f32,
|
||||||
|
|
||||||
|
device: Arc<Device>,
|
||||||
|
descriptor_layout: Arc<DescriptorSetLayout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RFactorData {
|
impl RFactorData {
|
||||||
pub fn new(device: Arc<Device>, descriptor_layout: &Arc<DescriptorSetLayout>) -> Result<Self> {
|
pub fn new(
|
||||||
let radar_extent = 0.2;
|
config: DataConfig,
|
||||||
let car_height = 0.05;
|
device: Arc<Device>,
|
||||||
let car_width = 0.025;
|
descriptor_layout: &Arc<DescriptorSetLayout>,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let radar_extent = width as f32 * 0.075 * config.radar_scale;
|
||||||
|
let car_height = radar_extent * 0.2;
|
||||||
|
let car_width = car_height * 0.5;
|
||||||
|
let radar_center = vec2(
|
||||||
|
width as f32 / 2.0,
|
||||||
|
height as f32 / 2.0 + height as f32 * 0.25,
|
||||||
|
);
|
||||||
|
|
||||||
|
let ortho = ortho(0.0, width as f32, 0.0, height as f32, -1.0, 1.0);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
// telemetry_reader: TelemetryReader::new()?,
|
config,
|
||||||
// scoring_reader: ScoringReader::new()?,
|
|
||||||
|
telemetry_reader: TelemetryReader::new()?,
|
||||||
|
scoring_reader: ScoringReader::new()?,
|
||||||
|
|
||||||
background: RadarObject::new(
|
background: RadarObject::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
descriptor_layout,
|
descriptor_layout,
|
||||||
PositionOnlyVertex::from_2d_corners([
|
PositionOnlyVertex::from_2d_corners(
|
||||||
vec2(-radar_extent, -radar_extent),
|
ortho,
|
||||||
vec2(-radar_extent, radar_extent),
|
[
|
||||||
vec2(radar_extent, radar_extent),
|
vec2(radar_center.x - radar_extent, radar_center.y - radar_extent),
|
||||||
vec2(radar_extent, -radar_extent),
|
vec2(radar_center.x - radar_extent, radar_center.y + radar_extent),
|
||||||
]),
|
vec2(radar_center.x + radar_extent, radar_center.y + radar_extent),
|
||||||
|
vec2(radar_center.x + radar_extent, radar_center.y - radar_extent),
|
||||||
|
],
|
||||||
|
),
|
||||||
[0.5, 0.5, 0.5, 0.5],
|
[0.5, 0.5, 0.5, 0.5],
|
||||||
)?,
|
)?,
|
||||||
player_car: RadarObject::new(
|
player_car: RadarObject::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
descriptor_layout,
|
descriptor_layout,
|
||||||
PositionOnlyVertex::from_2d_corners([
|
PositionOnlyVertex::from_2d_corners(
|
||||||
vec2(-car_width, -car_height),
|
ortho,
|
||||||
vec2(-car_width, car_height),
|
[
|
||||||
vec2(car_width, car_height),
|
vec2(radar_center.x - car_width, radar_center.y - car_height),
|
||||||
vec2(car_width, -car_height),
|
vec2(radar_center.x - car_width, radar_center.y + car_height),
|
||||||
]),
|
vec2(radar_center.x + car_width, radar_center.y + car_height),
|
||||||
|
vec2(radar_center.x + car_width, radar_center.y - car_height),
|
||||||
|
],
|
||||||
|
),
|
||||||
[0.9, 0.9, 0.0, 0.9],
|
[0.9, 0.9, 0.0, 0.9],
|
||||||
)?,
|
)?,
|
||||||
cars: Vec::new(),
|
cars: Vec::new(),
|
||||||
|
|
||||||
|
player_id: None,
|
||||||
|
|
||||||
|
radar_center,
|
||||||
|
ortho,
|
||||||
|
window_width: width,
|
||||||
|
window_height: height,
|
||||||
|
car_width,
|
||||||
|
car_height,
|
||||||
|
|
||||||
|
device,
|
||||||
|
descriptor_layout: descriptor_layout.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_car_object(&self, offset: Vector2<f32>, color: [f32; 4]) -> Result<RadarObject> {
|
||||||
|
RadarObject::new(
|
||||||
|
self.device.clone(),
|
||||||
|
&self.descriptor_layout,
|
||||||
|
PositionOnlyVertex::from_2d_corners(
|
||||||
|
self.ortho,
|
||||||
|
[
|
||||||
|
vec2(
|
||||||
|
self.radar_center.x - self.car_width + offset.x,
|
||||||
|
self.radar_center.y - self.car_height + offset.y,
|
||||||
|
),
|
||||||
|
vec2(
|
||||||
|
self.radar_center.x - self.car_width + offset.x,
|
||||||
|
self.radar_center.y + self.car_height + offset.y,
|
||||||
|
),
|
||||||
|
vec2(
|
||||||
|
self.radar_center.x + self.car_width + offset.x,
|
||||||
|
self.radar_center.y + self.car_height + offset.y,
|
||||||
|
),
|
||||||
|
vec2(
|
||||||
|
self.radar_center.x + self.car_width + offset.x,
|
||||||
|
self.radar_center.y - self.car_height + offset.y,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
color,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) -> Result<()> {
|
pub fn update(&mut self) -> Result<()> {
|
||||||
|
// get scoring info
|
||||||
|
let (scoring_info, vehicle_scorings) = self.scoring_reader.vehicle_scoring();
|
||||||
|
|
||||||
|
// check for player id
|
||||||
|
if scoring_info.mNumVehicles == 0 {
|
||||||
|
self.player_id = None;
|
||||||
|
} else if self.player_id.is_none() {
|
||||||
|
for vehicle_scoring in vehicle_scorings.iter() {
|
||||||
|
if vehicle_scoring.mIsPlayer != 0 {
|
||||||
|
self.player_id = Some(vehicle_scoring.mID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if player id is set (a map is loaded), check telemetry data
|
||||||
|
if let Some(player_id) = &self.player_id {
|
||||||
|
let telemetries = self.telemetry_reader.query_telemetry();
|
||||||
|
|
||||||
|
let mut player_position = CarPosition::default();
|
||||||
|
let mut other_positions = Vec::new();
|
||||||
|
|
||||||
|
for telemetry in telemetries {
|
||||||
|
if telemetry.id == *player_id {
|
||||||
|
player_position.position = convert_vec(telemetry.position);
|
||||||
|
player_position.local_rotation = convert_vec(telemetry.local_rotation);
|
||||||
|
} else {
|
||||||
|
other_positions.push(CarPosition {
|
||||||
|
position: convert_vec(telemetry.position),
|
||||||
|
local_rotation: convert_vec(telemetry.local_rotation),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update radar objects
|
||||||
|
|
||||||
|
// naive way: clear cars and create them new if near enough
|
||||||
|
self.cars.clear();
|
||||||
|
|
||||||
|
for other_position in other_positions {
|
||||||
|
let diff = player_position.position - other_position.position;
|
||||||
|
let distance = diff.magnitude();
|
||||||
|
|
||||||
|
// check if car is close enough the players car
|
||||||
|
if distance < self.config.radar_car_distance {
|
||||||
|
let offset = diff.truncate();
|
||||||
|
let color = self.config.danger_color.lerp(
|
||||||
|
self.config.safe_color,
|
||||||
|
distance / self.config.radar_car_distance,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.cars
|
||||||
|
.push(self.create_car_object(offset, [color.x, color.y, color.z, 0.9])?);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn objects(&self) -> Vec<&dyn RenderObject> {
|
pub fn objects(&self) -> Vec<&dyn RenderObject> {
|
||||||
let mut objects: Vec<&dyn RenderObject> = Vec::new();
|
let mut objects: Vec<&dyn RenderObject> = Vec::new();
|
||||||
|
|
||||||
|
// only draw radar when player is loaded into a map
|
||||||
|
if let Some(player_id) = &self.player_id {
|
||||||
|
// only draw radar when any car is near enough
|
||||||
|
if !self.cars.is_empty() {
|
||||||
objects.push(&self.background);
|
objects.push(&self.background);
|
||||||
|
|
||||||
for other_player_cars in &self.cars {
|
for other_player_cars in &self.cars {
|
||||||
|
@ -72,6 +222,8 @@ impl RFactorData {
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.push(&self.player_car);
|
objects.push(&self.player_car);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
objects
|
objects
|
||||||
}
|
}
|
||||||
|
@ -134,3 +286,17 @@ impl RenderObject for RadarObject {
|
||||||
&self.position_buffer
|
&self.position_buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CarPosition {
|
||||||
|
pub position: Vector3<f32>,
|
||||||
|
pub local_rotation: Vector3<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CarPosition {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
position: vec3(0.0, 0.0, 0.0),
|
||||||
|
local_rotation: vec3(0.0, 0.0, 0.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue