Revision: 8681
http://playerstage.svn.sourceforge.net/playerstage/?rev=8681&view=rev
Author: natepak
Date: 2010-05-14 21:48:52 +0000 (Fri, 14 May 2010)
Log Message:
-----------
added more generic mouse handling
Modified Paths:
--------------
code/gazebo/trunk/benchmarks/CMakeLists.txt
code/gazebo/trunk/server/gui/BoxMaker.cc
code/gazebo/trunk/server/gui/BoxMaker.hh
code/gazebo/trunk/server/gui/CMakeLists.txt
code/gazebo/trunk/server/gui/CylinderMaker.cc
code/gazebo/trunk/server/gui/CylinderMaker.hh
code/gazebo/trunk/server/gui/GLWindow.cc
code/gazebo/trunk/server/gui/GLWindow.hh
code/gazebo/trunk/server/gui/SphereMaker.cc
code/gazebo/trunk/server/gui/SphereMaker.hh
code/gazebo/trunk/server/rendering/CMakeLists.txt
code/gazebo/trunk/server/rendering/OgreAdaptor.cc
code/gazebo/trunk/server/rendering/OgreCamera.cc
code/gazebo/trunk/server/rendering/OgreCamera.hh
code/gazebo/trunk/server/rendering/UserCamera.cc
Added Paths:
-----------
code/gazebo/trunk/benchmarks/spinningbox_benchmark.cc
code/gazebo/trunk/server/gui/MouseEvent.hh
code/gazebo/trunk/server/rendering/FPSViewController.cc
code/gazebo/trunk/server/rendering/FPSViewController.hh
code/gazebo/trunk/server/rendering/ViewController.cc
code/gazebo/trunk/server/rendering/ViewController.hh
code/gazebo/trunk/worlds/single_box.world
Modified: code/gazebo/trunk/benchmarks/CMakeLists.txt
===================================================================
--- code/gazebo/trunk/benchmarks/CMakeLists.txt 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/benchmarks/CMakeLists.txt 2010-05-14 21:48:52 UTC (rev
8681)
@@ -25,7 +25,9 @@
box_grid_benchmark.cc
box_pile_benchmark.cc
joint_chain_benchmark.cc
- camera_benchmark.cc)
+ camera_benchmark.cc
+ spinningbox_benchmark.cc
+ )
set_source_files_properties(${sources} PROPERTIES COMPILE_FLAGS "-ggdb -g2
-Wall")
@@ -34,25 +36,29 @@
add_executable(box_grid_benchmark box_grid_benchmark.cc)
add_executable(joint_chain_benchmark joint_chain_benchmark.cc)
add_executable(camera_benchmark camera_benchmark.cc)
+add_executable(spinningbox_benchmark spinningbox_benchmark.cc)
target_link_libraries(laser_benchmark gazebo ${LINK_LIBS} )
target_link_libraries(box_grid_benchmark gazebo ${LINK_LIBS} )
target_link_libraries(box_pile_benchmark gazebo ${LINK_LIBS} )
target_link_libraries(joint_chain_benchmark gazebo ${LINK_LIBS} )
target_link_libraries(camera_benchmark gazebo ${LINK_LIBS} )
+target_link_libraries(spinningbox_benchmark gazebo ${LINK_LIBS} )
set_target_properties(laser_benchmark PROPERTIES SKIP_BUILD_RPATH TRUE)
set_target_properties(box_grid_benchmark PROPERTIES SKIP_BUILD_RPATH TRUE)
set_target_properties(box_pile_benchmark PROPERTIES SKIP_BUILD_RPATH TRUE)
set_target_properties(joint_chain_benchmark PROPERTIES SKIP_BUILD_RPATH TRUE)
set_target_properties(camera_benchmark PROPERTIES SKIP_BUILD_RPATH TRUE)
+set_target_properties(spinningbox_benchmark PROPERTIES SKIP_BUILD_RPATH
TRUE)
set_target_properties(laser_benchmark PROPERTIES LINK_FLAGS
"${LINK_FLAGS} ${gazebo_lflags}")
set_target_properties(box_grid_benchmark PROPERTIES LINK_FLAGS
"${LINK_FLAGS} ${gazebo_lflags}")
set_target_properties(box_pile_benchmark PROPERTIES LINK_FLAGS
"${LINK_FLAGS} ${gazebo_lflags}")
set_target_properties(joint_chain_benchmark PROPERTIES LINK_FLAGS
"${LINK_FLAGS} ${gazebo_lflags}")
set_target_properties(camera_benchmark PROPERTIES LINK_FLAGS
"${LINK_FLAGS} ${gazebo_lflags}")
+set_target_properties(spinningbox_benchmark PROPERTIES LINK_FLAGS
"${LINK_FLAGS} ${gazebo_lflags}")
-install (TARGETS laser_benchmark box_grid_benchmark box_pile_benchmark
joint_chain_benchmark camera_benchmark DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
+install (TARGETS laser_benchmark box_grid_benchmark box_pile_benchmark
joint_chain_benchmark camera_benchmark spinningbox_benchmark DESTINATION
${CMAKE_INSTALL_PREFIX}/bin)
Added: code/gazebo/trunk/benchmarks/spinningbox_benchmark.cc
===================================================================
--- code/gazebo/trunk/benchmarks/spinningbox_benchmark.cc
(rev 0)
+++ code/gazebo/trunk/benchmarks/spinningbox_benchmark.cc 2010-05-14
21:48:52 UTC (rev 8681)
@@ -0,0 +1,98 @@
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <vector>
+#include <libgazebo/gz.h>
+
+gazebo::Client *client = NULL;
+gazebo::SimulationIface *simIface = NULL;
+
+std::string test_name="Spinning Box Benchmark";
+std::string xlabel = "Spinning Box Count";
+std::string ylabel = "Simtime / Realtime";
+std::string data_filename = "/tmp/" + test_name + ".data";
+
+void make_plot()
+{
+ std::ostringstream cmd;
+
+ cmd << "echo \"";
+ cmd << "set xlabel '" << xlabel << "'\n";
+ cmd << "set ylabel '" << ylabel << "'\n";
+ cmd << "set title '" << test_name << "'\n";
+ cmd << "set terminal png\n";
+ cmd << "set output '" << test_name << ".png'\n";
+ cmd << "plot '" << data_filename << "' with lines\n";
+ cmd << "\" | gnuplot";
+
+ if (system(cmd.str().c_str() ) < 0)
+ std::cerr << "Error\n";
+}
+
+int main(int argc, char **argv)
+{
+ client = new gazebo::Client();
+ simIface = new gazebo::SimulationIface();
+
+ float vel = 1.0;
+ if (argc > 1)
+ vel = atof(argv[1]);
+
+ try
+ {
+ client->ConnectWait(0, GZ_CLIENT_ID_USER_FIRST);
+ }
+ catch(std::string e)
+ {
+ std::cerr << "Gazebo Error: Unable to connect: " << e << "\n";
+ return -1;
+ }
+
+ /// Open the sim iface
+ try
+ {
+ simIface->Open(client, "default");
+ }
+ catch (std::string e)
+ {
+ std::cerr << "Gazebo error: Unable to connect to sim iface:" << e << "\n";
+ return -1;
+ }
+
+ //FILE *out = fopen(data_filename.c_str(), "w");
+
+ /*if (!out)
+ std::cerr << "Unable to open log file";
+ */
+
+ //double simTime = 0;
+ //double realTime = 0;
+
+
+ gazebo::Vec3 linearVel, angularVel, linearAccel, angularAccel;
+ gazebo::Pose modelPose;
+
+ bool done = false;
+ while (!done)
+ {
+ simIface->SetAngularVel("box_model", gazebo::Vec3(0,0,vel));
+
+ simIface->GetState("box_model", modelPose, linearVel, angularVel,
+ linearAccel, angularAccel);
+ printf("Pos[%4.2f %4.2f %4.2f] RPY[%4.2f %4.2f %4.2f] ", modelPose.pos.x,
modelPose.pos.y, modelPose.pos.z, modelPose.roll, modelPose.pitch,
modelPose.yaw);
+ printf("LV[%4.2f %4.2f %4.2f] ",linearVel.x, linearVel.y, linearVel.z );
+ printf("AV[%4.2f %4.2f %4.2f] ",angularVel.x, angularVel.y, angularVel.z);
+ printf("LA[%4.2f %4.2f %4.2f] ",linearAccel.x, linearAccel.y,
linearAccel.z);
+ printf("AA[%4.2f %4.2f %4.2f]\n",angularAccel.x, angularAccel.y,
angularAccel.z );
+ }
+
+ //double percent = simTime / realTime;
+ //fprintf(out,"%f\n",percent);
+
+ //fclose(out);
+
+ //make_plot();
+
+ simIface->Close();
+ client->Disconnect();
+}
Modified: code/gazebo/trunk/server/gui/BoxMaker.cc
===================================================================
--- code/gazebo/trunk/server/gui/BoxMaker.cc 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/server/gui/BoxMaker.cc 2010-05-14 21:48:52 UTC (rev
8681)
@@ -1,6 +1,7 @@
#include <iostream>
#include <FL/Fl.H>
+#include "MouseEvent.hh"
#include "Simulator.hh"
#include "GLWindow.hh"
#include "OgreVisual.hh"
@@ -16,7 +17,6 @@
{
this->state = 0;
this->visualName = "";
- this->leftMousePressed = false;
this->index = 0;
}
@@ -54,24 +54,15 @@
return this->state > 0;
}
-void BoxMaker::MousePushCB(Vector2<int> mousePos)
+void BoxMaker::MousePushCB(const MouseEvent &event)
{
if (this->state == 0)
return;
- this->leftMousePressed = false;
-
- this->mousePushPos = mousePos;
-
- switch (Fl::event_button())
- {
- case FL_LEFT_MOUSE:
- this->leftMousePressed = true;
- break;
- }
+ this->mousePushPos = event.pressPos;
}
-void BoxMaker::MouseReleaseCB(Vector2<int> mousePos)
+void BoxMaker::MouseReleaseCB(const MouseEvent &event)
{
if (this->state == 0)
return;
@@ -85,23 +76,16 @@
}
}
-void BoxMaker::MouseDragCB(Vector2<int> mousePos)
+void BoxMaker::MouseDragCB(const MouseEvent &event)
{
if (this->state == 0)
return;
- Vector3 norm;
+ Vector3 norm(0,0,1);
Vector3 p1, p2;
- //if (this->state == 1)
- norm.Set(0,0,1);
- /*else if (this->state == 2)
- {
- norm = CameraManager::Instance()->GetActiveCamera()->GetDirection();
- }*/
-
p1 = GLWindow::GetWorldPointOnPlane(this->mousePushPos.x,
this->mousePushPos.y, norm, 0);
- p2 = GLWindow::GetWorldPointOnPlane(mousePos.x, mousePos.y ,norm, 0);
+ p2 = GLWindow::GetWorldPointOnPlane(event.pos.x, event.pos.y ,norm, 0);
OgreVisual *vis = NULL;
if (OgreCreator::Instance()->GetVisual(this->visualName))
@@ -125,7 +109,7 @@
else
{
scale = vis->GetScale();
- scale.z = (this->mousePushPos.y - mousePos.y)*0.01;
+ scale.z = (this->mousePushPos.y - event.pos.y)*0.01;
p.z = scale.z/2.0;
}
Modified: code/gazebo/trunk/server/gui/BoxMaker.hh
===================================================================
--- code/gazebo/trunk/server/gui/BoxMaker.hh 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/server/gui/BoxMaker.hh 2010-05-14 21:48:52 UTC (rev
8681)
@@ -5,6 +5,8 @@
namespace gazebo
{
+ class MouseEvent;
+
class BoxMaker
{
public: BoxMaker();
@@ -14,9 +16,9 @@
public: void Stop();
public: bool IsActive() const;
- public: void MousePushCB(Vector2<int> mousePos);
- public: void MouseReleaseCB(Vector2<int> mousePos);
- public: void MouseDragCB(Vector2<int> mousePos);
+ public: void MousePushCB(const MouseEvent &event);
+ public: void MouseReleaseCB(const MouseEvent &event);
+ public: void MouseDragCB(const MouseEvent &event);
private: void CreateTheBox();
private: int state;
Modified: code/gazebo/trunk/server/gui/CMakeLists.txt
===================================================================
--- code/gazebo/trunk/server/gui/CMakeLists.txt 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/server/gui/CMakeLists.txt 2010-05-14 21:48:52 UTC (rev
8681)
@@ -21,7 +21,6 @@
BoxMaker.cc
SphereMaker.cc
CylinderMaker.cc
- HingeJointMaker.cc
Events.cc
)
@@ -36,8 +35,8 @@
BoxMaker.hh
SphereMaker.hh
CylinderMaker.hh
- HingeJointMaker.hh
Events.hh
+ MouseEvent.hh
)
LIST_TO_STRING(GAZEBO_CFLAGS "${gazeboserver_cflags}")
Modified: code/gazebo/trunk/server/gui/CylinderMaker.cc
===================================================================
--- code/gazebo/trunk/server/gui/CylinderMaker.cc 2010-05-14 17:38:12 UTC
(rev 8680)
+++ code/gazebo/trunk/server/gui/CylinderMaker.cc 2010-05-14 21:48:52 UTC
(rev 8681)
@@ -1,6 +1,7 @@
#include <iostream>
#include <FL/Fl.H>
+#include "MouseEvent.hh"
#include "Simulator.hh"
#include "GLWindow.hh"
#include "OgreVisual.hh"
@@ -14,7 +15,6 @@
{
this->state = 0;
this->visualName = "";
- this->leftMousePressed = false;
this->index = 0;
}
@@ -52,24 +52,15 @@
return this->state > 0;
}
-void CylinderMaker::MousePushCB(Vector2<int> mousePos)
+void CylinderMaker::MousePushCB(const MouseEvent &event)
{
if (this->state == 0)
return;
- this->leftMousePressed = false;
-
- this->mousePushPos = mousePos;
-
- switch (Fl::event_button())
- {
- case FL_LEFT_MOUSE:
- this->leftMousePressed = true;
- break;
- }
+ this->mousePushPos = event.pressPos;
}
-void CylinderMaker::MouseReleaseCB(Vector2<int> mousePos)
+void CylinderMaker::MouseReleaseCB(const MouseEvent &event)
{
if (this->state == 0)
return;
@@ -83,7 +74,7 @@
}
}
-void CylinderMaker::MouseDragCB(Vector2<int> mousePos)
+void CylinderMaker::MouseDragCB(const MouseEvent &event)
{
if (this->state == 0)
return;
@@ -97,7 +88,7 @@
norm.Set(1,0,0);
p1 = GLWindow::GetWorldPointOnPlane(this->mousePushPos.x,
this->mousePushPos.y, norm, 0);
- p2 = GLWindow::GetWorldPointOnPlane(mousePos.x, mousePos.y ,norm, 0);
+ p2 = GLWindow::GetWorldPointOnPlane(event.pos.x, event.pos.y ,norm, 0);
OgreVisual *vis = NULL;
if (OgreCreator::Instance()->GetVisual(this->visualName))
@@ -123,7 +114,7 @@
{
scale = vis->GetScale();
// scale.z = p2.z - p1.z;
- scale.z = (this->mousePushPos.y - mousePos.y)*0.01;
+ scale.z = (this->mousePushPos.y - event.pos.y)*0.01;
p.z = scale.z/2.0;
}
Modified: code/gazebo/trunk/server/gui/CylinderMaker.hh
===================================================================
--- code/gazebo/trunk/server/gui/CylinderMaker.hh 2010-05-14 17:38:12 UTC
(rev 8680)
+++ code/gazebo/trunk/server/gui/CylinderMaker.hh 2010-05-14 21:48:52 UTC
(rev 8681)
@@ -5,6 +5,8 @@
namespace gazebo
{
+ class MouseEvent;
+
class CylinderMaker
{
public: CylinderMaker();
@@ -14,9 +16,9 @@
public: void Stop();
public: bool IsActive() const;
- public: void MousePushCB(Vector2<int> mousePos);
- public: void MouseReleaseCB(Vector2<int> mousePos);
- public: void MouseDragCB(Vector2<int> mousePos);
+ public: void MousePushCB(const MouseEvent &event);
+ public: void MouseReleaseCB(const MouseEvent &event);
+ public: void MouseDragCB(const MouseEvent &event);
private: void CreateTheCylinder();
private: int state;
Modified: code/gazebo/trunk/server/gui/GLWindow.cc
===================================================================
--- code/gazebo/trunk/server/gui/GLWindow.cc 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/server/gui/GLWindow.cc 2010-05-14 21:48:52 UTC (rev
8681)
@@ -72,15 +72,10 @@
this->userCamera = NULL;
this->moveAmount = 0.1;
- this->moveScale = 1;
- this->rotateAmount = 0.1;
this->directionVec.x = 0;
this->directionVec.y = 0;
this->directionVec.z = 0;
- this->leftMousePressed = false;
- this->rightMousePressed = false;
- this->middleMousePressed = false;
this->keys.clear();
@@ -125,7 +120,6 @@
{
this->show();
Fl::check();
- this->mouseDrag = false;
if (this->userCamera == NULL)
{
@@ -166,18 +160,8 @@
// Update function
void GLWindow::Update()
{
- if (this->activeCamera && this->activeCamera->GetUserMovable())
- {
- Time diff = Simulator::Instance()->GetRealTime() - this->lastUpdateTime;
- this->activeCamera->Translate( this->directionVec * diff.Double() );
- this->directionVec.Set(0,0,0);
- }
-
-
- this->lastUpdateTime = Simulator::Instance()->GetRealTime();
}
-
////////////////////////////////////////////////////////////////////////////////
/// Get a pointer to the camera
UserCamera *GLWindow::GetCamera() const
@@ -203,36 +187,36 @@
/// Handle a mouse button push
void GLWindow::HandleMousePush()
{
- this->mousePushPos = this->mousePos;
+ this->mouseEvent.pressPos = this->mouseEvent.pos;
- this->boxMaker.MousePushCB(this->mousePos);
- this->sphereMaker.MousePushCB(this->mousePos);
- this->cylinderMaker.MousePushCB(this->mousePos);
- this->hingeJointMaker.MousePushCB(this->mousePos);
+ this->boxMaker.MousePushCB(this->mouseEvent);
+ this->sphereMaker.MousePushCB(this->mouseEvent);
+ this->cylinderMaker.MousePushCB(this->mouseEvent);
if (this->boxMaker.IsActive() || this->sphereMaker.IsActive() ||
- this->cylinderMaker.IsActive() || this->hingeJointMaker.IsActive())
+ this->cylinderMaker.IsActive())
return;
if (World::Instance()->GetSelectedEntity())
{
OgreAdaptor::Instance()->GetEntityAt(this->activeCamera,
- this->mousePos, this->mouseModifier);
+ this->mouseEvent.pos,
+ this->mouseModifier);
}
// Get the mouse button that was pressed (if one was pressed)
switch (Fl::event_button())
{
case FL_LEFT_MOUSE:
- this->leftMousePressed = true;
+ this->mouseEvent.left = MouseEvent::DOWN;
break;
case FL_RIGHT_MOUSE:
- this->rightMousePressed = true;
+ this->mouseEvent.right = MouseEvent::DOWN;
break;
case FL_MIDDLE_MOUSE:
- this->middleMousePressed = true;
+ this->mouseEvent.middle = MouseEvent::DOWN;
break;
}
}
@@ -244,35 +228,34 @@
OgreCreator::SetVisible("guiline", false);
- this->boxMaker.MouseReleaseCB(this->mousePos);
- this->sphereMaker.MouseReleaseCB(this->mousePos);
- this->cylinderMaker.MouseReleaseCB(this->mousePos);
- this->hingeJointMaker.MouseReleaseCB(this->mousePos);
+ this->boxMaker.MouseReleaseCB(this->mouseEvent);
+ this->sphereMaker.MouseReleaseCB(this->mouseEvent);
+ this->cylinderMaker.MouseReleaseCB(this->mouseEvent);
if (this->boxMaker.IsActive() || this->sphereMaker.IsActive() ||
- this->cylinderMaker.IsActive() || this->hingeJointMaker.IsActive())
+ this->cylinderMaker.IsActive())
return;
// Get the mouse button that was pressed (if one was pressed)
switch (Fl::event_button())
{
case FL_LEFT_MOUSE:
- this->leftMousePressed = false;
+ this->mouseEvent.left = MouseEvent::UP;
break;
case FL_RIGHT_MOUSE:
- this->rightMousePressed = false;
+ this->mouseEvent.right = MouseEvent::UP;
break;
case FL_MIDDLE_MOUSE:
- this->middleMousePressed = false;
+ this->mouseEvent.middle = MouseEvent::UP;
break;
}
- if (!this->mouseDrag && this->GetCursorState() == "manip")
+ if (!this->mouseEvent.dragging && this->GetCursorState() == "manip")
{
Entity *entity = OgreAdaptor::Instance()->GetEntityAt(this->activeCamera,
- this->mousePos, this->mouseModifier);
+ this->mouseEvent.pos,
this->mouseModifier);
Model *model = Simulator::Instance()->GetParentModel(entity);
Body *body = Simulator::Instance()->GetParentBody(entity);
@@ -282,13 +265,11 @@
case FL_LEFT_MOUSE:
if (model)
World::Instance()->SetSelectedEntity( model );
- this->mouseOriginPos = Vector2<int>( Fl::event_x(), Fl::event_y() );
break;
case FL_RIGHT_MOUSE:
if (body)
World::Instance()->SetSelectedEntity( body );
- this->mouseOriginPos = Vector2<int>( Fl::event_x(), Fl::event_y() );
break;
case FL_MIDDLE_MOUSE:
@@ -296,7 +277,7 @@
}
}
- this->mouseDrag = false;
+ this->mouseEvent.dragging = false;
}
////////////////////////////////////////////////////////////////////////////////
@@ -306,23 +287,22 @@
// stop simulation when this is happening
boost::recursive_mutex::scoped_lock
lock(*Simulator::Instance()->GetMRMutex());
- this->mouseDrag = true;
+ this->mouseEvent.dragging = true;
- this->boxMaker.MouseDragCB(this->mousePos);
- this->sphereMaker.MouseDragCB(this->mousePos);
- this->cylinderMaker.MouseDragCB(this->mousePos);
- this->hingeJointMaker.MouseDragCB(this->mousePos);
+ this->boxMaker.MouseDragCB(this->mouseEvent);
+ this->sphereMaker.MouseDragCB(this->mouseEvent);
+ this->cylinderMaker.MouseDragCB(this->mouseEvent);
if (this->boxMaker.IsActive() || this->sphereMaker.IsActive() ||
- this->cylinderMaker.IsActive() || this->hingeJointMaker.IsActive())
+ this->cylinderMaker.IsActive())
return;
- if (this->activeCamera && this->activeCamera->GetUserMovable())
+ if (this->activeCamera)
{
- Vector2<int> drag = this->mousePos - this->prevMousePos;
+ Vector2<int> drag = this->mouseEvent.pos - this->mouseEvent.prevPos;
Entity *entity = World::Instance()->GetSelectedEntity();
- if (this->leftMousePressed)
+ if (this->mouseEvent.left == MouseEvent::DOWN)
{
if ( entity && (entity->GetType() == Entity::MODEL ||
entity->GetType() == Entity::BODY) &&
@@ -335,27 +315,16 @@
}
else if(this->GetCursorState() == "default")
{
- //
- // interactively rotate view
- //
- this->activeCamera->RotateYaw(DTOR(drag.x * this->rotateAmount));
- this->activeCamera->RotatePitch(DTOR(-drag.y * this->rotateAmount));
+ this->activeCamera->HandleMouseEvent( this->mouseEvent );
}
}
- else if (this->rightMousePressed && this->GetCursorState() == "default")
+ else if (this->mouseEvent.right == MouseEvent::DOWN &&
this->GetCursorState() == "default")
{
- //
- // interactively pan view
- //
- this->directionVec.x = 0;
- this->directionVec.y = drag.x * this->moveAmount;
- this->directionVec.z = drag.y * this->moveAmount;
+ this->activeCamera->HandleMouseEvent( this->mouseEvent );
}
- else if (this->middleMousePressed && this->GetCursorState() == "default")
+ else if (this->mouseEvent.middle == MouseEvent::DOWN &&
this->GetCursorState() == "default")
{
- this->directionVec.x = drag.y * this->moveAmount;
- this->directionVec.y = 0;
- this->directionVec.z = 0;
+ this->activeCamera->HandleMouseEvent( this->mouseEvent );
}
}
}
@@ -367,12 +336,13 @@
// stop simulation when this is happening
boost::recursive_mutex::scoped_lock
lock(*Simulator::Instance()->GetMRMutex());
- if (this->activeCamera && this->activeCamera->GetUserMovable() &&
- this->GetCursorState() == "default")
+ this->mouseEvent.scroll.x = dx;
+ this->mouseEvent.scroll.y = dy;
+ this->mouseEvent.middle = MouseEvent::SCROLL;
+
+ if (this->activeCamera && this->GetCursorState() == "default")
{
- this->directionVec.x -= 50.0 * dy * this->moveAmount;
- this->directionVec.y = 0;
- this->directionVec.z = 0;
+ this->activeCamera->HandleMouseEvent(this->mouseEvent);
}
}
@@ -381,7 +351,7 @@
void GLWindow::HandleKeyPress(int keyNum)
{
if (this->boxMaker.IsActive() || this->sphereMaker.IsActive() ||
- this->cylinderMaker.IsActive() || this->hingeJointMaker.IsActive())
+ this->cylinderMaker.IsActive())
return;
std::map<int,int>::iterator iter;
@@ -501,7 +471,8 @@
bool handled = false;
// Get the mouse position
- this->mousePos = Vector2<int>( Fl::event_x(), Fl::event_y() );
+ this->mouseEvent.pos.x = Fl::event_x();
+ this->mouseEvent.pos.y = Fl::event_y();
// Handle Events
switch(event)
@@ -533,7 +504,7 @@
break;
case FL_DRAG:
- if (this->prevMousePos.Distance(this->mousePos) > 0)
+ if (this->mouseEvent.prevPos.Distance(this->mouseEvent.pos) > 0)
this->HandleMouseDrag();
handled = true;
break;
@@ -568,7 +539,7 @@
break;
}
- this->prevMousePos = this->mousePos;
+ this->mouseEvent.prevPos = this->mouseEvent.pos;
if (Fl::event_key() == FL_Escape)
{
@@ -682,11 +653,11 @@
planeNorm = modelPose.rot.RotateVector(ray);
double d = -modelPose.pos.GetDotProd(planeNorm);
- p1 = this->GetWorldPointOnPlane( this->mousePos.x, this->mousePos.y,
- planeNorm, d);
+ p1 = this->GetWorldPointOnPlane( this->mouseEvent.pos.x,
+ this->mouseEvent.pos.y, planeNorm, d);
- p2 = this->GetWorldPointOnPlane( this->prevMousePos.x,
- this->prevMousePos.y, planeNorm, d);
+ p2 = this->GetWorldPointOnPlane( this->mouseEvent.prevPos.x,
+ this->mouseEvent.prevPos.y, planeNorm, d);
OgreCreator::DrawLine(entity->GetAbsPose().pos,p1, "guiline");
@@ -736,10 +707,10 @@
Vector3 origin2, dir2, p2;
// Cast two rays from the camera into the world
- this->activeCamera->GetCameraToViewportRay(this->mousePos.x,
- this->mousePos.y, origin1, dir1);
- this->activeCamera->GetCameraToViewportRay(this->prevMousePos.x,
- this->prevMousePos.y, origin2, dir2);
+ this->activeCamera->GetCameraToViewportRay(this->mouseEvent.pos.x,
+ this->mouseEvent.pos.y, origin1, dir1);
+ this->activeCamera->GetCameraToViewportRay(this->mouseEvent.prevPos.x,
+ this->mouseEvent.prevPos.y, origin2, dir2);
Vector3 moveVector(0,0,0);
Vector3 planeNorm(0,0,1);
@@ -786,7 +757,6 @@
this->boxMaker.Stop();
this->sphereMaker.Stop();
this->cylinderMaker.Stop();
- this->hingeJointMaker.Stop();
this->SetCursorState("create");
@@ -799,8 +769,6 @@
this->cylinderMaker.Start();
else if (name == "sphere")
this->sphereMaker.Start();
- else if (name == "hingejoint")
- this->hingeJointMaker.Start();
else
this->SetCursorState("default");
}
Modified: code/gazebo/trunk/server/gui/GLWindow.hh
===================================================================
--- code/gazebo/trunk/server/gui/GLWindow.hh 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/server/gui/GLWindow.hh 2010-05-14 21:48:52 UTC (rev
8681)
@@ -46,7 +46,7 @@
#include "SphereMaker.hh"
#include "BoxMaker.hh"
#include "CylinderMaker.hh"
-#include "HingeJointMaker.hh"
+#include "MouseEvent.hh"
namespace gazebo
{
@@ -156,34 +156,19 @@
/// Pointer to the Xvisual
private: XVisualInfo *visual;
- /// colormap
- private: Colormap colormap;
-
/// pointer to the display
private: Display *display;
private: float moveAmount;
- private: float moveScale;
- private: float rotateAmount;
-
private: Vector3 directionVec;
- private: bool leftMousePressed;
- private: bool rightMousePressed;
- private: bool middleMousePressed;
- private: Vector2<int> prevMousePos;
- private: Vector2<int> mousePushPos;
- private: Vector2<int> mousePos;
- private: Vector2<int> mouseOriginPos; // for applying external forces
- private: Vector3 forceVec; // for applying external forces
- private: Vector3 torqueVec; // for applying external forces
+ private: MouseEvent mouseEvent;
+
private: std::map<int,int> keys;
private: Time lastUpdateTime;
- private: bool mouseDrag;
-
/// Pointer to the camera
private: UserCamera *userCamera;
private: OgreCamera *activeCamera;
@@ -195,7 +180,6 @@
private: BoxMaker boxMaker;
private: SphereMaker sphereMaker;
private: CylinderMaker cylinderMaker;
- private: HingeJointMaker hingeJointMaker;
private: std::string cursorState;
Added: code/gazebo/trunk/server/gui/MouseEvent.hh
===================================================================
--- code/gazebo/trunk/server/gui/MouseEvent.hh (rev 0)
+++ code/gazebo/trunk/server/gui/MouseEvent.hh 2010-05-14 21:48:52 UTC (rev
8681)
@@ -0,0 +1,29 @@
+#ifndef MOUSEEVENT_HH
+#define MOUSEEVENT_HH
+
+#include "Vector2.hh"
+
+namespace gazebo
+{
+ class MouseEvent
+ {
+ public: enum ButtonState {DOWN, UP, SCROLL};
+
+ public: MouseEvent()
+ : pos(0,0), prevPos(0,0), pressPos(0,0), scroll(0,0),
+ dragging(false), left(UP), right(UP), middle(UP)
+ {}
+
+ public: Vector2<int> pos;
+ public: Vector2<int> prevPos;
+ public: Vector2<int> pressPos;
+ public: Vector2<int> scroll;
+
+ public: bool dragging;
+
+ public: ButtonState left;
+ public: ButtonState right;
+ public: ButtonState middle;
+ };
+};
+#endif
Modified: code/gazebo/trunk/server/gui/SphereMaker.cc
===================================================================
--- code/gazebo/trunk/server/gui/SphereMaker.cc 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/server/gui/SphereMaker.cc 2010-05-14 21:48:52 UTC (rev
8681)
@@ -1,6 +1,7 @@
#include <iostream>
#include <FL/Fl.H>
+#include "MouseEvent.hh"
#include "Simulator.hh"
#include "GLWindow.hh"
#include "OgreVisual.hh"
@@ -14,7 +15,6 @@
{
this->state = 0;
this->visualName = "";
- this->leftMousePressed = false;
this->index = 0;
}
@@ -52,24 +52,15 @@
return this->state > 0;
}
-void SphereMaker::MousePushCB(Vector2<int> mousePos)
+void SphereMaker::MousePushCB(const MouseEvent &event)
{
if (this->state == 0)
return;
- this->leftMousePressed = false;
-
- this->mousePushPos = mousePos;
-
- switch (Fl::event_button())
- {
- case FL_LEFT_MOUSE:
- this->leftMousePressed = true;
- break;
- }
+ this->mousePushPos = event.pressPos;
}
-void SphereMaker::MouseReleaseCB(Vector2<int> mousePos)
+void SphereMaker::MouseReleaseCB(const MouseEvent &event)
{
if (this->state == 0)
return;
@@ -83,7 +74,7 @@
}
}
-void SphereMaker::MouseDragCB(Vector2<int> mousePos)
+void SphereMaker::MouseDragCB(const MouseEvent &event)
{
if (this->state == 0)
return;
@@ -94,7 +85,7 @@
norm.Set(0,0,1);
p1 = GLWindow::GetWorldPointOnPlane(this->mousePushPos.x,
this->mousePushPos.y, norm, 0);
- p2 = GLWindow::GetWorldPointOnPlane(mousePos.x, mousePos.y ,norm, 0);
+ p2 = GLWindow::GetWorldPointOnPlane(event.pos.x, event.pos.y ,norm, 0);
OgreVisual *vis = NULL;
if (OgreCreator::Instance()->GetVisual(this->visualName))
Modified: code/gazebo/trunk/server/gui/SphereMaker.hh
===================================================================
--- code/gazebo/trunk/server/gui/SphereMaker.hh 2010-05-14 17:38:12 UTC (rev
8680)
+++ code/gazebo/trunk/server/gui/SphereMaker.hh 2010-05-14 21:48:52 UTC (rev
8681)
@@ -5,6 +5,8 @@
namespace gazebo
{
+ class MouseEvent;
+
class SphereMaker
{
public: SphereMaker();
@@ -14,9 +16,9 @@
public: void Stop();
public: bool IsActive() const;
- public: void MousePushCB(Vector2<int> mousePos);
- public: void MouseReleaseCB(Vector2<int> mousePos);
- public: void MouseDragCB(Vector2<int> mousePos);
+ public: void MousePushCB(const MouseEvent &event);
+ public: void MouseReleaseCB(const MouseEvent &event);
+ public: void MouseDragCB(const MouseEvent &event);
private: void CreateTheSphere();
private: int state;
Modified: code/gazebo/trunk/server/rendering/CMakeLists.txt
===================================================================
--- code/gazebo/trunk/server/rendering/CMakeLists.txt 2010-05-14 17:38:12 UTC
(rev 8680)
+++ code/gazebo/trunk/server/rendering/CMakeLists.txt 2010-05-14 21:48:52 UTC
(rev 8681)
@@ -23,6 +23,8 @@
Light.cc
RTShaderSystem.cc
SelectionObj.cc
+ ViewController.cc
+ FPSViewController.cc
)
set (headers OgreMovableText.hh
@@ -43,6 +45,8 @@
Light.hh
RTShaderSystem.hh
SelectionObj.hh
+ ViewController.hh
+ FPSViewController.hh
)
add_library(gazebo_rendering SHARED ${sources})
Added: code/gazebo/trunk/server/rendering/FPSViewController.cc
===================================================================
--- code/gazebo/trunk/server/rendering/FPSViewController.cc
(rev 0)
+++ code/gazebo/trunk/server/rendering/FPSViewController.cc 2010-05-14
21:48:52 UTC (rev 8681)
@@ -0,0 +1,70 @@
+#include "Simulator.hh"
+#include "Global.hh"
+#include "OgreCamera.hh"
+#include "Vector2.hh"
+#include "MouseEvent.hh"
+#include "FPSViewController.hh"
+
+using namespace gazebo;
+
+////////////////////////////////////////////////////////////////////////////////
+/// Constructor
+FPSViewController::FPSViewController(OgreCamera *camera)
+ : ViewController(camera)
+{
+ this->directionVec.x = 0;
+ this->directionVec.y = 0;
+ this->directionVec.z = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Destructor
+FPSViewController::~FPSViewController()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Update
+void FPSViewController::Update()
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Handle a mouse event
+void FPSViewController::HandleMouseEvent(const MouseEvent &event)
+{
+ if (!this->camera->GetUserMovable())
+ return;
+
+ Vector2<int> drag = event.pos - event.prevPos;
+
+ this->directionVec.Set(0,0,0);
+
+ if (event.left == MouseEvent::DOWN)
+ {
+ this->camera->RotateYaw(DTOR(drag.x * 0.1));
+ this->camera->RotatePitch(DTOR(-drag.y * 0.1));
+ }
+ else if (event.right == MouseEvent::DOWN)
+ {
+ // interactively pan view
+ this->directionVec.x = 0;
+ this->directionVec.y = drag.x * 0.01;//this->moveAmount;
+ this->directionVec.z = drag.y * 0.01;//this->moveAmount;
+ }
+ else if (event.middle == MouseEvent::DOWN)
+ {
+ this->directionVec.x = drag.y * 0.01;//this->moveAmount;
+ this->directionVec.y = 0;
+ this->directionVec.z = 0;
+ }
+ else if (event.middle == MouseEvent::SCROLL)
+ {
+ this->directionVec.x -= 50.0 * event.scroll.y * 0.01;//this->moveAmount;
+ this->directionVec.y = 0;
+ this->directionVec.z = 0;
+ }
+
+ this->camera->Translate(directionVec);
+ this->directionVec.Set(0,0,0);
+}
Added: code/gazebo/trunk/server/rendering/FPSViewController.hh
===================================================================
--- code/gazebo/trunk/server/rendering/FPSViewController.hh
(rev 0)
+++ code/gazebo/trunk/server/rendering/FPSViewController.hh 2010-05-14
21:48:52 UTC (rev 8681)
@@ -0,0 +1,28 @@
+#ifndef FPSVIEWCONTROLLER_HH
+#define FPSVIEWCONTROLLER_HH
+
+#include "ViewController.hh"
+#include "Vector3.hh"
+#include "Time.hh"
+
+namespace gazebo
+{
+ class FPSViewController : public ViewController
+ {
+ /// \brief Constructor
+ public: FPSViewController(OgreCamera *camera);
+
+ /// \brief Destructor
+ public: virtual ~FPSViewController();
+
+ /// \brief Update
+ public: virtual void Update();
+
+ /// \brief Handle a mouse event
+ public: virtual void HandleMouseEvent(const MouseEvent &event);
+
+ protected: Time lastUpdateTime;
+ protected: Vector3 directionVec;
+ };
+}
+#endif
Modified: code/gazebo/trunk/server/rendering/OgreAdaptor.cc
===================================================================
--- code/gazebo/trunk/server/rendering/OgreAdaptor.cc 2010-05-14 17:38:12 UTC
(rev 8680)
+++ code/gazebo/trunk/server/rendering/OgreAdaptor.cc 2010-05-14 21:48:52 UTC
(rev 8681)
@@ -618,7 +618,7 @@
OgreCreator::Instance()->Update();
- /*this->root->_fireFrameStarted();
+ this->root->_fireFrameStarted();
// Draw all the non-user cameras
for (iter = this->cameras.begin(); iter != this->cameras.end(); iter++)
@@ -626,10 +626,9 @@
if (dynamic_cast<UserCamera*>((*iter)) == NULL)
(*iter)->Render();
}
-
- this->root->_fireFrameEnded();
-*/
+
this->root->renderOneFrame();
+
// Must update the user camera's last.
for (iter = this->cameras.begin(); iter != this->cameras.end(); iter++)
{
@@ -638,7 +637,7 @@
userCam->Update();
}
-
+ this->root->_fireFrameEnded();
}
////////////////////////////////////////////////////////////////////////////////
Modified: code/gazebo/trunk/server/rendering/OgreCamera.cc
===================================================================
--- code/gazebo/trunk/server/rendering/OgreCamera.cc 2010-05-14 17:38:12 UTC
(rev 8680)
+++ code/gazebo/trunk/server/rendering/OgreCamera.cc 2010-05-14 21:48:52 UTC
(rev 8681)
@@ -29,6 +29,7 @@
#include <Ogre.h>
#include <dirent.h>
+#include "FPSViewController.hh"
#include "PhysicsEngine.hh"
#include "Global.hh"
#include "World.hh"
@@ -94,9 +95,10 @@
this->pitchNode = NULL;
this->sceneNode = NULL;
this->origParentNode = NULL;
+
+ this->viewController = new FPSViewController(this);
}
-
//////////////////////////////////////////////////////////////////////////////
// Destructor
OgreCamera::~OgreCamera()
@@ -115,6 +117,7 @@
delete this->imageFormatP;
delete this->visMaskP;
delete this->hfovP;
+ delete this->viewController;
if (this->pitchNode)
{
@@ -250,6 +253,7 @@
// Update the drawing
void OgreCamera::UpdateCam()
{
+ this->viewController->Update();
if (this->animState)
{
@@ -1000,4 +1004,9 @@
return result;
}
-
+////////////////////////////////////////////////////////////////////////////////
+/// Hande a mouse event
+void OgreCamera::HandleMouseEvent(const MouseEvent &evt)
+{
+ this->viewController->HandleMouseEvent(evt);
+}
Modified: code/gazebo/trunk/server/rendering/OgreCamera.hh
===================================================================
--- code/gazebo/trunk/server/rendering/OgreCamera.hh 2010-05-14 17:38:12 UTC
(rev 8680)
+++ code/gazebo/trunk/server/rendering/OgreCamera.hh 2010-05-14 21:48:52 UTC
(rev 8681)
@@ -50,6 +50,8 @@
class XMLConfigNode;
class Model;
class Entity;
+ class MouseEvent;
+ class ViewController;
/// \addtogroup gazebo_rendering
/// \brief Basic camera
@@ -233,9 +235,13 @@
/// \brief Get the direction the camera is facing
public: Vector3 GetDirection() const;
+ /// \brief Hande a mouse event
+ public: void HandleMouseEvent(const MouseEvent &evt);
+
/// \brief if user requests bayer image, post process rgb from ogre to
generate bayer formats
private: void ConvertRGBToBAYER(unsigned char* dst, unsigned char* src,
std::string format,int width, int height);
+
// Save the camera frame
protected: virtual void SaveFrame();
@@ -287,6 +293,8 @@
protected: Time renderPeriod;
protected: Time lastUpdate;
private: Ogre::AnimationState *animState;
+
+ private: ViewController *viewController;
};
/// \}
Modified: code/gazebo/trunk/server/rendering/UserCamera.cc
===================================================================
--- code/gazebo/trunk/server/rendering/UserCamera.cc 2010-05-14 17:38:12 UTC
(rev 8680)
+++ code/gazebo/trunk/server/rendering/UserCamera.cc 2010-05-14 21:48:52 UTC
(rev 8681)
@@ -189,7 +189,6 @@
{
boost::recursive_mutex::scoped_lock
md_lock(*Simulator::Instance()->GetMDMutex());
OgreCamera::UpdateCam();
- this->window->update();
}
if (this->saveFramesP->GetValue())
Added: code/gazebo/trunk/server/rendering/ViewController.cc
===================================================================
--- code/gazebo/trunk/server/rendering/ViewController.cc
(rev 0)
+++ code/gazebo/trunk/server/rendering/ViewController.cc 2010-05-14
21:48:52 UTC (rev 8681)
@@ -0,0 +1,17 @@
+#include "OgreCamera.hh"
+#include "ViewController.hh"
+
+using namespace gazebo;
+
+////////////////////////////////////////////////////////////////////////////////
+// Constructor
+ViewController::ViewController(OgreCamera *camera)
+ : camera(camera)
+{
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Destructor
+ViewController::~ViewController()
+{
+}
Added: code/gazebo/trunk/server/rendering/ViewController.hh
===================================================================
--- code/gazebo/trunk/server/rendering/ViewController.hh
(rev 0)
+++ code/gazebo/trunk/server/rendering/ViewController.hh 2010-05-14
21:48:52 UTC (rev 8681)
@@ -0,0 +1,25 @@
+#ifndef VIEWCONTROLLER_HH
+#define VIEWCONTROLLER_HH
+
+namespace gazebo
+{
+ class OgreCamera;
+ class MouseEvent;
+
+ class ViewController
+ {
+ /// \brief Constructor
+ public: ViewController(OgreCamera *camera);
+
+ /// \brief Destructor
+ public: virtual ~ViewController();
+
+ public: virtual void Update() = 0;
+
+ /// \brief Handle a mouse event
+ public: virtual void HandleMouseEvent(const MouseEvent &event) = 0;
+
+ protected: OgreCamera *camera;
+ };
+}
+#endif
Added: code/gazebo/trunk/worlds/single_box.world
===================================================================
--- code/gazebo/trunk/worlds/single_box.world (rev 0)
+++ code/gazebo/trunk/worlds/single_box.world 2010-05-14 21:48:52 UTC (rev
8681)
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+
+<gazebo:world
+ xmlns:gazebo="http://playerstage.sourceforge.net/gazebo/xmlschema/#gz"
+ xmlns:model="http://playerstage.sourceforge.net/gazebo/xmlschema/#model"
+ xmlns:sensor="http://playerstage.sourceforge.net/gazebo/xmlschema/#sensor"
+ xmlns:body="http://playerstage.sourceforge.net/gazebo/xmlschema/#body"
+ xmlns:geom="http://playerstage.sourceforge.net/gazebo/xmlschema/#geom"
+ xmlns:joint="http://playerstage.sourceforge.net/gazebo/xmlschema/#joint"
+
xmlns:interface="http://playerstage.sourceforge.net/gazebo/xmlschema/#interface"
+
xmlns:rendering="http://playerstage.sourceforge.net/gazebo/xmlschema/#rendering"
+
xmlns:controller="http://playerstage.sourceforge.net/gazebo/xmlschema/#controller"
+ xmlns:physics="http://playerstage.sourceforge.net/gazebo/xmlschema/#physics"
>
+
+ <verbosity>5</verbosity>
+
+ <physics:ode>
+ <stepTime>0.001</stepTime>
+ <gravity>0 0 -9.8</gravity>
+ <cfm>10e-10</cfm>
+ <erp>0.2</erp>
+ <quickStep>true</quickStep>
+ <quickStepIters>50</quickStepIters>
+ <quickStepW>1.3</quickStepW>
+ <contactMaxCorrectingVel>100.0</contactMaxCorrectingVel>
+ <contactSurfaceLayer>0.001</contactSurfaceLayer>
+
+ <!-- updateRate: <0 == throttle simTime to match realTime.
+ 0 == No throttling
+ >0 == Frequency at which to throttle the sim -->
+ <updateRate>0</updateRate>
+ </physics:ode>
+
+ <rendering:gui>
+ <type>fltk</type>
+ <size>800 600</size>
+ <pos>0 0</pos>
+ </rendering:gui>
+
+ <rendering:ogre>
+ <ambient>1 1 1 1</ambient>
+ <sky>
+ <material>Gazebo/CloudySky</material>
+ </sky>
+ <shadowTechnique>stencilModulative</shadowTechnique>
+ <grid>false</grid>
+ </rendering:ogre>
+
+ <model:physical name="box_model">
+ <xyz>0 0 0.5</xyz>
+ <rpy>0 0 0</rpy>
+ <static>false</static>
+
+ <body:box name="body">
+ <geom:box name="geom">
+ <size>1</size>
+ <mass>1.0</mass>
+
+ <mu1>109999.0</mu1>
+
+ <visual>
+ <size>1 1 1</size>
+ <mesh>unit_box</mesh>
+ <shader>pixel</shader>
+ <material>Gazebo/Rocky</material>
+ </visual>
+ </geom:box>
+ </body:box>
+ </model:physical>
+
+ <!-- Ground Plane -->
+ <model:physical name="plane1_model">
+ <xyz>0 0 0</xyz>
+ <rpy>0 0 0</rpy>
+ <static>true</static>
+
+ <body:plane name="plane1_body">
+ <geom:plane name="plane1_geom">
+ <normal>0 0 1</normal>
+ <size>100 100</size>
+ <segments>10 10</segments>
+ <uvTile>100 100</uvTile>
+ <material>Gazebo/GrayGrid</material>
+ <mu1>109999.0</mu1>
+ <mu2>1000.0</mu2>
+ </geom:plane>
+ </body:plane>
+ </model:physical>
+
+ <!-- White Point light -->
+ <model:renderable name="point_white">
+ <xyz>-5 5 20</xyz>
+ <static>false</static>
+
+ <light>
+ <type>point</type>
+ <diffuseColor>0.3 0.3 0.3</diffuseColor>
+ <specularColor>.1 .1 .1</specularColor>
+ <range>40</range>
+
+ <attenuation>0.1 0.01 0.002</attenuation>
+ </light>
+ </model:renderable>
+
+</gazebo:world>
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit