m3g/m3gcore11/src/m3g_world.c
changeset 0 5d03bc08d59c
--- /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;
+}
+