triangles_renderer.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <rve_render_server/batching/triangles_renderer.h>
00031 #include <rve_render_server/init.h>
00032 #include <rve_render_server/renderer.h>
00033 #include <rve_render_server/batching/triangles_material_generator.h>
00034 #include <rve_render_server/convert.h>
00035 
00036 #include <rve_msgs/Triangles.h>
00037 
00038 #include <OGRE/OgreRoot.h>
00039 #include <OGRE/OgreSceneNode.h>
00040 #include <OGRE/OgreHardwareBufferManager.h>
00041 #include <OGRE/OgreHardwareVertexBuffer.h>
00042 
00043 #define TRIANGLES_PER_VBO (1024 * 8)
00044 
00045 namespace rve_render_server
00046 {
00047 
00048 TrianglesRenderable::TrianglesRenderable(const TrianglesRendererDesc& desc, bool alpha)
00049 : Parent(desc, alpha)
00050 {
00051   mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;
00052   mRenderOp.useIndexes = false;
00053   mRenderOp.vertexData = new Ogre::VertexData;
00054   mRenderOp.vertexData->vertexStart = 0;
00055   mRenderOp.vertexData->vertexCount = 0;
00056 
00057   Ogre::VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
00058   size_t offset = 0;
00059 
00060   decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
00061   offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
00062 
00063   decl->addElement(0, offset, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
00064   offset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
00065 
00066   decl->addElement(0, offset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
00067 
00068   Ogre::HardwareVertexBufferSharedPtr vbuf =
00069     Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
00070       mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
00071           TRIANGLES_PER_VBO * 3,
00072       Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
00073 
00074   // Bind buffer
00075   mRenderOp.vertexData->vertexBufferBinding->setBinding(0, vbuf);
00076 }
00077 
00078 TrianglesRenderable::~TrianglesRenderable()
00079 {
00080   delete mRenderOp.vertexData;
00081   delete mRenderOp.indexData;
00082 }
00083 
00084 void TrianglesRenderable::add(const rve_common::UUID& id, const rve_msgs::Triangles& triangles, uint32_t start, uint32_t& out_start, uint32_t& out_count)
00085 {
00086   ROS_ASSERT(triangles.positions.size() == triangles.colors.size());
00087   ROS_ASSERT(triangles.positions.size() % 3 == 0);
00088   ROS_ASSERT(triangles.normals.empty() || triangles.normals.size() == triangles.positions.size());
00089 
00090   uint32_t verts_per_triangle = 3;
00091   uint32_t triangle_stride = getVertexStride() * verts_per_triangle;
00092   bool alpha = alpha_;
00093 
00094   Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
00095   out_start = (mRenderOp.vertexData->vertexStart / verts_per_triangle) + (mRenderOp.vertexData->vertexCount / verts_per_triangle);
00096 
00097   uint32_t end = std::min((size_t)TRIANGLES_PER_VBO, out_start + (triangles.positions.size() - start));
00098   out_count = 0;
00099 
00100   uint32_t lock_start = out_start * triangle_stride * verts_per_triangle;
00101   uint32_t lock_size = end * triangle_stride * verts_per_triangle;
00102   void* data = vbuf->lock(lock_start, lock_size, Ogre::HardwareVertexBuffer::HBL_NO_OVERWRITE);
00103   float* fptr = (float*)data;
00104 
00105   bool has_normals = triangles.normals.size() == triangles.positions.size();
00106 
00107   Ogre::Root* root = Ogre::Root::getSingletonPtr();
00108 
00109   rve_msgs::Triangles::_normals_type::const_iterator norm_it;
00110   if (has_normals)
00111   {
00112     norm_it = triangles.normals.begin() + start;
00113   }
00114 
00115   rve_msgs::Triangles::_positions_type::const_iterator pos_it = triangles.positions.begin() + start;
00116   rve_msgs::Triangles::_colors_type::const_iterator col_it = triangles.colors.begin() + start;
00117   for (uint32_t i = out_start; i < end;)
00118   {
00119     Ogre::Vector3 positions[3];
00120     Ogre::Vector3 normals[3];
00121     Ogre::ColourValue colors[3];
00122 
00123     for (uint32_t j = 0; j < 3; ++i, ++j, ++pos_it, ++col_it)
00124     {
00125       positions[j] = fromRobot(Ogre::Vector3(pos_it->x, pos_it->y, pos_it->z));
00126       colors[j] = Ogre::ColourValue(col_it->r, col_it->g, col_it->b, col_it->a);
00127 
00128       if (has_normals)
00129       {
00130         normals[j] = normalFromRobot(Ogre::Vector3(norm_it->x, norm_it->y, norm_it->z));
00131         normals[j].normalise();
00132         ++norm_it;
00133       }
00134     }
00135 
00136     bool has_alpha = colors[0].a < 0.99 || colors[1].a < 0.99 || colors[2].a < 0.99;
00137 
00138     if (has_alpha != alpha)
00139     {
00140       continue;
00141     }
00142 
00143     if (!has_normals)
00144     {
00145       Ogre::Vector3 v0 = positions[1] - positions[0];
00146       Ogre::Vector3 v1 = positions[2] - positions[1];
00147       Ogre::Vector3 n = v0.crossProduct(v1);
00148       n.normalise();
00149       normals[0] = n;
00150       normals[1] = n;
00151       normals[2] = n;
00152     }
00153 
00154     out_count += 3;
00155 
00156     for (uint32_t j = 0; j < 3; ++j)
00157     {
00158       mBox.merge(positions[j]);
00159 
00160       uint32_t color = 0;
00161       root->convertColourValue(colors[j], &color);
00162 
00163       *fptr++ = positions[j].x;
00164       *fptr++ = positions[j].y;
00165       *fptr++ = positions[j].z;
00166 
00167       *fptr++ = normals[j].x;
00168       *fptr++ = normals[j].y;
00169       *fptr++ = normals[j].z;
00170 
00171       uint32_t* iptr = (uint32_t*)fptr;
00172       *iptr = color;
00173       ++fptr;
00174     }
00175   }
00176 
00177   vbuf->unlock();
00178 
00179   mRenderOp.vertexData->vertexCount += out_count;
00180   count_ += out_count;
00181 }
00182 
00183 void TrianglesRenderable::remove(uint32_t start, uint32_t count)
00184 {
00185   ROS_ASSERT_MSG(count <= count_, "count = %d, count_ = %d", count, count_);
00186   ROS_ASSERT_MSG(start + count < TRIANGLES_PER_VBO, "start = %d, count = %d, TRIANGLES_PER_VBO = %d", start, count, TRIANGLES_PER_VBO);
00187 
00188   uint32_t verts_per_triangle = 3;
00189   uint32_t triangle_stride = getVertexStride() * verts_per_triangle;
00190 
00191   Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
00192   uint8_t* data = (uint8_t*)vbuf->lock(start * triangle_stride * verts_per_triangle, count * triangle_stride * verts_per_triangle, Ogre::HardwareVertexBuffer::HBL_NORMAL);
00193 
00194   uint32_t total_vertices = verts_per_triangle * count;
00195   data = data + (triangle_stride * verts_per_triangle * start);
00196   for (uint32_t i = 0; i < total_vertices; ++i)
00197   {
00198     // Assign positions outside the viewable area
00199     float* fptr = (float*)data;
00200     *fptr++ = 99999999.0f;
00201     *fptr++ = 99999999.0f;
00202     *fptr++ = 99999999.0f;
00203 
00204     data += triangle_stride;
00205   }
00206 
00207   count_ -= count;
00208 
00209   vbuf->unlock();
00210 
00211   if (isEmpty())
00212   {
00213     mBox.setNull();
00214   }
00215 }
00216 
00217 uint32_t TrianglesRenderable::getElementsPerVBO()
00218 {
00219   return TRIANGLES_PER_VBO;
00220 }
00221 
00222 uint32_t TrianglesRenderable::getVertexStride()
00223 {
00224   return mRenderOp.vertexData->vertexDeclaration->getVertexSize(0);
00225 }
00226 
00227 
00231 
00232 TrianglesRenderer::TrianglesRenderer(Ogre::SceneManager* scene_manager, const TrianglesRendererDesc& desc)
00233 : Parent(scene_manager, desc)
00234 {
00235 }
00236 
00237 std::pair<Ogre::MaterialPtr, Ogre::MaterialPtr> TrianglesRenderer::createMaterials(const TrianglesRendererDesc& desc)
00238 {
00239   return generateMaterialsForTriangles(desc);
00240 }
00241 
00242 size_t TrianglesRenderer::getInputCount(const rve_msgs::Triangles& triangles)
00243 {
00244   return triangles.positions.size();
00245 }
00246 
00247 } // namespace rve_render_server


rve_render_server
Author(s): Josh Faust
autogenerated on Wed Dec 11 2013 14:31:15