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 <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
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
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 }