From 6bb82d82ead2df522e85cf65a2273ed7e717b10a Mon Sep 17 00:00:00 2001 From: ohlidalp Date: Fri, 7 Mar 2025 23:21:06 +0100 Subject: [PATCH] :truck: Added videocamera role `MIRROR_NOFLIP` (2) Same as `MIRROR` (1), but without flipping the texture horizontally (expects texcoords to be already flipped in the mesh) To make naming consistent, enum VideoCamType was renamed to VideoCamRole and moved to Application.h so that both RigDef fileformat and GfxActor can easily #include it. --- source/main/Application.h | 15 ++++++++++++ source/main/gfx/GfxActor.cpp | 12 +++++----- source/main/gfx/GfxData.h | 16 +++---------- source/main/physics/ActorSpawner.cpp | 24 ++++++++----------- .../rig_def_fileformat/RigDef_File.cpp | 12 ---------- .../rig_def_fileformat/RigDef_File.h | 20 +++++++--------- .../rig_def_fileformat/RigDef_Parser.cpp | 18 +++++++++++++- .../rig_def_fileformat/RigDef_Parser.h | 1 + 8 files changed, 61 insertions(+), 57 deletions(-) diff --git a/source/main/Application.h b/source/main/Application.h index f3170ee8d2..eaa52b0480 100644 --- a/source/main/Application.h +++ b/source/main/Application.h @@ -370,6 +370,21 @@ enum class TObjSpecialObject }; const char* TObjSpecialObjectToString(TObjSpecialObject val); +enum VideoCamRole +{ + // DO NOT CHANGE NUMBERS, they match 'videocamera/camera_role' parameter in the .truck file + + VCAM_ROLE_VIDEOCAM = -1, + VCAM_ROLE_TRACKING_VIDEOCAM = 0, + VCAM_ROLE_MIRROR = 1, //!< Flips the video output and when not in driver cam, acts like a natural mirror, not a screen. + VCAM_ROLE_MIRROR_NOFLIP = 2, //!< Same as VCAM_ROLE_MIRROR, but without flipping the texture horizontally (expects texcoords to be already flipped in the mesh) + + // Internal types + VCAM_ROLE_MIRROR_PROP_LEFT = -1001, //!< The classic 'special prop/rear view mirror' + VCAM_ROLE_MIRROR_PROP_RIGHT = -1002, //!< The classic 'special prop/rear view mirror' + VCAM_ROLE_INVALID = -9999, +}; + // ------------------------------------------------------------------------------------------------ // Global variables // ------------------------------------------------------------------------------------------------ diff --git a/source/main/gfx/GfxActor.cpp b/source/main/gfx/GfxActor.cpp index a7294cedeb..5929097d50 100644 --- a/source/main/gfx/GfxActor.cpp +++ b/source/main/gfx/GfxActor.cpp @@ -483,13 +483,13 @@ void RoR::GfxActor::UpdateVideoCameras(float dt) } #endif // USE_CAELUM - if ((vidcam.vcam_type == VCTYPE_MIRROR_PROP_LEFT) - || (vidcam.vcam_type == VCTYPE_MIRROR_PROP_RIGHT)) + if ((vidcam.vcam_role == VCAM_ROLE_MIRROR_PROP_LEFT) + || (vidcam.vcam_role == VCAM_ROLE_MIRROR_PROP_RIGHT)) { // Mirror prop - special processing. float mirror_angle = 0.f; Ogre::Vector3 offset(Ogre::Vector3::ZERO); - if (vidcam.vcam_type == VCTYPE_MIRROR_PROP_LEFT) + if (vidcam.vcam_role == VCAM_ROLE_MIRROR_PROP_LEFT) { mirror_angle = m_actor->ar_left_mirror_angle; offset = Ogre::Vector3(0.07f, -0.22f, 0); @@ -545,14 +545,14 @@ void RoR::GfxActor::UpdateVideoCameras(float dt) frustumUP.normalise(); vidcam.vcam_ogre_camera->setFixedYawAxis(true, frustumUP); - if (vidcam.vcam_type == VCTYPE_MIRROR) + if (vidcam.vcam_role == VCAM_ROLE_MIRROR) { //rotate the normal of the mirror by user rotation setting so it reflects correct normal = vidcam.vcam_rotation * normal; // merge camera direction and reflect it on our plane vidcam.vcam_ogre_camera->setDirection((pos - App::GetCameraManager()->GetCameraNode()->getPosition()).reflect(normal)); } - else if (vidcam.vcam_type == VCTYPE_VIDEOCAM) + else if (vidcam.vcam_role == VCAM_ROLE_VIDEOCAM) { // rotate the camera according to the nodes orientation and user rotation Ogre::Vector3 refx = abs_pos_z - abs_pos_center; @@ -562,7 +562,7 @@ void RoR::GfxActor::UpdateVideoCameras(float dt) Ogre::Quaternion rot = Ogre::Quaternion(-refx, -refy, -normal); vidcam.vcam_ogre_camera->setOrientation(rot * vidcam.vcam_rotation); // rotate the camera orientation towards the calculated cam direction plus user rotation } - else if (vidcam.vcam_type == VCTYPE_TRACKING_VIDEOCAM) + else if (vidcam.vcam_role == VCAM_ROLE_TRACKING_VIDEOCAM) { normal = m_simbuf.simbuf_nodes[vidcam.vcam_node_lookat].AbsPosition - pos; normal.normalise(); diff --git a/source/main/gfx/GfxData.h b/source/main/gfx/GfxData.h index ce779ef613..cca501fe72 100644 --- a/source/main/gfx/GfxData.h +++ b/source/main/gfx/GfxData.h @@ -216,26 +216,16 @@ struct Prop } }; -enum VideoCamType -{ - VCTYPE_INVALID, - VCTYPE_VIDEOCAM, - VCTYPE_TRACKING_VIDEOCAM, - VCTYPE_MIRROR, - VCTYPE_MIRROR_PROP_LEFT, //!< The classic 'special prop/rear view mirror' - VCTYPE_MIRROR_PROP_RIGHT, //!< The classic 'special prop/rear view mirror' -}; - /// An Ogre::Camera mounted on the actor and rendering into /// either in-scene texture or external window. struct VideoCamera { - VideoCamType vcam_type = VCTYPE_INVALID; + VideoCamRole vcam_role = VCAM_ROLE_INVALID; NodeNum_t vcam_node_center = NODENUM_INVALID; NodeNum_t vcam_node_dir_y = NODENUM_INVALID; NodeNum_t vcam_node_dir_z = NODENUM_INVALID; NodeNum_t vcam_node_alt_pos = NODENUM_INVALID; - NodeNum_t vcam_node_lookat = NODENUM_INVALID; //!< Only for VCTYPE_TRACK_CAM + NodeNum_t vcam_node_lookat = NODENUM_INVALID; //!< Only for VCAM_ROLE_TRACK_CAM Ogre::Quaternion vcam_rotation; Ogre::Vector3 vcam_pos_offset = Ogre::Vector3::ZERO; Ogre::MaterialPtr vcam_material; @@ -245,7 +235,7 @@ struct VideoCamera Ogre::TexturePtr vcam_render_tex; Ogre::SceneNode* vcam_debug_node = nullptr; Ogre::RenderWindow* vcam_render_window = nullptr; - Ogre::SceneNode* vcam_prop_scenenode = nullptr; //!< Only for VCTYPE_MIRROR_PROP_* + Ogre::SceneNode* vcam_prop_scenenode = nullptr; //!< Only for VCAM_ROLE_MIRROR_PROP_* }; /// Gfx attributes/state of a softbody node diff --git a/source/main/physics/ActorSpawner.cpp b/source/main/physics/ActorSpawner.cpp index 3281e76fd2..b2c46e2368 100644 --- a/source/main/physics/ActorSpawner.cpp +++ b/source/main/physics/ActorSpawner.cpp @@ -6981,20 +6981,17 @@ void ActorSpawner::CreateVideoCamera(RigDef::VideoCamera* def) { RoR::VideoCamera vcam; - vcam.vcam_material = this->FindOrCreateCustomizedMaterial(def->material_name, m_custom_resource_group); - if (vcam.vcam_material.isNull()) + vcam.vcam_role = def->camera_role; + if (vcam.vcam_role == VCAM_ROLE_INVALID) { - this->AddMessage(Message::TYPE_ERROR, "Failed to create VideoCamera with material: " + def->material_name); + this->AddMessage(Message::TYPE_ERROR, "VideoCamera (mat: " + def->material_name + ") has invalid 'role': " + TOSTRING(def->camera_role)); return; } - switch (def->camera_role) + vcam.vcam_material = this->FindOrCreateCustomizedMaterial(def->material_name, m_custom_resource_group); + if (vcam.vcam_material.isNull()) { - case -1: vcam.vcam_type = VCTYPE_VIDEOCAM; break; - case 0: vcam.vcam_type = VCTYPE_TRACKING_VIDEOCAM; break; - case 1: vcam.vcam_type = VCTYPE_MIRROR; break; - default: - this->AddMessage(Message::TYPE_ERROR, "VideoCamera (mat: " + def->material_name + ") has invalid 'role': " + TOSTRING(def->camera_role)); + this->AddMessage(Message::TYPE_ERROR, "Failed to create VideoCamera with material: " + def->material_name); return; } @@ -7024,11 +7021,10 @@ void ActorSpawner::CreateVideoCamera(RigDef::VideoCamera* def) if (def->alt_orientation_node.IsValidAnyState()) { // This is a tracker camera - vcam.vcam_type = VCTYPE_TRACKING_VIDEOCAM; + vcam.vcam_role = VCAM_ROLE_TRACKING_VIDEOCAM; vcam.vcam_node_lookat = this->GetNodeIndexOrThrow(def->alt_orientation_node); } - // TODO: Eliminate gEnv vcam.vcam_ogre_camera = App::GetGfxScene()->GetSceneManager()->createCamera(vcam.vcam_material->getName() + "_camera"); if (!App::gfx_window_videocams->getBool()) @@ -7075,7 +7071,7 @@ void ActorSpawner::CreateVideoCamera(RigDef::VideoCamera* def) vcam.vcam_material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(vcam.vcam_render_tex->getName()); // this is a mirror, flip the image left<>right to have a mirror and not a cameraimage - if (def->camera_role == 1) + if (def->camera_role == VCAM_ROLE_MIRROR) vcam.vcam_material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureUScale(-1); } @@ -7123,11 +7119,11 @@ void ActorSpawner::CreateMirrorPropVideoCam( switch (type) { case CustomMaterial::MirrorPropType::MPROP_LEFT: - vcam.vcam_type = VCTYPE_MIRROR_PROP_LEFT; + vcam.vcam_role = VCAM_ROLE_MIRROR_PROP_LEFT; break; case CustomMaterial::MirrorPropType::MPROP_RIGHT: - vcam.vcam_type = VCTYPE_MIRROR_PROP_RIGHT; + vcam.vcam_role = VCAM_ROLE_MIRROR_PROP_RIGHT; break; default: diff --git a/source/main/resources/rig_def_fileformat/RigDef_File.cpp b/source/main/resources/rig_def_fileformat/RigDef_File.cpp index f96b5a1590..04add1c5e1 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_File.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_File.cpp @@ -151,18 +151,6 @@ TractionControl::TractionControl(): attr_no_toggle(false) {} -VideoCamera::VideoCamera(): - offset(Ogre::Vector3::ZERO), - rotation(Ogre::Vector3::ZERO), - field_of_view(0), - texture_width(0), - texture_height(0), - min_clip_distance(0), - max_clip_distance(0), - camera_role(0), - camera_mode(0) -{} - void Animation::AddMotorSource(unsigned int source, unsigned int motor) { Animation::MotorSource motor_source; diff --git a/source/main/resources/rig_def_fileformat/RigDef_File.h b/source/main/resources/rig_def_fileformat/RigDef_File.h index ebd10e4f1a..c3eb8f9161 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_File.h +++ b/source/main/resources/rig_def_fileformat/RigDef_File.h @@ -1423,22 +1423,20 @@ struct Turboprop2 // Section TURBOPROPS, TURBOPROPS2 struct VideoCamera { - VideoCamera(); - Node::Ref reference_node; Node::Ref left_node; Node::Ref bottom_node; Node::Ref alt_reference_node; Node::Ref alt_orientation_node; - Ogre::Vector3 offset; - Ogre::Vector3 rotation; - float field_of_view; - unsigned int texture_width; - unsigned int texture_height; - float min_clip_distance; - float max_clip_distance; - int camera_role; - int camera_mode; + Ogre::Vector3 offset = Ogre::Vector3::ZERO; + Ogre::Vector3 rotation = Ogre::Vector3::ZERO; + float field_of_view = 0.f; + unsigned int texture_width = 0u; + unsigned int texture_height = 0u; + float min_clip_distance = 0.f; + float max_clip_distance = 0.f; + RoR::VideoCamRole camera_role = RoR::VCAM_ROLE_INVALID; + int camera_mode = 0; Ogre::String material_name; Ogre::String camera_name; }; diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp index c322f56192..7445881b09 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp @@ -1685,7 +1685,7 @@ void Parser::ParseVideoCamera() videocamera.texture_height = this->GetArgInt (13); videocamera.min_clip_distance = this->GetArgFloat (14); videocamera.max_clip_distance = this->GetArgFloat (15); - videocamera.camera_role = this->GetArgInt (16); + videocamera.camera_role = this->GetArgVideoCamRole(16); videocamera.camera_mode = this->GetArgInt (17); videocamera.material_name = this->GetArgStr (18); @@ -3367,6 +3367,22 @@ ManagedMaterialType Parser::GetArgManagedMatType(int index) return ManagedMaterialType::INVALID; } +VideoCamRole Parser::GetArgVideoCamRole(int index) +{ + int role = this->GetArgInt(index); + switch (role) + { + case VCAM_ROLE_VIDEOCAM: return VCAM_ROLE_VIDEOCAM; + case VCAM_ROLE_TRACKING_VIDEOCAM: return VCAM_ROLE_TRACKING_VIDEOCAM; + case VCAM_ROLE_MIRROR: return VCAM_ROLE_MIRROR; + case VCAM_ROLE_MIRROR_NOFLIP: return VCAM_ROLE_MIRROR_NOFLIP; + default: + this->LogMessage(Console::CONSOLE_SYSTEM_WARNING, + fmt::format("Invalid value of 'camera role' ({}), videocamera will not work", role)); + return VCAM_ROLE_INVALID; + } +} + int Parser::TokenizeCurrentLine() { int cur_arg = 0; diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.h b/source/main/resources/rig_def_fileformat/RigDef_Parser.h index 587cc0e9cc..81897749a5 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.h +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.h @@ -230,6 +230,7 @@ class Parser BitMask_t GetArgNodeOptions (int index); EngineType GetArgEngineType (int index); ManagedMaterialType GetArgManagedMatType(int index); + RoR::VideoCamRole GetArgVideoCamRole (int index); float ParseArgFloat (const char* str); int ParseArgInt (const char* str);