Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp')
-rwxr-xr-xintern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp656
1 files changed, 656 insertions, 0 deletions
diff --git a/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp b/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp
new file mode 100755
index 00000000000..92e5198f139
--- /dev/null
+++ b/intern/bsp/test/BSP_GhostTest/BSP_GhostTest3D.cpp
@@ -0,0 +1,656 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/**
+
+* $Id$
+* Copyright (C) 2001 NaN Technologies B.V.
+*/
+
+#if defined(WIN32) || defined(__APPLE__)
+# ifdef WIN32
+# include <windows.h>
+# include <GL/gl.h>
+# include <GL/glu.h>
+# else // WIN32
+# include <AGL/gl.h>
+# endif // WIN32
+#else // defined(WIN32) || defined(__APPLE__)
+# include <GL/gl.h>
+# include <GL/glu.h>
+#endif // defined(WIN32) || defined(__APPLE__)
+
+
+#include "BSP_GhostTest3D.h"
+#include "BSP_MeshDrawer.h"
+
+#include "GHOST_ISystem.h"
+#include "GHOST_IWindow.h"
+
+#include "MT_Quaternion.h"
+#include "MT_Transform.h"
+#include "CSG_BooleanOps.h"
+
+#include <iostream>
+
+
+using namespace std;
+
+
+BSP_GhostTestApp3D::
+BSP_GhostTestApp3D(
+) :
+ m_window(NULL),
+ m_system(NULL),
+ m_finish_me_off(false),
+ m_current_object(0)
+{
+ //nothing to do;
+}
+
+ void
+BSP_GhostTestApp3D::
+SetMesh(
+ MEM_SmartPtr<BSP_TMesh> mesh
+){
+ m_meshes.push_back(mesh);
+
+ BSP_RotationSetting rotation_setting;
+ BSP_TranslationSetting translation_setting;
+
+ rotation_setting.m_angle_x = MT_Scalar(0);
+ rotation_setting.m_angle_y = MT_Scalar(0);
+ rotation_setting.m_moving = false;
+ rotation_setting.x_old = 0;
+ rotation_setting.y_old = 0;
+
+ translation_setting.m_t_x = MT_Scalar(0);
+ translation_setting.m_t_y = MT_Scalar(0);
+ translation_setting.m_t_z = MT_Scalar(0);
+ translation_setting.m_moving = false;
+ translation_setting.x_old = 0;
+ translation_setting.y_old = 0;
+
+ m_rotation_settings.push_back(rotation_setting);
+ m_translation_settings.push_back(translation_setting);
+ m_render_modes.push_back(e_wireframe_shaded);
+ m_scale_settings.push_back(MT_Scalar(1));
+
+}
+
+ void
+BSP_GhostTestApp3D::
+Swap(
+ int i
+){
+
+ if (!m_rotation_settings[i].m_moving && !m_translation_settings[i].m_moving) {
+ swap(m_meshes[i],m_meshes.back());
+ swap(m_rotation_settings[i],m_rotation_settings.back());
+ swap(m_translation_settings[i],m_translation_settings.back());
+ swap(m_scale_settings[i],m_scale_settings.back());
+ swap(m_render_modes[i],m_render_modes.back());
+ }
+}
+
+
+
+
+
+
+ MT_Transform
+BSP_GhostTestApp3D::
+GetTransform(
+ int i
+){
+
+ MT_Quaternion q_ax(MT_Vector3(0,1,0),m_rotation_settings[i].m_angle_x);
+ MT_Quaternion q_ay(MT_Vector3(1,0,0),m_rotation_settings[i].m_angle_y);
+
+ MT_Point3 tr(
+ m_translation_settings[i].m_t_x,
+ m_translation_settings[i].m_t_y,
+ m_translation_settings[i].m_t_z
+ );
+
+
+ MT_Matrix3x3 rotx(q_ax);
+ MT_Matrix3x3 roty(q_ay);
+
+ MT_Matrix3x3 rot = rotx * roty;
+
+ MT_Transform trans(tr,rot);
+
+ MT_Transform scalet;
+ scalet.setIdentity();
+ scalet.scale(m_scale_settings[i],m_scale_settings[i],m_scale_settings[i]);
+
+ return trans * scalet;
+}
+
+ void
+BSP_GhostTestApp3D::
+Operate(
+ int type
+){
+
+ CSG_VertexIteratorDescriptor * vA = VertexIt_Construct(m_meshes[0],GetTransform(0));
+ CSG_FaceIteratorDescriptor * fA = FaceIt_Construct(m_meshes[0]);
+
+ CSG_VertexIteratorDescriptor * vB = VertexIt_Construct(m_meshes[1],GetTransform(1));
+ CSG_FaceIteratorDescriptor * fB = FaceIt_Construct(m_meshes[1]);
+
+ // describe properties.
+
+ CSG_MeshPropertyDescriptor props;
+ props.mesh_property_flags = 0;
+ props.user_data_size = 0;
+
+ CSG_BooleanOperation * op = CSG_NewBooleanFunction();
+ props = CSG_DescibeOperands(op,props,props);
+
+ CSG_PerformBooleanOperation(op,CSG_OperationType(type),
+ *fA,*vA,*fB,*vB
+ );
+
+ CSG_FaceIteratorDescriptor * out_f = CSG_OutputFaceDescriptor(op);
+ CSG_VertexIteratorDescriptor * out_v = CSG_OutputVertexDescriptor(op);
+
+ MEM_SmartPtr<BSP_TMesh> new_mesh (BuildMesh(props,*out_f,*out_v));
+
+ // free stuff
+
+ CSG_FreeVertexDescriptor(out_v);
+ CSG_FreeFaceDescriptor(out_f);
+ CSG_FreeBooleanOperation(op);
+
+ op = NULL;
+ SetMesh(new_mesh);
+}
+
+
+ void
+BSP_GhostTestApp3D::
+UpdateFrame(
+){
+if (m_window) {
+
+ GHOST_Rect v_rect;
+ m_window->getClientBounds(v_rect);
+
+ glViewport(0,0,v_rect.getWidth(),v_rect.getHeight());
+
+}
+}
+
+
+MT_Vector3
+BSP_GhostTestApp3D::
+UnProject(
+ const MT_Vector3 & vec
+) {
+
+ GLint viewport[4];
+ GLdouble mvmatrix[16],projmatrix[16];
+
+ glGetIntegerv(GL_VIEWPORT,viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX,mvmatrix);
+ glGetDoublev(GL_PROJECTION_MATRIX,projmatrix);
+
+ GLdouble realy = viewport[3] - vec.y() - 1;
+ GLdouble outx,outy,outz;
+
+ gluUnProject(vec.x(),realy,vec.z(),mvmatrix,projmatrix,viewport,&outx,&outy,&outz);
+
+ return MT_Vector3(outx,outy,outz);
+}
+
+
+ bool
+BSP_GhostTestApp3D::
+InitApp(
+){
+
+ // create a system and window with opengl
+ // rendering context.
+
+ GHOST_TSuccess success = GHOST_ISystem::createSystem();
+ if (success == GHOST_kFailure) return false;
+
+ m_system = GHOST_ISystem::getSystem();
+ if (m_system == NULL) return false;
+
+ m_system->addEventConsumer(this);
+
+ m_window = m_system->createWindow(
+ "GHOST crud3D!",
+ 100,100,640,480,GHOST_kWindowStateNormal,
+ GHOST_kDrawingContextTypeOpenGL
+ );
+
+ if (
+ m_window == NULL
+ ) {
+ m_system = NULL;
+ GHOST_ISystem::disposeSystem();
+ return false;
+ }
+
+ // make an opengl frustum for this wind
+
+ MT_Vector3 min,max;
+
+ min = m_meshes[0]->m_min;
+ max = m_meshes[0]->m_max;
+ InitOpenGl(min,max);
+
+ return true;
+}
+
+ void
+BSP_GhostTestApp3D::
+Run(
+){
+ if (m_system == NULL) {
+ return;
+ }
+
+ while (!m_finish_me_off) {
+ m_system->processEvents(true);
+ m_system->dispatchEvents();
+ };
+}
+
+ bool
+BSP_GhostTestApp3D::
+processEvent(
+ GHOST_IEvent* event
+){
+
+ bool handled = false;
+
+ switch(event->getType()) {
+ case GHOST_kEventWindowSize:
+ case GHOST_kEventWindowActivate:
+ UpdateFrame();
+ case GHOST_kEventWindowUpdate:
+ DrawPolies();
+ handled = true;
+ break;
+ case GHOST_kEventButtonDown:
+ {
+ int x,y;
+ m_system->getCursorPosition(x,y);
+
+ int wx,wy;
+ m_window->screenToClient(x,y,wx,wy);
+
+ GHOST_TButtonMask button =
+ static_cast<GHOST_TEventButtonData *>(event->getData())->button;
+
+ if (button == GHOST_kButtonMaskLeft) {
+ m_rotation_settings[m_current_object].m_moving = true;
+ m_rotation_settings[m_current_object].x_old = x;
+ m_rotation_settings[m_current_object].y_old = y;
+ } else
+ if (button == GHOST_kButtonMaskRight) {
+ m_translation_settings[m_current_object].m_moving = true;
+ m_translation_settings[m_current_object].x_old = x;
+ m_translation_settings[m_current_object].y_old = y;
+ } else
+
+ m_window->invalidate();
+ handled = true;
+ break;
+
+ }
+
+ case GHOST_kEventButtonUp:
+ {
+
+ GHOST_TButtonMask button =
+ static_cast<GHOST_TEventButtonData *>(event->getData())->button;
+
+ if (button == GHOST_kButtonMaskLeft) {
+ m_rotation_settings[m_current_object].m_moving = false;
+ m_rotation_settings[m_current_object].x_old = 0;
+ m_rotation_settings[m_current_object].y_old = 0;
+ } else
+ if (button == GHOST_kButtonMaskRight) {
+ m_translation_settings[m_current_object].m_moving = false;
+ m_translation_settings[m_current_object].x_old;
+ m_translation_settings[m_current_object].y_old;
+
+ }
+ m_window->invalidate();
+ handled = true;
+ break;
+
+ }
+
+ case GHOST_kEventCursorMove:
+ {
+ int x,y;
+ m_system->getCursorPosition(x,y);
+ int wx,wy;
+ m_window->screenToClient(x,y,wx,wy);
+
+ if (m_rotation_settings[m_current_object].m_moving) {
+ m_rotation_settings[m_current_object].m_angle_x = MT_Scalar(wx)/20;
+ m_rotation_settings[m_current_object].x_old = wx;
+ m_rotation_settings[m_current_object].m_angle_y = MT_Scalar(wy)/20;
+ m_rotation_settings[m_current_object].y_old = wy;
+
+ m_window->invalidate();
+ }
+ if (m_translation_settings[m_current_object].m_moving) {
+
+ // project current objects bounding box centre into screen space.
+ // unproject mouse point into object space using z-value from
+ // projected bounding box centre.
+
+ GHOST_Rect bounds;
+ m_window->getClientBounds(bounds);
+
+ int w_h = bounds.getWidth();
+
+ y = w_h - wy;
+
+ double mvmatrix[16];
+ double projmatrix[16];
+ GLint viewport[4];
+
+ double px, py, pz,sz;
+
+ /* Get the matrices needed for gluUnProject */
+ glGetIntegerv(GL_VIEWPORT, viewport);
+ glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
+ glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
+
+ // work out the position of the end effector in screen space
+
+ GLdouble ex,ey,ez;
+
+ MT_Vector3 bbox_min, bbox_max;
+
+ bbox_min = m_meshes[0]->m_min;
+ bbox_max = m_meshes[0]->m_max;
+
+ MT_Vector3 bbox_centre = (bbox_min + bbox_max)/2;
+
+ ex = bbox_centre.x();
+ ey = bbox_centre.y();
+ ez = bbox_centre.z();
+
+ gluProject(ex, ey, ez, mvmatrix, projmatrix, viewport, &px, &py, &sz);
+ gluUnProject((GLdouble) x, (GLdouble) y, sz, mvmatrix, projmatrix, viewport, &px, &py, &pz);
+
+ m_translation_settings[m_current_object].m_t_x = px;
+ m_translation_settings[m_current_object].m_t_y = py;
+ m_translation_settings[m_current_object].m_t_z = pz;
+ m_window->invalidate();
+
+ }
+
+ handled = true;
+ break;
+ }
+
+ case GHOST_kEventKeyDown :
+ {
+ GHOST_TEventKeyData *kd =
+ static_cast<GHOST_TEventKeyData *>(event->getData());
+
+
+ switch(kd->key) {
+ case GHOST_kKeyI:
+ {
+ // now intersect meshes.
+ Operate(e_csg_intersection);
+ handled = true;
+ m_window->invalidate();
+ break;
+ }
+ case GHOST_kKeyU:
+ {
+ Operate(e_csg_union);
+ handled = true;
+ m_window->invalidate();
+ break;
+ }
+ case GHOST_kKeyD:
+ {
+ Operate(e_csg_difference);
+ handled = true;
+ m_window->invalidate();
+ break;
+ }
+
+ case GHOST_kKeyA:
+ {
+
+ m_scale_settings[m_current_object] *= 1.1;
+ handled = true;
+ m_window->invalidate();
+ break;
+ }
+ case GHOST_kKeyZ:
+ {
+ m_scale_settings[m_current_object] *= 0.8;
+
+ handled = true;
+ m_window->invalidate();
+ break;
+ }
+
+ case GHOST_kKeyR:
+
+ m_render_modes[m_current_object]++;
+
+ if (m_render_modes[m_current_object] > e_last_render_mode) {
+ m_render_modes[m_current_object] = e_first_render_mode;
+ }
+
+ handled = true;
+ m_window->invalidate();
+ break;
+
+
+
+ case GHOST_kKeyB:
+ handled = true;
+ m_window->invalidate();
+ break;
+
+ case GHOST_kKeyQ:
+ m_finish_me_off = true;
+ handled = true;
+ break;
+
+ case GHOST_kKeyS:
+ Swap(m_current_object);
+ m_window->invalidate();
+ handled = true;
+ break;
+
+ case GHOST_kKeySpace:
+
+ // increment the current object only if the object is not being
+ // manipulated.
+ if (! (m_rotation_settings[m_current_object].m_moving || m_translation_settings[m_current_object].m_moving)) {
+ m_current_object ++;
+ if (m_current_object >= m_meshes.size()) {
+ m_current_object = 0;
+ }
+ }
+ m_window->invalidate();
+
+
+ handled = true;
+ break;
+ default :
+ break;
+ }
+ }
+
+ default :
+ break;
+ }
+
+ return handled;
+
+};
+
+BSP_GhostTestApp3D::
+~BSP_GhostTestApp3D(
+){
+
+ if (m_window) {
+ m_system->disposeWindow(m_window);
+ m_window = NULL;
+ GHOST_ISystem::disposeSystem();
+ m_system = NULL;
+ }
+};
+
+ void
+BSP_GhostTestApp3D::
+DrawPolies(
+){
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ for (int i = 0; i < m_meshes.size(); ++i) {
+
+ MT_Transform trans = GetTransform(i);
+
+ float opengl_mat[16];
+ trans.getValue(opengl_mat);
+
+ opengl_mat[14] -= 30;
+
+ glPushMatrix();
+ glLoadMatrixf(opengl_mat);
+
+ MT_Vector3 color(1.0,1.0,1.0);
+
+ if (i == m_current_object) {
+ color = MT_Vector3(1.0,0,0);
+ }
+
+ BSP_MeshDrawer::DrawMesh(m_meshes[i].Ref(),m_render_modes[i]);
+
+ glPopMatrix();
+ }
+
+ m_window->swapBuffers();
+}
+
+ void
+BSP_GhostTestApp3D::
+InitOpenGl(
+ const MT_Vector3 &min,
+ const MT_Vector3 &max
+){
+
+ GLfloat light_diffuse0[] = {1.0, 0.0, 0.0, 0.5}; /* Red diffuse light. */
+ GLfloat light_position0[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */
+
+ GLfloat light_diffuse1[] = {1.0, 1.0, 1.0, 0.5}; /* Red diffuse light. */
+ GLfloat light_position1[] = {1.0, 0, 0, 0.0}; /* Infinite light location. */
+
+ /* Enable a single OpenGL light. */
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
+
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
+ glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
+
+ glEnable(GL_LIGHT0);
+ glEnable(GL_LIGHT1);
+ glEnable(GL_LIGHTING);
+
+ // make sure there is no back face culling.
+// glDisable(GL_CULL_FACE);
+
+
+ // use two sided lighting model
+
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
+
+ /* Use depth buffering for hidden surface elimination. */
+ glEnable(GL_DEPTH_TEST);
+
+ /* Setup the view of the cube. */
+ glMatrixMode(GL_PROJECTION);
+
+ // centre of the box + 3* depth of box
+
+ MT_Vector3 centre = (min + max) * 0.5;
+ MT_Vector3 diag = max - min;
+
+ float depth = diag.length();
+ float distance = 5;
+
+ gluPerspective(
+ /* field of view in degree */ 40.0,
+ /* aspect ratio */ 1.0,
+ /* Z near */ 1.0,
+ /* Z far */ distance * depth * 2
+ );
+ glMatrixMode(GL_MODELVIEW);
+
+ gluLookAt(
+ centre.x(), centre.y(), centre.z() + distance*depth, //eye
+ centre.x(), centre.y(), centre.z(), //centre
+ 0.0, 1.0, 0.); /* up is in positive Y direction */
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+