irrlicht实现沿平面移动物体

来源:互联网 发布:如何屏蔽公司网络监控 编辑:程序博客网 时间:2024/04/30 04:32

使用到的原理:射线与面相交性检测

源码引用地址:http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=33059&p=190974&hilit=drag+move+model#p190974


// IrrEditor.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <irrlicht.h>using namespace irr;using namespace core;using namespace scene;using namespace video;using namespace io;using namespace gui;#pragma comment(lib, "Irrlicht.lib")IrrlichtDevice         *device         = 0;IVideoDriver         *driver         = 0;ISceneManager         *smgr         = 0;IGUIEnvironment         *guienv         = 0;ICameraSceneNode      *camera         = 0;ISceneCollisionManager   *CollMan      = 0;enum EditorMode{   MODE_NONE,   MODE_QUIT,   MODE_TRANSLATE,   MODE_ROTATE,   MODE_SCALE,};position2di            initialCursorPosition;      // where mouse cursor startedposition2di            initialObjectPosition;      // where ray from camera to object intersected screenISceneNode*            SelectedNode      = 0;   // the selected nodebool               ShiftIsPressed      = 0;   // is the shift key pressed?bool               LMouseButtonDown   = 0;   // is the left mouse button down?EditorMode            Mode            = MODE_TRANSLATE;float               RotateSpeed         = 0.01f;float               ScaleSpeed         = 0.01f;#define ID_QUIT         101#define ID_TRANSLATE   102#define ID_ROTATE      103#define ID_SCALE      104class MyEventReceiver : public IEventReceiver{public:  virtual bool OnEvent(const SEvent& anevent)  {       switch(anevent.EventType)       {         case EET_GUI_EVENT :         {            switch (anevent.GUIEvent.EventType)               {                  case EGET_BUTTON_CLICKED:                     {                        switch (anevent.GUIEvent.Caller->getID())                          {                             case ID_QUIT      :                                 {                                   Mode = MODE_QUIT;                                         } break;                              case ID_TRANSLATE   :                                 {                                   Mode = MODE_TRANSLATE;                                   } break;                              case ID_ROTATE   :                                 {                                   Mode = MODE_ROTATE;                                } break;                              case ID_SCALE      :                                 {                                   Mode = MODE_SCALE;                                } break;                           } break;                     } break;               }         }  break;                  case EET_KEY_INPUT_EVENT :         {            if (anevent.KeyInput.Shift) ShiftIsPressed = true;             else ShiftIsPressed = false;         } break;         // if it is a mouse event         case EET_MOUSE_INPUT_EVENT :         {            // based upon the mouse event type            switch (anevent.MouseInput.Event)            {               case EMIE_LMOUSE_PRESSED_DOWN :                {                   // what a freakin hack                  LMouseButtonDown = true;                   // check for a node being selected                   SelectedNode = CollMan->getSceneNodeFromScreenCoordinatesBB(device->getCursorControl()->getPosition(),0,true);                    // If we selected a node                    if(SelectedNode)                    {                      // Remember where the node and cursor were when it was clicked on                      initialCursorPosition = device->getCursorControl()->getPosition();                      initialObjectPosition = CollMan->getScreenCoordinatesFrom3DPosition(SelectedNode->getAbsolutePosition(), camera);                    }                   // we used this message?                   return (SelectedNode != 0);                } break;               case EMIE_LMOUSE_LEFT_UP :                {                   LMouseButtonDown = false;                  return false;                } break;               case EMIE_MOUSE_MOVED :               {                  if (!LMouseButtonDown) return false;                  if (Mode == MODE_TRANSLATE)                  {                     if (SelectedNode)                     {                        vector3df p = SelectedNode->getPosition();                                                if (ShiftIsPressed)                         {                           plane3df const planeXY(SelectedNode->getAbsolutePosition(), vector3df(1.f, 0.f, 0.f));                            position2di currentCursorPosition(device->getCursorControl()->getPosition());                            position2di effectiveObjectPosition = initialObjectPosition + currentCursorPosition - initialCursorPosition;                           line3df ray(CollMan->getRayFromScreenCoordinates(effectiveObjectPosition, camera));                            vector3df intersectWithPlane;                            vector3df oldPos = SelectedNode->getAbsolutePosition();                           if(planeXY.getIntersectionWithLine(ray.start, ray.getVector(), intersectWithPlane))                            {                              intersectWithPlane.X = oldPos.X;                              intersectWithPlane.Z = oldPos.Z;                              SelectedNode->setPosition(intersectWithPlane);                           }                         }                         else                         {                           plane3df const planeXZ(SelectedNode->getAbsolutePosition(), vector3df(0.f, 1.f, 0.f));                            position2di currentCursorPosition(device->getCursorControl()->getPosition());                            position2di effectiveObjectPosition = initialObjectPosition + currentCursorPosition - initialCursorPosition;                           line3df ray(CollMan->getRayFromScreenCoordinates(effectiveObjectPosition, camera));                            vector3df intersectWithPlane;                            if(planeXZ.getIntersectionWithLine(ray.start, ray.getVector(), intersectWithPlane))                            {                              SelectedNode->setPosition(intersectWithPlane);                           }                         }                     }                  } // end mode translate                  else                  if (Mode == MODE_ROTATE)                  {                     if (SelectedNode)                     {                        vector3df rot = SelectedNode->getRotation();                        position2di currentCursorPosition(device->getCursorControl()->getPosition());                         if (ShiftIsPressed)                        {                           if (initialObjectPosition.X < currentCursorPosition.X) rot.X -= RotateSpeed;                           if (initialObjectPosition.X > currentCursorPosition.X) rot.X += RotateSpeed;                        }                        else                        {                           if (initialObjectPosition.X < currentCursorPosition.X) rot.Y -= RotateSpeed;                           if (initialObjectPosition.X > currentCursorPosition.X) rot.Y += RotateSpeed;                           if (initialObjectPosition.Y < currentCursorPosition.Y) rot.Z -= 1;                           if (initialObjectPosition.Y > currentCursorPosition.Y) rot.Z += 1;                        }                        initialObjectPosition = currentCursorPosition;                        SelectedNode->setRotation(rot);                     }                  }                  else                   if (Mode == MODE_SCALE)                  {                     if (SelectedNode)                     {                        vector3df scale = SelectedNode->getScale();                        position2di currentCursorPosition(device->getCursorControl()->getPosition());                         if (initialObjectPosition.X > currentCursorPosition.X)                         {                           scale.X -= ScaleSpeed;                           scale.Y -= ScaleSpeed;                           scale.Z -= ScaleSpeed;                        }                        if (initialObjectPosition.X < currentCursorPosition.X)                         {                           scale.X += ScaleSpeed;                           scale.Y += ScaleSpeed;                           scale.Z += ScaleSpeed;                        }                        initialObjectPosition = currentCursorPosition;                        SelectedNode->setScale(scale);                     }                  }               } break;            }         }      }      return 0;   }};int _tmain(int argc, _TCHAR* argv[]){   // create the device   device =  createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 16, false, false, false, 0);    if (!device) return 1;   MyEventReceiver receiver;    device->setEventReceiver(&receiver);   // get a pointer to all of the irr items   driver      = device->getVideoDriver();    smgr      = device->getSceneManager();    guienv      = device->getGUIEnvironment();   CollMan      = smgr->getSceneCollisionManager();   // add my little plug   int x      = 10;   int y      = 10;   int width   = 100;   int height   = 20;   int space   = 5;   guienv->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_QUIT,L"QUIT");   y += height + space;   guienv->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_TRANSLATE,L"Translate");   y += height + space;   guienv->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_ROTATE,L"Rotate");   y += height + space;   guienv->addButton(core::rect<s32>(x,y,x+width,y+height),0,ID_SCALE,L"Scale");   // load a mesh   IAnimatedMesh* mesh = smgr->getMesh("../media/sydney.md2");    if (!mesh) return 1;   // create a node   IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );   if (node)    {      node->setMaterialFlag(EMF_LIGHTING, false);      node->setMD2Animation(scene::EMAT_STAND);      node->setMaterialTexture( 0, driver->getTexture("../media/sydney.bmp") );    }   // add a camera   camera = smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));   camera->setIsDebugObject(true);   // run the scne   while(Mode != MODE_QUIT)   {      device->run();      driver->beginScene(true, true, SColor(255,100,101,140));        smgr->drawAll();        guienv->drawAll();        driver->endScene();    }   // kill the device   device->drop();   return 0;}


0 0