Skip to main content

History: ManualObject

Source of version: 28

Copy to clipboard
            {img src=img/wiki_up/ManualObject.png imalign=center align=right stylebox=border max=400 rel=box} 

Using a ManualObject you don't need to load ressources and it's nice to create dynamic objects or simple ones.

To do so, you define the needed points (((-Vertex|vertices))), rendering type (points, lines, surfaces) and assign a ((-Material|material)). To add it to the ((-Scene|scene)), it has to be attached to a ((-SceneNode|SceneNode)) (e.g. the ((-RootSceneNode|RootSceneNode))).

It's possible to add several code blocks {SUB()}''begin(), ...add content..., end()''{SUB} to the one ManualObject. So you can use different materials and rendering types. As a result you can get lines, surfaces or a combination of it. Transparency is also possible (by use of materials with transparency property). 

If several instances (copies) of a ManualObject are needed, you have to create a ((-Mesh|Mesh)) from it by use of  ''ManualObject::convertToMesh()''. When you load such a Mesh to your scene, it becomes an ((-Entity|Entity)). An other advantage of the ToMesh conversion is, that you can apply different materials to the same shape.

In some cases the ''identity projection'' can be interesting. With this the coordinates are in 2D screen space of the current camera. Useful for ((-Overlay|overlay)) rendering.


!!Examples

!!!Example 1

A very minimal example that creates a __line__ in 3D space.

{CODE(wrap="1", colors="c++")}
// create ManualObject
ManualObject* manual = mSceneMgr->createManualObject("manual");

// specify the material (by name) and rendering type
manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_LIST);

// define start and end point
manual->position(-100, -100, -100);
manual->position(100, 100, 100);

// tell Ogre, your definition has finished
manual->end();

// add ManualObject to the RootSceneNode (so it will be visible)
mSceneMgr->getRootSceneNode()->attachObject(manual);
{CODE}



%%%
!!!Example 2

This example gives an outlined __square__ (or quad):
{CODE(wrap="1", colors="c++")}
ManualObject* manual = mSceneMgr->createManualObject("manual");
manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP);

manual->position(-100.0, -100.0, 0.0);  // start position
manual->position( 100.0, -100.0, 0.0);  // draw first line
manual->position( 100.0,  100.0, 0.0);
manual->position(-100.0,  100.0, 0.0);
manual->position(-100.0, -100.0, 0.0);  // draw fourth line

manual->end();
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
{CODE}





%%%
!!!Example 3

This example is similar to the previous one, but uses __indexes__. 
Differences:
* Vertex positions and the usage order are defined seperatly
* Vertex positions can be updated (changed) later without re-build of the whole ManualObject
* Index definitions are needed if you want to create a ((-Mesh|Mesh)) out of the ManualObject

{CODE(wrap="1", colors="c++")}
ManualObject* manual = mSceneMgr->createManualObject("manual");
manual->begin("BaseWhiteNoLighting", RenderOperation::OT_LINE_STRIP);

// define vertex position of index 0..3
manual->position(-100.0, -100.0, 0.0);
manual->position( 100.0, -100.0, 0.0);
manual->position( 100.0,  100.0, 0.0);
manual->position(-100.0,  100.0, 0.0);

// define usage of vertices by refering to the indexes
manual->index(0);
manual->index(1);
manual->index(2);
manual->index(3);
manual->index(0);

manual->end();
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);{CODE}




%%%
!!!Advanced operations

When you want to __move, rotate, scale__ or make temporarily __invisible__ the ManualObject, attach it to a dedicated SceneNode. 
Then you can apply the wanted operations to its SceneNode.

Here you see an example for moving:
{CODE(wrap="1", colors="c++")}
SceneNode mySceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("mySceneNode");

// attach ManualObject
mySceneNode->attachObject(manual);

// move it
mySceneNode->setPosition(0, 10, 0);
{CODE}


If you want to clamp the ManualObject to a movable object (e.g. a vehicle), just attach the ManualObject (or its dedicated SceneNode) to the SceneNode of the movable object.


%%%
!!Rendering Types
enum Ogre::RenderOperation::OperationType
|| OT_POINT_LIST |  A list of points |  1 vertex per point
 OT_LINE_LIST |  A list of lines |  2 vertices per line
 OT_LINE_STRIP |  A strip of connected lines  |  1 start vertex and 1 vertex per line
 OT_TRIANGLE_LIST |  A list of triangles |  3 vertices per triangle
 OT_TRIANGLE_STRIP |  A strip of triangles |  3 vertices for the first triangle and 1 per triangle after that
 OT_TRIANGLE_FAN |  A fan of triangles |  3 vertices for the first triangle and 1 per triangle after that
||

%%%

{img fileId="1947" thumb="y" align="right" stylebox="border"} 
__Triangle Strip:__

A triangle strip is a series of connected triangles, sharing vertices, allowing for faster rendering and more efficient memory usage. They are optimized on most graphics cards, making them the most efficient way of describing an object.
More details you find in this [http://en.wikipedia.org/wiki/Triangle_strip|Wikipedia page].

{img fileId="1948" thumb="y" align="right" stylebox="border"} 
__Triangle Fan:__
A triangle fan describes a set of connected triangles that share one central vertex. 
More details you find in this [http://en.wikipedia.org/wiki/Triangle_fan|Wikipedia page].

Using a ''triangle strip'' or ''triangle fan'' you need just N+2 vertices for describing N triangles (instead of 3N as for seperately defined triangles). 

__Points:__
The size of one point is 1 pixel, independent of its distance to the camera. The point size can be changed by the ((-material|material)) settings. Use [http://www.ogre3d.org/docs/api/html/classOgre_1_1Material.html#a8c26b7ccb050d96cd031db31bf996b48|Material::setPointSize()] for the whole material or more differentiated [http://www.ogre3d.org/docs/api/html/classOgre_1_1Technique.html#a1b7d1d264b34c50b7606c646415a50e8|Technique::setPointSize()] or [http://www.ogre3d.org/docs/api/html/classOgre_1_1Pass.html#a2b0cfe1d55b1c03e59c4e3f546d2ec78|Pass::setPointSize()].
It's also possible to render the line thickness dependent to the distance. For details look to [http://www.ogre3d.org/docs/api/html/classOgre_1_1Pass.html#a0d44f9c4a2e69fd31a4687ffe2b8335d|setPointAttenuation], [http://www.ogre3d.org/docs/api/html/classOgre_1_1Pass.html#a75a3e18e0d2c3e7f51a47cedcec0246c|setPointMinSize], [http://www.ogre3d.org/docs/api/html/classOgre_1_1Pass.html#a463b59eaa324934370441a98b8b619b3|setPointMaxSize] and
[http://www.ogre3d.org/docs/api/html/classOgre_1_1Pass.html#a9683c2f40ed7c96b708eb2db5e02c842|setPointSpritesEnabled] of the ''Pass'' class.


%%%
!!Details

''This detailed description was copied from the Ogre 1.7.1 class reference of ManualObject.''


Building one-off geometry objects manually usually requires getting down and dirty with the vertex buffer and vertex declaration API, which some people find a steep learning curve. This class gives you a simpler interface specifically for the purpose of building a 3D object simply and quickly. Note that if you intend to instance your object you will still need to become familiar with the Mesh class. 


This class draws heavily on the interface for OpenGL immediate-mode (glBegin, glVertex, glNormal etc), since this is generally well-liked by people. There are a couple of differences in the results though - internally this class still builds hardware buffers which can be re-used, so you can render the resulting object multiple times without re-issuing all the same commands again. Secondly, the rendering is not immediate, it is still queued just like all OGRE objects. This makes this object more efficient than the equivalent GL immediate-mode commands, so it's feasible to use it for large objects if you really want to. 


To construct some geometry with this object:

* If you know roughly how many vertices (and indices, if you use them) you're going to submit, call estimateVertexCount and estimateIndexCount. This is not essential but will make the process more efficient by saving memory reallocations.
* Call __begin()__ to begin entering data
* For each vertex, call __position()__, __normal()__, __textureCoord()__, __colour()__ to define your vertex data. Note that each time you call __position()__ you start a new vertex. Note that the first vertex defines the components of the vertex - you can't add more after that. For example if you didn't call __normal()__ in the first vertex, you cannot call it in any others. You ought to call the same combination of methods per vertex.
* If you want to define triangles (or lines/points) by indexing into the vertex list, you can call __index()__ as many times as you need to define them. If you don't do this, the class will assume you want triangles drawn directly as defined by the vertex list, i.e. non-indexed geometry. Note that stencil shadows are only supported on indexed geometry, and that indexed geometry is a little faster; so you should try to use it.
* Call __end()__ to finish entering data.
* Optionally repeat the begin-end cycle if you want more geometry using different rendering operation types, or different materials After calling __end()__, the class will organise the data for that section internally and make it ready to render with. Like any other ((-MovableObject|MovableObject)) you should attach the object to a ((-SceneNode|SceneNode)) to make it visible. Other aspects like the relative render order can be controlled using standard MovableObject methods like __setRenderQueueGroup__.

You can also use __beginUpdate()__ to alter the geometry later on if you wish. If you do this, you should call __setDynamic(true)__ before your first call to __begin()__, and also consider using __estimateVertexCount__ / __estimateIndexCount__ if your geometry is going to be growing, to avoid buffer recreation during growth. 

Note that like all OGRE geometry, __triangles should be specified in anti-clockwise winding order__ (whether you're doing it with just vertices, or using indexes too). That is to say that the front of the face is the one where the vertices are listed in anti-clockwise order. 


!!Basics about 3D objects

!!!A Crash Course in 3D Objects
''This section was taken from the ((Intermediate Tutorial 4)).''

Before we start diving directly into making a mesh, it would probably be useful to talk about what a mesh is, and what it is made up of. Though this is a gross oversimplification, a mesh consists of roughly two parts: the ''vertex buffer'' and the ''index buffer''.

__Vertex buffers__ define points in 3D space. Each element in the vertex buffer is defined by several attributes you can set. The only attribute you ''must'' set is the position of the vertex. Aside from that, there are many optional properties you can set, such as the color of the vertex, the texture coordinates, and so on. Which ones you will actually need to use is dependent on what you are trying to do with the mesh.

__Index buffers__ "connect the dots" by selecting points from the vertex buffer. Every three indexes specified in the index buffer defines a single triangle to be drawn by the GPU. The order in which you select vertices in the index buffer tells the graphics card which way the triangle faces. A triangle which is drawn counter-clockwise is facing you, one drawn clockwise is facing away from you. Normally only the front of a triangle is rendered, so it is important to be sure that your triangles are setup properly.

Though all meshes have a vertex buffer, not all meshes will have an index buffer. For example, the mesh we are about to create will not have an index buffer since we want to create an empty rectangle (as opposed to a filled rectangle). Lastly, note that vertex and index buffers are usually stored in the video card's own memory, so your software can just send the card one simple, discrete set of commands to tell it to use those predefined buffers to render an entire 3D mesh in one go.

!!!How to create 3D objects (by code)
''This section was taken from the ((Intermediate Tutorial 4)).''

There are two ways to create your own mesh within Ogre. The first way is to subclass the __SimpleRenderable__ object and provide it with the vertex and index buffers directly. This is the most direct way to create one, but it's also the most cryptic. The ((Generating A Mesh)) code snippet shows an example of this. 

To make things easier, Ogre provides a much nicer interface called __ManualObject__, which allows you to use some simple functions to define a mesh instead of writing raw data to the buffer objects. Instead of dropping the position, color, and so on into a buffer, you simply call the "position" and "colour" functions.



{TRANSCLUDE(page="seebox")}
* [http://www.ogre3d.org/docs/api/html/classOgre_1_1ManualObject.html|Class reference] for ManualObject
* Other ManualObject examples: ((Line 3D|Line3D)), ((DynamicLineDrawing)), ((Circle3D)), ((ManualObject 2D))
* MOGRE: ((MOGRE Line 3D|Line 3D)), ((Create Tetrahedron with MOGRE|Create Tetrahedron)), ((MOGRE GeneratingAGrid|Generating a grid))
* ((MadMarx Tutorial 3)) - ManualObject Quad
* ((MadMarx Tutorial 4)) - ManualObject to Mesh
* Important remarks are in its [http://www.ogre3d.org/docs/api/html/classOgre_1_1ManualObject.html#_details|API description] of ManualObject
* API description of ''[http://www.ogre3d.org/docs/api/html/classOgre_1_1ManualObject.html#657275e617d9558951a3037f02b07efe|convertToMesh()]''
* API description of [http://www.ogre3d.org/docs/api/html/classOgre_1_1SimpleRenderable.html|SimpleRenderable]
* API description of [http://www.ogre3d.org/docs/api/html/classOgre_1_1ManualObject.html#7f832d5605c489db7be396ec7cd20b85|identity projection]
* ((Ogre Procedural Geometry Library)) -  A library to quickly create geometric primitives
* ((DynamicLineDrawing)) - create a line by the class ''SimpleRenderable'', which can be modified with better performance (e.g. change size of a circle)
* ((Debug Drawing Utility Class))

{TRANSCLUDE}

        

History

Information Version
Fri 15 of Jun, 2018 13:35 GMT-0000 paroj 40
Fri 27 of Jul, 2012 09:36 GMT-0000 Arkiruthis Added note about "tangent vectors" to avoid posts about mysterious "Assertion Failed! expression: pRep" caused by MeshPtr and non-indexed Manual Objects. 39
Fri 24 of Feb, 2012 12:33 GMT-0000 Beauty Added note for performance leak related to strips/fans 38
Fri 24 of Feb, 2012 12:21 GMT-0000 Beauty added note for "less triangles per section" 37
Mon 06 of Feb, 2012 13:34 GMT-0000 Beauty added links 36
Mon 06 of Feb, 2012 13:16 GMT-0000 Beauty improved section "Basics about ManualObject" 35
Wed 01 of Feb, 2012 17:42 GMT-0000 Beauty new section "Modification" + tiny changes 34
Wed 16 of Nov, 2011 16:40 GMT-0000 spacegaier compacted the layout; changed order of text blocks 33
Wed 16 of Nov, 2011 11:00 GMT-0000 Beauty added notes related to the RenderTypes 32
Wed 09 of Nov, 2011 17:02 GMT-0000 Beauty added link 31
Thu 27 of Oct, 2011 11:32 GMT-0000 Beauty added Table of content and quick description 30
Thu 27 of Oct, 2011 00:05 GMT-0000 Beauty added "notes" section 29
Sun 31 of Jul, 2011 23:39 GMT-0000 jacmoe 28
Sun 06 of Mar, 2011 19:32 GMT-0000 Beauty removed redundant code comments 27
Sun 06 of Mar, 2011 19:30 GMT-0000 Beauty extended the example section + added missing line of code (the first square example had only 3 lines instead of 4) 26
Sun 06 of Mar, 2011 18:34 GMT-0000 Beauty updated page description 25
Sun 06 of Mar, 2011 18:31 GMT-0000 Beauty mistype correction 24
Sun 06 of Mar, 2011 18:00 GMT-0000 Beauty replaced ugly LEX-Tags by "normal" links. .... It's not even ugly - it also hides the links from the "backlinks" box. 23
Sun 06 of Mar, 2011 17:55 GMT-0000 Beauty added more information (mesh + multiple materials) 22
Sat 05 of Mar, 2011 19:45 GMT-0000 Beauty added link to ((Ogre Procedural Geometry Library)) 21
Fri 18 of Feb, 2011 11:27 GMT-0000 Beauty added tiny addition 20
Fri 18 of Feb, 2011 11:26 GMT-0000 Beauty mistype correction 19
Fri 18 of Feb, 2011 11:25 GMT-0000 Beauty added information about point display 18
Thu 03 of Feb, 2011 15:53 GMT-0000 Beauty added 2 links 17
Wed 12 of Jan, 2011 20:20 GMT-0000 Beauty added section "basics about 3D objects" + added link 16
  • «
  • 1 (current)
  • 2