CameraMaster::CameraMaster( Context *context, MasterControl *masterControl ) : Object(context), masterControl_{masterControl} { SubscribeToEvent(E_SCENEUPDATE, HANDLER(CameraMaster, HandleSceneUpdate)); //Create the camera. Limit far clip distance to match the fog translationNode_ = masterControl_->world_.scene->CreateChild("CamTrans"); rotationNode_ = translationNode_->CreateChild("CamRot"); camera_ = rotationNode_->CreateComponent<Camera>(); camera_->SetFarClip(1024.0f); //Set an initial position for the camera scene node above the origin //translationNode_->SetPosition(Vector3(0.0f, 3.0f, 0.0f)); translationNode_->SetPosition(Vector3(0.0, 3.0,-20.0)); rotationNode_->SetRotation(Quaternion(0.0f, 90.0f, 0.0f)); rigidBody_ = translationNode_->CreateComponent<RigidBody>(); rigidBody_->SetAngularDamping(10.0f); CollisionShape* collisionShape = translationNode_->CreateComponent<CollisionShape>(); collisionShape->SetSphere(0.1f); rigidBody_->SetMass(1.0f); Node* lightNode = translationNode_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.0f, -1.0f, 0.0f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_POINT); light->SetBrightness(0.5f); light->SetColor(Color(0.7f, 0.9f, 0.6f)); light->SetCastShadows(false); SetupViewport(); }
TileMaster::TileMaster(Context *context, MasterControl* masterControl): Object(context), masterControl_{masterControl} { rootNode_ = masterControl_->world.scene->CreateChild("TileMaster"); //Create hexagonal field //Lays a field of hexagons at the origin int bigHexSize = 23; for (int i = 0; i < bigHexSize; i++) { for (int j = 0; j < bigHexSize; j++) { if (i < (bigHexSize - bigHexSize / 4) + j / 2 && //Exclude bottom right i > (bigHexSize / 4) - (j + 1) / 2 && //Exclude bottom left i + 1 < (bigHexSize - bigHexSize / 4) + ((bigHexSize - j + 1)) / 2 && //Exclude top right i - 1 > (bigHexSize / 4) - ((bigHexSize - j + 2) / 2)) { //Exclude top left Vector3 tilePos = Vector3((-bigHexSize / 2.0f + i) * 2.0f + j % 2, -0.1f, (-bigHexSize / 2.0f + j + 0.5f) * 1.8f); tileMap_[IntVector2(i, j)] = new Tile(context_, this, tilePos); } } } //Add a directional light to the arena. Enable cascaded shadows on it Node* lightNode = rootNode_->CreateChild("Sun"); lightNode->SetPosition(Vector3::UP*5.0f); lightNode->SetRotation(Quaternion(90.0f, 0.0f, 0.0f)); Light* playLight = lightNode->CreateComponent<Light>(); playLight->SetLightType(LIGHT_DIRECTIONAL); playLight->SetBrightness(0.8f); playLight->SetRange(10.0f); playLight->SetColor(Color(1.0f, 0.9f, 0.95f)); playLight->SetCastShadows(false); }
Node* SceneReplication::CreateControllableObject() { ResourceCache* cache = GetSubsystem<ResourceCache>(); // Create the scene node & visual representation. This will be a replicated object Node* ballNode = scene_->CreateChild("Ball"); ballNode->SetPosition(Vector3(Random(40.0f) - 20.0f, 5.0f, Random(40.0f) - 20.0f)); ballNode->SetScale(0.5f); StaticModel* ballObject = ballNode->CreateComponent<StaticModel>(); ballObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl")); ballObject->SetMaterial(cache->GetResource<Material>("Materials/StoneSmall.xml")); // Create the physics components RigidBody* body = ballNode->CreateComponent<RigidBody>(); body->SetMass(1.0f); body->SetFriction(1.0f); // In addition to friction, use motion damping so that the ball can not accelerate limitlessly body->SetLinearDamping(0.5f); body->SetAngularDamping(0.5f); CollisionShape* shape = ballNode->CreateComponent<CollisionShape>(); shape->SetSphere(1.0f); // Create a random colored point light at the ball so that can see better where is going Light* light = ballNode->CreateComponent<Light>(); light->SetRange(3.0f); light->SetColor(Color(0.5f + (Rand() & 1) * 0.5f, 0.5f + (Rand() & 1) * 0.5f, 0.5f + (Rand() & 1) * 0.5f)); return ballNode; }
void SceneReplication::CreateScene() { scene_ = new Scene(context_); // Create scene content on the server only ResourceCache* cache = GetSubsystem<ResourceCache>(); // Create octree and physics world with default settings. Create them as local so that they are not needlessly replicated // when a client connects scene_->CreateComponent<Octree>(LOCAL); scene_->CreateComponent<PhysicsWorld>(LOCAL); // All static scene content and the camera are also created as local, so that they are unaffected by scene replication and are // not removed from the client upon connection. Create a Zone component first for ambient lighting & fog control. Node* zoneNode = scene_->CreateChild("Zone", LOCAL); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.1f, 0.1f, 0.1f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); // Create a directional light without shadows Node* lightNode = scene_->CreateChild("DirectionalLight", LOCAL); lightNode->SetDirection(Vector3(0.5f, -1.0f, 0.5f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetColor(Color(0.2f, 0.2f, 0.2f)); light->SetSpecularIntensity(1.0f); // Create a "floor" consisting of several tiles. Make the tiles physical but leave small cracks between them for (int y = -20; y <= 20; ++y) { for (int x = -20; x <= 20; ++x) { Node* floorNode = scene_->CreateChild("FloorTile", LOCAL); floorNode->SetPosition(Vector3(x * 20.2f, -0.5f, y * 20.2f)); floorNode->SetScale(Vector3(20.0f, 1.0f, 20.0f)); StaticModel* floorObject = floorNode->CreateComponent<StaticModel>(); floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); floorObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); RigidBody* body = floorNode->CreateComponent<RigidBody>(); body->SetFriction(1.0f); CollisionShape* shape = floorNode->CreateComponent<CollisionShape>(); shape->SetBox(Vector3::ONE); } } // Create the camera. Limit far clip distance to match the fog // The camera needs to be created into a local node so that each client can retain its own camera, that is unaffected by // network messages. Furthermore, because the client removes all replicated scene nodes when connecting to a server scene, // the screen would become blank if the camera node was replicated (as only the locally created camera is assigned to a // viewport in SetupViewports() below) cameraNode_ = scene_->CreateChild("Camera", LOCAL); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); // Set an initial position for the camera scene node above the plane cameraNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f)); }
void LightWidget::onLightColorChanged(Urho3D::Color color) { if(bEditNotify == false) return; Light* pLight = (Light*)component_; if(pLight != NULL) { pLight->SetColor(color); } }
void Sample::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); sceneHierarchyWindow_->SetScene(scene_); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) // Also create a DebugRenderer component so that we can draw debug geometry scene_->CreateComponent<Octree>(); scene_->CreateComponent<DebugRenderer>(); // Create a Zone component for ambient lighting & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.5f, 0.5f, 0.5f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); // Create a directional light without shadows Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.5f, -1.0f, 0.5f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetColor(Color(0.2f, 0.2f, 0.2f)); light->SetSpecularIntensity(1.0f); // Create a "floor" consisting of several tiles for (int y = -5; y <= 5; ++y) { for (int x = -5; x <= 5; ++x) { Node* floorNode = scene_->CreateChild("FloorTile"); floorNode->SetPosition(Vector3(x * 20.5f, -0.5f, y * 20.5f)); floorNode->SetScale(Vector3(20.0f, 1.0f, 20.f)); StaticModel* floorObject = floorNode->CreateComponent<StaticModel>(); floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); floorObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); } } // Create the camera. Limit far clip distance to match the fog camNode_ = scene_->CreateChild("Camera"); Camera* camera = camNode_->CreateComponent<Camera>(); camera->SetFarClip(1300.0f); // Set an initial position for the camera scene node above the plane camNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f)); }
void GameObjectLightComponentWidget::on_m_ColorChangerButton_clicked() { if (!m_IsReady) { return; } Light* light = nullptr; //////////////////////////////////////// // Verify LOC and Get Light Object light = GetLight(); if(light == nullptr) { AETODO("Add log"); return; } //////////////////////////////////////// // Get QColor from Dialog QColorDialog qColorDiaglog; int result = qColorDiaglog.exec(); if(result != QDialog::Accepted) { return; } QColor qColor = qColorDiaglog.selectedColor(); //////////////////////////////////////// // Set Color to Widget SetColorToColorWidget(qColor); //////////////////////////////////////// // Set Color to Instance Color color = AEQTHelpers::GetColorFromQColor(qColor); light->SetColor(color); }
void DaeParser::ParseLight (Parser::Iterator light_iter) { const char* id = get<const char*> (*light_iter, "id"); Parser::Iterator iter = light_iter->First ("technique_common"); if (!iter) return; if (iter->NextNamesake ()) raise_parser_exception (iter->NextNamesake (), "Only one 'technique_common' tag allowed"); //чтение типа источника света static String2Value<LightType> light_types [] = { {"ambient", LightType_Ambient}, {"directional", LightType_Direct}, {"point", LightType_Point}, {"spot", LightType_Spot} }; static const size_t light_types_count = sizeof (light_types) / sizeof (*light_types); size_t i; LightType type = LightType_Point; for (i=0; i<light_types_count; i++) if (common::ParseNode param_node = iter->First (light_types [i].string)) { type = light_types [i].value; iter = param_node; break; } if (i == light_types_count) raise_parser_exception (*iter, "Incorrect 'technique_common' tag. No light type sub-tag (one of 'ambient', 'directional', 'point' or 'spot')"); //создание источника света Light light; light.SetId (id); //установка типа источника light.SetType (type); //чтение цвета if (common::ParseNode param_node = iter->First ("color.#text")) light.SetColor (get<vec3f> (param_node, "")); //чтение интенсивности for (Parser::NamesakeIterator technique_iter=light_iter->First ("extra.technique"); technique_iter; ++technique_iter) { const char* profile = get<const char*> (*technique_iter, "profile", ""); if (!xtl::xstricmp (profile, "OpenCOLLADA3dsMax")) { float intensity = get<float> (*technique_iter, "max_light.multiplier.#text", 1.0f); light.SetIntensity (intensity); } } //чтение параметров источника света static String2Value<LightParam> light_params [] = { {"constant_attenuation.#text", LightParam_AttenuationConstant}, {"linear_attenuation.#text", LightParam_AttenuationLinear}, {"quadratic_attenuation.#text", LightParam_AttenuationQuadratic}, {"falloff_angle.#text", LightParam_FalloffAngle}, {"falloff_exponent.#text", LightParam_FalloffExponent} }; static const size_t light_params_num = sizeof (light_params) / sizeof (*light_params); for (i=0; i<light_params_num; i++) if (common::ParseNode param_node = iter->First (light_params [i].string)) light.SetParam (light_params [i].value, get<float> (param_node, "")); //добавление источника в библиотеку model.Lights ().Insert (id, light); }
void HugeObjectCount::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); if (!scene_) scene_ = new Scene(context_); else { scene_->Clear(); boxNodes_.Clear(); } // Create the Octree component to the scene so that drawable objects can be rendered. Use default volume // (-1000, -1000, -1000) to (1000, 1000, 1000) scene_->CreateComponent<Octree>(); // Create a Zone for ambient light & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetFogColor(Color(0.2f, 0.2f, 0.2f)); zone->SetFogStart(200.0f); zone->SetFogEnd(300.0f); // Create a directional light Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(-0.6f, -1.0f, -0.8f)); // The direction vector does not need to be normalized Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); if (!useGroups_) { light->SetColor(Color(0.7f, 0.35f, 0.0f)); // Create individual box StaticModels in the scene for (int y = -125; y < 125; ++y) { for (int x = -125; x < 125; ++x) { Node* boxNode = scene_->CreateChild("Box"); boxNode->SetPosition(Vector3(x * 0.3f, 0.0f, y * 0.3f)); boxNode->SetScale(0.25f); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); boxNodes_.Push(SharedPtr<Node>(boxNode)); } } } else { light->SetColor(Color(0.6f, 0.6f, 0.6f)); light->SetSpecularIntensity(1.5f); // Create StaticModelGroups in the scene StaticModelGroup* lastGroup = 0; for (int y = -125; y < 125; ++y) { for (int x = -125; x < 125; ++x) { // Create new group if no group yet, or the group has already "enough" objects. The tradeoff is between culling // accuracy and the amount of CPU processing needed for all the objects. Note that the group's own transform // does not matter, and it does not render anything if instance nodes are not added to it if (!lastGroup || lastGroup->GetNumInstanceNodes() >= 25 * 25) { Node* boxGroupNode = scene_->CreateChild("BoxGroup"); lastGroup = boxGroupNode->CreateComponent<StaticModelGroup>(); lastGroup->SetModel(cache->GetResource<Model>("Models/Box.mdl")); } Node* boxNode = scene_->CreateChild("Box"); boxNode->SetPosition(Vector3(x * 0.3f, 0.0f, y * 0.3f)); boxNode->SetScale(0.25f); boxNodes_.Push(SharedPtr<Node>(boxNode)); lastGroup->AddInstanceNode(boxNode); } } } // Create the camera. Create it outside the scene so that we can clear the whole scene without affecting it if (!cameraNode_) { cameraNode_ = new Node(context_); cameraNode_->SetPosition(Vector3(0.0f, 10.0f, -100.0f)); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); } }
void DataViewer_GameObject::_ApplyChanges() { if ( _changeList["GameObject"] ) { _selectedObject->SetSavable( _ReadWidget_Bool( _dataGameObject.savable ) ); _selectedObject->SetEnabled( _ReadWidget_Bool( _dataGameObject.enable ) ); _selectedObject->SetName( _ReadWidget_String( _dataGameObject.name ) ); _Colorize_GameObject( _selectedObject->IsEnabled() ); _Colorize_Transform( _selectedObject->IsEnabled() ); I_Component* comp; comp = _selectedObject->GetComponent<Camera>(); if ( comp != NULL ) { _Colorize_Camera( _selectedObject->IsEnabled() && comp->IsEnabled() ); } comp = _selectedObject->GetComponent<Light>(); if ( comp != NULL ) { _Colorize_Light( _selectedObject->IsEnabled() && comp->IsEnabled() ); } comp = _selectedObject->GetComponent<MeshDrawing>(); if ( comp != NULL ) { _Colorize_MeshDrawing( _selectedObject->IsEnabled() && comp->IsEnabled() ); } for (auto& dataScript : _dataScripts) { Script* script = _selectedObject->GetComponent<Script>( dataScript.scriptName ); _Colorize_Script( _selectedObject->IsEnabled() && script->IsEnabled(), dataScript ); } _changeList["GameObject"] = false; return; } if ( _changeList["Transform_Local"] ) { Transform* transform = _selectedObject->GetComponent<Transform>(); transform->SetPositionLocal( _ReadWidget_Vector3( _dataTransform.posLocal ) ); transform->SetEulerRotationLocal( _ReadWidget_Vector3( _dataTransform.rotLocal ) ); transform->SetScaleLocal( _ReadWidget_Vector3( _dataTransform.scaleLocal ) ); _changeList["Transform_Local"] = false; return; } if ( _changeList["Transform_World"] ) { Transform* transform = _selectedObject->GetComponent<Transform>(); transform->SetPositionWorld( _ReadWidget_Vector3( _dataTransform.posWorld ) ); transform->SetEulerRotationWorld( _ReadWidget_Vector3( _dataTransform.rotWorld ) ); transform->SetScaleWorld( _ReadWidget_Vector3( _dataTransform.scaleWorld ) ); _changeList["Transform_World"] = false; return; } if ( _changeList["Light"] ) { Light* light = _selectedObject->GetComponent<Light>(); light->SetEnabled( _ReadWidget_Bool( _dataLight.enable ) ); light->SetType( EnumConvertor::s2e_LightType[ _ReadWidget_Choice( _dataLight.type ) ] ); light->SetColor( _ReadWidget_Vector3( _dataLight.color ) ); light->SetIntensity( _ReadWidget_Float( _dataLight.intensity ) ); light->SetRange( _ReadWidget_Float( _dataLight.range ) ); light->SetSpotAngle( _ReadWidget_Float( _dataLight.spotAngle ) ); light->SetCastShadows( _ReadWidget_Bool( _dataLight.castShadows ) ); _Colorize_Light( light->IsEnabled() && _selectedObject->IsEnabled() ); _changeList["Light"] = false; return; } if ( _changeList["Camera"] ) { Camera* camera = _selectedObject->GetComponent<Camera>(); camera->SetEnabled( _ReadWidget_Bool( _dataCamera.enable ) ); camera->SetType( EnumConvertor::s2e_CameraType[ _ReadWidget_Choice( _dataCamera.type ) ] ); camera->SetOrthoSize( _ReadWidget_Vector2( _dataCamera.orthoSize ) ); camera->SetFovYAngle( _ReadWidget_Float( _dataCamera.fovYAngle ) ); camera->SetAspectRatio( _ReadWidget_Float( _dataCamera.aspectRatio ) ); camera->SetNearClipping( _ReadWidget_Float( _dataCamera.nearClipping ) ); camera->SetFarClipping( _ReadWidget_Float( _dataCamera.farClipping ) ); _Colorize_Camera( camera->IsEnabled() && _selectedObject->IsEnabled() ); _changeList["Camera"] = false; return; } if ( _changeList["MeshDrawing"] ) { MeshDrawing* meshDrawing = _selectedObject->GetComponent<MeshDrawing>(); meshDrawing->SetEnabled( _ReadWidget_Bool( _dataMeshDrawing.enable ) ); String materialName = _ReadWidget_Picking( _dataMeshDrawing.material ); meshDrawing->SetMaterial( Systems::Resource()->GetMaterial( materialName ) ); String meshName = _ReadWidget_Picking( _dataMeshDrawing.mesh ); meshDrawing->SetMesh( Systems::Resource()->GetMesh( meshName ) ); meshDrawing->SetCastShadows( _ReadWidget_Bool( _dataMeshDrawing.castShadows ) ); meshDrawing->SetReceiveShadows( _ReadWidget_Bool( _dataMeshDrawing.receiveShadows ) ); _Colorize_MeshDrawing( meshDrawing->IsEnabled() && _selectedObject->IsEnabled() ); _changeList["MeshDrawing"] = false; return; } if ( _changeList["Script"] ) { for (auto& dataScript : _dataScripts) { Script* script = _selectedObject->GetComponent<Script>( dataScript.scriptName ); script->SetEnabled( _ReadWidget_Bool( dataScript.enable ) ); _Colorize_Script( script->IsEnabled() && _selectedObject->IsEnabled(), dataScript ); } _changeList["Script"] = false; return; } }
void VehicleDemo::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create scene subsystem components scene_->CreateComponent<Octree>(); scene_->CreateComponent<PhysicsWorld>(); scene_->CreateComponent<DebugRenderer>(); // Create camera and define viewport. We will be doing load / save, so it's convenient to create the camera outside the scene, // so that it won't be destroyed and recreated, and we don't have to redefine the viewport on load cameraNode_ = new Node(context_); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(500.0f); GetSubsystem<Renderer>()->SetViewport(0, new Viewport(context_, scene_, camera)); //GetSubsystem<Renderer>()->SetHDRRendering(true); RenderPath* effectRenderPath=GetSubsystem<Renderer>()->GetViewport(0)->GetRenderPath(); //effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/AutoExposure.xml")); effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/Blur.xml")); effectRenderPath->SetShaderParameter("BlurRadius", Variant(0.002f) ); effectRenderPath->SetShaderParameter("BlurSigma", Variant(0.001f) ); effectRenderPath->SetEnabled("Blur", false); // Create static scene content. First create a zone for ambient lighting and fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); //zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(0.2f, 0.2f, 0.3f)); zone->SetFogStart(300.0f); zone->SetFogEnd(500.0f); zone->SetBoundingBox(BoundingBox(-2000.0f, 2000.0f)); /* // Create a directional light with cascaded shadow mapping Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.3f, -0.5f, 0.425f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); light->SetShadowCascade(CascadeParameters(20.0f, 50.0f, 200.0f, 0.0f, 0.8f)); light->SetSpecularIntensity(0.5f); */ // Create heightmap terrain with collision Node* terrainNode = scene_->CreateChild("Terrain"); terrainNode->SetPosition(Vector3::ZERO); Terrain* terrain = terrainNode->CreateComponent<Terrain>(); terrain->SetPatchSize(64); terrain->SetSpacing(Vector3(2.0f, 0.1f, 2.0f)); // Spacing between vertices and vertical resolution of the height map terrain->SetSmoothing(true); terrain->SetHeightMap(cache->GetResource<Image>("Textures/HeightMap.png")); terrain->SetMaterial(cache->GetResource<Material>("Materials/Terrain.xml")); // The terrain consists of large triangles, which fits well for occlusion rendering, as a hill can occlude all // terrain patches and other objects behind it terrain->SetOccluder(true); RigidBody* body = terrainNode->CreateComponent<RigidBody>(); body->SetCollisionLayer(2); // Use layer bitmask 2 for static geometry CollisionShape* shape = terrainNode->CreateComponent<CollisionShape>(); shape->SetTerrain(); // Create skybox. The Skybox component is used like StaticModel, but it will be always located at the camera, giving the // illusion of the box planes being far away. Use just the ordinary Box model and a suitable material, whose shader will // generate the necessary 3D texture coordinates for cube mapping /* Node* skyNode2 = scene_->CreateChild("Sky"); skyNode2->SetScale(80.0f); // The scale actually does not matter Skybox* skybox2 = skyNode2->CreateComponent<Skybox>(); skybox2->SetModel(cache->GetResource<Model>("Models/Box.mdl")); skybox2->SetMaterial(cache->GetResource<Material>("Materials/Skybox.xml")); */ Node* skyNode = scene_->CreateChild("ProcSkyNode"); skyNode->SetEnabled(true); skyNode->SetName("ProcSkyNode"); skyNode->SetPosition(Urho3D::Vector3(0.0, 0.0, 0.0)); skyNode->SetRotation(Urho3D::Quaternion(1, 0, 0, 0)); skyNode->SetScale(Urho3D::Vector3(100.0, 100.0, 100.0)); ProcSky* procSky = skyNode->CreateComponent<ProcSky>(); procSky->SetEnabled(true); Node* skyLightNode = skyNode->CreateChild("ProcSkyLight"); skyLightNode->SetEnabled(true); skyLightNode->SetPosition(Urho3D::Vector3(0.0, 0.0, 0.0)); skyLightNode->SetRotation(Urho3D::Quaternion(0.707107, 0, -0.707107, 0)); skyLightNode->SetScale(Urho3D::Vector3(1, 1, 1)); Light* skyLight = skyLightNode->CreateComponent<Light>(); skyLight->SetLightType(LIGHT_DIRECTIONAL); skyLight->SetColor(Urho3D::Color(0.753, 0.749, 0.678, 1)); skyLight->SetSpecularIntensity(0); skyLight->SetOccludee(false); skyLight->SetOccluder(false); skyLight->SetCastShadows(true); skyLight->SetShadowCascade(Urho3D::CascadeParameters(20, 50, 100, 500, 0.8f)); skyLight->SetShadowFocus(Urho3D::FocusParameters(true, true, true, 1.0f, 5.0f)); skyLight->SetShadowBias(Urho3D::BiasParameters(1e-005, 0.001)); if (skyNode) { //ProcSky* procSky(skyNode->GetComponent<ProcSky>()); if (procSky) { // Can set other parameters here; e.g., SetUpdateMode(), SetUpdateInterval(), SetRenderSize() procSky->Initialize(); URHO3D_LOGINFO("ProcSky Initialized."); } else { URHO3D_LOGERROR("ProcSky node missing ProcSky component."); } } else { URHO3D_LOGERROR("ProcSky node not found in scene."); } // Create 1000 mushrooms in the terrain. Always face outward along the terrain normal /* const unsigned NUM_MUSHROOMS = 0; for (unsigned i = 0; i < NUM_MUSHROOMS; ++i) { Node* objectNode = scene_->CreateChild("SafetyCone"); Vector3 position(Random(2000.0f) - 1000.0f, 0.0f, Random(2000.0f) - 1000.0f); position.y_ = terrain->GetHeight(position); objectNode->SetPosition(position); // Create a rotation quaternion from up vector to terrain normal objectNode->SetRotation(Quaternion(Vector3::UP, terrain->GetNormal(position))); objectNode->SetScale(3.0f); StaticModel* object = objectNode->CreateComponent<StaticModel>(); object->SetModel(cache->GetResource<Model>("MyProjects/SafetyCone/SafetyCone.mdl")); object->SetMaterial(cache->GetResource<Material>("MyProjects/SafetyCone/ConeBase.xml")); object->SetMaterial(cache->GetResource<Material>("MyProjects/SafetyCone/SafetyCone.xml")); object->SetCastShadows(true); RigidBody* body = objectNode->CreateComponent<RigidBody>(); //body->SetCollisionLayer(2); body->SetMass(2.0f); body->SetFriction(0.75f); CollisionShape* shape = objectNode->CreateComponent<CollisionShape>(); //shape->SetTriangleMesh(object->GetModel(), 0); shape->SetConvexHull(object->GetModel(), 0); } */ }
void SceneManager::LoadFromText(const char *text) { TextParser parser; parser.Parse(text); TextParser::NODE *node = NULL; if ((node = parser.GetNode("FILETYPE")) && node->values[0] == "SCENE") { TextParser::NODE *node_data = parser.GetNode("DATA"); if (node_data) { // Models TextParser::NODE *node_models = node_data->FindChild("MODELS"); if (node_models) { for(size_t i=0;i<node_models->children.size();i++) { TextParser::NODE *child = node_models->children[i]; TextParser::NODE *node_filename = NULL; if ( child->name == "MODEL" && (node_filename = child->FindChild("FILENAME"))) { // MODEL Model *model = new Model(node_filename->values[0].GetCharPtr()); TextParser::NODE *node_position = child->FindChild("POSITION"); if (node_position) model->SetPosition(node_position->ToFVector3()); TextParser::NODE *node_scale = child->FindChild("SCALE"); if (node_scale) model->SetScale(node_scale->ToFVector3()); TextParser::NODE *node_rotation = child->FindChild("ROTATION"); if (node_rotation) model->SetRotation(node_rotation->ToFVector3()); mModels.push_back(model); } } } // Lights TextParser::NODE *node_lights = node_data->FindChild("LIGHTS"); if (node_lights) { for(size_t i=0;i<node_lights->children.size();i++) { Light *light = NULL; TextParser::NODE *child = node_lights->children[i]; TextParser::NODE *node_type = child->FindChild("TYPE"); if (node_type->values[0] == "Point") { light = new PointLight(); } else if (node_type->values[0] == "Directional") { light = new DirectionalLight(); } else if (node_type->values[0] == "Ambient") { light = new AmbientLight(); } if (!light) continue; TextParser::NODE *node_color = child->FindChild("COLOR"); if (node_color) { light->SetColor(node_color->ToFVector3()); } TextParser::NODE *node_intensity = child->FindChild("INTENSITY"); if (node_intensity) { light->SetIntensity(node_intensity->values[0].ToFloat()); } TextParser::NODE *node_pos = child->FindChild("POSITION"); if (node_pos && light->GetType() == Light::TYPE_POINT) { ((PointLight*)light)->SetPosition(node_pos->ToFVector3()); } TextParser::NODE *node_scl = child->FindChild("SCALE"); if (node_scl && light->GetType() == Light::TYPE_POINT) { ((PointLight*)light)->SetScale(node_scl->ToFVector3()); } switch(light->GetType()) { case Light::TYPE_POINT: { TextParser::NODE *node_range = child->FindChild("RANGE"); if (node_range) { ((PointLight*)light)->SetRange(node_range->values[0].ToFloat()); } TextParser::NODE *node_exp = child->FindChild("EXPONENT"); if (node_exp) { ((PointLight*)light)->SetExponent(node_exp->values[0].ToFloat()); } } break; } AddLight(light); } } } } }
void MasterControl::CreateScene() { world_.scene = new Scene(context_); //Create octree, use default volume (-1000, -1000, -1000) to (1000,1000,1000) { world_.scene->CreateComponent<Octree>(); } //Create the physics { PhysicsWorld * const physicsWorld = world_.scene->CreateComponent<PhysicsWorld>(); physicsWorld->SetGravity(Vector3::ZERO); } world_.scene->CreateComponent<DebugRenderer>(); //Create an invisible plane for mouse raycasting world_.voidNode = world_.scene->CreateChild("Void"); //Location is set in update since the plane moves with the camera. world_.voidNode->SetScale(Vector3(1000.0f, 1.0f, 1000.0f)); StaticModel* planeModel = world_.voidNode->CreateComponent<StaticModel>(); planeModel->SetModel(cache_->GetResource<Model>("Models/Plane.mdl")); planeModel->SetMaterial(cache_->GetResource<Material>("Materials/Terrain.xml")); CreateBackground(); { // Create skybox. The Skybox component is used like StaticModel, but it will be always located at the camera, giving the // illusion of the box planes being far away. Use just the ordinary Box model and a suitable material, whose shader will // generate the necessary 3D texture coordinates for cube mapping Node* skyNode = world_.scene->CreateChild("Sky"); skyNode->SetScale(500.0f); // The scale actually does not matter Skybox* skybox = skyNode->CreateComponent<Skybox>(); skybox->SetModel(cache_->GetResource<Model>("Models/Box.mdl")); skybox->SetMaterial(cache_->GetResource<Material>("Materials/Skybox.xml")); } //Create a directional light to the world. Enable cascaded shadows on it { Node* lightNode = world_.scene->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.0f, -1.0f, 0.0f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetBrightness(1.0f); light->SetColor(Color(1.0f, 0.8f, 0.7f)); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); //Set cascade splits at 10, 50, 200 world unitys, fade shadows at 80% of maximum shadow distance light->SetShadowCascade(CascadeParameters(7.0f, 23.0f, 42.0f, 500.0f, 0.8f)); } //Create a second directional light without shadows { Node * const lightNode = world_.scene->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.0, 1.0, 0.0)); Light * const light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetBrightness(0.25); light->SetColor(Color(1.0, 1.0, 1.0)); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); } //Create camera world_.camera = new CameraMaster(context_, this); }
void Water::CreateScene() { ResourceCache* cache = GetContext()->m_ResourceCache.get(); scene_ = new Scene(GetContext()); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) scene_->CreateComponent<Octree>(); // Create a Zone component for ambient lighting & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(1.0f, 1.0f, 1.0f)); zone->SetFogStart(500.0f); zone->SetFogEnd(750.0f); // Create a directional light to the world. Enable cascaded shadows on it Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f)); light->SetSpecularIntensity(0.5f); // Apply slightly overbright lighting to match the skybox light->SetColor(Color(1.2f, 1.2f, 1.2f)); // Create skybox. The Skybox component is used like StaticModel, but it will be always located at the camera, giving the // illusion of the box planes being far away. Use just the ordinary Box model and a suitable material, whose shader will // generate the necessary 3D texture coordinates for cube mapping Node* skyNode = scene_->CreateChild("Sky"); skyNode->SetScale(500.0f); // The scale actually does not matter Skybox* skybox = skyNode->CreateComponent<Skybox>(); skybox->SetModel(cache->GetResource<Model>("Models/Box.mdl")); skybox->SetMaterial(cache->GetResource<Material>("Materials/Skybox.xml")); // Create heightmap terrain Node* terrainNode = scene_->CreateChild("Terrain"); terrainNode->SetPosition(Vector3(0.0f, 0.0f, 0.0f)); Terrain* terrain = terrainNode->CreateComponent<Terrain>(); terrain->SetPatchSize(64); terrain->SetSpacing(Vector3(2.0f, 0.5f, 2.0f)); // Spacing between vertices and vertical resolution of the height map terrain->SetSmoothing(true); terrain->SetHeightMap(cache->GetResource<Image>("Textures/HeightMap.png")); terrain->SetMaterial(cache->GetResource<Material>("Materials/Terrain.xml")); // The terrain consists of large triangles, which fits well for occlusion rendering, as a hill can occlude all // terrain patches and other objects behind it terrain->SetOccluder(true); // Create 1000 boxes in the terrain. Always face outward along the terrain normal unsigned NUM_OBJECTS = 1000; for (unsigned i = 0; i < NUM_OBJECTS; ++i) { Node* objectNode = scene_->CreateChild("Box"); Vector3 position(Random(2000.0f) - 1000.0f, 0.0f, Random(2000.0f) - 1000.0f); position.y_ = terrain->GetHeight(position) + 2.25f; objectNode->SetPosition(position); // Create a rotation quaternion from up vector to terrain normal objectNode->SetRotation(Quaternion(Vector3(0.0f, 1.0f, 0.0f), terrain->GetNormal(position))); objectNode->SetScale(5.0f); StaticModel* object = objectNode->CreateComponent<StaticModel>(); object->SetModel(cache->GetResource<Model>("Models/Box.mdl")); object->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); object->SetCastShadows(true); } Node* shipNode = scene_->CreateChild("Ship"); shipNode->SetPosition(Vector3(0.0f, 4.6f, 0.0f)); //shipNode->SetRotation(Quaternion(0.0f, Random(360.0f), 0.0f)); shipNode->SetScale(0.5f + Random(2.0f)); StaticModel* shipObject = shipNode->CreateComponent<StaticModel>(); shipObject->SetModel(cache->GetResource<Model>("Models/ship04.mdl")); shipObject->SetMaterial(0,cache->GetResource<Material>("Materials/ship04_Material0.xml")); shipObject->SetMaterial(1,cache->GetResource<Material>("Materials/ship04_Material1.xml")); shipObject->SetMaterial(2,cache->GetResource<Material>("Materials/ship04_Material2.xml")); shipObject->SetCastShadows(true); // Create a water plane object that is as large as the terrain waterNode_ = scene_->CreateChild("Water"); waterNode_->SetScale(Vector3(2048.0f, 1.0f, 2048.0f)); waterNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f)); StaticModel* water = waterNode_->CreateComponent<StaticModel>(); water->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); water->SetMaterial(cache->GetResource<Material>("Materials/Water.xml")); // Set a different viewmask on the water plane to be able to hide it from the reflection camera water->SetViewMask(0x80000000); // Create the camera. Set far clip to match the fog. Note: now we actually create the camera node outside // the scene, because we want it to be unaffected by scene load / save cameraNode_ = new Node(GetContext()); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->setFarClipDistance(750.0f); // Set an initial position for the camera scene node above the ground cameraNode_->SetPosition(Vector3(0.0f, 7.0f, -20.0f)); }
void MasterControl::CreateScene() { world.scene = new Scene(context_); world.octree = world.scene->CreateComponent<Octree>(); physicsWorld_ = world.scene->CreateComponent<PhysicsWorld>(); physicsWorld_->SetGravity(Vector3::ZERO); world.scene->CreateComponent<DebugRenderer>(); //Create a Zone component for ambient ing & fog control Node* zoneNode = world.scene->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(Vector3(-100.0f, -50.0f, -100.0f),Vector3(100.0f, 0.0f, 100.0f))); zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f)); zone->SetFogColor(Color(0.0f, 0.0f, 0.0f)); zone->SetFogStart(56.8f); zone->SetFogEnd(61.8f); //Add a directional light to the world. Enable cascaded shadows on it Node* lightNode = world.scene->CreateChild("PointLight"); lightNode->SetPosition(Vector3::UP*5.0); lightNode->SetRotation(Quaternion(90.0f, 0.0f, 0.0f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetBrightness(1.0f); light->SetRange(7.0f); light->SetColor(Color(1.0f, 0.9f, 0.95f)); light->SetCastShadows(false); light->SetShadowBias(BiasParameters(0.00025f, 0.5f)); //Set cascade splits at 10, 50, 200 world unitys, fade shadows at 80% of maximum shadow distance light->SetShadowCascade(CascadeParameters(7.0f, 23.0f, 42.0f, 500.0f, 0.8f)); //Create cursor world.cursor.sceneCursor = world.scene->CreateChild("Cursor"); //world.cursor.sceneCursor->SetPosition(Vector3(0.0f,0.0f,0.0f)); StaticModel* cursorObject = world.cursor.sceneCursor->CreateComponent<StaticModel>(); cursorObject->SetModel(cache_->GetResource<Model>("Resources/Models/Hexagon.mdl")); cursorObject->SetMaterial(cache_->GetResource<Material>("Resources/Materials/Glow.xml")); world.cursor.sceneCursor->SetEnabled(false); //Create an invisible plane for mouse raycasting world.voidNode = world.scene->CreateChild("Void"); //Location is set in update since the plane moves with the camera. world.voidNode->SetScale(Vector3(1000.0f, 1.0f, 1000.0f)); StaticModel* planeObject = world.voidNode->CreateComponent<StaticModel>(); planeObject->SetModel(cache_->GetResource<Model>("Models/Plane.mdl")); planeObject->SetMaterial(cache_->GetResource<Material>("Resources/Materials/Invisible.xml")); //Create camera world.camera = new heXoCam(context_, this); //Create arena tileMaster_ = new TileMaster(context_, this); for (int i = 0; i < 6; i++){ new ArenaEdge(context_, this, (60.0f * i)+30.0f); } spawnMaster_ = new SpawnMaster(context_, this); player_ = new Player(context_, this); apple_ = new Apple(context_, this); heart_ = new Heart(context_, this); }
void DynamicGeometry::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create the Octree component to the scene so that drawable objects can be rendered. Use default volume // (-1000, -1000, -1000) to (1000, 1000, 1000) scene_->CreateComponent<Octree>(); // Create a Zone for ambient light & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetFogColor(Color(0.2f, 0.2f, 0.2f)); zone->SetFogStart(200.0f); zone->SetFogEnd(300.0f); // Create a directional light Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(-0.6f, -1.0f, -0.8f)); // The direction vector does not need to be normalized Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetColor(Color(0.4f, 1.0f, 0.4f)); light->SetSpecularIntensity(1.5f); // Get the original model and its unmodified vertices, which are used as source data for the animation Model* originalModel = cache->GetResource<Model>("Models/Box.mdl"); if (!originalModel) { ATOMIC_LOGERROR("Model not found, cannot initialize example scene"); return; } // Get the vertex buffer from the first geometry's first LOD level VertexBuffer* buffer = originalModel->GetGeometry(0, 0)->GetVertexBuffer(0); const unsigned char* vertexData = (const unsigned char*)buffer->Lock(0, buffer->GetVertexCount()); if (vertexData) { unsigned numVertices = buffer->GetVertexCount(); unsigned vertexSize = buffer->GetVertexSize(); // Copy the original vertex positions for (unsigned i = 0; i < numVertices; ++i) { const Vector3& src = *reinterpret_cast<const Vector3*>(vertexData + i * vertexSize); originalVertices_.Push(src); } buffer->Unlock(); // Detect duplicate vertices to allow seamless animation vertexDuplicates_.Resize(originalVertices_.Size()); for (unsigned i = 0; i < originalVertices_.Size(); ++i) { vertexDuplicates_[i] = i; // Assume not a duplicate for (unsigned j = 0; j < i; ++j) { if (originalVertices_[i].Equals(originalVertices_[j])) { vertexDuplicates_[i] = j; break; } } } } else { ATOMIC_LOGERROR("Failed to lock the model vertex buffer to get original vertices"); return; } // Create StaticModels in the scene. Clone the model for each so that we can modify the vertex data individually for (int y = -1; y <= 1; ++y) { for (int x = -1; x <= 1; ++x) { Node* node = scene_->CreateChild("Object"); node->SetPosition(Vector3(x * 2.0f, 0.0f, y * 2.0f)); StaticModel* object = node->CreateComponent<StaticModel>(); SharedPtr<Model> cloneModel = originalModel->Clone(); object->SetModel(cloneModel); // Store the cloned vertex buffer that we will modify when animating animatingBuffers_.Push(SharedPtr<VertexBuffer>(cloneModel->GetGeometry(0, 0)->GetVertexBuffer(0))); } } // Finally create one model (pyramid shape) and a StaticModel to display it from scratch // Note: there are duplicated vertices to enable face normals. We will calculate normals programmatically { const unsigned numVertices = 18; float vertexData[] = { // Position Normal 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f }; const unsigned short indexData[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; // Calculate face normals now for (unsigned i = 0; i < numVertices; i += 3) { Vector3& v1 = *(reinterpret_cast<Vector3*>(&vertexData[6 * i])); Vector3& v2 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 1)])); Vector3& v3 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 2)])); Vector3& n1 = *(reinterpret_cast<Vector3*>(&vertexData[6 * i + 3])); Vector3& n2 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 1) + 3])); Vector3& n3 = *(reinterpret_cast<Vector3*>(&vertexData[6 * (i + 2) + 3])); Vector3 edge1 = v1 - v2; Vector3 edge2 = v1 - v3; n1 = n2 = n3 = edge1.CrossProduct(edge2).Normalized(); } SharedPtr<Model> fromScratchModel(new Model(context_)); SharedPtr<VertexBuffer> vb(new VertexBuffer(context_)); SharedPtr<IndexBuffer> ib(new IndexBuffer(context_)); SharedPtr<Geometry> geom(new Geometry(context_)); // Shadowed buffer needed for raycasts to work, and so that data can be automatically restored on device loss vb->SetShadowed(true); // We could use the "legacy" element bitmask to define elements for more compact code, but let's demonstrate // defining the vertex elements explicitly to allow any element types and order PODVector<VertexElement> elements; elements.Push(VertexElement(TYPE_VECTOR3, SEM_POSITION)); elements.Push(VertexElement(TYPE_VECTOR3, SEM_NORMAL)); vb->SetSize(numVertices, elements); vb->SetData(vertexData); ib->SetShadowed(true); ib->SetSize(numVertices, false); ib->SetData(indexData); geom->SetVertexBuffer(0, vb); geom->SetIndexBuffer(ib); geom->SetDrawRange(TRIANGLE_LIST, 0, numVertices); fromScratchModel->SetNumGeometries(1); fromScratchModel->SetGeometry(0, 0, geom); fromScratchModel->SetBoundingBox(BoundingBox(Vector3(-0.5f, -0.5f, -0.5f), Vector3(0.5f, 0.5f, 0.5f))); // Though not necessary to render, the vertex & index buffers must be listed in the model so that it can be saved properly Vector<SharedPtr<VertexBuffer> > vertexBuffers; Vector<SharedPtr<IndexBuffer> > indexBuffers; vertexBuffers.Push(vb); indexBuffers.Push(ib); // Morph ranges could also be not defined. Here we simply define a zero range (no morphing) for the vertex buffer PODVector<unsigned> morphRangeStarts; PODVector<unsigned> morphRangeCounts; morphRangeStarts.Push(0); morphRangeCounts.Push(0); fromScratchModel->SetVertexBuffers(vertexBuffers, morphRangeStarts, morphRangeCounts); fromScratchModel->SetIndexBuffers(indexBuffers); Node* node = scene_->CreateChild("FromScratchObject"); node->SetPosition(Vector3(0.0f, 3.0f, 0.0f)); StaticModel* object = node->CreateComponent<StaticModel>(); object->SetModel(fromScratchModel); } // Create the camera cameraNode_ = new Node(context_); cameraNode_->SetPosition(Vector3(0.0f, 2.0f, -20.0f)); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); }
void RenderToTexture::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); { // Create the scene which will be rendered to a texture rttScene_ = new Scene(context_); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) rttScene_->CreateComponent<Octree>(); // Create a Zone for ambient light & fog control Node* zoneNode = rttScene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); // Set same volume as the Octree, set a close bluish fog and some ambient light zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.05f, 0.1f, 0.15f)); zone->SetFogColor(Color(0.1f, 0.2f, 0.3f)); zone->SetFogStart(10.0f); zone->SetFogEnd(100.0f); // Create randomly positioned and oriented box StaticModels in the scene const unsigned NUM_OBJECTS = 2000; for (unsigned i = 0; i < NUM_OBJECTS; ++i) { Node* boxNode = rttScene_->CreateChild("Box"); boxNode->SetPosition(Vector3(Random(200.0f) - 100.0f, Random(200.0f) - 100.0f, Random(200.0f) - 100.0f)); // Orient using random pitch, yaw and roll Euler angles boxNode->SetRotation(Quaternion(Random(360.0f), Random(360.0f), Random(360.0f))); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); // Add our custom Rotator component which will rotate the scene node each frame, when the scene sends its update event. // Simply set same rotation speed for all objects Rotator* rotator = boxNode->CreateComponent<Rotator>(); rotator->SetRotationSpeed(Vector3(10.0f, 20.0f, 30.0f)); } // Create a camera for the render-to-texture scene. Simply leave it at the world origin and let it observe the scene rttCameraNode_ = rttScene_->CreateChild("Camera"); Camera* camera = rttCameraNode_->CreateComponent<Camera>(); camera->SetFarClip(100.0f); // Create a point light to the camera scene node Light* light = rttCameraNode_->CreateComponent<Light>(); light->SetLightType(LIGHT_POINT); light->SetRange(30.0f); } { // Create the scene in which we move around scene_ = new Scene(context_); // Create octree, use also default volume (-1000, -1000, -1000) to (1000, 1000, 1000) scene_->CreateComponent<Octree>(); // Create a Zone component for ambient lighting & fog control Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.1f, 0.1f, 0.1f)); zone->SetFogStart(100.0f); zone->SetFogEnd(300.0f); // Create a directional light without shadows Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.5f, -1.0f, 0.5f)); Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetColor(Color(0.2f, 0.2f, 0.2f)); light->SetSpecularIntensity(1.0f); // Create a "floor" consisting of several tiles for (int y = -5; y <= 5; ++y) { for (int x = -5; x <= 5; ++x) { Node* floorNode = scene_->CreateChild("FloorTile"); floorNode->SetPosition(Vector3(x * 20.5f, -0.5f, y * 20.5f)); floorNode->SetScale(Vector3(20.0f, 1.0f, 20.f)); StaticModel* floorObject = floorNode->CreateComponent<StaticModel>(); floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); floorObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); } } // Create a "screen" like object for viewing the second scene. Construct it from two StaticModels, a box for the frame // and a plane for the actual view { Node* boxNode = scene_->CreateChild("ScreenBox"); boxNode->SetPosition(Vector3(0.0f, 10.0f, 0.0f)); boxNode->SetScale(Vector3(21.0f, 16.0f, 0.5f)); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); Node* screenNode = scene_->CreateChild("Screen"); screenNode->SetPosition(Vector3(0.0f, 10.0f, -0.27f)); screenNode->SetRotation(Quaternion(-90.0f, 0.0f, 0.0f)); screenNode->SetScale(Vector3(20.0f, 0.0f, 15.0f)); StaticModel* screenObject = screenNode->CreateComponent<StaticModel>(); screenObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); // Create a renderable texture (1024x768, RGB format), enable bilinear filtering on it SharedPtr<Texture2D> renderTexture(new Texture2D(context_)); renderTexture->SetSize(1024, 768, Graphics::GetRGBFormat(), TEXTURE_RENDERTARGET); renderTexture->SetFilterMode(FILTER_BILINEAR); // Create a new material from scratch, use the diffuse unlit technique, assign the render texture // as its diffuse texture, then assign the material to the screen plane object SharedPtr<Material> renderMaterial(new Material(context_)); renderMaterial->SetTechnique(0, cache->GetResource<Technique>("Techniques/DiffUnlit.xml")); renderMaterial->SetTexture(TU_DIFFUSE, renderTexture); screenObject->SetMaterial(renderMaterial); // Get the texture's RenderSurface object (exists when the texture has been created in rendertarget mode) // and define the viewport for rendering the second scene, similarly as how backbuffer viewports are defined // to the Renderer subsystem. By default the texture viewport will be updated when the texture is visible // in the main view RenderSurface* surface = renderTexture->GetRenderSurface(); SharedPtr<Viewport> rttViewport(new Viewport(context_, rttScene_, rttCameraNode_->GetComponent<Camera>())); surface->SetViewport(0, rttViewport); } // Create the camera which we will move around. Limit far clip distance to match the fog cameraNode_ = scene_->CreateChild("Camera"); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); // Set an initial position for the camera scene node above the plane cameraNode_->SetPosition(Vector3(0.0f, 7.0f, -30.0f)); } }
bool NffFileLoader::Load( const char* filename, SceneDescription& theScene ) { Reset(); ScenePtr = &theScene; FILE* infile = fopen( filename, "r" ); FileLineNumber = 0; if ( !infile ) { fprintf(stderr, "LoadNffFile: Unable to open file: %s\n", filename); return false; } const Material* curMaterial = &Material::Default; // Information for view ("v") command int viewCmdStatus = false; // True if currently handling a "v" command VectorR3 viewPos; VectorR3 lookAtPos; VectorR3 upVector; double fovy; // Field of view angle (in radians) int screenWidth, screenHeight; double hither; char inbuffer[1026]; while ( true ) { if ( !fgets( inbuffer, 1026, infile ) ) { if ( viewCmdStatus ) { SetCameraViewInfo( theScene.GetCameraView(), viewPos, lookAtPos, upVector, fovy, screenWidth, screenHeight, hither ); } fclose( infile ); PrintCmdNotSupportedErrors(stderr); return true; } FileLineNumber++; char *findStart = PreparseNff( inbuffer ); if ( findStart==0 ) { // Ignore if a comment or a blank line if ( viewCmdStatus ) { SetCameraViewInfo( theScene.GetCameraView(), viewPos, lookAtPos, upVector, fovy, screenWidth, screenHeight, hither ); viewCmdStatus = false; } continue; } bool parseErrorOccurred = false; char theCommand[17]; int scanCode = sscanf( inbuffer, "%16s", theCommand ); if ( scanCode!=1 ) { parseErrorOccurred = true; } int cmdNum = GetCommandNumber( theCommand ); if ( cmdNum==-1 ) { AddUnsupportedCmd( theCommand ); continue; } if ( viewCmdStatus && cmdNum<8 ) { SetCameraViewInfo( theScene.GetCameraView(), viewPos, lookAtPos, upVector, fovy, screenWidth, screenHeight, hither ); viewCmdStatus = false; } char* args = ObjFileLoader::ScanForSecondField( findStart ); bool ok = true; switch ( cmdNum ) { case 0: // 'v' command viewCmdStatus = true; break; case 1: // 'b' command - background color { VectorR3 bgColor; scanCode = sscanf( args, "%lf %lf %lf", &(bgColor.x), &(bgColor.y), &(bgColor.z) ); if ( scanCode!=3 ) { ok = false; break; } theScene.SetBackGroundColor( bgColor ); } break; case 2: // 'l' command - positional light { VectorR3 lightPos, lightColor; scanCode = sscanf( args, "%lf %lf %lf %lf %lf %lf", &(lightPos.x), &(lightPos.y), &(lightPos.z), &(lightColor.x), &(lightColor.y), &(lightColor.z) ); if ( scanCode==3 || scanCode==6 ) { Light* aLight = new Light(); aLight->SetPosition( lightPos ); if ( scanCode==6 ) { aLight->SetColor( lightColor ); } theScene.AddLight( aLight ); } else { ok = false; } } break; case 3: // 'f' command - material properties { VectorR3 color; // Material color double Kd, Ks; // Diffuse and specular components double shininess; double transmission; // Transmission coefficient double indexOfRefraction; scanCode = sscanf( args, "%lf %lf %lf %lf %lf %lf %lf %lf", &color.x, &color.y, &color.z, &Kd, &Ks, &shininess, &transmission, &indexOfRefraction ); if ( scanCode==8 ) { Material* mat = new Material(); theScene.AddMaterial( mat ); // theScene can take of deleting this material mat->SetColorAmbientDiffuse( Kd*color ); mat->SetColorSpecular( Ks*color ); mat->SetShininess( shininess ); if ( transmission>0.0 ) { mat->SetColorTransmissive( transmission, transmission, transmission ); mat->SetIndexOfRefraction( indexOfRefraction ); } curMaterial = mat; } else { ok = false; } } break; case 4: // 'c' command - cylinder or cone or truncated cone { VectorR3 baseCenter; VectorR3 topCenter; double baseRadius; double topRadius; scanCode = sscanf( args, "%lf %lf %lf %lf %lf %lf %lf %lf", &baseCenter.x, &baseCenter.y, &baseCenter.z, &baseRadius, &topCenter.x, &topCenter.y, &topCenter.z, &topRadius ); if ( scanCode==8 ) { ProcessConeCylNFF( baseCenter, baseRadius, topCenter, topRadius ); } else { ok = false; } } case 5: // 's' command - sphere { VectorR3 sphereCenter; double radius; scanCode = sscanf( args, "%lf %lf %lf %lf", &sphereCenter.x, &sphereCenter.y, &sphereCenter.z, &radius ); if ( scanCode==4 && radius>0.0 ) { ViewableSphere* vs = new ViewableSphere( sphereCenter, radius, curMaterial ); theScene.AddViewable( vs ); } else { ok = false; } } break; case 7: // 'pp' command - normals will be ignored UnsupportedNormals(); // Fall thru to 'p' command. case 6: // 'p' command { int numVerts; const int maxNumVerts = 256; scanCode = sscanf( args, "%d", &numVerts ); if (scanCode!=1 || numVerts<3 ) { ok = false; } else if ( numVerts>maxNumVerts ) { UnsupportedTooManyVerts( maxNumVerts ); } else { ProcessFaceNFF( numVerts, curMaterial, infile ); } } break; case 8: // 'from' command { scanCode = sscanf( args, "%lf %lf %lf", &(viewPos.x), &(viewPos.y), &(viewPos.z) ); if ( scanCode!=3 || !viewCmdStatus ) { ok = false; viewCmdStatus = false; } break; } case 9: // 'lookat' command { scanCode = sscanf( args, "%lf %lf %lf", &(lookAtPos.x), &(lookAtPos.y), &(lookAtPos.z) ); if ( scanCode!=3 || !viewCmdStatus ) { ok = false; viewCmdStatus = false; } break; } case 10: // 'up' command { scanCode = sscanf( args, "%lf %lf %lf", &(upVector.x), &(upVector.y), &(upVector.z) ); if ( scanCode!=3 || !viewCmdStatus ) { ok = false; viewCmdStatus = false; } break; } case 11: // 'angle' command { scanCode = sscanf( args, "%lf", &fovy ); if ( scanCode!=1 || !viewCmdStatus ) { ok = false; viewCmdStatus = false; } else { fovy *= PI/180.0; // Convert to radians } break; } case 12: // 'hither' command { scanCode = sscanf( args, "%lf", &hither ); if ( scanCode!=1 || !viewCmdStatus ) { ok = false; viewCmdStatus = false; } break; } case 13: // 'resolution' command { scanCode = sscanf( args, "%d %d", &screenWidth, &screenHeight ); if ( scanCode!=2 || !viewCmdStatus ) { ok = false; viewCmdStatus = false; } break; } default: parseErrorOccurred = true; ok = false; break; } if ( !ok ) { fprintf(stderr, "Parse error in NFF file, line %ld: %40s.\n", FileLineNumber, inbuffer ); parseErrorOccurred = true; } } }