RigsofRods
Soft-body Physics Simulation
SceneMouse.cpp
Go to the documentation of this file.
1 /*
2  This source file is part of Rigs of Rods
3  Copyright 2005-2012 Pierre-Michel Ricordel
4  Copyright 2007-2012 Thomas Fischer
5  Copyright 2013-2014 Petr Ohlidal
6 
7  For more information, see http://www.rigsofrods.org/
8 
9  Rigs of Rods is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License version 3, as
11  published by the Free Software Foundation.
12 
13  Rigs of Rods is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
25 
26 #include "SceneMouse.h"
27 
28 #include "Actor.h"
29 #include "Application.h"
30 #include "GameContext.h"
31 #include "GfxScene.h"
32 #include "ScriptEngine.h"
33 
34 #include <Ogre.h>
35 
36 using namespace Ogre;
37 using namespace RoR;
38 
39 #define MOUSE_GRAB_FORCE 30000.0f
40 
41 SceneMouse::SceneMouse() :
42  mouseGrabState(0),
43  grab_truck(nullptr),
44  pickLine(nullptr),
45  pickLineNode(nullptr)
46 {
47  this->reset();
48 }
49 
51 {
52  // load 3d line for mouse picking
53  pickLine = App::GetGfxScene()->GetSceneManager()->createManualObject("PickLineObject");
54  pickLineNode = App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->createChildSceneNode("PickLineNode");
55 
56  MaterialPtr pickLineMaterial = MaterialManager::getSingleton().getByName("PickLineMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
57  if (pickLineMaterial.isNull())
58  {
59  pickLineMaterial = MaterialManager::getSingleton().create("PickLineMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
60  }
61  pickLineMaterial->setReceiveShadows(false);
62  pickLineMaterial->getTechnique(0)->setLightingEnabled(true);
63  pickLineMaterial->getTechnique(0)->getPass(0)->setDiffuse(0, 0, 1, 0);
64  pickLineMaterial->getTechnique(0)->getPass(0)->setAmbient(0, 0, 1);
65  pickLineMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(0, 0, 1);
66 
67  pickLine->begin("PickLineMaterial", RenderOperation::OT_LINE_LIST);
68  pickLine->position(0, 0, 0);
69  pickLine->position(0, 0, 0);
70  pickLine->end();
71  pickLineNode->attachObject(pickLine);
72  pickLineNode->setVisible(false);
73 }
74 
76 {
77  if (pickLineNode != nullptr)
78  {
79  App::GetGfxScene()->GetSceneManager()->getRootSceneNode()->removeAndDestroyChild("PickLineNode");
80  pickLineNode = nullptr;
81  }
82 
83  if (pickLine != nullptr)
84  {
85  App::GetGfxScene()->GetSceneManager()->destroyManualObject("PickLineObject");
86  pickLine = nullptr;
87  }
88 }
89 
91 {
92  if (App::sim_state->getEnum<SimState>() == SimState::PAUSED) { return; } // Do nothing when paused
93 
94  // remove forces
95  if (grab_truck)
96  grab_truck->mouseMove(minnode, Vector3::ZERO, 0);
97 
98  this->reset();
99 }
100 
102 {
104  grab_truck = 0;
105  mindist = 99999;
106  mouseGrabState = 0;
107  lastgrabpos = Vector3::ZERO;
108  lastMouseX = 0;
109  lastMouseY = 0;
110 
111  mouseGrabState = 0;
112 }
113 
114 bool SceneMouse::mouseMoved(const OIS::MouseEvent& _arg)
115 {
116  const OIS::MouseState ms = _arg.state;
117 
118  // experimental mouse hack
119  if (ms.buttonDown(OIS::MB_Left) && mouseGrabState == 0)
120  {
121  lastMouseY = ms.Y.abs;
122  lastMouseX = ms.X.abs;
123 
124  Ray mouseRay = getMouseRay();
125 
126  // walk all trucks
128  grab_truck = NULL;
129  for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors())
130  {
131  if (actor->ar_state == ActorState::LOCAL_SIMULATED)
132  {
133  // check if our ray intersects with the bounding box of the truck
134  std::pair<bool, Real> pair = mouseRay.intersects(actor->ar_bounding_box);
135  if (!pair.first)
136  continue;
137 
138  for (int j = 0; j < actor->ar_num_nodes; j++)
139  {
140  if (actor->ar_nodes[j].nd_no_mouse_grab)
141  continue;
142 
143  // check if our ray intersects with the node
144  std::pair<bool, Real> pair = mouseRay.intersects(Sphere(actor->ar_nodes[j].AbsPosition, 0.1f));
145  if (pair.first)
146  {
147  // we hit it, check if its the nearest node
148  if (pair.second < mindist)
149  {
150  mindist = pair.second;
151  minnode = (NodeNum_t)j;
152  grab_truck = actor;
153  }
154  }
155  }
156  }
157  }
158 
159  // check if we hit a node
161  {
162  mouseGrabState = 1;
163 
164  for (std::vector<hook_t>::iterator it = grab_truck->ar_hooks.begin(); it != grab_truck->ar_hooks.end(); it++)
165  {
166  if (it->hk_hook_node->pos == minnode)
167  {
168  //grab_truck->hookToggle(it->hk_group, HOOK_MOUSE_TOGGLE, minnode);
172  rq->alr_hook_group = it->hk_group;
175  }
176  }
177  }
178  }
179  else if (ms.buttonDown(OIS::MB_Left) && mouseGrabState == 1)
180  {
181  // force applying and so forth happens in update()
182  lastMouseY = ms.Y.abs;
183  lastMouseX = ms.X.abs;
184  // not fixed
185  return false;
186  }
187  else if (!ms.buttonDown(OIS::MB_Left) && mouseGrabState == 1)
188  {
190  // not fixed
191  return false;
192  }
193 
194  return false;
195 }
196 
198 {
199  if (mouseGrabState == 1 && grab_truck)
200  {
201  // get values
202  Ray mouseRay = getMouseRay();
203  lastgrabpos = mouseRay.getPoint(mindist);
204 
205  // add forces
207  }
208 }
209 
211 {
212  if (grab_truck == nullptr)
213  {
214  pickLineNode->setVisible(false); // Hide the line
215  }
216  else
217  {
218  pickLineNode->setVisible(true); // Show the line
219  // update visual line
220  pickLine->beginUpdate(0);
222  pickLine->position(lastgrabpos);
223  pickLine->end();
224  }
225 }
226 
227 bool SceneMouse::mousePressed(const OIS::MouseEvent& _arg, OIS::MouseButtonID _id)
228 {
229  if (App::sim_state->getEnum<SimState>() == SimState::PAUSED) { return true; } // Do nothing when paused
230 
231  const OIS::MouseState ms = _arg.state;
232 
233  if (ms.buttonDown(OIS::MB_Middle))
234  {
235  lastMouseY = ms.Y.abs;
236  lastMouseX = ms.X.abs;
237  Ray mouseRay = getMouseRay();
238 
239  if (App::sim_state->getEnum<SimState>() == SimState::EDITOR_MODE)
240  {
241  return true;
242  }
243 
244  ActorPtr player_actor = App::GetGameContext()->GetPlayerActor();
245 
246  // Reselect the player actor
247  {
248  Real nearest_ray_distance = std::numeric_limits<float>::max();
249 
250  for (ActorPtr& actor : App::GetGameContext()->GetActorManager()->GetActors())
251  {
252  if (actor != player_actor)
253  {
254  Vector3 pos = actor->getPosition();
255  std::pair<bool, Real> pair = mouseRay.intersects(Sphere(pos, actor->getMinCameraRadius()));
256  if (pair.first)
257  {
258  Real ray_distance = mouseRay.getDirection().crossProduct(pos - mouseRay.getOrigin()).length();
259  if (ray_distance < nearest_ray_distance)
260  {
261  nearest_ray_distance = ray_distance;
263  }
264  }
265  }
266  }
267  }
268 
269  // Reselect the vehicle orbit camera center
270  if (player_actor && App::GetCameraManager()->GetCurrentBehavior() == CameraManager::CAMERA_BEHAVIOR_VEHICLE)
271  {
272  Real nearest_camera_distance = std::numeric_limits<float>::max();
273  Real nearest_ray_distance = std::numeric_limits<float>::max();
274  NodeNum_t nearest_node_index = NODENUM_INVALID;
275 
276  for (int i = 0; i < player_actor->ar_num_nodes; i++)
277  {
278  Vector3 pos = player_actor->ar_nodes[i].AbsPosition;
279  std::pair<bool, Real> pair = mouseRay.intersects(Sphere(pos, 0.25f));
280  if (pair.first)
281  {
282  Real ray_distance = mouseRay.getDirection().crossProduct(pos - mouseRay.getOrigin()).length();
283  if (ray_distance < nearest_ray_distance || (ray_distance == nearest_ray_distance && pair.second < nearest_camera_distance))
284  {
285  nearest_camera_distance = pair.second;
286  nearest_ray_distance = ray_distance;
287  nearest_node_index = (NodeNum_t)i;
288  }
289  }
290  }
291  if (player_actor->ar_custom_camera_node != nearest_node_index)
292  {
293  player_actor->ar_custom_camera_node = nearest_node_index;
294  player_actor->calculateAveragePosition();
295  App::GetCameraManager()->NotifyContextChange(); // Reset last 'look at' pos
296  }
297  }
298  }
299 
300  return true;
301 }
302 
303 bool SceneMouse::mouseReleased(const OIS::MouseEvent& _arg, OIS::MouseButtonID _id)
304 {
305  if (App::sim_state->getEnum<SimState>() == SimState::PAUSED) { return true; } // Do nothing when paused
306 
307  if (mouseGrabState == 1)
308  {
310  }
311 
312  return true;
313 }
314 
316 {
317  Viewport* vp = App::GetCameraManager()->GetCamera()->getViewport();
318 
319  return App::GetCameraManager()->GetCamera()->getCameraToViewportRay((float)lastMouseX / (float)vp->getActualWidth(), (float)lastMouseY / (float)vp->getActualHeight());
320 }
GameContext.h
Game state manager and message-queue provider.
RoR::ActorLinkingRequest::alr_hook_group
int alr_hook_group
Definition: SimData.h:921
RoR::SceneMouse::lastMouseX
int lastMouseX
Definition: SceneMouse.h:62
RoR::SceneMouse::mousePressed
bool mousePressed(const OIS::MouseEvent &_arg, OIS::MouseButtonID _id)
Definition: SceneMouse.cpp:227
RoR::SceneMouse::mouseMoved
bool mouseMoved(const OIS::MouseEvent &_arg)
Definition: SceneMouse.cpp:114
RoR::SceneMouse::reset
void reset()
Definition: SceneMouse.cpp:101
RoR::SceneMouse::DiscardVisuals
void DiscardVisuals()
Definition: SceneMouse.cpp:75
RoR::App::GetCameraManager
CameraManager * GetCameraManager()
Definition: Application.cpp:275
RoR::node_t::AbsPosition
Ogre::Vector3 AbsPosition
absolute position in the world (shaky)
Definition: SimData.h:293
RoR::ActorLinkingRequest
Estabilishing a physics linkage between 2 actors modifies a global linkage table and triggers immedia...
Definition: SimData.h:916
RoR::GfxActor::GetSimNodeBuffer
NodeSB * GetSimNodeBuffer()
Definition: GfxActor.h:120
RoR::Actor::ar_instance_id
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Definition: Actor.h:370
RoR::Actor::ar_num_nodes
int ar_num_nodes
Definition: Actor.h:277
RoR::NODENUM_INVALID
static const NodeNum_t NODENUM_INVALID
Definition: ForwardDeclarations.h:53
RoR::ActorLinkingRequestType::HOOK_MOUSE_TOGGLE
@ HOOK_MOUSE_TOGGLE
RoR::Actor::mouseMove
void mouseMove(NodeNum_t node, Ogre::Vector3 pos, float force)
Definition: Actor.cpp:1343
RoR::ActorLinkingRequest::alr_type
ActorLinkingRequestType alr_type
Definition: SimData.h:919
RoR::SimState::EDITOR_MODE
@ EDITOR_MODE
Hacky, but whatever... added by Ulteq, 2016.
RoR::SceneMouse::UpdateSimulation
void UpdateSimulation()
Definition: SceneMouse.cpp:197
RoR::Actor::ar_hooks
std::vector< hook_t > ar_hooks
Definition: Actor.h:296
RoR::Actor::GetGfxActor
GfxActor * GetGfxActor()
Definition: Actor.h:263
RoR::ActorState::LOCAL_SIMULATED
@ LOCAL_SIMULATED
simulated (local) actor
RoR::App::sim_state
CVar * sim_state
Definition: Application.cpp:96
RefCountingObjectPtr< Actor >
RoR::SceneMouse::lastMouseY
int lastMouseY
Definition: SceneMouse.h:62
Actor.h
RoR::SceneMouse::mouseGrabState
int mouseGrabState
Definition: SceneMouse.h:56
RoR::GfxScene::GetSceneManager
Ogre::SceneManager * GetSceneManager()
Definition: GfxScene.h:64
RoR::CameraManager::NotifyContextChange
void NotifyContextChange()
Definition: CameraManager.cpp:613
RoR::SceneMouse::InitializeVisuals
void InitializeVisuals()
Definition: SceneMouse.cpp:50
RoR::CameraManager::GetCamera
Ogre::Camera * GetCamera()
Definition: CameraManager.h:64
RoR::NodeNum_t
uint16_t NodeNum_t
Node position within Actor::ar_nodes; use RoR::NODENUM_INVALID as empty value.
Definition: ForwardDeclarations.h:52
MOUSE_GRAB_FORCE
#define MOUSE_GRAB_FORCE
Definition: SceneMouse.cpp:39
RoR::MSG_SIM_SEAT_PLAYER_REQUESTED
@ MSG_SIM_SEAT_PLAYER_REQUESTED
Payload = RoR::ActorPtr (owner) | nullptr.
Definition: Application.h:122
ScriptEngine.h
RoR::GameContext::PushMessage
void PushMessage(Message m)
Doesn't guarantee order! Use ChainMessage() if order matters.
Definition: GameContext.cpp:66
RoR::SceneMouse::UpdateVisuals
void UpdateVisuals()
Definition: SceneMouse.cpp:210
GfxScene.h
RoR::CameraManager::CAMERA_BEHAVIOR_VEHICLE
@ CAMERA_BEHAVIOR_VEHICLE
Definition: CameraManager.h:48
RoR::SimState::PAUSED
@ PAUSED
Application.h
Central state/object manager and communications hub.
RoR::App::GetGameContext
GameContext * GetGameContext()
Definition: Application.cpp:280
RoR::SceneMouse::grab_truck
ActorPtr grab_truck
Definition: SceneMouse.h:60
RoR::SceneMouse::mindist
float mindist
Definition: SceneMouse.h:59
RoR::SceneMouse::getMouseRay
Ogre::Ray getMouseRay()
Definition: SceneMouse.cpp:315
RoR::SceneMouse::pickLine
Ogre::ManualObject * pickLine
Definition: SceneMouse.h:54
RoR::NodeSB::AbsPosition
Ogre::Vector3 AbsPosition
Definition: SimBuffers.h:69
RoR::Actor::ar_nodes
node_t * ar_nodes
Definition: Actor.h:273
RoR::SceneMouse::lastgrabpos
Ogre::Vector3 lastgrabpos
Definition: SceneMouse.h:61
RoR::MSG_SIM_ACTOR_LINKING_REQUESTED
@ MSG_SIM_ACTOR_LINKING_REQUESTED
Payload = RoR::ActorLinkingRequest* (owner)
Definition: Application.h:128
RoR::Message
Unified game event system - all requests and state changes are reported using a message.
Definition: GameContext.h:51
RoR::Actor::ar_custom_camera_node
NodeNum_t ar_custom_camera_node
Sim state; custom tracking node for 3rd-person camera.
Definition: Actor.h:418
RoR::SceneMouse::pickLineNode
Ogre::SceneNode * pickLineNode
Definition: SceneMouse.h:55
RoR::ActorPtr
RefCountingObjectPtr< Actor > ActorPtr
Definition: ForwardDeclarations.h:194
RoR::ActorLinkingRequest::alr_actor_instance_id
ActorInstanceID_t alr_actor_instance_id
Definition: SimData.h:918
RoR::SceneMouse::mouseReleased
bool mouseReleased(const OIS::MouseEvent &_arg, OIS::MouseButtonID _id)
Definition: SceneMouse.cpp:303
RoR::ActorLinkingRequest::alr_hook_mousenode
NodeNum_t alr_hook_mousenode
Definition: SimData.h:922
Ogre
Definition: ExtinguishableFireAffector.cpp:35
RoR::Actor::calculateAveragePosition
void calculateAveragePosition()
Definition: Actor.cpp:1133
RoR::SceneMouse::releaseMousePick
void releaseMousePick()
Definition: SceneMouse.cpp:90
SceneMouse.h
Mouse interaction with 3D scene.
RoR::SceneMouse::minnode
NodeNum_t minnode
Definition: SceneMouse.h:58
RoR::GameContext::GetPlayerActor
const ActorPtr & GetPlayerActor()
Definition: GameContext.h:134
RoR
Definition: AppContext.h:36
RoR::App::GetGfxScene
GfxScene * GetGfxScene()
Definition: Application.cpp:276