Suggerirei di utilizzare un boost::shared_ptr
in queste strutture di posizione. In questo modo, non devi preoccuparti dell'eliminazione e puoi utilizzarlo come puntatore condiviso con l'oggetto del motore di gioco o come puntatore indipendente.
Poiché è presente un sovraccarico, è possibile limitare il rapporto tra dati e puntatore. In altre parole, non mantenere uno shared_ptr
per ogni coordinata, ma un shared_ptr
per il vettore di posizione e un shared_ptr
per il rappresentante di rotazione o un shared_ptr
su una trasformazione o un frame omogeneo (sistema di coordinate, frame cinetico o cornice cinetostatica).
Ad esempio, si potrebbe avere questo:
class object {
public:
typedef boost::shared_ptr<Vector3D> pVector3D;
private:
pVector3D position;
public:
object(pVector3D aPos = pVector3D(new Vector3D(0.0,0.0,0.0))) : position(aPos) { };
};
La proprietà automatica e riferimento conteggio del shared_ptr farà in modo che non sarà necessario preoccuparsi di mettere una dichiarazione di cancellazione (automatico) e non non c'è pericolo che l'oggetto scompaia dal motore di gioco mentre il motore fisico ha ancora bisogno di quelle variabili (il conteggio dei riferimenti garantisce che verranno eliminati solo quando tutti gli oggetti che ne hanno bisogno vengono anch'essi cancellati).
EDIT
Preferirei non usare boost. Tuttavia non sono contrario a una soluzione che richiede un modello. Inoltre, con questo in parte una ottimizzazione delle prestazioni , boost :: shared_ptr, non sembra che la soluzione giusta sia .
Beh, shared_ptr
/shared_array
si possono trovare anche nella relazione tecnica libreria standard 1 (TR1) (quindi è std::tr1::shared_ptr
, invece, in modo che non c'è bisogno di utilizzare Boost usare quelli). Per quanto riguarda l'ottimizzazione delle prestazioni, è per questo che raccomando un rapporto abbastanza elevato di data-to-pointer.Il sovraccarico di shared_ptr è principalmente un overhead di memoria e qualche riferimento indiretto durante la cancellazione e la copia (che sono due operazioni che non vengono eseguite così spesso), non penso che ci sia molto overhead nell'accesso ai dati a cui punta rispetto a un normale puntatore o riferimento. Devi accettare che, anche utilizzando i riferimenti, stai scambiando i dati con un sovraccarico di dati con l'overhead di accesso diretto ai dati (stai sacrificando anche la località di memoria, che è un grosso problema!). Direi che il calo delle prestazioni legato alla localizzazione della memoria sarà molto peggiore rispetto alla sola indiretta. Quindi, quando si tratta di accedere a elementi, IMO, shared_ptr, puntatori e riferimenti grezzi avranno pochissime differenze di prestazioni. In molti algoritmi che utilizzano queste variabili condivise, probabilmente sarebbe meglio copiare i dati puntati dal puntatore/riferimento alle variabili locali, calcolare con e su quelle variabili locali e quindi copiarli nuovamente nella memoria puntata dal puntatore /riferimento.
Si consiglia di eseguire alcuni test personalizzati sulle prestazioni quando si utilizzano entrambe le soluzioni (utilizzando shared_ptr, utilizzando riferimenti o puntatori grezzi e copia dei dati tra il motore di gioco e il motore fisico) e vedere di persona, si potrebbe sii sorpreso di quello che trovi.
EDIT2
Hai pensato di usare schema di ereditarietà multipla. Questo problema può probabilmente essere molto ben servita con uno schema di diamante eredità:
class PositionedObject {
protected:
float Position[3];
public:
PositionedObject(float x,float y, float z) { Position[0] = x; ... };
virtual ~PositionedObject() { };
};
class VisibleObject : virtual public PositionedObject { //note that the "virtual" keyword is critical here.
... rendering-related code ... i.e. the game-engine side of the implementation
};
class RigidBody : virtual public PositionedObject { //again "virtual" is very important.
... physics code here ...
};
class MyObject : public VisibleObject, public RigidBody {
... code specific to MyObject ...
};
Questo sopra schemi fanno l'oggetto della fisica e la quota oggetto di gioco-motore gli stessi dati di posizione (con poca indirezione, poca memoria-in alto e poco problemi di memoria-località). Sono abbastanza sicuro che questo sarebbe più efficiente di qualsiasi altro schema, ma gli argomenti sulle prestazioni possono essere risolti solo con i risultati dei test che dovrai fare da soli se le prestazioni sono davvero la tua preoccupazione principale (assicurati di non farlo ottimizzazione prematura!).
Questo è quello che ho finito per fare, grazie. –