Skip to content

Commit

Permalink
🚚 Added videocamera role MIRROR_NOFLIP (2)
Browse files Browse the repository at this point in the history
Same as `MIRROR` (1), but without flipping the texture horizontally (expects texcoords to be already flipped in the mesh)

Additional Codechanges:
* 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.
* The rigdef (truck) parser now uses the enum instead of numeric constant. This simplifies the spawner as it just copies the value.
  • Loading branch information
ohlidalp committed Mar 9, 2025
1 parent 3816c27 commit 734b321
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 58 deletions.
15 changes: 15 additions & 0 deletions source/main/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
// ------------------------------------------------------------------------------------------------
Expand Down
12 changes: 6 additions & 6 deletions source/main/gfx/GfxActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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();
Expand Down
16 changes: 3 additions & 13 deletions source/main/gfx/GfxData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
30 changes: 15 additions & 15 deletions source/main/physics/ActorSpawner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -7004,7 +7001,11 @@ void ActorSpawner::CreateVideoCamera(RigDef::VideoCamera* def)
vcam.vcam_pos_offset = def->offset;

//rotate camera picture 180 degrees, skip for mirrors
float rotation_z = (def->camera_role != 1) ? def->rotation.z + 180 : def->rotation.z;
float rotation_z = def->rotation.z + 180;
if (def->camera_role == VCAM_ROLE_MIRROR || def->camera_role == VCAM_ROLE_MIRROR_NOFLIP)
{
rotation_z += 180.0f;
}
vcam.vcam_rotation
= Ogre::Quaternion(Ogre::Degree(rotation_z), Ogre::Vector3::UNIT_Z)
* Ogre::Quaternion(Ogre::Degree(def->rotation.y), Ogre::Vector3::UNIT_Y)
Expand All @@ -7024,11 +7025,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())
Expand Down Expand Up @@ -7075,7 +7075,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);
}

Expand Down Expand Up @@ -7123,11 +7123,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:
Expand Down
12 changes: 0 additions & 12 deletions source/main/resources/rig_def_fileformat/RigDef_File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
20 changes: 9 additions & 11 deletions source/main/resources/rig_def_fileformat/RigDef_File.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
18 changes: 17 additions & 1 deletion source/main/resources/rig_def_fileformat/RigDef_Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions source/main/resources/rig_def_fileformat/RigDef_Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 734b321

Please sign in to comment.