--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/m3g/m3gcore11/src/m3g_world.c Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,320 @@
+/*
+* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: World implementation
+*
+*/
+
+
+/*!
+ * \internal
+ * \file
+ * \brief World implementation
+ */
+
+#ifndef M3G_CORE_INCLUDE
+# error included by m3g_core.c; do not compile separately.
+#endif
+
+#include "m3g_world.h"
+#include "m3g_memory.h"
+
+/*----------------------------------------------------------------------
+ * Internal functions
+ *--------------------------------------------------------------------*/
+
+/*!
+ * \internal
+ * \brief Destroys this World object.
+ *
+ * \param obj World object
+ */
+static void m3gDestroyWorld(Object *obj)
+{
+ World *world = (World *) obj;
+ M3G_VALIDATE_OBJECT(world);
+
+ M3G_ASSIGN_REF(world->activeCamera, NULL);
+ M3G_ASSIGN_REF(world->background, NULL);
+
+ m3gDestroyGroup(obj);
+}
+
+/*!
+ * \internal
+ * \brief Overloaded Object3D method.
+ *
+ * \param self World object
+ * \param time current world time
+ * \return minimum validity
+ */
+static M3Gint m3gWorldApplyAnimation(Object *self, M3Gint time)
+{
+ M3Gint minValidity;
+ World *world = (World *)self;
+ M3G_VALIDATE_OBJECT(world);
+
+ minValidity = m3gGroupApplyAnimation(self, time);
+
+ if (world->background != NULL && minValidity > 0) {
+ M3Gint validity = M3G_VFUNC(Object, world->background, applyAnimation)((Object *)world->background, time);
+ minValidity = (minValidity < validity ? minValidity : validity);
+ }
+ return minValidity;
+}
+
+/*!
+ * \internal
+ * \brief Overloaded Object3D method.
+ *
+ * \param self World object
+ * \param references array of reference objects
+ * \return number of references
+ */
+static M3Gint m3gWorldDoGetReferences(Object *self, Object **references)
+{
+ World *world = (World *)self;
+ M3Gint num = m3gGroupDoGetReferences(self, references);
+ if (world->activeCamera != NULL) {
+ if (references != NULL)
+ references[num] = (Object *)world->activeCamera;
+ num++;
+ }
+ if (world->background != NULL) {
+ if (references != NULL)
+ references[num] = (Object *)world->background;
+ num++;
+ }
+ return num;
+}
+
+/*!
+ * \internal
+ * \brief Overloaded Object3D method.
+ */
+static Object *m3gWorldFindID(Object *self, M3Gint userID)
+{
+ World *world = (World *)self;
+ Object *found = m3gGroupFindID(self, userID);
+
+ if (!found && world->activeCamera != NULL) {
+ found = m3gFindID((Object*) world->activeCamera, userID);
+ }
+ if (!found && world->background != NULL) {
+ found = m3gFindID((Object*) world->background, userID);
+ }
+ return found;
+}
+
+/*!
+ * \internal
+ * \brief Overloaded Object3D method.
+ *
+ * \param originalObj original World object
+ * \param cloneObj pointer to cloned World object
+ * \param pairs array for all object-duplicate pairs
+ * \param numPairs number of pairs
+ */
+static M3Gbool m3gWorldDuplicate(const Object *originalObj,
+ Object **cloneObj,
+ Object **pairs,
+ M3Gint *numPairs)
+{
+ World *original = (World *)originalObj;
+ World *clone;
+ M3G_ASSERT(*cloneObj == NULL); /* no derived classes */
+
+ /* Create the clone object */
+
+ clone = (World *)m3gCreateWorld(originalObj->interface);
+ if (!clone) {
+ return M3G_FALSE;
+ }
+ *cloneObj = (Object *)clone;
+
+ /* Duplicate base class data */
+
+ if (!m3gGroupDuplicate(originalObj, cloneObj, pairs, numPairs)) {
+ return M3G_FALSE;
+ }
+
+ /* Duplicate our own data */
+
+ M3G_ASSIGN_REF(clone->background, original->background);
+ M3G_ASSIGN_REF(clone->activeCamera, original->activeCamera);
+
+ return M3G_TRUE;
+}
+
+/*!
+ * \internal
+ * \brief Overloaded Object3D method.
+ *
+ * \param self World object
+ * \param pairs array for all object-duplicate pairs
+ * \param numPairs number of pairs
+ */
+static void m3gWorldUpdateDuplicateReferences(Node *self, Object **pairs, M3Gint numPairs)
+{
+ World *world = (World *)self;
+ m3gGroupUpdateDuplicateReferences(self, pairs, numPairs);
+ if (world->activeCamera != NULL) {
+ Node *duplicatedInstance = m3gGetDuplicatedInstance(self, pairs, numPairs);
+ Node *activeCamDuplicate = m3gGetDuplicatedInstance((Node *)world->activeCamera, pairs, numPairs);
+ if (activeCamDuplicate != NULL &&
+ m3gIsChildOf(duplicatedInstance, activeCamDuplicate)) {
+ M3G_ASSIGN_REF(((World *)duplicatedInstance)->activeCamera, activeCamDuplicate);
+ }
+ }
+}
+
+/*!
+ * \internal
+ * \brief Initializes a World object. See specification
+ * for default values.
+ *
+ * \param m3g M3G interface
+ * \param world World object
+ */
+static void m3gInitWorld(Interface *m3g, World *world)
+{
+ /* World is derived from group */
+ m3gInitGroup(m3g, &world->group, M3G_CLASS_WORLD);
+}
+
+
+/*----------------------------------------------------------------------
+ * Virtual function table
+ *--------------------------------------------------------------------*/
+
+static const NodeVFTable m3gvf_World = {
+ {
+ {
+ m3gWorldApplyAnimation,
+ m3gNodeIsCompatible,
+ m3gNodeUpdateProperty,
+ m3gWorldDoGetReferences,
+ m3gWorldFindID,
+ m3gWorldDuplicate,
+ m3gDestroyWorld
+ }
+ },
+ m3gGroupAlign,
+ NULL, /* pure virtual DoRender */
+ m3gGroupGetBBox,
+ m3gGroupRayIntersect,
+ m3gGroupSetupRender,
+ m3gWorldUpdateDuplicateReferences,
+ m3gGroupValidate
+};
+
+
+/*----------------------------------------------------------------------
+ * Public API functions
+ *--------------------------------------------------------------------*/
+
+/*!
+ * \brief Creates a World object.
+ *
+ * \param interface M3G interface
+ * \retval World new World object
+ * \retval NULL World creating failed
+ */
+
+/*@access M3Ginterface@*/
+/*@access M3Gobject@*/
+M3G_API M3GWorld m3gCreateWorld(M3GInterface interface)
+{
+ Interface *m3g = (Interface *) interface;
+ M3G_VALIDATE_INTERFACE(m3g);
+
+ {
+ World *world = m3gAllocZ(m3g, sizeof(World));
+
+ if (world != NULL) {
+ m3gInitWorld(m3g, world);
+ }
+
+ return (M3GWorld) world;
+ }
+}
+
+/*!
+ * \brief Set active camera.
+ *
+ * \param handle World object
+ * \param hCamera Camera object
+ */
+
+/*@access M3Gobject@*/
+M3G_API void m3gSetActiveCamera(M3GWorld handle, M3GCamera hCamera)
+{
+ World *world = (World *) handle;
+ M3G_VALIDATE_OBJECT(world);
+
+ if(hCamera == NULL) {
+ m3gRaiseError(M3G_INTERFACE(world), M3G_NULL_POINTER);
+ return;
+ }
+
+ M3G_ASSIGN_REF(world->activeCamera, hCamera);
+}
+
+/*!
+ * \brief Set background.
+ *
+ * \param handle World object
+ * \param hBackground Background object
+ */
+
+/*@access M3Gobject@*/
+M3G_API void m3gSetBackground(M3GWorld handle, M3GBackground hBackground)
+{
+ World *world = (World *) handle;
+ M3G_VALIDATE_OBJECT(world);
+
+ M3G_ASSIGN_REF(world->background, hBackground);
+}
+
+/*!
+ * \brief Get background.
+ *
+ * \param handle World object
+ * \return Background object
+ */
+
+/*@access M3Gobject@*/
+M3G_API M3GBackground m3gGetBackground(M3GWorld handle)
+{
+ World *world = (World *) handle;
+ M3G_VALIDATE_OBJECT(world);
+
+ return world->background;
+}
+
+/*!
+ * \brief Get active camera.
+ *
+ * \param handle World object
+ * \return Camera object
+ */
+
+/*@access M3Gobject@*/
+M3G_API M3GCamera m3gGetActiveCamera(M3GWorld handle)
+{
+ World *world = (World *) handle;
+ M3G_VALIDATE_OBJECT(world);
+
+ return world->activeCamera;
+}
+