gtkradiant/plugins/md3model/doc/md3-design.txt
TTimo 12b372f89c ok
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant@1 8a3a26a2-13c4-0310-b231-cf6edde360e5
2006-02-10 22:01:20 +00:00

172 lines
5.5 KiB
Text

map objects module
==================
Objective:
----------
#1 Turn the md3 code into a module. That is handle all aspects of map objects in
a module. This involves:
- the rendering of the model (sleep mode / shader reload are associated issues)
- the manipulation in the editor (moving, rotating, (scaling?))
#2 Have an API generic enough to support other formats than md3. (md1 / md2 for
multiple games support, any other formats).
What we have:
-------------
What is the current implementation of md3 support? Were are the important
features that we will need to work with?
"misc_model" is the required classname for any map object
entity_t::md3Class
eclass_t *md3Class;
This holds the actual md3 object and the rendering information (tri soup,
shader etc.)
entity_t also has vRotation and vScale which are particular to the model
for selection of the brush (selection is preliminary step before any
manipulation operation), we create a bounding box from the md3 information
and use the entity's brush list as storage for it.
Requirements:
-------------
Some technical requirements go on top of our objective given the existing
implementation. The most important one is that the changes applied to the
core must remain focused around the md3 functionality, and must also lay
out the basics of some wider changes. We can identify some of those changes:
- introducing a more generalized way of selecting and manipulation things
in the editor.
- introducing a more generic way of rendering objects in the editor.
More specifically, the details of rendering and manipulation:
transformation
translate&rotate:
A transformation increment is provided
The object is transformed by a specified increment.
Depending on the object type, the transformations may affect
the local coordinate space transformation instead of the object.
This local transformation is used in selection and rendering.
selection:
ray:
Radiant asks model for its world-relative axis-alignedbounding box.
Radiant does intersection test with this bounding box.
If test shows intersection, radiant gives model a ray_t, model tests
for intersection with ray, model returns bool true if intersection
A selection ray in world-space (origin+direction) is provided.
The object must say whether or not it intersects with the ray.
map objects have a special configuration to test on bounding box or trisoup
this is set in preferences independently from the true/false selection tests
area:
radiant uses a bounding box for area selection. (bounding box can be
infinite in some directions for the 'select tall' operations, in practice
we just make them big enough).
rendering:
geometry:
Radiant tells the object what combination of 4 opengl states is currently active:
none - draw as wireframe
fill - draw as filled
alpha blend - provide an opacity value
texture_2d - provide a texture and texture coordinates
lighting - provide normals, enable/disable smooth shading
The object uses opengl to set up its geometry and to draw itself.
material:
The object provides a material name and is assigned a reference to
a shader that matches the name.
The shader contains the texture ID and the opacity value.
The shader is a reference to an external script and must be refreshed
on request.
Proposed implementation:
========================
changes in shared interfaces (include/ directory):
--------------------------------------------------
The following new interfaces will be added:
most likely those interfaces will be implemented in the module
/*!
something that can be selected
*/
class ISelect
{
bool TestRay(ray_t) = 0
bool TestBox(vec3_t vec_min, vec3_t vec_max) = 0;
}
/*!
something that can be selected for edition
this must be synced with entity epairs
(such as origin and angles keys)
*/
class IEdit
{
void Translate(vec3_t v) = 0;
void Rotate(vec3_t origin, vec3_t angles) = 0;
}
for rendering, the existing IGL2DWindow and IGL3DWindow APIs
we can define
class IRender : public IGL2DWindow, public IGL3DWindow
so that we have the Render2D and Render3D on the same class
entity_t will have to be modified, adding the following struct:
typedef struct entity_interfaces_s
{
ISelect *pSelect
IEdit *pEdit
IRender *pRender
}
entity_interfaces_t;
When one of the pointers inside entity_t::entity_interfaces
is != we will handle the entity differently that what we are
doing by default. We will rely on these APIs for rendering,
manipulation etc.
the AABB issue:
changes in the core:
--------------------
In all cases where the entity_t has to be drawn, tested for selection,
manipulated (translation and rotation), add new code to go through the APIs.
md3 module:
-----------
static function table API
- registering of "model" module
need some minors? "md3" etc.
- BuildEntity(entity_t)
if an entity involved with models is found, core will call this
entity_t::entity_interfaces will be filled with the relevant classes
(NOTE:L we don't have a need right now to manipulate a model that
would not be part of an entity. so let's not try to guess what it
would be like)
CModel
stores the trisoup, local AABBs, references to shaders
(CModel potentially needs a CModelManager to handle
model loads and cached models queries)
CModelEntity implements IRender ISelect IEdit
stores an entity_t*
implements the interfaces pointed to in the entity_t
is reference counted obviously
stores a CModel*, calls up to it with entity information for rendering