增加两个模型
修改世界坐标系 测试鼠标旋转相机
This commit is contained in:
parent
b806ccbf1a
commit
406cd03b02
@ -17,6 +17,9 @@ bool InitLocalAxis(RenderOption& opt) {
|
||||
opt.localAxisPlacement = new Geom_Axis2Placement(gp::XOY());
|
||||
opt.localAxis = new AIS_Trihedron(opt.localAxisPlacement);
|
||||
opt.localAxis->SetSize(50.0);
|
||||
opt.localAxis->SetDatumPartColor(Prs3d_DP_XAxis,Quantity_NOC_RED);
|
||||
opt.localAxis->SetDatumPartColor(Prs3d_DP_YAxis,Quantity_NOC_GREEN);
|
||||
opt.localAxis->SetDatumPartColor(Prs3d_DP_ZAxis,Quantity_NOC_BLUE);
|
||||
opt.context->Display(opt.localAxis, 0, 0, true);
|
||||
HILOG_INFO(NATIVE_TAG,"InitLocalAxis Done");
|
||||
return true;
|
||||
|
||||
@ -16,7 +16,18 @@ bool InitWorldAxis(RenderOption& opt) {
|
||||
// 添加世界坐标系(左下角)
|
||||
opt.worldAxisPlacement = new Geom_Axis2Placement(gp::XOY());
|
||||
opt.worldAxis = new AIS_Trihedron(opt.worldAxisPlacement);
|
||||
opt.worldAxis->SetSize(30.0); // 小一点,作为指示器
|
||||
opt.worldAxis->SetSize(100.0); // 小一点,作为指示器
|
||||
opt.worldAxis->SetZLayer(Graphic3d_ZLayerId_TopOSD);
|
||||
opt.worldAxis->SetTransformPersistence(
|
||||
new Graphic3d_TransformPers(
|
||||
Graphic3d_TMF_2d, // 2D 模式
|
||||
Aspect_TOTP_LEFT_LOWER, // 左下角对齐
|
||||
Graphic3d_Vec2i(100, 100) // 偏移量(像素)
|
||||
)
|
||||
);
|
||||
opt.worldAxis->SetDatumPartColor(Prs3d_DP_XAxis,Quantity_NOC_RED);
|
||||
opt.worldAxis->SetDatumPartColor(Prs3d_DP_YAxis,Quantity_NOC_GREEN);
|
||||
opt.worldAxis->SetDatumPartColor(Prs3d_DP_ZAxis,Quantity_NOC_BLUE);
|
||||
opt.context->Display(opt.worldAxis, 0, 0, false);
|
||||
HILOG_INFO(NATIVE_TAG,"InitWorldAxis Done");
|
||||
return true;
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#ifndef OPENCAX_WORLDAXIS_H
|
||||
#define OPENCAX_WORLDAXIS_H
|
||||
#include "../RenderStruct.h"
|
||||
#include <Prs3d_DatumParts.hxx>
|
||||
namespace NativeOpenCAX {
|
||||
bool InitWorldAxis(RenderOption& opt);
|
||||
void ChangeWorldAxis();
|
||||
|
||||
@ -77,39 +77,7 @@ std::string uuid_v4() {
|
||||
<< "-" << std::setw(12) << std::setfill('0') << (random_part & 0xFFFFFFFFFFFF);
|
||||
return ss.str();
|
||||
}
|
||||
// Surface回调事件
|
||||
//void OnSurfaceCreatedNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||
// auto window = OH_ArkUI_XComponent_GetNativeWindow(holder); // 获取native window
|
||||
// auto eglCore = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
||||
// eglCore->EglContextInit(window, 800, 600);
|
||||
//}
|
||||
//void OnSurfaceChangedNative(OH_ArkUI_SurfaceHolder *holder, uint64_t width, uint64_t height) {
|
||||
// EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
||||
// render->UpdateSize(width, height); // 设置绘制区域大小
|
||||
// //render->Draw(NativeManager::hasDraw_); // 绘制五角星
|
||||
//}
|
||||
//void OnSurfaceDestroyedNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||
// OH_LOG_Print(LOG_APP, LOG_ERROR, 0xff00, "onBind", "on destroyed");
|
||||
// EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
|
||||
// render->Release(); // 销毁eglSurface相关资源
|
||||
//}
|
||||
//void OnSurfaceShowNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||
// OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on surface show");
|
||||
//}
|
||||
//void OnSurfaceHideNative(OH_ArkUI_SurfaceHolder *holder) {
|
||||
// OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on surface hide");
|
||||
//}
|
||||
//void OnFrameCallbackNative(ArkUI_NodeHandle node, uint64_t timestamp, uint64_t targetTimestamp) {
|
||||
// if (!NativeManager::surfaceHolderMap_.count(node)) {
|
||||
// return;
|
||||
// }
|
||||
// static uint64_t count = 0;
|
||||
// count++;
|
||||
// // 在头文件plugin_manager.h中定义,FRAME_COUNT的值为50
|
||||
// if (count % FRAME_COUNT == 0) {
|
||||
// OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "OnFrameCallback count = %{public}ld", count);
|
||||
// }
|
||||
//}
|
||||
|
||||
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
|
||||
// [StartExclude plugin_on_surface_created]
|
||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB");
|
||||
@ -216,6 +184,73 @@ void onEvent(ArkUI_NodeEvent *event) {
|
||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on touch");
|
||||
}
|
||||
}
|
||||
void OnMouseEventCB(OH_NativeXComponent* component, void* window) {
|
||||
auto* pluginManager = NativeManager::GetInstance();
|
||||
if (!pluginManager || !window) {
|
||||
return;
|
||||
}
|
||||
auto *pluginManger = NativeManager::GetInstance();
|
||||
pluginManger->OnMouseEvent(component, window);
|
||||
}
|
||||
void NativeManager::OnMouseEvent(OH_NativeXComponent *component, void *window) {
|
||||
OH_NativeXComponent_MouseEvent event;
|
||||
int32_t ret;
|
||||
ret=OH_NativeXComponent_GetMouseEvent(component, window, &event);
|
||||
std::lock_guard<std::mutex> lock(mapMutex);
|
||||
//通过时间戳判断事件唯一性.保证单一时间戳只触发一次事件
|
||||
if(event.timestamp==NativeManager::timestamp){
|
||||
return;
|
||||
}
|
||||
NativeManager::timestamp=event.timestamp;
|
||||
int64_t id = 0;
|
||||
auto it = renderThreadMap.find(id);
|
||||
if (it == renderThreadMap.end()) {
|
||||
HILOG_WARN(NATIVE_TAG, "Render thread not found for rotation.");
|
||||
return;
|
||||
}
|
||||
auto renderThread = it->second;
|
||||
float curtX,curtY;
|
||||
HILOG_WARN(NATIVE_TAG, "ALLButton:%{public}d",event.button);
|
||||
HILOG_WARN(NATIVE_TAG, "ALLAction:%{public}d",event.action);
|
||||
HILOG_WARN(NATIVE_TAG, "ALLTimestamp:%{public}d",event.timestamp);
|
||||
//鼠标按下并且事件为鼠标中键
|
||||
if(event.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&event.action==OH_NATIVEXCOMPONENT_MOUSE_PRESS){
|
||||
//记录按下时候的X.Y坐标
|
||||
NativeManager::lastMouseX_=event.x;
|
||||
NativeManager::lastMouseY_=event.y;
|
||||
NativeManager::isMouseMiddleBtnPressed = true;
|
||||
HILOG_WARN(NATIVE_TAG, "AtlastMouseX:%{public}d",NativeManager::lastMouseX_);
|
||||
HILOG_WARN(NATIVE_TAG, "AtlastMouseY:%{public}d",NativeManager::lastMouseY_);
|
||||
HILOG_WARN(NATIVE_TAG, "AtButton:%{public}d",event.button);
|
||||
HILOG_WARN(NATIVE_TAG, "AtButtonAction:%{public}d",event.action);
|
||||
HILOG_WARN(NATIVE_TAG, "AtisMouseMiddleBtnPressed:%{public}d",NativeManager::isMouseMiddleBtnPressed);
|
||||
}else if(NativeManager::isMouseMiddleBtnPressed&&event.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE){
|
||||
// 计算鼠标移动距离
|
||||
float deltaX = curtX - NativeManager::lastMouseX_;
|
||||
float deltaY = curtY - NativeManager::lastMouseY_;
|
||||
// 将像素移动量映射到旋转角度
|
||||
// 这里的系数可以根据需要调整灵敏度
|
||||
float rotationSpeed = 0.005f;
|
||||
float angleX = deltaX * rotationSpeed;
|
||||
float angleY = deltaY * rotationSpeed;
|
||||
// 通知渲染线程执行旋转
|
||||
// 由于渲染在线程里,需要通过命令队列发送指令
|
||||
renderThread->setRotation(angleX, angleY);
|
||||
// 更新最后的位置
|
||||
//NativeManager::lastMouseX_ = deltaX;
|
||||
//NativeManager::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",event.button);
|
||||
HILOG_WARN(NATIVE_TAG, "MoveButtonAction:%{public}d",event.action);
|
||||
HILOG_WARN(NATIVE_TAG, "MoveIsMouseMiddleBtnPressed:%{public}d",NativeManager::isMouseMiddleBtnPressed);
|
||||
}
|
||||
else if(event.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&event.action==OH_NATIVEXCOMPONENT_MOUSE_RELEASE){
|
||||
//NativeManager::isMouseMiddleBtnPressed = false;
|
||||
HILOG_WARN(NATIVE_TAG, "ReleaseIsMouseMiddleBtnPressed:%{public}d",NativeManager::isMouseMiddleBtnPressed);
|
||||
}
|
||||
|
||||
}
|
||||
static std::string value2String(napi_env env, napi_value value) {
|
||||
size_t stringSize = 0;
|
||||
napi_get_value_string_utf8(env, value, nullptr, 0, &stringSize);
|
||||
@ -229,6 +264,7 @@ NativeManager::NativeManager() {
|
||||
xSurfaceTouchEventCallBack.OnSurfaceCreated = OnSurfaceCreatedCB;
|
||||
xSurfaceTouchEventCallBack.OnSurfaceChanged = OnSurfaceChangedCB;
|
||||
xSurfaceTouchEventCallBack.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
|
||||
xMouseEventCallBack.DispatchMouseEvent= OnMouseEventCB;
|
||||
}
|
||||
// 创建节点组件
|
||||
ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
|
||||
|
||||
@ -57,6 +57,7 @@ public:
|
||||
void OnSurfaceDestroyed(OH_NativeXComponent* component, void* window);
|
||||
void DispatchTouchEvent(OH_NativeXComponent* component, void* window);
|
||||
void OnSurfaceCreated(OH_NativeXComponent* component, void* window);
|
||||
void OnMouseEvent(OH_NativeXComponent *component, void *window);
|
||||
private:
|
||||
static NativeManager pluginManager_;
|
||||
std::unordered_map<std::string, OH_NativeXComponent*> nativeXComponentMap_;
|
||||
@ -67,8 +68,14 @@ public:
|
||||
std::string modelPath_;
|
||||
uint64_t width_;
|
||||
uint64_t height_;
|
||||
int64_t timestamp;
|
||||
static int32_t hasDraw_;
|
||||
static int32_t hasChangeColor_;
|
||||
//鼠标位置保存
|
||||
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 std::unordered_map<void *, OH_ArkUI_SurfaceHolder *> surfaceHolderMap_;
|
||||
|
||||
@ -119,7 +119,7 @@ bool NativeRender::loadModel(const std::string& filePath) {
|
||||
}
|
||||
|
||||
// 调整相机到合适位置
|
||||
rendOption.view->FitAll(0.05, Standard_True);
|
||||
rendOption.view->FitAll(0.5, Standard_True);
|
||||
rendOption.view->ZFitAll();
|
||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "LoadModel","Successfully loaded STEP file with %{public}d shapes",numShapes);
|
||||
return true;
|
||||
@ -136,28 +136,6 @@ void NativeRender::render() {
|
||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render","View Is Null");
|
||||
return;
|
||||
}
|
||||
|
||||
//glClearColor(1, 0, 0, 1);
|
||||
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
//glViewport(0, 0, width_, height_);
|
||||
// 应用旋转
|
||||
//Handle(Graphic3d_Camera) camera = view_->Camera();
|
||||
// 计算旋转
|
||||
//gp_Quaternion rotation;
|
||||
//rotation.SetEulerAngles(gp_EulerSequence::gp_Extrinsic_XYZ,
|
||||
// rotationX_ * M_PI / 180.0,
|
||||
// rotationY_ * M_PI / 180.0,
|
||||
// 0.0);
|
||||
|
||||
// 计算相机位置
|
||||
//gp_Dir camDir(0.0, 1.0, 0.0);
|
||||
//gp_Vec camVec = rotation * gp_Vec(camDir);
|
||||
//gp_Pnt camPos = gp_Pnt(0.0, 0.0, 0.0).Translated(camVec.Reversed() * 50.0 * zoomLevel_);
|
||||
|
||||
// 设置相机参数
|
||||
//camera->SetEye(camPos);
|
||||
//camera->SetCenter(gp_Pnt(translationX_, translationY_, 0.0));
|
||||
//camera->SetUp(gp_Dir(0.0, 0.0, 1.0));
|
||||
// 执行渲染
|
||||
rendOption.view->Redraw();
|
||||
}
|
||||
@ -171,8 +149,59 @@ void NativeRender::resize(int width, int height) {
|
||||
}
|
||||
|
||||
void NativeRender::setRotation(float xAngle, float yAngle) {
|
||||
axis.rotationX = xAngle;
|
||||
axis.rotationY = yAngle;
|
||||
//axis.rotationX = xAngle;
|
||||
//axis.rotationY = yAngle;
|
||||
if (rendOption.view.IsNull()) {
|
||||
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "addRotationDelta", "View Is Null");
|
||||
return;
|
||||
}
|
||||
|
||||
//Handle(Graphic3d_Camera) camera = rendOption.view->Camera();
|
||||
|
||||
// --- 方案一:直接对相机进行增量旋转 ---
|
||||
// 这种方式模拟了“轨道”行为,绕着相机看向的目标点旋转。
|
||||
// 获取当前相机状态
|
||||
gp_Pnt currentEye = rendOption.camera->Eye();
|
||||
gp_Pnt currentCenter = rendOption.camera->Center();
|
||||
gp_Dir currentUp = rendOption.camera->Up();
|
||||
|
||||
// 计算当前的视线方向和距离
|
||||
gp_Vec viewDir = currentCenter.XYZ() - currentEye.XYZ();
|
||||
double distance = viewDir.Magnitude();
|
||||
gp_Pnt rotationCenter = currentCenter; // 旋转中心设为当前目标点
|
||||
|
||||
// 创建旋转增量
|
||||
gp_Quaternion rotX, rotY;
|
||||
// 从 gp_Ax1 中提取方向向量 (gp_Dir -> gp_Vec)
|
||||
gp_Vec xRotationAxis = rendOption.camera->Direction().XYZ().Crossed(currentUp.XYZ()); // 叉积得到X旋转轴
|
||||
if (xRotationAxis.Magnitude() > gp::Resolution()) { // 防止零向量导致的无效四元数
|
||||
rotX.SetVectorAndAngle(xRotationAxis, xAngle * M_PI / 180.0);
|
||||
} else {
|
||||
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向量无效,则无旋转
|
||||
}
|
||||
// 组合旋转
|
||||
gp_Quaternion totalRotation = rotY * rotX;
|
||||
|
||||
// 应用旋转到眼睛位置
|
||||
gp_Vec newViewDir = totalRotation * viewDir.Normalized();
|
||||
gp_Pnt newEye = rotationCenter.XYZ() - newViewDir.XYZ() * distance;
|
||||
|
||||
// 计算新的 Up 方向
|
||||
gp_Dir newUp = totalRotation * currentUp;
|
||||
|
||||
// 设置新相机参数
|
||||
rendOption.camera->SetEye(newEye);
|
||||
rendOption.camera->SetCenter(rotationCenter);
|
||||
rendOption.camera->SetUp(newUp);
|
||||
HILOG_ERROR(NATIVE_TAG,"Rotation");
|
||||
//rendOption.view->Redraw();
|
||||
}
|
||||
|
||||
void NativeRender::setZoomLevel(float zoom) {
|
||||
|
||||
@ -15,8 +15,9 @@
|
||||
#include "TextStyle/TextStyle.h"
|
||||
#include "View/View.h"
|
||||
#include "Viewer/Viewer.h"
|
||||
|
||||
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_EulerSequence.hxx>
|
||||
#include <gp_Quaternion.hxx>
|
||||
namespace NativeOpenCAX {
|
||||
|
||||
class NativeRender {
|
||||
@ -33,6 +34,7 @@ public:
|
||||
void setClearColor(float r, float g, float b, float a);
|
||||
void setZoomLevel(float zoom);
|
||||
void setTranslation(float x, float y);
|
||||
void setCameraRotationMode(bool state);
|
||||
private:
|
||||
RenderOption rendOption;
|
||||
AxisOption axis;
|
||||
|
||||
@ -63,9 +63,8 @@ void NativeRenderThread::renderLoop() {
|
||||
while (isRunning_) {
|
||||
RenderCommand command;
|
||||
bool hasCommand = false;
|
||||
|
||||
std::unique_lock<std::mutex> lock(commandMutex_);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(commandMutex_);
|
||||
commandCondition_.wait_for(lock, std::chrono::milliseconds(16), [this] {
|
||||
return !commandQueue_.empty();
|
||||
});
|
||||
@ -123,7 +122,7 @@ void NativeRenderThread::renderLoop() {
|
||||
}
|
||||
|
||||
// 控制帧率
|
||||
usleep(16000); // ~60 FPS
|
||||
usleep(8333); // ~60 FPS
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ public:
|
||||
void stop();
|
||||
|
||||
void loadModel(const std::string& filePath);
|
||||
void setCameraRotationMode(bool state);
|
||||
void setRotation(float xAngle, float yAngle);
|
||||
void setTranslation(float x, float y);
|
||||
void resetView();
|
||||
@ -57,8 +58,9 @@ private:
|
||||
CommandType type;
|
||||
std::string param1; // For file path
|
||||
float param2, param3, param4, param5;
|
||||
bool param6;
|
||||
RenderCommand() : type(CMD_EXIT), param1(""), param2(0.0f), param3(0.0f), param4(0.0f), param5(0.0f) {}
|
||||
RenderCommand(CommandType t) : type(t), param1(""), param2(0), param3(0), param4(0), param5(0) {}
|
||||
RenderCommand(CommandType t) : type(t), param1(""), param2(0), param3(0), param4(0), param5(0),param6(true) {}
|
||||
};
|
||||
|
||||
std::queue<RenderCommand> commandQueue_;
|
||||
|
||||
@ -11,7 +11,7 @@ export struct ModelView {
|
||||
private displayController: XComponentController = new XComponentController();
|
||||
private displayContrId: string = 'OCCTRender';
|
||||
@State modelPath: string = '';
|
||||
@State modelName:string='linkrods.step';
|
||||
@State modelName:string='2027.stp';
|
||||
@State currentStatus: string = 'init';
|
||||
private nodeContent: NodeContent = new NodeContent();
|
||||
|
||||
|
||||
3641
entry/src/main/resources/rawfile/2026.stp
Normal file
3641
entry/src/main/resources/rawfile/2026.stp
Normal file
File diff suppressed because it is too large
Load Diff
5577
entry/src/main/resources/rawfile/2027.stp
Normal file
5577
entry/src/main/resources/rawfile/2027.stp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user