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)

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.
  • Loading branch information
ohlidalp committed Mar 7, 2025
1 parent 3816c27 commit 6bb82d8
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 57 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
24 changes: 10 additions & 14 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 Down Expand Up @@ -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())
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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:
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 6bb82d8

Please sign in to comment.