Пример #1
0
    void OnMouseDown(UINT button, int x, int y)
    {
        XOrientation camOrient;
        cameraEntity->GetOrientation(&camOrient);

        if (button == 0)
            cameraControl = true;

        //shoot a cube
        else if (button == 1)
        {
            Entity* pCube = g_pScene->CreateEntity();
            g_pSelectedEntity = pCube;
            pCube->SetPosition(cameraEntity->GetPosition() + camOrient.z);
            pCube->SetVelocity(0.1f * camOrient.z);
            //pCube->SetMaxLifeTime(5.0f);

            MeshComponent* pMesh = new MeshComponent(pCube);
            pMesh->SetMeshResource("cube.nfm");

            BodyComponent* pBody = new BodyComponent(pCube);
            pBody->SetMass(10.0f);
            pBody->EnablePhysics((CollisionShape*)EngineGetResource(ResourceType::COLLISION_SHAPE,
                                 "shape_box"));


            OmniLightDesc lightDesc;
            lightDesc.radius = 4.0f;
            lightDesc.shadowFadeStart = 20.0;
            lightDesc.shadowFadeEnd = 30.0;

            Entity* pLightEntity = g_pScene->CreateEntity();
            pCube->Attach(pLightEntity);
            //pLightEntity->SetLocalPosition(Vector(0.0f, 1.0f, 0.0f));

            LightComponent* pLight = new LightComponent(pLightEntity);
            pLight->SetOmniLight(&lightDesc);
            pLight->SetColor(Float3(1.0f, 1.0f, 10.0f));
            pLight->SetShadowMap(0);

        }
        else
        {
            Entity* pBarrel = g_pScene->CreateEntity();
            g_pSelectedEntity = pBarrel;
            pBarrel->SetPosition(cameraEntity->GetPosition() + camOrient.z);
            pBarrel->SetVelocity(30.0f * camOrient.z);

            MeshComponent* pMesh = new MeshComponent(pBarrel);
            pMesh->SetMeshResource("barrel.nfm");

            BodyComponent* pBody = new BodyComponent(pBarrel);
            pBody->SetMass(20.0f);
            pBody->EnablePhysics((CollisionShape*)EngineGetResource(ResourceType::COLLISION_SHAPE,
                                 "shape_barrel"));

        }
    }
Пример #2
0
/// Create an entity in this world.
///
/// @param[in] pLayer                Layer in which to create the entity.
/// @param[in] pType                 Entity type.
/// @param[in] rPosition             Entity position.
/// @param[in] rRotation             Entity rotation.
/// @param[in] rScale                Entity scale.
/// @param[in] pTemplate             Template from which to create the entity.
/// @param[in] name                  GameObject name to assign to the entity, or a null name to automatically generate a
///                                  name based on the entity type.
/// @param[in] bAssignInstanceIndex  True to assign an instance index to the entity, false to not include an
///                                  instance index.
///
/// @return  Pointer to the entity instance if created successfully, null if not.
///
/// @see DestroyEntity()
Entity* World::CreateEntity(
    Layer* pLayer,
    const GameObjectType* pType,
    const Simd::Vector3& rPosition,
    const Simd::Quat& rRotation,
    const Simd::Vector3& rScale,
    Entity* pTemplate,
    Name name,
    bool bAssignInstanceIndex )
{
    // Make sure the destination layer is valid.
    HELIUM_ASSERT( pLayer );
    if( !pLayer )
    {
        HELIUM_TRACE( TRACE_ERROR, TXT( "World::CreateEntity(): Missing entity layer.\n" ) );

        return NULL;
    }

    World* pLayerWorld = pLayer->GetWorld();
    HELIUM_ASSERT( pLayerWorld == this );
    if( pLayerWorld != this )
    {
        HELIUM_TRACE(
            TRACE_ERROR,
            TXT( "World::CreateEntity(): Layer \"%s\" is not bound to world \"%s\".\n" ),
            *pLayer->GetPath().ToString(),
            *GetPath().ToString() );

        return NULL;
    }

    // Attempt to create the entity.
    Entity* pEntity = pLayer->CreateEntity(
                          pType,
                          rPosition,
                          rRotation,
                          rScale,
                          pTemplate,
                          name,
                          bAssignInstanceIndex );
    if( !pEntity )
    {
        HELIUM_TRACE(
            TRACE_ERROR,
            TXT( "World::CreateEntity(): Failed to create entity in world \"%s\", layer \"%s\".\n" ),
            *GetPath().ToString(),
            *pLayer->GetPath().ToString() );

        return NULL;
    }

    // Attach the entity to the world.
    pEntity->Attach();

    return pEntity;
}
Пример #3
0
/// Add a layer to this world.
///
/// @param[in] pLayer  Layer to add.
///
/// @return  True if the layer was added successfully, false if not.
///
/// @see RemoveLayer()
bool World::AddLayer( Layer* pLayer )
{
    // Make sure a valid layer not already attached to a world was specified.
    HELIUM_ASSERT( pLayer );
    if( !pLayer )
    {
        HELIUM_TRACE( TRACE_ERROR, TXT( "World::AddLayer(): Null layer specified.\n" ) );

        return false;
    }

    World* pExistingWorld = pLayer->GetWorld();
    HELIUM_ASSERT( !pExistingWorld );
    if( pExistingWorld )
    {
        HELIUM_TRACE(
            TRACE_ERROR,
            TXT( "World::AddLayer(): Layer \"%s\" is already bound to world \"%s\".\n" ),
            *pLayer->GetPath().ToString(),
            *pExistingWorld->GetPath().ToString() );

        return false;
    }

    // Add the layer to our layer list and set it referencing back to this world.
    size_t layerIndex = m_layers.Push( LayerPtr( pLayer ) );
    HELIUM_ASSERT( IsValid( layerIndex ) );
    pLayer->SetWorldInfo( this, layerIndex );

    // Attach all entities in the layer.
    size_t entityCount = pLayer->GetEntityCount();
    for( size_t entityIndex = 0; entityIndex < entityCount; ++entityIndex )
    {
        Entity* pEntity = pLayer->GetEntity( entityIndex );
        HELIUM_ASSERT( pEntity );
        pEntity->Attach();
    }

    return true;
}
Пример #4
0
/// Update all worlds for the current frame.
void WorldManager::Update()
{
    // Update the world time.
    UpdateTime();

    // Perform the entity pre-update.
    m_updatePhase = UPDATE_PHASE_PRE;
    {
        JobContext::Spawner< 1 > entityUpdateSpawner;
        JobContext* pContext = entityUpdateSpawner.Allocate();
        HELIUM_ASSERT( pContext );
        WorldManagerUpdate< EntityPreUpdate >* pJob = pContext->Create< WorldManagerUpdate< EntityPreUpdate > >();
        HELIUM_ASSERT( pJob );
        WorldManagerUpdate< EntityPreUpdate >::Parameters& rParameters = pJob->GetParameters();
        rParameters.pspWorlds = m_worlds.GetData();
        rParameters.worldCount = m_worlds.GetSize();
    }

    // Perform the entity post-update.
    m_updatePhase = UPDATE_PHASE_POST;
    {
        JobContext::Spawner< 1 > entityUpdateSpawner;
        JobContext* pContext = entityUpdateSpawner.Allocate();
        HELIUM_ASSERT( pContext );
        WorldManagerUpdate< EntityPostUpdate >* pJob = pContext->Create< WorldManagerUpdate< EntityPostUpdate > >();
        HELIUM_ASSERT( pJob );
        WorldManagerUpdate< EntityPostUpdate >::Parameters& rParameters = pJob->GetParameters();
        rParameters.pspWorlds = m_worlds.GetData();
        rParameters.worldCount = m_worlds.GetSize();
    }

    // Perform the entity synchronous update.
    m_updatePhase = UPDATE_PHASE_SYNCHRONOUS;

    size_t worldCount = m_worlds.GetSize();
    for( size_t worldIndex = 0; worldIndex < worldCount; ++worldIndex )
    {
        World* pWorld = m_worlds[ worldIndex ];
        HELIUM_ASSERT( pWorld );
        size_t layerCount = pWorld->GetLayerCount();
        for( size_t layerIndex = 0; layerIndex < layerCount; ++layerIndex )
        {
            Layer* pLayer = pWorld->GetLayer( layerIndex );
            HELIUM_ASSERT( pLayer );
            size_t entityCount = pLayer->GetEntityCount();
            for( size_t entityIndex = 0; entityIndex < entityCount; ++entityIndex )
            {
                Entity* pEntity = pLayer->GetEntity( entityIndex );
                HELIUM_ASSERT( pEntity );

                bool bNeedsSynchronousUpdate = pEntity->NeedsSynchronousUpdate();
                uint32_t deferredWorkFlags = pEntity->GetDeferredWorkFlags();
                if( !bNeedsSynchronousUpdate && !deferredWorkFlags )
                {
                    continue;
                }

                if( deferredWorkFlags & Entity::DEFERRED_WORK_FLAG_DESTROY )
                {
                    pLayer->DestroyEntity( pEntity );
                    --entityIndex;

                    // Only the current entity should be destroyed; entity destruction should not trigger the
                    // immediate creation or destruction of other entities.
                    --entityCount;
                    HELIUM_ASSERT( pLayer->GetEntityCount() == entityCount );

                    continue;
                }

                // Entity::NeedsSynchronousUpdate() also checks the deferred work flags.
                if( bNeedsSynchronousUpdate /*deferredWorkFlags & Entity::DEFERRED_WORK_FLAG_UPDATE*/ )
                {
                    pEntity->SynchronousUpdate( m_frameDeltaSeconds );

                    // Update the entity count in case a new entity was created during the synchronous update.
                    entityCount = pLayer->GetEntityCount();
                    HELIUM_ASSERT( entityIndex < entityCount );

                    // Update the deferred work flags and reassess entity destruction after the synchronous update.
                    deferredWorkFlags = pEntity->GetDeferredWorkFlags();

                    if( deferredWorkFlags & Entity::DEFERRED_WORK_FLAG_DESTROY )
                    {
                        pLayer->DestroyEntity( pEntity );
                        --entityIndex;

                        // Only the current entity should be destroyed; entity destruction should not trigger the
                        // immediate creation or destruction of other entities.
                        --entityCount;
                        HELIUM_ASSERT( pLayer->GetEntityCount() == entityCount );

                        continue;
                    }
                }

                if( deferredWorkFlags & Entity::DEFERRED_WORK_FLAG_REATTACH )
                {
                    pEntity->Detach();
                    pEntity->Attach();

                    // Entities should only be spawned during the synchronous update call, so the count should not
                    // have changed as a result of reattachment.
                    HELIUM_ASSERT( pLayer->GetEntityCount() == entityCount );
                }

                pEntity->ClearDeferredWorkFlags();
            }
        }
    }

    m_updatePhase = UPDATE_PHASE_INVALID;

    // Update the graphics scene for each world.
    for( size_t worldIndex = 0; worldIndex < worldCount; ++worldIndex )
    {
        World* pWorld = m_worlds[ worldIndex ];
        HELIUM_ASSERT( pWorld );
        pWorld->UpdateGraphicsScene();
    }
}