--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef MARKLIN3D_OBJECT_H_
+#define MARKLIN3D_OBJECT_H_
+
+#include "libmarklin/geometry.h"
+
+namespace Marklin {
+
+class Object3D
+{
+protected:
+ Object3D() { }
+public:
+ virtual ~Object3D() { }
+
+ virtual Point get_node() const = 0;
+};
+
+} // namespace Marklin
+
+#endif
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include "layout.h"
+#include "train.h"
+
+namespace Marklin {
+
+Train3D::Train3D(Layout3D &l, const Train &t):
+ layout(l),
+ train(t)
+{
+ layout.add_train(*this);
+}
+
+Train3D::~Train3D()
+{
+ layout.remove_train(*this);
+}
+
+Point Train3D::get_node() const
+{
+ const Point &pos = train.get_position();
+ return Point(pos.x, pos.y, pos.z+0.02);
+}
+
+} // namespace Marklin
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef MARKLIN3D_TRAIN_H_
+#define MARKLIN3D_TRAIN_H_
+
+#include "libmarklin/train.h"
+#include "object.h"
+
+namespace Marklin {
+
+class Layout3D;
+
+class Train3D: public Object3D
+{
+private:
+ Layout3D &layout;
+ const Train &train;
+
+public:
+ Train3D(Layout3D &, const Train &);
+ ~Train3D();
+
+ const Train &get_train() const { return train; }
+
+ virtual Point get_node() const;
+};
+
+} // namespace Marklin
+
+#endif