Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions graf3d/eve7/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ ROOT_STANDARD_LIBRARY_PACKAGE(ROOTEve
ROOT/REveUtil.hxx
ROOT/REveVector.hxx
ROOT/REveViewer.hxx
ROOT/REveCamera.hxx
ROOT/REveViewContext.hxx
ROOT/REveVSD.hxx
ROOT/REveVSDStructs.hxx
Expand Down Expand Up @@ -126,6 +127,7 @@ ROOT_STANDARD_LIBRARY_PACKAGE(ROOTEve
src/REveUtil.cxx
src/REveVector.cxx
src/REveViewer.cxx
src/REveCamera.cxx
src/REveVSD.cxx
src/REveVSDStructs.cxx
DEPENDENCIES
Expand Down
4 changes: 4 additions & 0 deletions graf3d/eve7/inc/LinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,8 @@
// Tables
#pragma link C++ class ROOT::Experimental::REveTableViewInfo;

// Camera
#pragma link C++ class ROOT::Experimental::REveCamera+;
#pragma link C++ enum ROOT::Experimental::REveCamera::ECameraType;

#endif
91 changes: 91 additions & 0 deletions graf3d/eve7/inc/ROOT/REveCamera.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// @(#)root/eve7:$Id$
// Authors: Yuxiao Wang, 2025

/*************************************************************************
* Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/

#ifndef ROOT7_REveCamera
#define ROOT7_REveCamera

#include <ROOT/REveElement.hxx>
#include <ROOT/REveVector.hxx>
#include <ROOT/REveTrans.hxx>

#include <string>

namespace ROOT {
namespace Experimental {

class REveCamera : public REveElement
{
public:
enum ECameraType {
// Perspective
kCameraPerspXOZ, // XOZ floor
kCameraPerspYOZ, // YOZ floor
kCameraPerspXOY, // XOY floor
// Orthographic
kCameraOrthoXOY, // Looking down Z axis, X horz, Y vert
kCameraOrthoXOZ, // Looking along Y axis, X horz, Z vert
kCameraOrthoZOY, // Looking along X axis, Z horz, Y vert
kCameraOrthoZOX, // Looking along Y axis, Z horz, X vert
// Orthographic negative
kCameraOrthoXnOY, // Looking along Z axis, -X horz, Y vert
kCameraOrthoXnOZ, // Looking down Y axis, -X horz, Z vert
kCameraOrthoZnOY, // Looking down X axis, -Z horz, Y vert
kCameraOrthoZnOX // Looking down Y axis, -Z horz, X vert
};

private:
ECameraType fType;
std::string fName;

// Camera transformation matrices
REveTrans fCamBase; // Base camera matrix (main positioning)
REveTrans fCamTrans;

// Original direction vectors (for Setup)
Copy link
Owner

@alja alja Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented lines with V1, V2.
The camBase matrix is holding this info.

Lines 65-69 can also be removed.

// REveVector fV1; // Camera direction vector
// REveVector fV2; // Camera up vector

public:
REveCamera();
REveCamera(const std::string &name);
virtual ~REveCamera() {}

void Setup(ECameraType type, const std::string &name, const REveVector &v1, const REveVector &v2);

ECameraType GetType() const { return fType; }
const std::string &GetCameraName() const { return fName; }
// const REveVector &GetDir() const { return fV1; }
// const REveVector &GetUp() const { return fV2; }

// void SetDir(const REveVector &v) { fV1 = v; StampObjProps(); }
// void SetUp(const REveVector &v) { fV2 = v; StampObjProps(); }

// Camera matrix accessors
REveTrans &RefCamBase() { return fCamBase; }
const REveTrans &GetCamBase() const { return fCamBase; }

REveTrans &RefCamTrans() { return fCamTrans; }
const REveTrans &GetCamTrans() const { return fCamTrans; }

void SetCamBase(const REveTrans &base) { fCamBase = base; StampObjProps(); }

// receive mtx from client
void SetCamBaseMtx(const std::vector<Double_t> &arr);

void BuildRenderData() override{};

Int_t WriteCoreJson(nlohmann::json &j, Int_t rnr_offset) override;
};

} // namespace Experimental
} // namespace ROOT

#endif
4 changes: 3 additions & 1 deletion graf3d/eve7/inc/ROOT/REveManager.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <ROOT/REveElement.hxx>
#include <ROOT/REveSystem.hxx>
#include <ROOT/RLogger.hxx>

#include <ROOT/REveCamera.hxx>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better practice is to include the REveCamera.hxx header in REveManager.cxx.

#include <ROOT/RWebDisplayArgs.hxx>

#include "TSysEvtHandler.h"
Expand Down Expand Up @@ -127,6 +127,7 @@ protected:

REveViewerList *fViewers{nullptr};
REveSceneList *fScenes{nullptr};
REveElement *fCameras{nullptr}; // yuxiao
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fCamera declaration does not need a comment.


REveScene *fGlobalScene{nullptr};
REveScene *fEventScene{nullptr};
Expand Down Expand Up @@ -182,6 +183,7 @@ public:

REveSceneList *GetScenes() const { return fScenes; }
REveViewerList *GetViewers() const { return fViewers; }
REveElement *GetCameras() const { return fCameras; } //yuxiao

REveScene *GetGlobalScene() const { return fGlobalScene; }
REveScene *GetEventScene() const { return fEventScene; }
Expand Down
30 changes: 8 additions & 22 deletions graf3d/eve7/inc/ROOT/REveViewer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace ROOT {
namespace Experimental {

class REveScene;
class REveCamera; // yuxiao

////////////////////////////////////////////////////////////////////////////////
/// REveViewer
Expand Down Expand Up @@ -51,30 +52,13 @@ public:
kAxesEdge
};

// For the moment REveCamera is internal class
class REveCamera
{
ECameraType fType;
std::string fName;
REveVector fV2;
REveVector fV1;

public:
REveCamera() { Setup(kCameraPerspXOZ, "PerspXOZ", REveVector(-1.0, 0.0, 0.0), REveVector(0.0, 1.0, 0.0));}
~REveCamera() {}

void Setup(ECameraType type, const std::string& name, REveVector v1, REveVector v2);

ECameraType GetType() const { return fType; }

int WriteCoreJson(nlohmann::json &j, Int_t /*rnr_offset*/);
};

private:
REveViewer(const REveViewer&) = delete;
REveViewer& operator=(const REveViewer&) = delete;

REveCamera fCamera;
REveCamera* fCamera{0};
ElementId_t fCameraId{0}; // Reference to standalone REveCamera element. yuxiao

EAxesType fAxesType{kAxesNone};
bool fBlackBackground{false};

Expand All @@ -90,8 +74,10 @@ public:
virtual void AddScene(REveScene* scene);
// XXX Missing RemoveScene() ????

void SetCameraType(ECameraType t);
ECameraType GetCameraType() const { return fCamera.GetType(); }
// void SetCameraType(ECameraType t);
// ECameraType GetCameraType() const { return fCamera->GetType(); }
void SetCamera(::ROOT::Experimental::REveCamera *cam);
ElementId_t GetCameraId() const { return fCameraId; } // yuxiao
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps GetCameraId() can be replaced with:
REveCamera* GetCamera() {return fCamera; }

Just for the Get/Set symetry.

ElementId_t fCameraId member is not needed. One can get the if with fCamera->GetElementId()


void SetAxesType(int);
void SetBlackBackground(bool);
Expand Down
114 changes: 114 additions & 0 deletions graf3d/eve7/src/REveCamera.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// @(#)root/eve7:$Id$
// Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007, 2018

/*************************************************************************
* Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/

#include <ROOT/REveCamera.hxx>
#include <ROOT/REveManager.hxx>

#include <nlohmann/json.hpp>

using namespace ROOT::Experimental;

////////////////////////////////////////////////////////////////////////////////
/// Default constructor

REveCamera::REveCamera() : REveElement("REveCamera")
{
Setup(kCameraPerspXOZ, "PerspXOZ", REveVector(-1.0, 0.0, 0.0), REveVector(0.0, 1.0, 0.0));
fCamBase.UnitTrans();
fCamTrans.UnitTrans();
}

////////////////////////////////////////////////////////////////////////////////
/// Constructor with name

REveCamera::REveCamera(const std::string &name) : REveElement(name)
{
Setup(kCameraPerspXOZ, name, REveVector(-1.0, 0.0, 0.0), REveVector(0.0, 1.0, 0.0));
fCamBase.UnitTrans();
fCamTrans.UnitTrans();
}

////////////////////////////////////////////////////////////////////////////////
/// Setup camera with type, name, direction and up vectors

void REveCamera::Setup(ECameraType type, const std::string &name, const REveVector &v1, const REveVector &v2)
{
fType = type;
fName = name;
// fV1 = v1;
// fV2 = v2;

// Set up base camera matrix from direction and up vectors
fCamBase.UnitTrans();
fCamTrans.UnitTrans();

// Create a coordinate system from v1 (direction) and v2 (up)
REveVector dir = v1;
dir.Normalize();

REveVector up = v2;
up.Normalize();

// Right vector = dir × up
REveVector right;
right.fX = dir.fY * up.fZ - dir.fZ * up.fY;
right.fY = dir.fZ * up.fX - dir.fX * up.fZ;
right.fZ = dir.fX * up.fY - dir.fY * up.fX;
right.Normalize();

// Recalculate up = right × dir for orthogonality
REveVector newUp;
newUp.fX = right.fY * dir.fZ - right.fZ * dir.fY;
newUp.fY = right.fZ * dir.fX - right.fX * dir.fZ;
newUp.fZ = right.fX * dir.fY - right.fY * dir.fX;

// Set rotation part of matrix (as row vectors)
Double_t *M = fCamBase.Array();
M[0] = right.fX; M[4] = right.fY; M[8] = right.fZ;
M[1] = newUp.fX; M[5] = newUp.fY; M[9] = newUp.fZ;
M[2] = dir.fX; M[6] = dir.fY; M[10] = dir.fZ;

StampObjProps();
}

////////////////////////////////////////////////////////////////////////////////
/// Set camera base matrix from array (called from client via MIR)

void REveCamera::SetCamBaseMtx(const std::vector<Double_t> &arr)
{
if (arr.size() == 16) {
fCamBase.SetFromArray(arr.data());
StampObjProps();
}
}

////////////////////////////////////////////////////////////////////////////////
/// Write core JSON for camera

Int_t REveCamera::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
{
Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);

j["fType"] = fType;
j["fName"] = fName;
// j["fV1"] = {fV1.fX, fV1.fY, fV1.fZ};
// j["fV2"] = {fV2.fX, fV2.fY, fV2.fZ};

// Stream both matrices
// Client will read these as fMatrix arrays (16 elements each)
const Double_t *camBaseArr = fCamBase.Array();
j["camBase"] = std::vector<Double_t>(camBaseArr, camBaseArr + 16);

const Double_t *camTransArr = fCamTrans.Array();
j["camTrans"] = std::vector<Double_t>(camTransArr, camTransArr + 16);

return ret;
}
56 changes: 55 additions & 1 deletion graf3d/eve7/src/REveManager.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <ROOT/REveManager.hxx>

#include <ROOT/REveCamera.hxx>
#include <ROOT/REveUtil.hxx>
#include <ROOT/REveSelection.hxx>
#include <ROOT/REveViewer.hxx>
Expand Down Expand Up @@ -139,9 +140,62 @@ REveManager::REveManager()
fWorld->AddElement(fViewers);

fScenes = new REveSceneList("Scenes");
fScenes->IncDenyDestroy();
fScenes->IncDenyDestroy();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restore align.

fWorld->AddElement(fScenes);

// --------------------------------
// Create camera list
// --------------------------------
fCameras = new REveElement("Cameras", "Camera list");
fCameras->IncDenyDestroy();
fWorld->AddElement(fCameras);

// Create predefined cameras with their view vectors, yuxiao
struct CameraDef {
REveCamera::ECameraType type;
const char* name;
REveVector v1;
REveVector v2;
};

CameraDef predefinedCameras[] = {
// Perspective cameras
{REveCamera::kCameraPerspXOZ, "PerspXOZ",
REveVector(-1.0, 0.0, 0.0), REveVector(0.0, 1.0, 0.0)},
{REveCamera::kCameraPerspYOZ, "PerspYOZ",
REveVector(0.0, -1.0, 0.0), REveVector(1.0, 0.0, 0.0)},
{REveCamera::kCameraPerspXOY, "PerspXOY",
REveVector(-1.0, 0.0, 0.0), REveVector(0.0, 0.0, 1.0)},

// Orthographic cameras
{REveCamera::kCameraOrthoXOY, "OrthoXOY",
REveVector(0.0, 0.0, 1.0), REveVector(0.0, 1.0, 0.0)},
{REveCamera::kCameraOrthoXOZ, "OrthoXOZ",
REveVector(0.0, -1.0, 0.0), REveVector(0.0, 0.0, 1.0)},
{REveCamera::kCameraOrthoZOY, "OrthoZOY",
REveVector(-1.0, 0.0, 0.0), REveVector(0.0, 1.0, 0.0)},
{REveCamera::kCameraOrthoZOX, "OrthoZOX",
REveVector(0.0, -1.0, 0.0), REveVector(1.0, 0.0, 0.0)},

// Orthographic negative cameras
{REveCamera::kCameraOrthoXnOY, "OrthoXnOY",
REveVector(0.0, 0.0, -1.0), REveVector(0.0, 1.0, 0.0)},
{REveCamera::kCameraOrthoXnOZ, "OrthoXnOZ",
REveVector(0.0, 1.0, 0.0), REveVector(0.0, 0.0, 1.0)},
{REveCamera::kCameraOrthoZnOY, "OrthoZnOY",
REveVector(1.0, 0.0, 0.0), REveVector(0.0, 1.0, 0.0)},
{REveCamera::kCameraOrthoZnOX, "OrthoZnOX",
REveVector(0.0, 1.0, 0.0), REveVector(1.0, 0.0, 0.0)}
};

// Create and add all predefined cameras
for (const auto &camDef : predefinedCameras) {
auto cam = new REveCamera(camDef.name);
cam->Setup(camDef.type, camDef.name, camDef.v1, camDef.v2);
fCameras->AddElement(cam);
std::cout << "camera ID: " << cam->GetElementId() << std::endl;
}

fGlobalScene = new REveScene("Geometry scene");
fGlobalScene->IncDenyDestroy();
fScenes->AddElement(fGlobalScene);
Expand Down
Loading