验证部分功能

This commit is contained in:
JackLee 2026-04-17 17:33:15 +08:00
parent 1c7e28fa1c
commit d2e81404bc
7 changed files with 97 additions and 67 deletions

View File

@ -226,22 +226,14 @@ void NativeMgr::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
//移动模式:均为鼠标点按下后记录坐标增量移动
//鼠标按下并且事件为鼠标中键
if(mouseEvent.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_PRESS){
if(NativeMgr::isMouseMiddleBtnPressed){
NativeMgr::isMouseMiddleBtnPressed=false;
return;
}
//记录按下时候的X.Y坐标
//按下鼠标右键记录坐标
if((mouseEvent.button==OH_NATIVEXCOMPONENT_RIGHT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_PRESS)||
(mouseEvent.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_PRESS))
{
NativeMgr::lastMouseX_=mouseEvent.x;
NativeMgr::lastMouseY_=mouseEvent.y;
NativeMgr::isMouseMiddleBtnPressed = true;
//HILOG_WARN(NATIVE_TAG, "AtlastMouseX:%{public}d",NativeMgr::lastMouseX_);
//HILOG_WARN(NATIVE_TAG, "AtlastMouseY:%{public}d",NativeMgr::lastMouseY_);
//HILOG_WARN(NATIVE_TAG, "AtButton:%{public}d",mouseEvent.button);
//HILOG_WARN(NATIVE_TAG, "AtButtonAction:%{public}d",mouseEvent.action);
//HILOG_WARN(NATIVE_TAG, "AtisMouseMiddleBtnPressed:%{public}d",NativeMgr::isMouseMiddleBtnPressed);
}else if(mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE&&NativeMgr::isMouseMiddleBtnPressed){
}
if(mouseEvent.button==OH_NATIVEXCOMPONENT_RIGHT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE){
// 计算鼠标移动距离
float deltaX = curtX - NativeMgr::lastMouseX_;
float deltaY = curtY - NativeMgr::lastMouseY_;
@ -256,13 +248,19 @@ void NativeMgr::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
// 更新最后的位置
//NativeMgr::lastMouseX_ = deltaX;
//NativeMgr::lastMouseY_ = deltaY;
//HILOG_WARN(NATIVE_TAG, "MoveAngleX:%{public}d",angleX);
//HILOG_WARN(NATIVE_TAG, "MoveAngleY:%{public}d",angleY);
//HILOG_WARN(NATIVE_TAG, "MoveButton:%{public}d",mouseEvent.button);
//HILOG_WARN(NATIVE_TAG, "MoveButtonAction:%{public}d",mouseEvent.action);
//HILOG_WARN(NATIVE_TAG, "MoveIsMouseMiddleBtnPressed:%{public}d",NativeMgr::isMouseMiddleBtnPressed);
}else if(mouseEvent.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE){
// 计算鼠标移动距离
float deltaX = curtX - NativeMgr::lastMouseX_;
float deltaY = curtY - NativeMgr::lastMouseY_;
// 将像素移动量映射到旋转角度
// 这里的系数可以根据需要调整灵敏度
float rotationSpeed = 0.001f;
float angleX = deltaX * rotationSpeed;
float angleY = deltaY * rotationSpeed;
// 通知渲染线程执行旋转
// 由于渲染在线程里,需要通过命令队列发送指令
renderThread->setTranslation(angleX, angleY);
}
}
static std::string value2String(napi_env env, napi_value value) {
size_t stringSize = 0;
@ -495,7 +493,8 @@ void NativeMgr::DispatchTouchEvent(OH_NativeXComponent* component, void* window)
if (touchEvent_.type == OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_MOVE) {
float dtx=(NativeMgr::x-touchEvent_.x)*0.1;
float dty=(NativeMgr::y-touchEvent_.y)*0.1;
renderThread->setRotation(dtx, dty);
//renderThread->setRotation(dtx, dty);
renderThread->setTranslation(dtx, dty);
OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent_);
NativeMgr::x=touchEvent_.x;
NativeMgr::y=touchEvent_.y;
@ -508,7 +507,8 @@ void NativeMgr::DispatchTouchEvent(OH_NativeXComponent* component, void* window)
if(touchEvent_.touchPoints[0].isPressed
&&touchEvent_.touchPoints[1].isPressed){
//当双指按下时候,分别记录每个指的坐标
NativeMgr::x=touchEvent_.x;
NativeMgr::y=touchEvent_.y;
//双指移动,计算移动位移量,同时根据移动缩放因子计算视距,从调整相机相对于模型的距离.从而实现双指缩放
}else if(touchEvent_.type==OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_MOVE){

View File

@ -104,8 +104,7 @@ public:
//鼠标位置保存
float lastMouseX_;
float lastMouseY_;
//鼠标按下状态保存
bool isMouseMiddleBtnPressed;
static std::unordered_map<std::string, ArkUI_NodeHandle> nodeHandleMap_;
static std::unordered_map<void *, OH_ArkUI_SurfaceCallback *> callbackMap_;
static ArkUI_AccessibilityProvider *provider_;

View File

@ -134,9 +134,8 @@ bool Render::loadModel(const std::string &filePath) {
}
// setTranslation
void Render::setTranslation(float tx, float ty) {
v3dTri->SetTranslationX(tx);
v3dTri->SetTranslationY(ty);
void Render::SetMoveTo(float tx, float ty) {
v3dCamera->SetMoveTo(tx, ty);
}
void Render::render() {
@ -153,10 +152,12 @@ void Render::resize(int w, int h) {
v3dWin->Resize(w, h);
}
void Render::setRotation(float xAngle, float yAngle) { v3dCamera->SetRotation(xAngle, yAngle); }
void Render::setRotation(float xAngle, float yAngle) {
v3dCamera->SetRotation(xAngle, yAngle);
}
void Render::setZoomLevel(float zoom) {
v3dTri->SetZoomLevel(std::max(0.1f, std::min(zoom, 5.0f))); // 限制缩放范围
void Render::setZoomLevel(float factor) {
v3dTri->SetZoomLevel(std::max(0.1f, std::min(factor, 5.0f))); // 限制缩放范围
}
void Render::setClearColor(float r, float g, float b, float a) { v3dView->SetClearColor(r, g, b, a); }
void Render::resetView() { v3dView->ResetView(); }

View File

@ -39,7 +39,7 @@ public:
void resetView();
void setClearColor(float r, float g, float b, float a);
void setZoomLevel(float zoom);
void setTranslation(float x, float y);
void SetMoveTo(float dx, float dy);
void setCameraRotationMode(bool state);
//视图
void SwitchView(std::string);

View File

@ -124,7 +124,7 @@ void RenderThread::renderLoop() {
render->setRotation(command.param2, command.param3);
break;
case CMD_SET_TRANSLATION:
render->setTranslation(command.param2, command.param3);
render->SetMoveTo(command.param2, command.param3);
break;
case CMD_RESET_VIEW:
render->resetView();
@ -183,11 +183,12 @@ void RenderThread::setRotation(float xAngle, float yAngle) {
void RenderThread::setTranslation(float x, float y) {
std::lock_guard<std::mutex> lock(commandMutex_);
RenderCommand cmd(CMD_SET_TRANSLATION);
cmd.param2 = x;
cmd.param3 = y;
commandQueue_.push(cmd);
commandCondition_.notify_one();
// RenderCommand cmd(CMD_SET_TRANSLATION);
// cmd.param2 = x;
// cmd.param3 = y;
// commandQueue_.push(cmd);
// commandCondition_.notify_one();
render->SetMoveTo(x,y);
}
void RenderThread::resetView() {

View File

@ -12,22 +12,18 @@
namespace NativeOpenCAX {
V3dCamera::V3dCamera() :
camera(nullptr)
{
}
V3dCamera::V3dCamera() : camera(nullptr) {}
V3dCamera::~V3dCamera() {}
bool V3dCamera::InitV3dCamera(Handle(V3d_View)& _view) {
bool V3dCamera::InitV3dCamera(Handle(V3d_View) & _view) {
try {
view=_view;
view = _view;
camera = new Graphic3d_Camera;
// 将角度转换为弧度并计算对应的缩放因子
camera->SetFOVy(45.0);
camera->SetZRange(1, 10.0);
camera->SetScale(1.0);
view->SetCamera(camera);
HILOG_ERROR(NATIVE_TAG,"Camera Scale:%{public}f",camera->Scale());
HILOG_ERROR(NATIVE_TAG, "Camera Scale:%{public}f", camera->Scale());
HILOG_INFO(NATIVE_TAG, "InitCamera Done");
return true;
} catch (std::exception &e) {
@ -35,7 +31,8 @@ bool V3dCamera::InitV3dCamera(Handle(V3d_View)& _view) {
return false;
}
}
//切换视图
// 切换视图
void V3dCamera::SwitchView(std::string nView) {
V3d_TypeOfOrientation tV3d;
if (nView == "CMD_VIEW_FRONT") {
@ -57,7 +54,7 @@ void V3dCamera::SwitchView(std::string nView) {
}
view->SetProj(tV3d);
}
void V3dCamera::SetRotation(float xAngle, float yAngle) {
void V3dCamera::SetRotation(float dx, float dy) {
gp_Pnt currentEye = camera->Eye();
gp_Pnt currentCenter = camera->Center();
gp_Dir currentUp = camera->Up();
@ -65,40 +62,71 @@ void V3dCamera::SetRotation(float xAngle, float yAngle) {
// 计算当前的视线方向和距离
gp_Vec viewDir = currentCenter.XYZ() - currentEye.XYZ();
double distance = viewDir.Magnitude();
gp_Pnt rotationCenter = currentCenter; // 旋转中心设为当前目标点
gp_Pnt rotationCenter = currentCenter;
// 创建旋转增量
// 更稳定地计算旋转轴
gp_Vec forward = viewDir.Normalized();
gp_Vec up = currentUp.XYZ();
// 计算右侧方向 (right = forward × up)
gp_Vec right = forward.Crossed(up).Normalized();
// 重新计算up方向 (up = right × forward),确保正交
up = right.Crossed(forward).Normalized();
// 使用固定的全局坐标系或稳定的局部坐标系
gp_Quaternion rotX, rotY;
// 从 gp_Ax1 中提取方向向量 (gp_Dir -> gp_Vec)
gp_Vec xRotationAxis = camera->Direction().XYZ().Crossed(currentUp.XYZ()); // 叉积得到X旋转轴
if (xRotationAxis.Magnitude() > gp::Resolution()) { // 防止零向量导致的无效四元数
rotX.SetVectorAndAngle(xRotationAxis, xAngle * M_PI / 180.0);
// X旋转使用right向量
if (right.Magnitude() > gp::Resolution()) {
rotX.SetVectorAndAngle(right, dx * M_PI / 180.0);
} else {
rotX.SetIdent(); // 如果叉积为零,则无旋转
rotX.SetIdent();
}
// 从 gp_Ax1 中提取方向向量 (gp_Dir -> gp_Vec)
gp_Vec yRotationAxis = currentUp.XYZ(); // Y旋转轴就是当前的Up方向
if (yRotationAxis.Magnitude() > gp::Resolution()) {
rotY.SetVectorAndAngle(yRotationAxis, yAngle * M_PI / 180.0);
} else {
rotY.SetIdent(); // 如果Up向量无效则无旋转
}
// 组合旋转
// Y旋转使用up向量
if (up.Magnitude() > gp::Resolution()) {
rotY.SetVectorAndAngle(up, dy * M_PI / 180.0);
} else {
rotY.SetIdent();
}
// 组合旋转 (注意顺序)
gp_Quaternion totalRotation = rotY * rotX;
// 应用旋转到眼睛位置
gp_Vec newViewDir = totalRotation * viewDir.Normalized();
gp_Pnt newEye = rotationCenter.XYZ() - newViewDir.XYZ() * distance;
// 计算新的 Up 方向
// 计算新的Up方向
gp_Dir newUp = totalRotation * currentUp;
// 设置新相机参数
camera->SetEye(newEye);
camera->SetCenter(rotationCenter);
camera->SetUp(newUp);
//HILOG_ERROR(NATIVE_TAG,"Rotation");
}
void V3dCamera::SetMoveTo(float dx, float dy) {
gp_Pnt eye = camera->Eye();
gp_Pnt center = camera->Center();
gp_Dir up = camera->Up();
// 计算视平面中的平移向量
gp_Vec viewDir = center.XYZ() - eye.XYZ();
double distance = viewDir.Magnitude();
gp_Vec right = viewDir.Normalized().Crossed(up.XYZ()).Normalized();
gp_Vec actualUp = right.Crossed(viewDir.Normalized()).Normalized();
// 根据视距调整平移量
double panFactor = distance * 0.001; // 可调整的平移系数
gp_Vec translation = right * (-dx * panFactor) + actualUp * (dy * panFactor);
// 移动相机和目标点
center.Translate(translation);
eye.Translate(translation);
camera->SetEye(eye);
camera->SetCenter(center);
}
} // namespace NativeOpenCAX

View File

@ -17,8 +17,9 @@ public:
V3dCamera();
~V3dCamera();
bool InitV3dCamera(Handle(V3d_View)& view);
void SwitchView(std::string view);
void SetRotation(float xAngle, float yAngle);
void SwitchView(std::string nView);
void SetMoveTo(float dx, float dy);
void SetRotation(float dx, float dy);
public:
Handle(Graphic3d_Camera) camera;
Handle(V3d_View) view;