Exposed StaticModelGroup to script. Ported HugeObjectCount example group mode switching to script versions.

This commit is contained in:
Lasse Öörni 2013-09-19 22:44:06 +00:00
Родитель 6e58119be9
Коммит 1cd73e46fd
13 изменённых файлов: 246 добавлений и 47 удалений

Просмотреть файл

@ -95,7 +95,7 @@ function CreateInstructions()
-- Position the text relative to the screen center
instructionText.horizontalAlignment = HA_CENTER
instructionText.verticalAlignment= VA_CENTER
instructionText.verticalAlignment = VA_CENTER
instructionText:SetPosition(0, ui.root.height / 4)
end

Просмотреть файл

@ -94,7 +94,7 @@ function CreateInstructions()
-- Position the text relative to the screen center
instructionText.horizontalAlignment = HA_CENTER
instructionText.verticalAlignment= VA_CENTER
instructionText.verticalAlignment = VA_CENTER
instructionText:SetPosition(0, ui.root.height / 4)
end

Просмотреть файл

@ -3,6 +3,7 @@
-- - Creating a scene with 250 x 250 simple objects;
-- - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :);
-- - Allowing examination of performance hotspots in the rendering code;
-- - Optionally speeding up rendering by grouping the objects using StaticModelGroup component;
require "LuaScripts/Utilities/Sample"
@ -12,6 +13,7 @@ local boxNodes = {}
local yaw = 0.0
local pitch = 0.0
local animate = false
local useGroups = false
local context = GetContext()
@ -38,7 +40,12 @@ function Start()
end
function CreateScene()
scene_ = Scene(context)
if scene_ == nil then
scene_ = Scene(context)
else
scene_:Clear()
boxNodes = {}
end
-- Create the Octree component to the scene so that drawable objects can be rendered. Use default volume
-- (-1000, -1000, -1000) to (1000, 1000, 1000)
@ -54,42 +61,74 @@ function CreateScene()
-- Create a directional light
local lightNode = scene_:CreateChild("DirectionalLight")
lightNode.direction = Vector3(0.5, -1.0, 0.5) -- The direction vector does not need to be normalized
lightNode.direction = Vector3(-0.6, -1.0, -0.8) -- The direction vector does not need to be normalized
local light = lightNode:CreateComponent("Light")
light.lightType = LIGHT_DIRECTIONAL
light.color = Color(0.7, 0.35, 0.0)
-- Create box StaticModels in the scene
for y = -125, 125 do
for x = -125, 125 do
local boxNode = scene_:CreateChild("Box")
boxNode.position = Vector3(x * 0.3, 0.0, y * 0.3)
boxNode:SetScale(0.25)
local boxObject = boxNode:CreateComponent("StaticModel")
boxObject.model = cache:GetResource("Model", "Models/Box.mdl")
table.insert(boxNodes, boxNode)
if not useGroups then
light.color = Color(0.7, 0.35, 0.0)
-- Create individual box StaticModels in the scene
for y = -125, 125 do
for x = -125, 125 do
local boxNode = scene_:CreateChild("Box")
boxNode.position = Vector3(x * 0.3, 0.0, y * 0.3)
boxNode:SetScale(0.25)
local boxObject = boxNode:CreateComponent("StaticModel")
boxObject.model = cache:GetResource("Model", "Models/Box.mdl")
table.insert(boxNodes, boxNode)
end
end
else
light.color = Color(0.6, 0.6, 0.6);
light.specularIntensity = 1.5;
-- Create StaticModelGroups in the scene
local lastGroup = nil
for y = -125, 125 do
for x = -125, 125 do
-- 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 == nil or lastGroup.numInstanceNodes >= 25 * 25 then
local boxGroupNode = scene_:CreateChild("BoxGroup")
lastGroup = boxGroupNode:CreateComponent("StaticModelGroup")
lastGroup.model = cache:GetResource("Model", "Models/Box.mdl")
end
local boxNode = scene_:CreateChild("Box");
boxNode.position = Vector3(x * 0.3, 0.0, y * 0.3)
boxNode:SetScale(0.25)
table.insert(boxNodes, boxNode)
lastGroup:AddInstanceNode(boxNode);
end
end
end
-- Create the camera
cameraNode = scene_:CreateChild("Camera")
cameraNode.position = Vector3(0.0, 10.0, -100.0)
local camera = cameraNode:CreateComponent("Camera")
camera.farClip = 300.0
-- Create the camera. Create it outside the scene so that we can clear the whole scene without affecting it
if cameraNode == nil then
cameraNode = Node(context)
cameraNode.position = Vector3(0.0, 10.0, -100.0)
local camera = cameraNode:CreateComponent("Camera")
camera.farClip = 300.0
end
end
function CreateInstructions()
-- Construct new Text object, set string to display and font to use
local instructionText = ui.root:CreateChild("Text")
instructionText:SetText("Use WASD keys and mouse to move\n"..
"Space to toggle animation")
"Space to toggle animation\n"..
"G to toggle object group optimization")
instructionText:SetFont(cache:GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15)
-- The text has multiple rows. Center them in relation to each other
instructionText.textAlignment = HA_CENTER
-- Position the text relative to the screen center
instructionText.horizontalAlignment = HA_CENTER
instructionText.verticalAlignment= VA_CENTER
instructionText.verticalAlignment = VA_CENTER
instructionText:SetPosition(0, ui.root.height / 4)
end
@ -157,6 +196,12 @@ function HandleUpdate(eventType, eventData)
animate = not animate
end
-- Toggle grouped / ungrouped mode
if input:GetKeyPress(KEY_G) then
useGroups = not useGroups
CreateScene()
end
-- Move the camera, scale movement with time step
MoveCamera(timeStep)

Просмотреть файл

@ -92,7 +92,7 @@ void CreateInstructions()
// Position the text relative to the screen center
instructionText.horizontalAlignment = HA_CENTER;
instructionText.verticalAlignment= VA_CENTER;
instructionText.verticalAlignment = VA_CENTER;
instructionText.SetPosition(0, ui.root.height / 4);
}

Просмотреть файл

@ -94,7 +94,7 @@ void CreateInstructions()
// Position the text relative to the screen center
instructionText.horizontalAlignment = HA_CENTER;
instructionText.verticalAlignment= VA_CENTER;
instructionText.verticalAlignment = VA_CENTER;
instructionText.SetPosition(0, ui.root.height / 4);
}

Просмотреть файл

@ -3,6 +3,7 @@
// - Creating a scene with 250 x 250 simple objects;
// - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :)
// - Allowing examination of performance hotspots in the rendering code;
// - Optionally speeding up rendering by grouping the objects using StaticModelGroup component;
#include "Scripts/Utilities/Sample.as"
@ -12,6 +13,7 @@ Array<Node@> boxNodes;
float yaw = 0.0f;
float pitch = 0.0f;
bool animate = false;
bool useGroups = false;
void Start()
{
@ -33,7 +35,13 @@ void Start()
void CreateScene()
{
scene_ = Scene();
if (scene_ is null)
scene_ = Scene();
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)
@ -46,49 +54,87 @@ void CreateScene()
zone.fogColor = Color(0.2f, 0.2f, 0.2f);
zone.fogStart = 200.0f;
zone.fogEnd = 300.0f;
// Create a directional light
Node@ lightNode = scene_.CreateChild("DirectionalLight");
lightNode.direction = Vector3(0.5f, -1.0f, 0.5f); // The direction vector does not need to be normalized
lightNode.direction = Vector3(-0.6f, -1.0f, -0.8f); // The direction vector does not need to be normalized
Light@ light = lightNode.CreateComponent("Light");
light.lightType = LIGHT_DIRECTIONAL;
light.color = Color(0.7f, 0.35f, 0.0f);
// Create box StaticModels in the scene
for (int y = -125; y < 125; ++y)
if (!useGroups)
{
for (int x = -125; x < 125; ++x)
light.color = Color(0.7f, 0.35f, 0.0f);
// Create individual box StaticModels in the scene
for (int y = -125; y < 125; ++y)
{
Node@ boxNode = scene_.CreateChild("Box");
boxNode.position = Vector3(x * 0.3f, 0.0f, y * 0.3f);
boxNode.SetScale(0.25f);
StaticModel@ boxObject = boxNode.CreateComponent("StaticModel");
boxObject.model = cache.GetResource("Model", "Models/Box.mdl");
boxNodes.Push(boxNode);
for (int x = -125; x < 125; ++x)
{
Node@ boxNode = scene_.CreateChild("Box");
boxNode.position = Vector3(x * 0.3f, 0.0f, y * 0.3f);
boxNode.SetScale(0.25f);
StaticModel@ boxObject = boxNode.CreateComponent("StaticModel");
boxObject.model = cache.GetResource("Model", "Models/Box.mdl");
boxNodes.Push(boxNode);
}
}
}
else
{
light.color = Color(0.6f, 0.6f, 0.6f);
light.specularIntensity = 1.5f;
// Create StaticModelGroups in the scene
StaticModelGroup@ lastGroup;
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 is null || lastGroup.numInstanceNodes >= 25 * 25)
{
Node@ boxGroupNode = scene_.CreateChild("BoxGroup");
lastGroup = boxGroupNode.CreateComponent("StaticModelGroup");
lastGroup.model = cache.GetResource("Model", "Models/Box.mdl");
}
Node@ boxNode = scene_.CreateChild("Box");
boxNode.position = Vector3(x * 0.3f, 0.0f, y * 0.3f);
boxNode.SetScale(0.25f);
boxNodes.Push(boxNode);
lastGroup.AddInstanceNode(boxNode);
}
}
}
// Create the camera
cameraNode = scene_.CreateChild("Camera");
cameraNode.position = Vector3(0.0f, 10.0f, -100.0f);
Camera@ camera = cameraNode.CreateComponent("Camera");
camera.farClip = 300.0f;
// Create the camera. Create it outside the scene so that we can clear the whole scene without affecting it
if (cameraNode is null)
{
cameraNode = Node("Camera");
cameraNode.position = Vector3(0.0f, 10.0f, -100.0f);
Camera@ camera = cameraNode.CreateComponent("Camera");
camera.farClip = 300.0f;
}
}
void CreateInstructions()
{
// Construct new Text object, set string to display and font to use
Text@ instructionText = ui.root.CreateChild("Text");
instructionText.text =
instructionText.text =
"Use WASD keys and mouse to move\n"
"Space to toggle animation";
"Space to toggle animation\n"
"G to toggle object group optimization";
instructionText.SetFont(cache.GetResource("Font", "Fonts/Anonymous Pro.ttf"), 15);
// The text has multiple rows. Center them in relation to each other
instructionText.textAlignment = HA_CENTER;
// Position the text relative to the screen center
instructionText.horizontalAlignment = HA_CENTER;
instructionText.verticalAlignment= VA_CENTER;
instructionText.verticalAlignment = VA_CENTER;
instructionText.SetPosition(0, ui.root.height / 4);
}
@ -155,6 +201,13 @@ void HandleUpdate(StringHash eventType, VariantMap& eventData)
if (input.keyPress[KEY_SPACE])
animate = !animate;
// Toggle grouped / ungrouped mode
if (input.keyPress['G'])
{
useGroups = !useGroups;
CreateScene();
}
// Move the camera, scale movement with time step
MoveCamera(timeStep);

Просмотреть файл

@ -1982,6 +1982,18 @@ Properties:<br>
- unsigned numGeometries (readonly)
- unsigned occlusionLodLevel
StaticModelGroup : StaticModel
Methods:<br>
- void AddInstanceNode(Node* node)
- void RemoveInstanceNode(Node* node);
- void RemoveAllInstanceNodes()
- unsigned GetNumInstanceNodes() const
- Node* GetInstanceNode(unsigned index) const
Properties:<br>
- unsigned numInstanceNodes (readonly)
Pass : RefCounted
Methods:<br>

Просмотреть файл

@ -2436,6 +2436,66 @@ Properties:<br>
- uint occlusionLodLevel
StaticModelGroup
Methods:<br>
- void SendEvent(const String&, VariantMap& arg1 = VariantMap ( ))
- bool Load(File@, bool arg1 = false)
- bool Save(File@) const
- bool LoadXML(const XMLElement&, bool arg1 = false)
- bool SaveXML(XMLElement&) const
- void ApplyAttributes()
- bool SetAttribute(const String&, const Variant&)
- void ResetToDefault()
- void RemoveInstanceDefault()
- Variant GetAttribute(const String&) const
- Variant GetAttributeDefault(const String&) const
- void Remove()
- void MarkNetworkUpdate() const
- void DrawDebugGeometry(DebugRenderer@, bool)
- void AddInstanceNode(Node@)
- void RemoveInstanceNode(Node@)
- void RemoveAllInstanceNodes()
Properties:<br>
- int refs (readonly)
- int weakRefs (readonly)
- ShortStringHash type (readonly)
- String typeName (readonly)
- String category (readonly)
- uint numAttributes (readonly)
- Variant[] attributes
- Variant[] attributeDefaults (readonly)
- AttributeInfo[] attributeInfos (readonly)
- bool temporary
- bool enabled
- bool enabledEffective (readonly)
- uint id (readonly)
- Node@ node (readonly)
- bool inView (readonly)
- bool castShadows
- bool occluder
- bool occludee
- float drawDistance
- float shadowDistance
- float lodBias
- uint viewMask
- uint lightMask
- uint shadowMask
- uint zoneMask
- uint maxLights
- BoundingBox boundingBox (readonly)
- BoundingBox worldBoundingBox (readonly)
- Model@ model
- Material@ material (writeonly)
- Material@[] materials
- uint numGeometries (readonly)
- Zone@ zone (readonly)
- uint occlusionLodLevel
- uint numInstanceNodes (readonly)
- Node@[] instanceNodes (readonly)
Skybox
Methods:<br>

Просмотреть файл

@ -38,6 +38,7 @@
#include "RenderPath.h"
#include "Scene.h"
#include "SmoothedTransform.h"
#include "StaticModelGroup.h"
#include "Technique.h"
#include "Terrain.h"
#include "TerrainPatch.h"
@ -817,6 +818,18 @@ static void RegisterStaticModel(asIScriptEngine* engine)
engine->RegisterObjectMethod("StaticModel", "uint get_occlusionLodLevel() const", asMETHOD(StaticModel, GetOcclusionLodLevel), asCALL_THISCALL);
}
static void RegisterStaticModelGroup(asIScriptEngine* engine)
{
RegisterStaticModel<StaticModelGroup>(engine, "StaticModelGroup", true);
engine->RegisterObjectMethod("StaticModelGroup", "void set_occlusionLodLevel(uint) const", asMETHOD(StaticModelGroup, SetOcclusionLodLevel), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "uint get_occlusionLodLevel() const", asMETHOD(StaticModelGroup, GetOcclusionLodLevel), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "void AddInstanceNode(Node@+)", asMETHOD(StaticModelGroup, AddInstanceNode), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "void RemoveInstanceNode(Node@+)", asMETHOD(StaticModelGroup, RemoveInstanceNode), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "void RemoveAllInstanceNodes()", asMETHOD(StaticModelGroup, RemoveAllInstanceNodes), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "uint get_numInstanceNodes() const", asMETHOD(StaticModelGroup, GetNumInstanceNodes), asCALL_THISCALL);
engine->RegisterObjectMethod("StaticModelGroup", "Node@+ get_instanceNodes(uint) const", asMETHOD(StaticModelGroup, GetInstanceNode), asCALL_THISCALL);
}
static void RegisterSkybox(asIScriptEngine* engine)
{
RegisterStaticModel<Skybox>(engine, "Skybox", true);
@ -1438,6 +1451,7 @@ void RegisterGraphicsAPI(asIScriptEngine* engine)
RegisterLight(engine);
RegisterZone(engine);
RegisterStaticModel(engine);
RegisterStaticModelGroup(engine);
RegisterSkybox(engine);
RegisterAnimatedModel(engine);
RegisterAnimationController(engine);

Просмотреть файл

@ -0,0 +1,13 @@
$#include "StaticModelGroup.h"
class StaticModelGroup : public StaticModel
{
void AddInstanceNode(Node* node);
void RemoveInstanceNode(Node* node);
void RemoveAllInstanceNodes();
unsigned GetNumInstanceNodes() const;
Node* GetInstanceNode(unsigned index) const;
tolua_readonly tolua_property__get_set unsigned numInstanceNodes;
};

Просмотреть файл

@ -21,6 +21,7 @@ $pfile "Graphics/RenderSurface.pkg"
$pfile "Graphics/Skeleton.pkg"
$pfile "Graphics/Skybox.pkg"
$pfile "Graphics/StaticModel.pkg"
$pfile "Graphics/StaticModelGroup.pkg"
$pfile "Graphics/Technique.pkg"
$pfile "Graphics/Terrain.pkg"
$pfile "Graphics/TerrainPatch.pkg"

Просмотреть файл

@ -134,7 +134,7 @@ void HugeObjectCount::CreateScene()
// 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)
if (!lastGroup || lastGroup->GetNumInstanceNodes() >= 25 * 25)
{
Node* boxGroupNode = scene_->CreateChild("BoxGroup");
lastGroup = boxGroupNode->CreateComponent<StaticModelGroup>();
@ -170,7 +170,7 @@ void HugeObjectCount::CreateInstructions()
instructionText->SetText(
"Use WASD keys and mouse to move\n"
"Space to toggle animation\n"
"G to toggle object group optimization\n"
"G to toggle object group optimization"
);
instructionText->SetFont(cache->GetResource<Font>("Fonts/Anonymous Pro.ttf"), 15);
// The text has multiple rows. Center them in relation to each other

Просмотреть файл

@ -38,6 +38,7 @@ class Scene;
/// - Competing with http://yosoygames.com.ar/wp/2013/07/ogre-2-0-is-up-to-3x-faster/ :)
/// - Allowing examination of performance hotspots in the rendering code;
/// - Using the profiler to measure the time taken to animate the scene;
/// - Optionally speeding up rendering by grouping the objects using StaticModelGroup component;
class HugeObjectCount : public Sample
{
OBJECT(HugeObjectCount);