• R/O
  • SSH
  • HTTPS

opennurbsviewer: Commit


Commit MetaInfo

Revisão11 (tree)
Hora2016-04-25 02:11:21
Autormocchi_2012

Mensagem de Log

・ 描画の更新が不要な時は draw しないように変更
・ イベント処理周りの改善
・ 選択要素の協調表示
・ 複数3dmファイルの対応
・ Pan、Zoom の操作手段の追加
・ 表示/非表示を選択する機能の追加

Mudança Sumário

Diff

--- trunk/src/OpenNurbsViewer/CONObjSceneNode.h (revision 10)
+++ trunk/src/OpenNurbsViewer/CONObjSceneNode.h (revision 11)
@@ -6,19 +6,29 @@
66
77 class CONObjSceneNode : public irr::scene::ISceneNode{
88 irr::core::aabbox3d<irr::f32> Box;
9+public:
10+ enum RenderingMode{
11+ Simplified, Full
12+ };
13+private:
14+ RenderingMode *rendering_mode;
915
1016 public:
17+ bool *show_flag;
1118 irr::video::SMaterial Material, WMaterial;
1219 bool IsSelectable;
1320 bool Selected;
14- const ONX_Model *ONModel;
21+ int wire_mode; // 0: ワイヤ情報なし、 1: ファセットの縁、 2: メッシュの縁
22+// const ONX_Model *ONModel;
1523 ON_3dmObjectAttributes ONAttribute;
1624
17- irr::core::array<irr::video::S3DVertex> Vertices;
25+ irr::core::array<irr::video::S3DVertex> Vertices, WVertices[2];
1826 irr::core::array<irr::u32> Indices;
27+ irr::core::array<irr::u32> WIndices;
1928
20- CONObjSceneNode(const ONX_Model *model, const ON_Mesh *mesh, ON_3dmObjectAttributes &attr, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id);
21- CONObjSceneNode(const ONX_Model *model, const ON_Brep *brep, ON_3dmObjectAttributes &attr, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id);
29+ CONObjSceneNode(const ONX_Model *model, const ON_Mesh *mesh, ON_3dmObjectAttributes &attr, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, irr::core::vector3df upv,
30+ int wire_mode, RenderingMode *rendering_mode, bool *showflag);
31+// CONObjSceneNode(const ONX_Model *model, const ON_Brep *brep, ON_3dmObjectAttributes &attr, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, irr::core::vector3df upv, int wire_mode, RenderingMode *rendering_mode);
2232
2333 virtual void OnRegisterSceneNode();
2434
--- trunk/src/OpenNurbsViewer/CONObjSceneNode.cpp (revision 10)
+++ trunk/src/OpenNurbsViewer/CONObjSceneNode.cpp (revision 11)
@@ -3,6 +3,8 @@
33 #include "CONObjSceneNode.h"
44
55 #include <vector>
6+#include <set>
7+#include <map>
68
79 #include "gl_mangle.h"
810 #include <GL/gl.h>
@@ -37,10 +39,11 @@
3739 // CONObjSceneNode(ONX_Model &model, scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
3840 // : scene::ISceneNode(parent, mgr, id)
3941 // {
40-CONObjSceneNode::CONObjSceneNode(const ONX_Model *model, const ON_Mesh *mesh, ON_3dmObjectAttributes &attr, ISceneNode* parent, ISceneManager* mgr, s32 id)
41- : ISceneNode(parent, mgr, id) {
42+CONObjSceneNode::CONObjSceneNode(const ONX_Model *model, const ON_Mesh *mesh, ON_3dmObjectAttributes &attr, ISceneNode* parent, ISceneManager* mgr, s32 id, irr::core::vector3df upv,
43+ int wire_mode_, RenderingMode *rendering_mode_, bool *show_flag_)
44+ : ISceneNode(parent, mgr, id), wire_mode(wire_mode_), rendering_mode(rendering_mode_), show_flag(show_flag_) {
4245
43- ONModel = model;
46+// ONModel = model;
4447 ONAttribute = attr;
4548 IsSelectable = true;
4649 Selected = false;
@@ -48,55 +51,83 @@
4851
4952 ON_Color col = GetColorFromAttr(attr, model->m_layer_table);
5053
54+ // 色は選択・非選択で変えたいため、 render 関数で設定する。
5155 Material.Wireframe = false;
5256 Material.Lighting = true;
53- Material.AmbientColor = irr::video::SColor(255,col.Red()/4,col.Green()/4,col.Blue()/4);
54- Material.DiffuseColor = irr::video::SColor(255,col.Red()/4,col.Green()/4,col.Blue()/4);
55- Material.SpecularColor = irr::video::SColor(255,255,255,255);
56- Material.EmissiveColor = irr::video::SColor(255,col.Red()/4,col.Green()/4,col.Blue()/4);
57- Material.Shininess = 0.2f;
57+ Material.Shininess = 1.0f;
5858 Material.FrontfaceCulling = false;
5959 Material.BackfaceCulling = false;
6060 Material.ZBuffer = true;
6161 Material.ZWriteEnable = true;
62+ Material.GouraudShading = false;
63+ Material.NormalizeNormals = false;
64+ Material.UseMipMaps = false;
6265
6366 WMaterial.Wireframe = true;
6467 WMaterial.Lighting = false;
65- WMaterial.Thickness = 4.0f;
68+ WMaterial.FrontfaceCulling = false;
69+ WMaterial.BackfaceCulling = false;
70+ WMaterial.ZBuffer = true;
71+ WMaterial.ZWriteEnable = true;
72+ WMaterial.GouraudShading = false;
73+ WMaterial.NormalizeNormals = false;
74+ WMaterial.UseMipMaps = false;
6675
6776 ON_Mesh cmesh;
68- if (!mesh->HasVertexNormals()){
77+// if (!mesh->HasVertexNormals()){
78+ {
6979 cmesh.CopyFrom(mesh);
80+ cmesh.ConvertQuadsToTriangles();
81+ cmesh.CombineIdenticalVertices(true, true);
7082 cmesh.ComputeVertexNormals();
83+ mesh = &cmesh;
7184 }
7285
86+ std::map<vector2d<int>, int> edge_cnt;
7387 {
7488 const ON_3fPointArray &pts = mesh->m_V;
75- const ON_3fVectorArray &nrms = (mesh->HasVertexNormals()) ? mesh->m_N : cmesh.m_N;
89+ const ON_3fVectorArray &nrms = mesh->m_N;
7690 for (s32 i = 0; i < pts.Count(); ++i){
7791 ON_Color col = (mesh->m_C.Count() > i) ? mesh->m_C[i] : ON_Color(0,0,0,0);
7892 SColor irrcol(255-col.Alpha(), col.Red(), col.Green(), col.Blue());
93+ vector3df nrm(nrms[i].x, nrms[i].y, nrms[i].z);
94+ if (upv.getLengthSQ() > 0 && nrm.dotProduct(upv) < 0) nrm.invert();
95+ nrm.normalize();
7996
8097 Vertices.push_back(video::S3DVertex(
81- pts[i].x, pts[i].y, pts[i].z,
82- nrms[i].x, nrms[i].y, nrms[i].z,
83- irrcol, 0, 0
98+ pts[i].x, pts[i].y, pts[i].z, nrm.X, nrm.Y, nrm.Z, irrcol, 0, 0
8499 ));
85100 }
86101 u32 prevIndices = Indices.size();
87102 for (s32 i = 0; i < mesh->m_F.Count(); ++i){
88103 const ON_MeshFace &face = mesh->m_F[i];
104+ std::set<int> idx_cnt;
105+ for (s32 h = 0; h < 4; ++h) idx_cnt.insert(face.vi[h]);
106+ if (idx_cnt.size() < 3) continue;
89107 Indices.push_back(prevIndices + face.vi[0]);
90108 Indices.push_back(prevIndices + face.vi[1]);
91109 Indices.push_back(prevIndices + face.vi[2]);
110+ bool quad = false;
92111 if (face.vi[2] != face.vi[3]){
93112 Indices.push_back(prevIndices + face.vi[2]);
94113 Indices.push_back(prevIndices + face.vi[3]);
95114 Indices.push_back(prevIndices + face.vi[0]);
115+ quad = true;
96116 }
117+
118+ if (wire_mode == 2){
119+ vector2d<int> e;
120+ e.set(face.vi[0], face.vi[1]); if (e.X > e.Y) std::swap(e.X, e.Y); ++edge_cnt[e];
121+ e.set(face.vi[1], face.vi[2]); if (e.X > e.Y) std::swap(e.X, e.Y); ++edge_cnt[e];
122+ e.set(face.vi[3], face.vi[0]); if (e.X > e.Y) std::swap(e.X, e.Y); ++edge_cnt[e];
123+ if (quad){
124+ e.set(face.vi[2], face.vi[3]); if (e.X > e.Y) std::swap(e.X, e.Y); ++edge_cnt[e];
125+ }
126+ }
97127 }
98128 }
99129
130+#if 0
100131 if (Vertices.size() == 0){
101132 Vertices.push_back(video::S3DVertex(0,0,10, 1,1,0,
102133 video::SColor(255,0,255,255), 0, 1));
@@ -110,6 +141,7 @@
110141 u32 indices[] = { 0,2,3, 2,1,3, 1,0,3, 2,0,1 };
111142 for (s32 i = 0; i < 12; ++i) Indices.push_back(indices[i]);
112143 }
144+#endif
113145
114146 /*
115147 The Irrlicht Engine needs to know the bounding box of a scene node.
@@ -123,9 +155,18 @@
123155 for (u32 i=1; i<Vertices.size(); ++i)
124156 Box.addInternalPoint(Vertices[i].Pos);
125157
158+ if (wire_mode == 2){
159+ for (std::map<vector2d<int>, int>::iterator iter = edge_cnt.begin(); iter != edge_cnt.end(); ++iter){
160+ if (iter->second != 1) continue;
161+ WIndices.push_back(iter->first.X);
162+ WIndices.push_back(iter->first.Y);
163+ }
164+ }
165+
126166 }
127167
128-CONObjSceneNode::CONObjSceneNode(const ONX_Model *model, const ON_Brep *brep, ON_3dmObjectAttributes &attr, ISceneNode* parent, ISceneManager* mgr, s32 id)
168+#if 0
169+CONObjSceneNode::CONObjSceneNode(const ONX_Model *model, const ON_Brep *brep, ON_3dmObjectAttributes &attr, ISceneNode* parent, ISceneManager* mgr, s32 id, irr::core::vector3df upv, int wire_mode_)
129170 : ISceneNode(parent, mgr, id) {
130171
131172 ONModel = model;
@@ -136,18 +177,15 @@
136177
137178 ON_Color col = GetColorFromAttr(attr, model->m_layer_table);
138179
180+ // 色は選択・非選択で変えたいため、 render 関数で設定する。
139181 Material.Wireframe = false;
140182 Material.Lighting = true;
141- Material.AmbientColor = irr::video::SColor(255-col.Alpha(),col.Red()*3/4,col.Green()*3/4,col.Blue()*3/4);
142- Material.DiffuseColor = irr::video::SColor(255-col.Alpha(),col.Red()*3/4,col.Green()*3/4,col.Blue()*3/4);
143- Material.SpecularColor = irr::video::SColor(255-col.Alpha(),255,255,255);
144- Material.EmissiveColor = irr::video::SColor(255-col.Alpha(),col.Red()/2,col.Green()/2,col.Blue()/2);
145- Material.Shininess = 0.2f;
183+ Material.Shininess = 0.5f;
146184 Material.FrontfaceCulling = false;
147185 Material.BackfaceCulling = false;
186+ Material.ZBuffer = false;
148187 Material.GouraudShading = true;
149- Material.ZBuffer = true;
150- Material.NormalizeNormals = true;
188+ Material.NormalizeNormals = false;
151189
152190 // Material.ZBuffer = false;
153191 // Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
@@ -265,6 +303,7 @@
265303 Box.addInternalPoint(Vertices[i].Pos);
266304 }
267305 }
306+#endif
268307
269308 /*
270309 Before it is drawn, the irr::scene::ISceneNode::OnRegisterSceneNode()
@@ -297,10 +336,12 @@
297336 */
298337 void CONObjSceneNode::render() {
299338 if (Indices.size() == 0 || Vertices.size() == 0) return;
339+ if (!(*show_flag)) return;
300340
301- ON_Color col = Selected ? ON_Color(255, 128, 0, 255) : GetColorFromAttr(ONAttribute, ONModel->m_layer_table);
341+// ON_Color col = Selected ? ON_Color(255, 128, 0, 255) : GetColorFromAttr(ONAttribute, ONModel->m_layer_table);
342+ ON_Color col = Selected ? ON_Color(255, 128, 0, 255) : ON_Color(0, 0, 0);
302343
303- Material.SpecularColor = Selected ? irr::video::SColor(255-col.Alpha(), 0, 0, 0) : irr::video::SColor(255-col.Alpha(), 64, 64, 64);
344+ Material.SpecularColor = Selected ? irr::video::SColor(255-col.Alpha(), 0, 0, 0) : irr::video::SColor(255-col.Alpha(), 128, 128, 128);
304345 Material.AmbientColor = irr::video::SColor(255-col.Alpha(), 64 + col.Red()*3/4, 64 + col.Green()*3/4, 64 + col.Blue()*3/4);
305346 Material.DiffuseColor = irr::video::SColor(255-col.Alpha(), 64 + col.Red()*3/4, 64 + col.Green()*3/4, 64 + col.Blue()*3/4);
306347 Material.EmissiveColor = irr::video::SColor(255-col.Alpha(), 64 + col.Red()/2, 64 + col.Green()/2, 64 + col.Blue()/2);
@@ -309,10 +350,47 @@
309350 video::IVideoDriver* driver = SceneManager->getVideoDriver();
310351
311352 matrix4 trans = AbsoluteTransformation;
353+ driver->setTransform(video::ETS_WORLD, trans);
312354
313- driver->setTransform(video::ETS_WORLD, trans);
355+ // 面の描画
314356 driver->setMaterial(Material);
315357 driver->drawVertexPrimitiveList(&Vertices[0], Vertices.size(), &Indices[0], Indices.size() / 3, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_32BIT);
358+
359+ // 縁の描画
360+ if (!Selected && *rendering_mode == Simplified) return;
361+ if (wire_mode != 1 && wire_mode != 2) return;
362+
363+ WMaterial.Thickness = Selected ? 3.0f : 1.0f;
364+ WMaterial.AmbientColor.set(0, 0, 0, 0);
365+ driver->setMaterial(WMaterial);
366+
367+ u32 *pWIndices = 0, cntWIndices = 0;
368+ E_PRIMITIVE_TYPE type;
369+ switch (wire_mode) {
370+ case 1:
371+ pWIndices = &Indices[0], cntWIndices = Indices.size() / 3, type = scene::EPT_TRIANGLES;
372+ break;
373+ case 2:
374+ pWIndices = &WIndices[0], cntWIndices = WIndices.size() / 2, type = scene::EPT_LINES;
375+ break;
376+ }
377+ if (Selected){
378+ for (u32 j = 0; j < 2; ++j){
379+ array<video::S3DVertex> &WVertices = this->WVertices[j];
380+ if (WVertices.size() != Vertices.size()){
381+ WVertices.reallocate(Vertices.size());
382+ for (u32 i = 0; i < Vertices.size(); ++i){
383+ WVertices.push_back(Vertices[i]);
384+ WVertices.getLast().Pos += Vertices[i].Normal * ((j == 0) ? 0.125f : -0.125f);
385+ }
386+ }
387+ driver->drawVertexPrimitiveList(&WVertices[0], WVertices.size(), pWIndices, cntWIndices, video::EVT_STANDARD, type, video::EIT_32BIT);
388+ }
389+ }else{
390+ if (!WVertices[0].empty()) WVertices[0].clear();
391+ if (!WVertices[1].empty()) WVertices[1].clear();
392+ driver->drawVertexPrimitiveList(&Vertices[0], Vertices.size(), pWIndices, cntWIndices, video::EVT_STANDARD, type, video::EIT_32BIT);
393+ }
316394 #if 0
317395 driver->setMaterial(WMaterial);
318396 driver->drawVertexPrimitiveList(&Vertices[0], Vertices.size(), &Indices[0], Indices.size() / 3, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_32BIT);
--- trunk/src/OpenNurbsViewer/App.cpp (revision 10)
+++ trunk/src/OpenNurbsViewer/App.cpp (revision 11)
@@ -48,9 +48,11 @@
4848 }
4949 return true;
5050 }
51+
5152 inline double ProjectPointToLine(const ON_2dPoint &pq, const ON_2dPoint &pl, const ON_2dVector &v1){
5253 return ON_DotProduct((pq - pl), v1);
5354 }
55+
5456 inline bool Intersect2Lines(const ON_2dPoint &p11, const ON_2dPoint &p12, const ON_2dPoint &p21, const ON_2dPoint &p22, ON_2dPoint &po){
5557 // 直線の方程式 ax - by + c = 0
5658 // l1: a1*x - b1*y + c1 = 0
@@ -276,52 +278,108 @@
276278
277279 class App : public IEventReceiver
278280 {
281+ bool view_to_update;
279282 public:
280283 // We'll create a struct to record info on the mouse state
281- struct SMouseState
284+ struct SHIDState
282285 {
283- core::position2di Position;
284- bool LeftButtonDown, MiddleButtonDown, RightButtonDown;
285- SMouseState() : LeftButtonDown(false), MiddleButtonDown(false), RightButtonDown(false) { }
286- } MouseState;
286+ core::position2di Position, PrevPosition;
287+ double ZoomRatio;
288+ bool LeftButtonDown, MiddleButtonDown, RightButtonDown, ShiftDown, CtrlDown;
289+ SHIDState() :
290+ ZoomRatio(0),
291+ LeftButtonDown(false), MiddleButtonDown(false), RightButtonDown(false),
292+ ShiftDown(false), CtrlDown(false) { }
293+ } HIDState;
287294 f32 CameraWidth, CameraHeight;
288295 s32 WindowWidth, WindowHeight;
289296 vector3df EyePos, TargetPos, UpVector;
297+ CONObjSceneNode::RenderingMode rendering_mode;
290298
291299 // === Implement of IEventReceiver ===
292300 virtual bool OnEvent(const SEvent& event)
293301 {
302+ enum Operation{
303+ Nothing, Select, Pan, Zoom, Rotate, SetCenter
304+ }operation = Nothing;
305+ HIDState.ZoomRatio = 1.0f;
294306 // Remember the mouse state
295307 if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
296308 switch(event.MouseInput.Event) {
297- case EMIE_RMOUSE_PRESSED_DOWN:
298- MouseState.RightButtonDown = true;
299- break;
300- case EMIE_RMOUSE_LEFT_UP:
301- MouseState.RightButtonDown = false;
302- break;
303- case EMIE_MMOUSE_PRESSED_DOWN:
304- MouseState.MiddleButtonDown = true;
305- break;
306- case EMIE_MMOUSE_LEFT_UP:
307- MouseState.MiddleButtonDown = false;
308- break;
309- case EMIE_LMOUSE_PRESSED_DOWN:
310- MouseState.LeftButtonDown = true;
311- break;
309+ case EMIE_RMOUSE_PRESSED_DOWN:
310+ HIDState.RightButtonDown = true;
311+ break;
312+ case EMIE_RMOUSE_LEFT_UP:
313+ HIDState.RightButtonDown = false;
314+ break;
315+ case EMIE_MMOUSE_PRESSED_DOWN:
316+ HIDState.MiddleButtonDown = true;
317+ break;
318+ case EMIE_MMOUSE_LEFT_UP:
319+ HIDState.MiddleButtonDown = false;
320+ break;
321+ case EMIE_LMOUSE_PRESSED_DOWN:
322+ HIDState.LeftButtonDown = true;
323+ break;
324+ case EMIE_LMOUSE_LEFT_UP:
325+ HIDState.LeftButtonDown = false;
326+ operation = Select;
327+ break;
328+ case EMIE_RMOUSE_DOUBLE_CLICK:
329+ operation = SetCenter;
330+ break;
331+ case EMIE_MOUSE_MOVED: {
332+ HIDState.PrevPosition = HIDState.Position;
333+ HIDState.Position.X = event.MouseInput.X;
334+ HIDState.Position.Y = event.MouseInput.Y;
312335
313- case EMIE_RMOUSE_DOUBLE_CLICK:
314- case EMIE_LMOUSE_LEFT_UP:{
315- MouseState.LeftButtonDown = false;
316- f32 WindowWidthF = static_cast<f32>(WindowWidth);
317- f32 WindowHeightF = static_cast<f32>(WindowHeight);
336+ if (HIDState.MiddleButtonDown || (HIDState.RightButtonDown && HIDState.ShiftDown)) {
337+ operation = Pan;
338+ }else if (HIDState.RightButtonDown && HIDState.CtrlDown) {
339+ operation = Zoom;
340+ f32 dY = HIDState.Position.Y - HIDState.PrevPosition.Y;
341+ HIDState.ZoomRatio = std::pow((dY < 0) ? 0.85f : 1.15f, std::abs(dY) * 20.0f / WindowHeight);
342+ }else if (HIDState.RightButtonDown){
343+ operation = Rotate;
344+ }
345+ break;
346+ }
347+ case EMIE_MOUSE_WHEEL: {
348+ std::fprintf(stderr, "wheel %f\n", static_cast<double>(event.MouseInput.Wheel));
318349
319- f32 CameraWidthF = static_cast<f32>(CameraWidth);
320- f32 CameraHeightF = static_cast<f32>(CameraHeight);
350+ operation = Zoom;
351+ HIDState.ZoomRatio = std::pow((event.MouseInput.Wheel < 0) ? 1.15f : 0.85f, static_cast<int>(std::abs(event.MouseInput.Wheel)));
352+ break;
353+ }
354+ }
355+ } else if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
356+ HIDState.ShiftDown = event.KeyInput.Shift;
357+ HIDState.CtrlDown = event.KeyInput.Control;
358+ }
359+ if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED) {
360+ s32 id = event.GUIEvent.Caller->getID();
361+ std::fprintf(stderr, "CheckBoxChanged:%d\n", id);
362+ bool checked = static_cast<gui::IGUICheckBox*>(event.GUIEvent.Caller)->isChecked();
363+ --id;
364+ for (list<Group>::Iterator iter = groups.begin(); iter != groups.end() && id >= 0; ++iter, --id){
365+ if (id == 0){
366+ iter->showflag = checked;
367+ view_to_update = true;
368+ break;
369+ }
370+ }
371+ }
321372
322- f32 dx = (static_cast<f32>(MouseState.Position.X) / WindowWidthF - 0.5f) * CameraWidthF;
323- f32 dy = -(static_cast<f32>(MouseState.Position.Y) / WindowHeightF - 0.5f) * CameraHeightF;
373+ switch (operation){
374+ case SetCenter:
375+ case Select: {
376+ HIDState.LeftButtonDown = false;
377+ f32 WindowWidthF = static_cast<f32>(WindowWidth), WindowHeightF = static_cast<f32>(WindowHeight);
378+ f32 CameraWidthF = static_cast<f32>(CameraWidth), CameraHeightF = static_cast<f32>(CameraHeight);
324379
380+ f32 dx = (static_cast<f32>(HIDState.Position.X) / WindowWidthF - 0.5f) * CameraWidthF;
381+ f32 dy = -(static_cast<f32>(HIDState.Position.Y) / WindowHeightF - 0.5f) * CameraHeightF;
382+
325383 ON_BoundingBox bb;
326384 Selector.getBoundingBox(bb);
327385
@@ -350,11 +408,7 @@
350408 Selector.queryBoxFromThickRay(ray, 0.125f, true, results);
351409 timer->tick();
352410 ticks[1] = timer->getTime();
353-#if 0
354- // dbg
355- ONX_Model model_dbg;
356- // dbg
357-#endif
411+
358412 // とりあえず一番近いSceneNodeを選択
359413 f32 dist_min = std::numeric_limits<f32>::max();
360414 CONObjSceneNode *sn_nearest = 0;
@@ -367,6 +421,7 @@
367421 printf("Hit %u nodes from grid \n", res.sceneNodes.size());
368422 for (u32 i = 0; i < res.sceneNodes.size(); ++i){
369423 CONObjSceneNode *sn = res.sceneNodes[i];
424+ if (!(*sn->show_flag)) continue;
370425 array<u32> &extr_by_bb = extr_by_bbs[sn];
371426 ExtractIntersectedElements(res.box, &sn->Vertices[0], sn->Vertices.size(),
372427 &sn->Indices[0], sn->Indices.size(), 3, extr_by_bb);
@@ -375,42 +430,23 @@
375430 timer->tick();
376431 ticks[2] = timer->getTime();
377432
378-
379433 for (extr_by_bb_map_t::iterator iter = extr_by_bbs.begin(); iter != extr_by_bbs.end(); ++iter){
380434 array<u32> &extr_by_bb = iter->second;
381435 if (extr_by_bb.size() == 0) continue;
382436 CONObjSceneNode *sn = iter->first;
437+ if (!(*sn->show_flag)) continue;
383438 array<u32> extr_by_ray;
384439 array<f32> distance;
385440 ExtractIntersectedElements(ray, 0.0625f, &sn->Vertices[0], sn->Vertices.size(),
386441 &extr_by_bb[0], extr_by_bb.size(), 3, extr_by_ray, distance);
387- // printf(" node:%p\n", sn);
388-
389- for (u32 i = 0; i < distance.size(); ++i){
390- // printf(" distance:%f\n", distance[i]);
442+ for (u32 i = 0; i < distance.size(); ++i){
391443 if (dist_min > distance[i]) dist_min = distance[i], sn_nearest = sn;
392444 }
393-#if 0
394- // dbg
395- for (u32 i3 = 0; i3 < extr_by_ray.size(); i3 += 3){
396- ON_3dPointArray pts;
397- for (int h = 0; h < 3; ++h){
398- Convert(sn->Vertices[extr_by_ray[i3+h]].Pos, pts.AppendNew());
399- }
400- pts.Append(*pts.First());
401- ONX_Model_Object &obj = model_dbg.m_object_table.AppendNew();
402- obj.m_object = new ON_PolylineCurve(pts);
403- obj.m_attributes.m_color.SetRGB(255,128,0);
404- obj.m_attributes.SetColorSource(ON::color_from_object);
405- obj.m_bDeleteObject = false;
406- }
407- // dbg
408-#endif
409445 }
410446 if (sn_nearest){
411- if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP){
447+ if (operation == Select){
412448 sn_nearest->Selected = (sn_nearest->Selected) ? false : true;
413- }else if (event.MouseInput.Event == EMIE_RMOUSE_DOUBLE_CLICK){
449+ }else if (operation == SetCenter){
414450 TargetPos = EyePos + ZDir * dist_min + XDir * dx + YDir * dy;
415451 EyePos = TargetPos - ZDir * distEye2Target;
416452 }
@@ -419,74 +455,53 @@
419455 ticks[3] = timer->getTime();
420456
421457 printf("time: %d %d %d [msec]\n", ticks[1]-ticks[0], ticks[2]-ticks[1], ticks[1]-ticks[0]);
422-
423-#if 0
424- // dbg
425- model_dbg.Write("d:/intersect_tri.3dm", 4);
426- // dbg
427-#endif
428458 }
429-// camera->drop(); // getActiveCameraでとったオブジェクトはdropしてはいけない
430459 break;
431460 }
432-
433- case EMIE_MOUSE_MOVED:{
434- if (MouseState.MiddleButtonDown){
435- MoveCamera_Pan(
436- event.MouseInput.X, event.MouseInput.Y, MouseState.Position.X, MouseState.Position.Y,
437- CameraWidth, CameraHeight, WindowWidth, WindowHeight,
438- UpVector, TargetPos, EyePos);
439- }
440- if (MouseState.RightButtonDown){
441- MoveCamera_RotateXY(
442- event.MouseInput.X, event.MouseInput.Y, MouseState.Position.X, MouseState.Position.Y,
443- CameraWidth, CameraHeight, WindowWidth, WindowHeight,
444- UpVector, TargetPos, EyePos);
445- }
446-
447- LightNodes[0]->getLightData().Direction = (TargetPos - EyePos).normalize();
448- LightNodes[0]->getLightData().Position = EyePos;
449-#if 0
450- LightNodes[1]->getLightData().Direction = LightNodes[0]->getLightData().Direction * (-1.0f);
451- LightNodes[1]->getLightData().Position = TargetPos * 2.0 - EyePos;
452-#endif
453- MouseState.Position.X = event.MouseInput.X;
454- MouseState.Position.Y = event.MouseInput.Y;
461+ case Pan: {
462+ MoveCamera_Pan(
463+ HIDState.Position.X, HIDState.Position.Y, HIDState.PrevPosition.X, HIDState.PrevPosition.Y,
464+ CameraWidth, CameraHeight, WindowWidth, WindowHeight,
465+ UpVector, TargetPos, EyePos);
455466 break;
456467 }
457-
458- case EMIE_MOUSE_WHEEL:{
459- std::fprintf(stderr, "wheel %f\n", static_cast<double>(event.MouseInput.Wheel));
460- f32 r = std::pow((event.MouseInput.Wheel < 0) ? 1.15f : 0.85f, static_cast<int>(std::abs(event.MouseInput.Wheel)));
461- CameraWidth *= r;
462- CameraHeight *= r;
468+ case Rotate: {
469+ MoveCamera_RotateXY(
470+ HIDState.Position.X, HIDState.Position.Y, HIDState.PrevPosition.X, HIDState.PrevPosition.Y,
471+ CameraWidth, CameraHeight, WindowWidth, WindowHeight,
472+ UpVector, TargetPos, EyePos);
463473 break;
464474 }
465-
466- default:
467- // We won't use the wheel
475+ case Zoom: {
476+ CameraWidth *= HIDState.ZoomRatio;
477+ CameraHeight *= HIDState.ZoomRatio;
468478 break;
469479 }
470- } else if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
480+ }
481+ if (operation != Nothing){
482+ rendering_mode = CONObjSceneNode::Simplified;
483+ view_to_update = true;
484+ }else{
485+ if (rendering_mode == CONObjSceneNode::Simplified){
486+ rendering_mode = CONObjSceneNode::Full;
487+ view_to_update = true;
488+ }
489+ }
471490
472- }
473491 return false;
474492 }
475493
476- const SMouseState & GetMouseState(void) const {
477- return MouseState;
494+ const SHIDState & GetHIDState(void) const {
495+ return HIDState;
478496 }
479497
480498 bool Initialize(){
481499 // ask user for driver
482- video::E_DRIVER_TYPE driverType=driverChoiceConsole();
483- if (driverType==video::EDT_COUNT) return false;
500+ video::E_DRIVER_TYPE driverType = driverChoiceConsole();
501+ if (driverType == video::EDT_COUNT) return false;
484502
485503 // CameraWidth : CameraHeight = WindowWidth : WindowHeight に
486504 // しないと表示の縦横比が1:1にならない。
487-// CameraWidth = 64;
488-// CameraHeight = 48;
489-
490505 WindowWidth = 640;
491506 WindowHeight = 480;
492507
@@ -515,35 +530,61 @@
515530
516531 Driver = Device->getVideoDriver();
517532 Smgr = Device->getSceneManager();
533+ GUIEnv = Device->getGUIEnvironment();
518534
535+ gui::IGUISkin* skin = GUIEnv->getSkin();
536+ for (u32 i=0; i<gui::EGDC_COUNT; ++i) {
537+ video::SColor col = skin->getColor( static_cast<gui::EGUI_DEFAULT_COLOR>(i) );
538+ col.setAlpha(128);
539+ skin->setColor(static_cast<gui::EGUI_DEFAULT_COLOR>(i), col);
540+ }
519541 return true;
520542 }
521543
544+ void CreateShowHideList(){
545+ using namespace irr::gui;
546+ GUIEnv = Device->getGUIEnvironment();
547+ IGUITabControl* tabctrl = GUIEnv->addTabControl(core::rect<int>(0,10,160,400), 0, true, true);
548+ IGUITab* showhideTab = tabctrl->addTab(L"Show/Hide");
549+ int idx = 1;
550+ int wy = 5, height = 25;
551+ for (list<Group>::ConstIterator iter = groups.begin(); iter != groups.end(); ++iter, ++idx, wy += height){
552+ const Group &gr = *iter;
553+ GUIEnv->addCheckBox(gr.showflag, core::rect<int>( 5, wy, 140, wy + height), showhideTab, idx, ON_wString(gr.name));
554+ }
555+ }
556+
522557 ~App(){
523558 Device->drop();
524559 }
525560
526- // ためしにつくったメソッド
527- void createSceneNodes(ONX_Model &model){
561+ void addSceneNodes(ONX_Model &model, ON_String name){
562+ groups.push_back(Group());
563+ Group &gr = *groups.getLast();
564+ gr.name = name;
565+ gr.showflag = true;
528566
529- // const irr::scene::IGeometryCreator *gc = Smgr->getGeometryCreator();
530- // irr::scene::IMesh *cmesh = gc->createCubeMesh(irr::core::vector3df(80.0f,80.0f,200.0f));
531- // Smgr->addMeshSceneNode(cmesh, Smgr->getRootSceneNode());
532- // cmesh->drop();
533-
534567 aabbox3d<f32> bbox;
535568
536569 int count = 0;
537- CustomNodes.clear();
538570
571+ // 形状設定
539572 for (s32 j = 0; j < model.m_object_table.Count(); ++j){
540573 const ON_Mesh *mesh = ON_Mesh::Cast(model.m_object_table[j].m_object);
574+ if (!mesh) continue;
575+ if (mesh->m_V.Count() == 0) continue;
576+ CONObjSceneNode *myNode = new CONObjSceneNode(&model, mesh, model.m_object_table[j].m_attributes, Smgr->getRootSceneNode(), Smgr, 666, vector3df(0,0,1), 2, &rendering_mode, &gr.showflag);
577+
578+#if 0
579+ const ON_Mesh *mesh = ON_Mesh::Cast(model.m_object_table[j].m_object);
541580 const ON_Brep *brep = ON_Brep::Cast(model.m_object_table[j].m_object);
542581 if (!mesh && !brep) continue;
543582
583+ if (mesh->m_V.Count() == 0) continue;
544584 CONObjSceneNode *myNode = (mesh) ?
545- new CONObjSceneNode(&model, mesh, model.m_object_table[j].m_attributes, Smgr->getRootSceneNode(), Smgr, 666) :
546- new CONObjSceneNode(&model, brep, model.m_object_table[j].m_attributes, Smgr->getRootSceneNode(), Smgr, 666);
585+ new CONObjSceneNode(&model, mesh, model.m_object_table[j].m_attributes, Smgr->getRootSceneNode(), Smgr, 666, vector3df(0,0,1)) :
586+ new CONObjSceneNode(&model, brep, model.m_object_table[j].m_attributes, Smgr->getRootSceneNode(), Smgr, 666, vector3df(0,0,1));
587+#endif
547588
548589 aabbox3d<f32> bbox_cur = myNode->getBoundingBox();
549590 if (j == 0) bbox = bbox_cur;
@@ -551,9 +592,19 @@
551592
552593 CustomNodes.push_back(myNode);
553594 }
595+ }
554596
597+ void InitializeViewSettings(){
598+ // セレクタ設定
599+ aabbox3d<f32> bbox;
600+ for (u32 j = 0; j < CustomNodes.size(); ++j){
601+ if (!CustomNodes[j]) continue;
602+ aabbox3d<f32> bbox_cur = CustomNodes[j]->getBoundingBox();
603+ if (bbox.isEmpty()) bbox = bbox_cur;
604+ else bbox.addInternalBox(bbox_cur);
605+ }
606+
555607 Selector.Initialize(bbox.getExtent().getLength()/8.0f, bbox);
556-// Selector.Initialize(.125f, bbox);
557608
558609 for (u32 j = 0; j < CustomNodes.size(); ++j){
559610 CONObjSceneNode *n = CustomNodes[j];
@@ -561,46 +612,42 @@
561612 Selector.addTriangles(n, &n->Indices[0], &n->Vertices[0], n->Indices.size());
562613 }
563614
615+ // 光源設定
616+ double diag = bbox.getExtent().getLength();
617+ vector3df dir[3] = {vector3df(1.0f, 0.8f, -0.5f), vector3df(-1.0f, -0.5f, 0.0f), vector3df(-1.0f, -0.8f, 0.5f)};
618+ for (int i = 0; i < 1; ++i){
619+ ILightSceneNode* lightNode =
620+ Smgr->addLightSceneNode(0, bbox.MaxEdge, video::SColorf(0.5f, 0.5f, 0.5f, 1.0f), 0.01f);
621+ lightNode->getLightData().Attenuation.set(1.0f/diag, 1.0f/diag, 0);
622+ lightNode->getLightData().DiffuseColor.set(0.0f, 0.0f, 0.0f);
623+ lightNode->getLightData().AmbientColor.set(0.5f, 0.5f, 0.5f);
624+ lightNode->getLightData().SpecularColor.set(0.01f, 0.01f, 0.01f);
625+ lightNode->setLightType(irr::video::ELT_POINT);
564626 #if 0
565- // debug
566- // create grid mesh for display
567- {
568- ON_Mesh mesh;
569- Selector.getGridMesh(mesh);
570-
571- ON_3dmObjectAttributes att;
572- att.m_color.SetAlpha(128);
573- CONObjSceneNode *myNode = new CONObjSceneNode(&mesh, att, model.m_layer_table, Smgr->getRootSceneNode(), Smgr, 666);
574- myNode->IsSelectable = false;
575- myNode->Material.Lighting = false;
627+ lightNode->getLightData().Direction = dir[i];
628+ lightNode->getLightData().AmbientColor.set(1.0f, 0.5f, 0.5f, 0.5f);
629+// lightNode->enableCastShadow(true);
630+ lightNode->enableCastShadow(false);
631+#endif
632+ LightNodes.push_back(lightNode);
576633 }
577634
578- // debug
579-#endif
580-
581- // create camera
582- // irr::scene::ICameraSceneNode * camera = Smgr->addCameraSceneNode();
583-
635+ // カメラ設定
584636 ICameraSceneNode* camera = new CCameraSceneNodeRH(Smgr->getRootSceneNode(), Smgr, 0);
585-// camera->bindTargetAndRotation(true);
586637 Smgr->setActiveCamera(camera);
587638 camera->drop();
588-
589- matrix4 proj;
590- // proj.buildProjectionMatrixOrthoRH(
591- // bbox.MaxEdge.getDistanceFrom(bbox.MinEdge), bbox.MaxEdge.getDistanceFrom(bbox.MinEdge), -300.0f, 300.0f);
592639 double diag2 = bbox.getExtent().getLengthSQ();
593640 double ww_wh = static_cast<double>(WindowWidth) / static_cast<double>(WindowHeight);
594641 double ch = std::sqrt(diag2 / (1 + ww_wh * ww_wh));
642+ CameraWidth = static_cast<s32>(ch * ww_wh);
595643 CameraHeight = static_cast<s32>(ch);
596- CameraWidth = static_cast<s32>(ch * ww_wh);
597644
598- proj.buildProjectionMatrixOrthoRH(CameraWidth, CameraHeight, -10000.0f, 10000.0f);
599-
600645 EyePos = bbox.getCenter() - vector3df(0.0f, 10.0f, 0.0f);
601646 TargetPos = bbox.getCenter();
602647 UpVector.set(0,0,1);
603648
649+ matrix4 proj;
650+ proj.buildProjectionMatrixOrthoRH(CameraWidth, CameraHeight, -10000.0f, 10000.0f);
604651 camera->setProjectionMatrix(proj, true);
605652 camera->setTarget(TargetPos);
606653 camera->setPosition(EyePos);
@@ -612,41 +659,11 @@
612659 dynamic light. We simply create a light scene node, let it fly around,
613660 and to make it look more cool, we attach a billboard scene node to it.
614661 */
615-
616- // create light
617- for (int i = 0; i < 1; ++i){
618- ILightSceneNode* lightNode = Smgr->addLightSceneNode(0, camera->getPosition(),
619- video::SColorf(1.0f, 1.0f, 1.0f, 1.0f), 1000.0f);
620- lightNode->getLightData().Direction.set(-1.0f, 0.0f, 0.0f);
621- lightNode->getLightData().Attenuation.set(1.0f, 0.0f, 0.0f);
622- lightNode->getLightData().AmbientColor.set(1.0f, 1.0f, 1.0f, 1.0f);
623- lightNode->getLightData().DiffuseColor.set(1.0f, 1.0f, 1.0f, 1.0f);
624- lightNode->getLightData().SpecularColor.set(1.0f, 0.5f, 0.5f, 0.5f);
625- lightNode->setLightType(irr::video::ELT_DIRECTIONAL);
626- lightNode->enableCastShadow(false);
627- LightNodes.push_back(lightNode);
628- }
629-
630-#if 0
631- ISceneNodeAnimator* anim = 0;
632- anim = Smgr->createFlyCircleAnimator (vector3df(0,1500,0),1000.0f, 0.0008f);
633- lightNode->addAnimator(anim);
634- anim->drop();
635-#endif
636-#if 0
637- {
638- ISceneNodeAnimator* anim = 0;
639- anim = Smgr->createFlyCircleAnimator (
640- camera->getTarget(), camera->getTarget().getDistanceFrom(camera->getPosition()),
641- 0.0005f, camera->getUpVector());
642- camera->addAnimator(anim);
643- lightNode->addAnimator(anim);
644- anim->drop();
645- }
646-#endif
647662 }
648663
649664 void Run(){
665+ view_to_update = true;
666+ rendering_mode = CONObjSceneNode::Full;
650667 /*
651668 Now draw everything and finish.
652669 */
@@ -665,31 +682,37 @@
665682 ch = std::sqrt(diag2 / (1 + ww_wh * ww_wh));
666683 CameraHeight = static_cast<s32>(ch), CameraWidth = static_cast<s32>(ch * ww_wh);
667684 PrevWindowWidth = WindowWidth, PrevWindowHeight = WindowHeight;
668- }
669685
670- // カメラの更新
671-// CameraWidth = static_cast<f32>(vp.getWidth()) / 10.0f, CameraHeight = static_cast<f32>(vp.getHeight()) / 10.0f;
672- {
673- matrix4 proj;
674- proj.buildProjectionMatrixOrthoRH(CameraWidth, CameraHeight, -100.0f, 100.0f);
675- ICameraSceneNode *camera = Smgr->getActiveCamera();
676-#if 1
677- camera->setTarget(TargetPos);
678- camera->setPosition(EyePos);
679- camera->setUpVector(UpVector);
680- camera->setProjectionMatrix(proj, true);
681-#endif
686+ view_to_update = true;
682687 }
683688
684- // オブジェクトの描画
685- Driver->beginScene(true, true, SColor(0,30,30,30));
689+ if (view_to_update){
690+ // カメラの更新
691+ {
692+ matrix4 proj;
693+ proj.buildProjectionMatrixOrthoRH(CameraWidth, CameraHeight, -100.0f, 100.0f);
694+ ICameraSceneNode *camera = Smgr->getActiveCamera();
686695
687- matrix4 mat = Driver->getTransform(ETS_PROJECTION);
688- Smgr->drawAll();
696+ camera->setTarget(TargetPos);
697+ camera->setPosition(EyePos);
698+ camera->setUpVector(UpVector);
699+ camera->setProjectionMatrix(proj, true);
700+ }
689701
690- Driver->endScene();
702+ // オブジェクト・ウィンドウの描画
703+ {
704+ Driver->beginScene(true, true, SColor(0,30,30,30));
691705
692- if (++frames==100)
706+ matrix4 mat = Driver->getTransform(ETS_PROJECTION);
707+ Smgr->drawAll();
708+ GUIEnv->drawAll();
709+
710+ Driver->endScene();
711+ }
712+ view_to_update = false;
713+ }
714+
715+ if (++frames == 100)
693716 {
694717 core::stringw str = L"Irrlicht Engine [";
695718 str += Driver->getName();
@@ -699,7 +722,7 @@
699722 Device->setWindowCaption(str.c_str());
700723 frames=0;
701724 }
702- Device->sleep(10);
725+ Device->sleep(25);
703726 // Device->yield();
704727 }
705728 }
@@ -708,7 +731,13 @@
708731 IrrlichtDevice *Device;
709732 IVideoDriver *Driver;
710733 ISceneManager *Smgr;
734+ gui::IGUIEnvironment *GUIEnv;
711735
736+ struct Group{
737+ ON_String name;
738+ bool showflag;
739+ };
740+ list<Group> groups;
712741 CGridSelector Selector;
713742 array<ILightSceneNode *> LightNodes;
714743 array<CONObjSceneNode *> CustomNodes;
@@ -720,16 +749,37 @@
720749 */
721750 int main(int argc, char *argv[])
722751 {
723- ONX_Model model;
752+ if (argc == 1) return 0;
753+ App app;
754+ app.Initialize();
755+
724756 if (argc >= 2){
725- model.Read(argv[1]);
757+ for (int i = 1; i < argc; ++i){
758+ ONX_Model model;
759+ model.Read(argv[i]);
760+ ON_String name = argv[i];
761+
762+ // パスからディレクトリを除外
763+ name.Replace("\\", "/");
764+ int idx = name.ReverseFind('/');
765+ if (idx < 0) idx = 0;
766+ else ++idx;
767+ name = name.Mid(idx);
768+
769+ // ファイル名から拡張子を除外
770+ idx = name.ReverseFind('.');
771+ if (idx >= 0) name = name.Left(idx-1);
772+
773+ app.addSceneNodes(model, name);
774+
775+ std::fprintf(stderr, "%s loaded\n", name.Array());
776+ }
726777 }else{
727778 return 0;
728779 }
729780
730- App app;
731- app.Initialize();
732- app.createSceneNodes(model);
781+ app.InitializeViewSettings();
782+ app.CreateShowHideList();
733783 app.Run();
734784
735785 return 0;
Show on old repository browser