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