"Mesh" should be an interface or an abstract class?

Started by
31 comments, last by swiftcoder 11 years, 6 months ago

class IMesh
{
public:
virtual void update(float dt) = 0;
virtual void render() = 0;
};

or

class AMesh
{
public:
virtual void update(float dt) = 0;
virtual void render() = 0;
public:
D3DXFRAME *m_Root;
};

Any advices please?
Thanks
Jack
Advertisement
If every every subclass of Mesh needs m_Root, put it there, else, don't. Also, you might want to hide m_Root.
What kind of classes are you going to have that inherit from IMesh/AMesh?
What is a mesh? (it's a collection of vertex buffers and an index buffer - not a transform matrix)

Why does a mesh know how to update itself? (it shouldn't - that's a job for a MeshAnimator)

Why does a mesh know how to render itself? (it shouldn't - that's a job for a MeshRenderer)

Required reading: single responsibility principle, open/closed principle

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

rnlf: Yes, all classes derived from it need a hierarchy of frames/meshcontainers
Hodgman: CCBMesh, CVNAMesh, COperatorMesh etc
swiftcoder: I think I should use aggregation here, comprises of a MeshRenderer and a MeshAnimator?

Represntation == mesh

I've got a diagram here

[attachment=11117:PerfectSim_ClassDiagram3.jpg]


BTW, should I add a class called RigidRepresentation, under it, there are Warehouse, VNA, CB and handtrolley?
You're over-designing things and using bad OO principles. swiftcoder has it right. Rather than creating a class for every single thing in your game, create only a few classes which work for a wide variety of cases. This is the essence of data-oriented design.

Always favor composition over inheritance whenever possible - rather than having an IMoveable interface and an IStatic interface for objects, use a boolean flag or enum instead. It will save a significant amount of headaches later and be more efficient.

Meshes use an almost universal representation - index buffer, vertex buffer, maybe a material/shader - so it makes sense to just have Mesh be a simple concrete class. A mesh is just data, nothing more. It should be another class's job to animate or render the mesh. After all, even if you have some complex shape representation (heightfield, curved surfaces) you will still likely be converting that to a basic triangle mesh before sending it to the hardware. I use an abstract 'Shape' class which can describe any type of shape. During rendering, each shape provides a mesh (or multiple meshes) representation of itself to the renderer. This allows you to do LOD really easily too. Each shape can manage its own LOD state and produce the best mesh for current scene configuration.
Hello Aressera,
Could you please recommend a good book on game design techniques based on OOP concepts?
What is a data-driven design anyway? Could you please give an example?

http://www.amazon.co...amming & Design

Yes, I also notice different meshes exhibit similar or common behaviours, they should be in the same "mesh" class.


Thanks
Jack
Data-oriented design is basically the process of describing the function of a program in data - be it an XML material specification, runtime scripting, etc. Rather than making large complex functions that operate on dumb data, the goal is to move the intelligence to the data: The application becomes analogous to an interpreter, doing what the data says, albeit at a high level.

When this strategy is applied to software design, I have noticed that certain patterns of classes emerge. First, I tend to have pure-data classes that just store and manage some data (i.e. the Mesh class). These pure data classes can then be aggregated into larger, more complex data models, or operated on by functions or classes that act as simple operations with some object state (MeshRenderer, MeshAnimator).

If I had to pick the most important 'commandments' of software design I've developed, they'd be:

  • Classes should in general only perform only one task or hold one type of data. Same goes for functions. This is the single responsibility principle. It keeps you from creating monolithic functions/classes that do 1001 things that produce hard to debug and unorganized code.
  • Avoid dependencies between classes and modules wherever possible. This keeps the individual parts small and simple, producing easier to debug and more robust code. Changes in one module rarely effect another.
  • Keep your code simple while providing maximum flexibility. This tends to result in a data-oriented design without even trying.
  • Make your code as clearly legible as possible. This means good use of whitespace and indentation as well as using class and function names that read like nouns and phrases and are very clear about what they are doing, even without comments. Keep actual comments concise and precise, noting any special behavior, rather than generic Doxygen-style @param comments.

When this strategy is applied to software design, I have noticed that certain patterns of classes emerge. First, I tend to have pure-data classes that just store and manage some data (i.e. the Mesh class). These pure data classes can then be aggregated into larger, more complex data models, or operated on by functions or classes that act as simple operations with some object state (MeshRenderer, MeshAnimator).

This also implies that Mesh is going to be a single, concrete class (every mesh, regardless of what it represents, where it is used, how it is loaded, how it is rendered etc. is a bundle of various vertex and index buffers as Swiftcoder suggests, or more generally a geometry representation that is cheap to render) while MeshRenderer, MeshAnimator and the like might have interfaces, multiple genuinely different implementations and possibly inheritance hierarchies: unlike meshes, such classes are going to have very few instances and, if they process whole Mesh collections, very few virtual function calls.

Omae Wa Mou Shindeiru


Data-oriented design is basically the process of describing the function of a program in data
N.B. this is "data-driven design", not "data-oriented design". The former is about making data more in control of behaviour rather than code, and the latter is a methodology for writing code that has optimal memory access patterns.

This topic is closed to new replies.

Advertisement