00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "point_cloud.h"
00031 #include <ros/assert.h>
00032
00033 #include <OGRE/OgreSceneManager.h>
00034 #include <OGRE/OgreSceneNode.h>
00035 #include <OGRE/OgreVector3.h>
00036 #include <OGRE/OgreQuaternion.h>
00037 #include <OGRE/OgreManualObject.h>
00038 #include <OGRE/OgreMaterialManager.h>
00039 #include <OGRE/OgreBillboardSet.h>
00040 #include <OGRE/OgreBillboard.h>
00041 #include <OGRE/OgreTexture.h>
00042 #include <OGRE/OgreTextureManager.h>
00043
00044 #include <sstream>
00045
00046 #define VERTEX_BUFFER_CAPACITY (36 * 1024 * 10)
00047 #define SIZE_PARAMETER 0
00048 #define ALPHA_PARAMETER 1
00049 #define PICK_COLOR_PARAMETER 2
00050 #define NORMAL_PARAMETER 3
00051 #define UP_PARAMETER 4
00052 #define HIGHLIGHT_PARAMETER 5
00053
00054 namespace rviz
00055 {
00056
00057 static float g_point_vertices[3] =
00058 {
00059 0.0f, 0.0f, 0.0f
00060 };
00061
00062 static float g_billboard_vertices[6*3] =
00063 {
00064 -0.5f, 0.5f, 0.0f,
00065 -0.5f, -0.5f, 0.0f,
00066 0.5f, 0.5f, 0.0f,
00067 0.5f, 0.5f, 0.0f,
00068 -0.5f, -0.5f, 0.0f,
00069 0.5f, -0.5f, 0.0f,
00070 };
00071
00072 static float g_billboard_sphere_vertices[3*3] =
00073 {
00074 0.0f, 1.5f, 0.0f,
00075 -1.5f, -1.5f, 0.0f,
00076 1.5f, -1.5f, 0.0f,
00077 };
00078
00079 static float g_box_vertices[6*6*3] =
00080 {
00081
00082 -0.5f, 0.5f, -0.5f,
00083 -0.5f, -0.5f, -0.5f,
00084 0.5f, 0.5f, -0.5f,
00085 0.5f, 0.5f, -0.5f,
00086 -0.5f, -0.5f, -0.5f,
00087 0.5f, -0.5f, -0.5f,
00088
00089
00090 -0.5f, 0.5f, 0.5f,
00091 0.5f, 0.5f, 0.5f,
00092 -0.5f, -0.5f, 0.5f,
00093 0.5f, 0.5f, 0.5f,
00094 0.5f, -0.5f, 0.5f,
00095 -0.5f, -0.5f, 0.5f,
00096
00097
00098 0.5, 0.5, 0.5,
00099 0.5, 0.5, -0.5,
00100 0.5, -0.5, 0.5,
00101 0.5, 0.5, -0.5,
00102 0.5, -0.5, -0.5,
00103 0.5, -0.5, 0.5,
00104
00105
00106 -0.5, 0.5, 0.5,
00107 -0.5, -0.5, 0.5,
00108 -0.5, 0.5, -0.5,
00109 -0.5, 0.5, -0.5,
00110 -0.5, -0.5, 0.5,
00111 -0.5, -0.5, -0.5,
00112
00113
00114 -0.5, 0.5, -0.5,
00115 0.5, 0.5, -0.5,
00116 -0.5, 0.5, 0.5,
00117 0.5, 0.5, -0.5,
00118 0.5, 0.5, 0.5,
00119 -0.5, 0.5, 0.5,
00120
00121
00122 -0.5, -0.5, -0.5,
00123 -0.5, -0.5, 0.5,
00124 0.5, -0.5, -0.5,
00125 0.5, -0.5, -0.5,
00126 -0.5, -0.5, 0.5,
00127 0.5, -0.5, 0.5,
00128 };
00129
00130 Ogre::String PointCloud::sm_Type = "PointCloud";
00131
00132 PointCloud::PointCloud()
00133 : bounding_radius_( 0.0f )
00134 , point_count_( 0 )
00135 , common_direction_( Ogre::Vector3::NEGATIVE_UNIT_Z )
00136 , common_up_vector_( Ogre::Vector3::UNIT_Y )
00137 , color_by_index_(false)
00138 , current_mode_supports_geometry_shader_(false)
00139 {
00140 std::stringstream ss;
00141 static int count = 0;
00142 ss << "PointCloudMaterial" << count++;
00143 point_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudPoint");
00144 point_material_ = point_material_->clone(ss.str() + "Point");
00145 billboard_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudBillboard");
00146 billboard_material_ = billboard_material_->clone(ss.str() + "Billboard");
00147 billboard_sphere_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudBillboardSphere");
00148 billboard_sphere_material_ = billboard_sphere_material_->clone(ss.str() + "BillboardSphere");
00149 billboard_common_facing_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudBillboardCommonFacing");
00150 billboard_common_facing_material_ = billboard_common_facing_material_->clone(ss.str() + "BillboardCommonFacing");
00151 box_material_ = Ogre::MaterialManager::getSingleton().getByName("rviz/PointCloudBox");
00152 box_material_ = box_material_->clone(ss.str() + "Box");
00153
00154 point_material_->load();
00155 billboard_material_->load();
00156 billboard_sphere_material_->load();
00157 billboard_common_facing_material_->load();
00158 box_material_->load();
00159
00160 setAlpha( 1.0f );
00161 setRenderMode(RM_BILLBOARD_SPHERES);
00162 setDimensions(0.01f, 0.01f, 0.01f);
00163
00164 clear();
00165 }
00166
00167 PointCloud::~PointCloud()
00168 {
00169 point_material_->unload();
00170 billboard_material_->unload();
00171 billboard_sphere_material_->unload();
00172 billboard_common_facing_material_->unload();
00173 box_material_->unload();
00174 }
00175
00176 const Ogre::AxisAlignedBox& PointCloud::getBoundingBox() const
00177 {
00178 return bounding_box_;
00179 }
00180
00181 float PointCloud::getBoundingRadius() const
00182 {
00183 return bounding_radius_;
00184 }
00185
00186 void PointCloud::getWorldTransforms(Ogre::Matrix4* xform) const
00187 {
00188 *xform = _getParentNodeFullTransform();
00189 }
00190
00191 void PointCloud::clear()
00192 {
00193 point_count_ = 0;
00194 bounding_box_.setNull();
00195 bounding_radius_ = 0.0f;
00196
00197 V_PointCloudRenderable::iterator it = renderables_.begin();
00198 V_PointCloudRenderable::iterator end = renderables_.end();
00199 for (; it != end; ++it)
00200 {
00201 (*it)->getRenderOperation()->vertexData->vertexStart = 0;
00202 (*it)->getRenderOperation()->vertexData->vertexCount = 0;
00203 }
00204
00205 if (getParentSceneNode())
00206 {
00207 getParentSceneNode()->needUpdate();
00208 }
00209 }
00210
00211 void PointCloud::regenerateAll()
00212 {
00213 if (point_count_ == 0)
00214 {
00215 return;
00216 }
00217
00218 V_Point points;
00219 points.swap(points_);
00220 uint32_t count = point_count_;
00221
00222 clear();
00223
00224 addPoints(&points.front(), count);
00225 }
00226
00227 void PointCloud::setColorByIndex(bool set)
00228 {
00229 color_by_index_ = set;
00230
00231 regenerateAll();
00232 }
00233
00234 void PointCloud::setHighlightColor( float r, float g, float b )
00235 {
00236 Ogre::Vector4 highlight( r, g, b, 0.0f );
00237
00238 V_PointCloudRenderable::iterator it = renderables_.begin();
00239 V_PointCloudRenderable::iterator end = renderables_.end();
00240 for (; it != end; ++it)
00241 {
00242 (*it)->setCustomParameter(HIGHLIGHT_PARAMETER, highlight);
00243 }
00244 }
00245
00246 void PointCloud::setRenderMode(RenderMode mode)
00247 {
00248 render_mode_ = mode;
00249
00250 if (mode == RM_POINTS)
00251 {
00252 current_material_ = point_material_;
00253 }
00254 else if (mode == RM_BILLBOARDS)
00255 {
00256 current_material_ = billboard_material_;
00257 }
00258 else if (mode == RM_BILLBOARD_SPHERES)
00259 {
00260 current_material_ = billboard_sphere_material_;
00261 }
00262 else if (mode == RM_BILLBOARDS_COMMON_FACING)
00263 {
00264 current_material_ = billboard_common_facing_material_;
00265 }
00266 else if (mode == RM_BOXES)
00267 {
00268 current_material_ = box_material_;
00269 }
00270
00271 current_material_->load();
00272
00273
00274
00275 bool geom_support_changed = false;
00276 Ogre::Technique* best = current_material_->getBestTechnique();
00277 if (best)
00278 {
00279 if (current_material_->getBestTechnique()->getName() == "gp")
00280 {
00281 if (!current_mode_supports_geometry_shader_)
00282 {
00283 geom_support_changed = true;
00284 }
00285
00286 current_mode_supports_geometry_shader_ = true;
00287
00288
00289 }
00290 else
00291 {
00292 if (current_mode_supports_geometry_shader_)
00293 {
00294 geom_support_changed = true;
00295 }
00296
00297 current_mode_supports_geometry_shader_ = false;
00298 }
00299 }
00300 else
00301 {
00302 geom_support_changed = true;
00303 current_mode_supports_geometry_shader_ = false;
00304
00305 ROS_ERROR("No techniques available for material [%s]", current_material_->getName().c_str());
00306 }
00307
00308 if (geom_support_changed)
00309 {
00310 renderables_.clear();
00311 }
00312
00313 V_PointCloudRenderable::iterator it = renderables_.begin();
00314 V_PointCloudRenderable::iterator end = renderables_.end();
00315 for (; it != end; ++it)
00316 {
00317 (*it)->setMaterial(current_material_->getName());
00318 }
00319
00320 regenerateAll();
00321 }
00322
00323 void PointCloud::setDimensions(float width, float height, float depth)
00324 {
00325 width_ = width;
00326 height_ = height;
00327 depth_ = depth;
00328
00329 Ogre::Vector4 size(width_, height_, depth_, 0.0f);
00330
00331 V_PointCloudRenderable::iterator it = renderables_.begin();
00332 V_PointCloudRenderable::iterator end = renderables_.end();
00333 for (; it != end; ++it)
00334 {
00335 (*it)->setCustomParameter(SIZE_PARAMETER, size);
00336 }
00337 }
00338
00339 void PointCloud::setCommonDirection(const Ogre::Vector3& vec)
00340 {
00341 common_direction_ = vec;
00342
00343 V_PointCloudRenderable::iterator it = renderables_.begin();
00344 V_PointCloudRenderable::iterator end = renderables_.end();
00345 for (; it != end; ++it)
00346 {
00347 (*it)->setCustomParameter(NORMAL_PARAMETER, Ogre::Vector4(vec));
00348 }
00349 }
00350
00351 void PointCloud::setCommonUpVector(const Ogre::Vector3& vec)
00352 {
00353 common_up_vector_ = vec;
00354
00355 V_PointCloudRenderable::iterator it = renderables_.begin();
00356 V_PointCloudRenderable::iterator end = renderables_.end();
00357 for (; it != end; ++it)
00358 {
00359 (*it)->setCustomParameter(UP_PARAMETER, Ogre::Vector4(vec));
00360 }
00361 }
00362
00363 void setAlphaBlending(const Ogre::MaterialPtr& mat)
00364 {
00365 if (mat->getBestTechnique())
00366 {
00367 mat->getBestTechnique()->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
00368 mat->getBestTechnique()->setDepthWriteEnabled( false );
00369 }
00370 }
00371
00372 void setReplace(const Ogre::MaterialPtr& mat)
00373 {
00374 if (mat->getBestTechnique())
00375 {
00376 mat->getBestTechnique()->setSceneBlending( Ogre::SBT_REPLACE );
00377 mat->getBestTechnique()->setDepthWriteEnabled( true );
00378 }
00379 }
00380
00381 void PointCloud::setAlpha(float alpha)
00382 {
00383 alpha_ = alpha;
00384
00385 if ( alpha < 0.9998 )
00386 {
00387 setAlphaBlending(point_material_);
00388 setAlphaBlending(billboard_material_);
00389 setAlphaBlending(billboard_sphere_material_);
00390 setAlphaBlending(billboard_common_facing_material_);
00391 setAlphaBlending(box_material_);
00392 }
00393 else
00394 {
00395 setReplace(point_material_);
00396 setReplace(billboard_material_);
00397 setReplace(billboard_sphere_material_);
00398 setReplace(billboard_common_facing_material_);
00399 setReplace(box_material_);
00400 }
00401
00402 Ogre::Vector4 alpha4(alpha_, alpha_, alpha_, alpha_);
00403 V_PointCloudRenderable::iterator it = renderables_.begin();
00404 V_PointCloudRenderable::iterator end = renderables_.end();
00405 for (; it != end; ++it)
00406 {
00407 (*it)->setCustomParameter(ALPHA_PARAMETER, alpha4);
00408 }
00409 }
00410
00411 void PointCloud::addPoints(Point* points, uint32_t num_points)
00412 {
00413 if (num_points == 0)
00414 {
00415 return;
00416 }
00417
00418 Ogre::Root* root = Ogre::Root::getSingletonPtr();
00419
00420 if ( points_.size() < point_count_ + num_points )
00421 {
00422 points_.resize( point_count_ + num_points );
00423 }
00424
00425 Point* begin = &points_.front() + point_count_;
00426 memcpy( begin, points, sizeof( Point ) * num_points );
00427
00428 uint32_t vpp = getVerticesPerPoint();
00429 Ogre::RenderOperation::OperationType op_type;
00430 if (current_mode_supports_geometry_shader_)
00431 {
00432 op_type = Ogre::RenderOperation::OT_POINT_LIST;
00433 }
00434 else
00435 {
00436 if (render_mode_ == RM_POINTS)
00437 {
00438 op_type = Ogre::RenderOperation::OT_POINT_LIST;
00439 }
00440 else
00441 {
00442 op_type = Ogre::RenderOperation::OT_TRIANGLE_LIST;
00443 }
00444 }
00445
00446 float* vertices = 0;
00447 if (current_mode_supports_geometry_shader_)
00448 {
00449 vertices = g_point_vertices;
00450 }
00451 else
00452 {
00453 if (render_mode_ == RM_POINTS)
00454 {
00455 vertices = g_point_vertices;
00456 }
00457 else if (render_mode_ == RM_BILLBOARDS)
00458 {
00459 vertices = g_billboard_vertices;
00460 }
00461 else if (render_mode_ == RM_BILLBOARD_SPHERES)
00462 {
00463 vertices = g_billboard_sphere_vertices;
00464 }
00465 else if (render_mode_ == RM_BILLBOARDS_COMMON_FACING)
00466 {
00467 vertices = g_billboard_vertices;
00468 }
00469 else if (render_mode_ == RM_BOXES)
00470 {
00471 vertices = g_box_vertices;
00472 }
00473 }
00474
00475 PointCloudRenderablePtr rend;
00476 Ogre::HardwareVertexBufferSharedPtr vbuf;
00477 void* vdata = 0;
00478 Ogre::RenderOperation* op = 0;
00479 float* fptr = 0;
00480
00481 Ogre::AxisAlignedBox aabb;
00482 aabb.setNull();
00483 uint32_t current_vertex_count = 0;
00484 bounding_radius_ = 0.0f;
00485 uint32_t vertex_size = 0;
00486 for (uint32_t current_point = 0; current_point < num_points; ++current_point)
00487 {
00488 while (current_vertex_count >= VERTEX_BUFFER_CAPACITY || !rend)
00489 {
00490 if (rend)
00491 {
00492 ROS_ASSERT(current_vertex_count == VERTEX_BUFFER_CAPACITY);
00493
00494 op->vertexData->vertexCount = VERTEX_BUFFER_CAPACITY - op->vertexData->vertexStart;
00495 ROS_ASSERT(op->vertexData->vertexCount + op->vertexData->vertexStart <= VERTEX_BUFFER_CAPACITY);
00496 vbuf->unlock();
00497 rend->setBoundingBox(aabb);
00498 }
00499
00500 rend = getOrCreateRenderable();
00501 vbuf = rend->getBuffer();
00502 vdata = vbuf->lock(Ogre::HardwareBuffer::HBL_NO_OVERWRITE);
00503
00504 op = rend->getRenderOperation();
00505 op->operationType = op_type;
00506 current_vertex_count = op->vertexData->vertexStart + op->vertexData->vertexCount;
00507
00508 vertex_size = op->vertexData->vertexDeclaration->getVertexSize(0);
00509 uint32_t data_pos = current_vertex_count * vertex_size;
00510 fptr = (float*)((uint8_t*)vdata + data_pos);
00511
00512 aabb.setNull();
00513 }
00514
00515 const Point& p = points[current_point];
00516 float x = p.x;
00517 float y = p.y;
00518 float z = p.z;
00519 uint32_t color = p.color;
00520
00521 if (color_by_index_)
00522 {
00523
00524 color = (current_point + point_count_ + 1);
00525 Ogre::ColourValue c;
00526 c.a = 1.0f;
00527 c.r = ((color >> 16) & 0xff) / 255.0f;
00528 c.g = ((color >> 8) & 0xff) / 255.0f;
00529 c.b = (color & 0xff) / 255.0f;
00530 root->convertColourValue(c, &color);
00531 }
00532
00533 Ogre::Vector3 pos(x, y, z);
00534 aabb.merge(pos);
00535 bounding_box_.merge( pos );
00536 bounding_radius_ = std::max( bounding_radius_, pos.squaredLength() );
00537
00538 for (uint32_t j = 0; j < vpp; ++j, ++current_vertex_count)
00539 {
00540 *fptr++ = x;
00541 *fptr++ = y;
00542 *fptr++ = z;
00543
00544 if (!current_mode_supports_geometry_shader_)
00545 {
00546 *fptr++ = vertices[(j*3)];
00547 *fptr++ = vertices[(j*3) + 1];
00548 *fptr++ = vertices[(j*3) + 2];
00549 }
00550
00551 uint32_t* iptr = (uint32_t*)fptr;
00552 *iptr = color;
00553 ++fptr;
00554
00555 ROS_ASSERT((uint8_t*)fptr <= (uint8_t*)vdata + VERTEX_BUFFER_CAPACITY * vertex_size);
00556 }
00557 }
00558
00559 op->vertexData->vertexCount = current_vertex_count - op->vertexData->vertexStart;
00560 rend->setBoundingBox(aabb);
00561 ROS_ASSERT(op->vertexData->vertexCount + op->vertexData->vertexStart <= VERTEX_BUFFER_CAPACITY);
00562
00563 vbuf->unlock();
00564
00565 point_count_ += num_points;
00566
00567 shrinkRenderables();
00568
00569 if (getParentSceneNode())
00570 {
00571 getParentSceneNode()->needUpdate();
00572 }
00573 }
00574
00575 void PointCloud::popPoints(uint32_t num_points)
00576 {
00577 uint32_t vpp = getVerticesPerPoint();
00578
00579 ROS_ASSERT(num_points <= point_count_);
00580 points_.erase(points_.begin(), points_.begin() + num_points);
00581
00582 point_count_ -= num_points;
00583
00584
00585 uint32_t popped_count = 0;
00586 while (popped_count < num_points * vpp)
00587 {
00588 PointCloudRenderablePtr rend = renderables_.front();
00589 Ogre::RenderOperation* op = rend->getRenderOperation();
00590
00591 uint32_t popped = std::min((size_t)(num_points * vpp - popped_count), op->vertexData->vertexCount);
00592 op->vertexData->vertexStart += popped;
00593 op->vertexData->vertexCount -= popped;
00594
00595 popped_count += popped;
00596
00597 if (op->vertexData->vertexCount == 0)
00598 {
00599 renderables_.erase(renderables_.begin(), renderables_.begin() + 1);
00600
00601 op->vertexData->vertexStart = 0;
00602 renderables_.push_back(rend);
00603 }
00604 }
00605 ROS_ASSERT(popped_count == num_points * vpp);
00606
00607
00608 bounding_box_.setNull();
00609 bounding_radius_ = 0.0f;
00610 for (uint32_t i = 0; i < point_count_; ++i)
00611 {
00612 Point& p = points_[i];
00613 Ogre::Vector3 pos(p.x, p.y, p.z);
00614 bounding_box_.merge(pos);
00615 bounding_radius_ = std::max(bounding_radius_, pos.squaredLength());
00616 }
00617
00618 shrinkRenderables();
00619
00620 if (getParentSceneNode())
00621 {
00622 getParentSceneNode()->needUpdate();
00623 }
00624 }
00625
00626 void PointCloud::shrinkRenderables()
00627 {
00628 while (!renderables_.empty())
00629 {
00630 PointCloudRenderablePtr rend = renderables_.back();
00631 Ogre::RenderOperation* op = rend->getRenderOperation();
00632 if (op->vertexData->vertexCount == 0)
00633 {
00634 renderables_.pop_back();
00635 }
00636 else
00637 {
00638 break;
00639 }
00640 }
00641 }
00642
00643 void PointCloud::_notifyCurrentCamera(Ogre::Camera* camera)
00644 {
00645 MovableObject::_notifyCurrentCamera( camera );
00646 }
00647
00648 void PointCloud::_updateRenderQueue(Ogre::RenderQueue* queue)
00649 {
00650 V_PointCloudRenderable::iterator it = renderables_.begin();
00651 V_PointCloudRenderable::iterator end = renderables_.end();
00652 for (; it != end; ++it)
00653 {
00654 queue->addRenderable((*it).get());
00655 }
00656 }
00657
00658 void PointCloud::_notifyAttached(Ogre::Node *parent, bool isTagPoint)
00659 {
00660 MovableObject::_notifyAttached(parent, isTagPoint);
00661 }
00662
00663 uint32_t PointCloud::getVerticesPerPoint()
00664 {
00665 if (current_mode_supports_geometry_shader_)
00666 {
00667 return 1;
00668 }
00669
00670 if (render_mode_ == RM_POINTS)
00671 {
00672 return 1;
00673 }
00674
00675 if (render_mode_ == RM_BILLBOARDS)
00676 {
00677 return 6;
00678 }
00679
00680 if (render_mode_ == RM_BILLBOARDS_COMMON_FACING)
00681 {
00682 return 6;
00683 }
00684
00685 if (render_mode_ == RM_BILLBOARD_SPHERES)
00686 {
00687 return 3;
00688 }
00689
00690 if (render_mode_ == RM_BOXES)
00691 {
00692 return 36;
00693 }
00694
00695 return 1;
00696 }
00697
00698 void PointCloud::setPickColor(const Ogre::ColourValue& color)
00699 {
00700 pick_color_ = color;
00701 Ogre::Vector4 pick_col(pick_color_.r, pick_color_.g, pick_color_.b, pick_color_.a);
00702
00703 V_PointCloudRenderable::iterator it = renderables_.begin();
00704 V_PointCloudRenderable::iterator end = renderables_.end();
00705 for (; it != end; ++it)
00706 {
00707 (*it)->setCustomParameter(PICK_COLOR_PARAMETER, pick_col);
00708 }
00709 }
00710
00711 PointCloudRenderablePtr PointCloud::getOrCreateRenderable()
00712 {
00713 V_PointCloudRenderable::iterator it = renderables_.begin();
00714 V_PointCloudRenderable::iterator end = renderables_.end();
00715 for (; it != end; ++it)
00716 {
00717 const PointCloudRenderablePtr& rend = *it;
00718 Ogre::RenderOperation* op = rend->getRenderOperation();
00719 if (op->vertexData->vertexCount + op->vertexData->vertexStart < VERTEX_BUFFER_CAPACITY)
00720 {
00721 return rend;
00722 }
00723 }
00724
00725 PointCloudRenderablePtr rend(new PointCloudRenderable(this, !current_mode_supports_geometry_shader_));
00726 rend->setMaterial(current_material_->getName());
00727 Ogre::Vector4 size(width_, height_, depth_, 0.0f);
00728 Ogre::Vector4 alpha(alpha_, 0.0f, 0.0f, 0.0f);
00729 Ogre::Vector4 highlight(0.0f, 0.0f, 0.0f, 0.0f);
00730 Ogre::Vector4 pick_col(pick_color_.r, pick_color_.g, pick_color_.b, pick_color_.a);
00731 rend->setCustomParameter(SIZE_PARAMETER, size);
00732 rend->setCustomParameter(ALPHA_PARAMETER, alpha);
00733 rend->setCustomParameter(HIGHLIGHT_PARAMETER, highlight);
00734 rend->setCustomParameter(PICK_COLOR_PARAMETER, pick_col);
00735 rend->setCustomParameter(NORMAL_PARAMETER, Ogre::Vector4(common_direction_));
00736 rend->setCustomParameter(UP_PARAMETER, Ogre::Vector4(common_up_vector_));
00737 if (getParentSceneNode())
00738 {
00739 getParentSceneNode()->attachObject(rend.get());
00740 }
00741 renderables_.push_back(rend);
00742
00743 return rend;
00744 }
00745
00746 #if (OGRE_VERSION_MAJOR >= 1 && OGRE_VERSION_MINOR >= 6)
00747 void PointCloud::visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables)
00748 {
00749
00750 }
00751 #endif
00752
00753
00757
00758 PointCloudRenderable::PointCloudRenderable(PointCloud* parent, bool use_tex_coords)
00759 : parent_(parent)
00760 {
00761
00762 mRenderOp.operationType = Ogre::RenderOperation::OT_POINT_LIST;
00763 mRenderOp.useIndexes = false;
00764 mRenderOp.vertexData = new Ogre::VertexData;
00765 mRenderOp.vertexData->vertexStart = 0;
00766 mRenderOp.vertexData->vertexCount = 0;
00767
00768 Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
00769 size_t offset = 0;
00770
00771 decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
00772 offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
00773
00774 if (use_tex_coords)
00775 {
00776 decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_TEXTURE_COORDINATES, 0);
00777 offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
00778 }
00779
00780 decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
00781
00782 Ogre::HardwareVertexBufferSharedPtr vbuf =
00783 Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
00784 mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
00785 VERTEX_BUFFER_CAPACITY,
00786 Ogre::HardwareBuffer::HBU_DYNAMIC);
00787
00788
00789 mRenderOp.vertexData->vertexBufferBinding->setBinding(0, vbuf);
00790 }
00791
00792 PointCloudRenderable::~PointCloudRenderable()
00793 {
00794 delete mRenderOp.vertexData;
00795 delete mRenderOp.indexData;
00796 }
00797
00798 Ogre::HardwareVertexBufferSharedPtr PointCloudRenderable::getBuffer()
00799 {
00800 return mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
00801 }
00802
00803 void PointCloudRenderable::_notifyCurrentCamera(Ogre::Camera* camera)
00804 {
00805 SimpleRenderable::_notifyCurrentCamera( camera );
00806 }
00807
00808 Ogre::Real PointCloudRenderable::getBoundingRadius(void) const
00809 {
00810 return Ogre::Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
00811 }
00812
00813 Ogre::Real PointCloudRenderable::getSquaredViewDepth(const Ogre::Camera* cam) const
00814 {
00815 Ogre::Vector3 vMin, vMax, vMid, vDist;
00816 vMin = mBox.getMinimum();
00817 vMax = mBox.getMaximum();
00818 vMid = ((vMax - vMin) * 0.5) + vMin;
00819 vDist = cam->getDerivedPosition() - vMid;
00820
00821 return vDist.squaredLength();
00822 }
00823
00824 void PointCloudRenderable::getWorldTransforms(Ogre::Matrix4* xform) const
00825 {
00826 *xform = m_matWorldTransform * parent_->getParentNode()->_getFullTransform();
00827 }
00828
00829 const Ogre::LightList& PointCloudRenderable::getLights() const
00830 {
00831 return parent_->queryLights();
00832 }
00833
00834 }