Răsfoiți Sursa

Some more code for decals and some refactoring

Panagiotis Christopoulos Charitos 9 ani în urmă
părinte
comite
9fb489dc17

+ 3 - 3
src/anki/scene/BodyNode.cpp

@@ -47,8 +47,8 @@ public:
 //==============================================================================
 
 //==============================================================================
-BodyNode::BodyNode(SceneGraph* scene)
-	: SceneNode(scene)
+BodyNode::BodyNode(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -58,7 +58,7 @@ BodyNode::~BodyNode()
 }
 
 //==============================================================================
-Error BodyNode::init(const CString& name, const CString& resourceFname)
+Error BodyNode::init(const CString& resourceFname)
 {
 	SceneComponent* comp;
 

+ 2 - 3
src/anki/scene/BodyNode.h

@@ -18,12 +18,11 @@ namespace anki
 class BodyNode : public SceneNode
 {
 public:
-	BodyNode(SceneGraph* scene);
+	BodyNode(SceneGraph* scene, CString name);
 
 	~BodyNode();
 
-	ANKI_USE_RESULT Error init(
-		const CString& name, const CString& resourceFname);
+	ANKI_USE_RESULT Error init(const CString& resourceFname);
 
 private:
 	CollisionResourcePtr m_rsrc;

+ 7 - 9
src/anki/scene/Camera.cpp

@@ -69,17 +69,15 @@ public:
 //==============================================================================
 
 //==============================================================================
-Camera::Camera(SceneGraph* scene, Type type)
-	: SceneNode(scene)
+Camera::Camera(SceneGraph* scene, Type type, CString name)
+	: SceneNode(scene, name)
 	, m_type(type)
 {
 }
 
 //==============================================================================
-Error Camera::init(const CString& name, Frustum* frustum)
+Error Camera::init(Frustum* frustum)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	SceneComponent* comp;
 
 	// Move component
@@ -162,8 +160,8 @@ void Camera::onMoveComponentUpdate(MoveComponent& move)
 //==============================================================================
 
 //==============================================================================
-PerspectiveCamera::PerspectiveCamera(SceneGraph* scene)
-	: Camera(scene, Type::PERSPECTIVE)
+PerspectiveCamera::PerspectiveCamera(SceneGraph* scene, CString name)
+	: Camera(scene, Type::PERSPECTIVE, name)
 {
 }
 
@@ -184,8 +182,8 @@ void PerspectiveCamera::setAll(F32 fovX, F32 fovY, F32 near, F32 far)
 //==============================================================================
 
 //==============================================================================
-OrthographicCamera::OrthographicCamera(SceneGraph* scene)
-	: Camera(scene, Type::ORTHOGRAPHIC)
+OrthographicCamera::OrthographicCamera(SceneGraph* scene, CString name)
+	: Camera(scene, Type::ORTHOGRAPHIC, name)
 {
 }
 

+ 8 - 8
src/anki/scene/Camera.h

@@ -31,11 +31,11 @@ public:
 		COUNT
 	};
 
-	Camera(SceneGraph* scene, Type type);
+	Camera(SceneGraph* scene, Type type, CString name);
 
 	virtual ~Camera();
 
-	ANKI_USE_RESULT Error init(const CString& name, Frustum* frustum);
+	ANKI_USE_RESULT Error init(Frustum* frustum);
 
 	Type getCameraType() const
 	{
@@ -58,13 +58,13 @@ private:
 class PerspectiveCamera : public Camera
 {
 public:
-	PerspectiveCamera(SceneGraph* scene);
+	PerspectiveCamera(SceneGraph* scene, CString name);
 
 	~PerspectiveCamera();
 
-	ANKI_USE_RESULT Error init(const CString& name)
+	ANKI_USE_RESULT Error init()
 	{
-		return Camera::init(name, &m_frustum);
+		return Camera::init(&m_frustum);
 	}
 
 	void setAll(F32 fovX, F32 fovY, F32 near, F32 far);
@@ -77,13 +77,13 @@ private:
 class OrthographicCamera : public Camera
 {
 public:
-	OrthographicCamera(SceneGraph* scene);
+	OrthographicCamera(SceneGraph* scene, CString name);
 
 	~OrthographicCamera();
 
-	ANKI_USE_RESULT Error init(const CString& name)
+	ANKI_USE_RESULT Error init()
 	{
-		return Camera::init(name, &m_frustum);
+		return Camera::init(&m_frustum);
 	}
 
 private:

+ 1 - 0
src/anki/scene/Common.h

@@ -16,6 +16,7 @@ namespace anki
 class SceneGraph;
 class SceneNode;
 class MoveComponent;
+class DecalComponent;
 
 /// @addtogroup Scene
 /// @{

+ 15 - 10
src/anki/scene/DecalComponent.cpp

@@ -10,6 +10,12 @@
 namespace anki
 {
 
+//==============================================================================
+DecalComponent::DecalComponent(SceneNode* node)
+	: SceneComponent(CLASS_TYPE, node)
+{
+}
+
 //==============================================================================
 DecalComponent::~DecalComponent()
 {
@@ -33,20 +39,19 @@ Error DecalComponent::setLayer(CString texAtlasFname,
 }
 
 //==============================================================================
-void DecalComponent::updateMatrices(const Obb& box)
+void DecalComponent::updateInternal()
 {
-	Mat4 worldTransform(
-		box.getCenter().xyz1(), box.getRotation().getRotationPart(), 1.0f);
+	Mat4 worldTransform(m_trf);
 
 	Mat4 viewMat = worldTransform.getInverse();
 
-	const Vec4& extend = box.getExtend();
-	Mat4 projMat = Mat4::calculateOrthographicProjectionMatrix(extend.x(),
-		-extend.x(),
-		extend.y(),
-		-extend.y(),
-		FRUSTUM_NEAR_PLANE,
-		extend.z() * 2.0);
+	Mat4 projMat =
+		Mat4::calculateOrthographicProjectionMatrix(m_sizes.x() / 2.0f,
+			-m_sizes.x() / 2.0f,
+			m_sizes.y() / 2.0f,
+			-m_sizes.y() / 2.0f,
+			FRUSTUM_NEAR_PLANE,
+			m_sizes.z());
 
 	static const Mat4 biasMat4(0.5,
 		0.0,

+ 30 - 11
src/anki/scene/DecalComponent.h

@@ -23,10 +23,7 @@ public:
 
 	static constexpr F32 FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
 
-	DecalComponent(SceneNode* node)
-		: SceneComponent(CLASS_TYPE, node)
-	{
-	}
+	DecalComponent(SceneNode* node);
 
 	~DecalComponent();
 
@@ -37,10 +34,32 @@ public:
 			texAtlasFname, texAtlasSubtexName, blendFactor, LayerType::DIFFUSE);
 	}
 
-	/// Update the internal structures using a world space Obb.
-	void updateShape(const Obb& box)
+	/// Update the internal structures.
+	void updateShape(F32 width, F32 height, F32 depth)
+	{
+		m_sizes = Vec3(width, height, depth);
+		m_markedForUpdate = true;
+	}
+
+	F32 getWidth() const
+	{
+		return m_sizes.x();
+	}
+
+	F32 getHeight() const
+	{
+		return m_sizes.y();
+	}
+
+	F32 getDepth() const
+	{
+		return m_sizes.z();
+	}
+
+	void updateTransform(const Transform& trf)
 	{
-		m_obb = box;
+		ANKI_ASSERT(trf.getScale() == 1.0f);
+		m_trf = trf;
 		m_markedForUpdate = true;
 	}
 
@@ -52,7 +71,7 @@ public:
 		if(m_markedForUpdate)
 		{
 			m_markedForUpdate = false;
-			updateMatrices(m_obb);
+			updateInternal();
 		}
 
 		return ErrorCode::NONE;
@@ -75,8 +94,8 @@ private:
 
 	Array<Layer, U(LayerType::COUNT)> m_layers;
 	Mat4 m_biasProjViewMat;
-	Obb m_obb =
-		Obb(Vec4(0.0f), Mat3x4::getIdentity(), Vec4(1.0f, 1.0f, 1.0f, 0.0f));
+	Vec3 m_sizes = Vec3(1.0);
+	Transform m_trf = Transform::getIdentity();
 	Bool8 m_markedForUpdate = true;
 
 	ANKI_USE_RESULT Error setLayer(CString texAtlasFname,
@@ -84,7 +103,7 @@ private:
 		F32 blendFactor,
 		LayerType type);
 
-	void updateMatrices(const Obb& box);
+	void updateInternal();
 };
 /// @}
 

+ 137 - 0
src/anki/scene/DecalNode.cpp

@@ -0,0 +1,137 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/scene/DecalNode.h>
+#include <anki/scene/DecalComponent.h>
+#include <anki/scene/MoveComponent.h>
+#include <anki/scene/SpatialComponent.h>
+
+namespace anki
+{
+
+//==============================================================================
+// DecalMoveFeedbackComponent                                                  =
+//==============================================================================
+
+/// Decal feedback component.
+class DecalMoveFeedbackComponent : public SceneComponent
+{
+public:
+	DecalMoveFeedbackComponent(SceneNode* node)
+		: SceneComponent(SceneComponentType::NONE, node)
+	{
+	}
+
+	ANKI_USE_RESULT Error update(SceneNode& node, F32, F32, Bool& updated)
+	{
+		updated = false;
+
+		MoveComponent& movec = node.getComponent<MoveComponent>();
+
+		if(movec.getTimestamp() == node.getGlobalTimestamp())
+		{
+			static_cast<DecalNode&>(node).onMove(movec);
+		}
+
+		return ErrorCode::NONE;
+	}
+};
+
+//==============================================================================
+// DecalShapeFeedbackComponent                                                 =
+//==============================================================================
+
+/// Decal feedback component.
+class DecalShapeFeedbackComponent : public SceneComponent
+{
+public:
+	DecalShapeFeedbackComponent(SceneNode* node)
+		: SceneComponent(SceneComponentType::NONE, node)
+	{
+	}
+
+	ANKI_USE_RESULT Error update(SceneNode& node, F32, F32, Bool& updated)
+	{
+		updated = false;
+
+		DecalComponent& decalc = node.getComponent<DecalComponent>();
+
+		if(decalc.getTimestamp() == node.getGlobalTimestamp())
+		{
+			static_cast<DecalNode&>(node).onDecalUpdated(decalc);
+		}
+
+		return ErrorCode::NONE;
+	}
+};
+
+//==============================================================================
+// DecalNode                                                                   =
+//==============================================================================
+
+//==============================================================================
+DecalNode::~DecalNode()
+{
+}
+
+//==============================================================================
+Error DecalNode::init()
+{
+	SceneComponent* comp;
+
+	comp = getSceneAllocator().newInstance<MoveComponent>(this);
+	addComponent(comp, true);
+
+	comp = getSceneAllocator().newInstance<DecalMoveFeedbackComponent>(this);
+	addComponent(comp, true);
+
+	comp = getSceneAllocator().newInstance<DecalComponent>(this);
+	addComponent(comp, true);
+
+	comp = getSceneAllocator().newInstance<DecalShapeFeedbackComponent>(this);
+	addComponent(comp, true);
+
+	comp = getSceneAllocator().newInstance<SpatialComponent>(this, &m_obbW);
+	addComponent(comp, true);
+}
+
+//==============================================================================
+void DecalNode::onMove(MoveComponent& movec)
+{
+	SpatialComponent& sc = getComponent<SpatialComponent>();
+	sc.setSpatialOrigin(movec.getWorldTransform().getOrigin());
+	sc.markForUpdate();
+
+	DecalComponent& decalc = getComponent<DecalComponent>();
+	decalc.updateTransform(movec.getWorldTransform());
+
+	updateObb(movec.getWorldTransform(), decalc);
+}
+
+//==============================================================================
+void DecalNode::onDecalUpdated(DecalComponent& decalc)
+{
+	SpatialComponent& sc = getComponent<SpatialComponent>();
+	sc.markForUpdate();
+
+	const MoveComponent& movec = getComponent<MoveComponent>();
+	updateObb(movec.getWorldTransform(), decalc);
+}
+
+//==============================================================================
+void DecalNode::updateObb(const Transform& trf, const DecalComponent& decalc)
+{
+	Vec4 center(0.0f, 0.0f, -decalc.getDepth() / 2.0f, 0.0f);
+	Vec4 extend(decalc.getWidth() / 2.0f,
+		decalc.getHeight() / 2.0f,
+		decalc.getDepth() / 2.0f,
+		0.0f);
+
+	Obb obbL(center, Mat3x4::getIdentity(), extend);
+
+	m_obbW = obbL.getTransformed(trf);
+}
+
+} // end namespace anki

+ 15 - 3
src/anki/scene/DecalNode.h

@@ -5,7 +5,8 @@
 
 #pragma once
 
-#include <anki/scene/Common.h>
+#include <anki/scene/SceneNode.h>
+#include <anki/collision/Obb.h>
 
 namespace anki
 {
@@ -16,14 +17,25 @@ namespace anki
 /// Node that has a decal component.
 class DecalNode : public SceneNode
 {
+	friend class DecalMoveFeedbackComponent;
+	friend class DecalShapeFeedbackComponent;
+
 public:
-	DecalNode(SceneGraph* scene);
+	DecalNode(SceneGraph* scene, CString name)
+		: SceneNode(scene, name)
+	{
+	}
 
 	~DecalNode();
 
-	ANKI_USE_RESULT Error init(const CString& name);
+	ANKI_USE_RESULT Error init();
 
 private:
+	Obb m_obbW; ///< OBB in world space.
+
+	void onMove(MoveComponent& movec);
+	void onDecalUpdated(DecalComponent& decalc);
+	void updateObb(const Transform& trf, const DecalComponent& decalc);
 };
 /// @}
 

+ 11 - 14
src/anki/scene/Light.cpp

@@ -53,8 +53,8 @@ public:
 //==============================================================================
 
 //==============================================================================
-Light::Light(SceneGraph* scene)
-	: SceneNode(scene)
+Light::Light(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -64,11 +64,8 @@ Light::~Light()
 }
 
 //==============================================================================
-Error Light::init(
-	const CString& name, LightComponent::LightType type, CollisionShape* shape)
+Error Light::init(LightComponent::LightType type, CollisionShape* shape)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	SceneComponent* comp;
 
 	// Move component
@@ -173,8 +170,8 @@ Error Light::loadLensFlare(const CString& filename)
 //==============================================================================
 
 //==============================================================================
-PointLight::PointLight(SceneGraph* scene)
-	: Light(scene)
+PointLight::PointLight(SceneGraph* scene, CString name)
+	: Light(scene, name)
 {
 }
 
@@ -185,9 +182,9 @@ PointLight::~PointLight()
 }
 
 //==============================================================================
-Error PointLight::init(const CString& name)
+Error PointLight::init()
 {
-	return Light::init(name, LightComponent::LightType::POINT, &m_sphereW);
+	return Light::init(LightComponent::LightType::POINT, &m_sphereW);
 }
 
 //==============================================================================
@@ -283,15 +280,15 @@ Error PointLight::frameUpdate(F32 prevUpdateTime, F32 crntTime)
 //==============================================================================
 
 //==============================================================================
-SpotLight::SpotLight(SceneGraph* scene)
-	: Light(scene)
+SpotLight::SpotLight(SceneGraph* scene, CString name)
+	: Light(scene, name)
 {
 }
 
 //==============================================================================
-Error SpotLight::init(const CString& name)
+Error SpotLight::init()
 {
-	ANKI_CHECK(Light::init(name, LightComponent::LightType::SPOT, &m_frustum));
+	ANKI_CHECK(Light::init(LightComponent::LightType::SPOT, &m_frustum));
 
 	FrustumComponent* fr =
 		getSceneAllocator().newInstance<FrustumComponent>(this, &m_frustum);

+ 7 - 8
src/anki/scene/Light.h

@@ -23,13 +23,12 @@ class Light : public SceneNode
 	friend class LightFeedbackComponent;
 
 public:
-	Light(SceneGraph* scene);
+	Light(SceneGraph* scene, CString name);
 
 	~Light();
 
-	ANKI_USE_RESULT Error init(const CString& name,
-		LightComponent::LightType type,
-		CollisionShape* shape);
+	ANKI_USE_RESULT Error init(
+		LightComponent::LightType type, CollisionShape* shape);
 
 	ANKI_USE_RESULT Error loadLensFlare(const CString& filename);
 
@@ -51,10 +50,10 @@ protected:
 class PointLight : public Light
 {
 public:
-	PointLight(SceneGraph* scene);
+	PointLight(SceneGraph* scene, CString name);
 	~PointLight();
 
-	ANKI_USE_RESULT Error init(const CString& name);
+	ANKI_USE_RESULT Error init();
 
 	ANKI_USE_RESULT Error frameUpdate(
 		F32 prevUpdateTime, F32 crntTime) override;
@@ -78,9 +77,9 @@ public:
 class SpotLight : public Light
 {
 public:
-	SpotLight(SceneGraph* scene);
+	SpotLight(SceneGraph* scene, CString name);
 
-	ANKI_USE_RESULT Error init(const CString& name);
+	ANKI_USE_RESULT Error init();
 
 	ANKI_USE_RESULT Error frameUpdate(
 		F32 prevUpdateTime, F32 crntTime) override;

+ 7 - 11
src/anki/scene/ModelNode.cpp

@@ -56,8 +56,8 @@ public:
 //==============================================================================
 
 //==============================================================================
-ModelPatchNode::ModelPatchNode(SceneGraph* scene)
-	: SceneNode(scene)
+ModelPatchNode::ModelPatchNode(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -67,10 +67,9 @@ ModelPatchNode::~ModelPatchNode()
 }
 
 //==============================================================================
-Error ModelPatchNode::init(const CString& name, const ModelPatch* modelPatch)
+Error ModelPatchNode::init(const ModelPatch* modelPatch)
 {
 	ANKI_ASSERT(modelPatch);
-	ANKI_CHECK(SceneNode::init(name));
 
 	m_modelPatch = modelPatch;
 
@@ -161,8 +160,8 @@ public:
 //==============================================================================
 
 //==============================================================================
-ModelNode::ModelNode(SceneGraph* scene)
-	: SceneNode(scene)
+ModelNode::ModelNode(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -173,10 +172,8 @@ ModelNode::~ModelNode()
 }
 
 //==============================================================================
-Error ModelNode::init(const CString& name, const CString& modelFname)
+Error ModelNode::init(const CString& modelFname)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	SceneComponent* comp;
 
 	ANKI_CHECK(getResourceManager().loadResource(modelFname, m_model));
@@ -191,8 +188,7 @@ Error ModelNode::init(const CString& name, const CString& modelFname)
 	{
 		ModelPatchNode* mpn;
 		StringAuto nname(getFrameAllocator());
-		nname.sprintf("%s_%d", &name[0], count);
-		ANKI_CHECK(getSceneGraph().newSceneNode(nname.toCString(), mpn, *it));
+		ANKI_CHECK(getSceneGraph().newSceneNode(CString(), mpn, *it));
 
 		m_modelPatches[count++] = mpn;
 		addChild(mpn);

+ 4 - 5
src/anki/scene/ModelNode.h

@@ -29,12 +29,11 @@ class ModelPatchNode : public SceneNode
 	friend class ModelPatchRenderComponent;
 
 public:
-	ModelPatchNode(SceneGraph* scene);
+	ModelPatchNode(SceneGraph* scene, CString name);
 
 	~ModelPatchNode();
 
-	ANKI_USE_RESULT Error init(
-		const CString& name, const ModelPatch* modelPatch);
+	ANKI_USE_RESULT Error init(const ModelPatch* modelPatch);
 
 private:
 	Obb m_obb; ///< In world space. ModelNode will update it.
@@ -50,11 +49,11 @@ class ModelNode : public SceneNode
 	friend class ModelMoveFeedbackComponent;
 
 public:
-	ModelNode(SceneGraph* scene);
+	ModelNode(SceneGraph* scene, CString name);
 
 	~ModelNode();
 
-	ANKI_USE_RESULT Error init(const CString& name, const CString& modelFname);
+	ANKI_USE_RESULT Error init(const CString& modelFname);
 
 	const Model& getModel() const
 	{

+ 1 - 3
src/anki/scene/OccluderNode.cpp

@@ -53,10 +53,8 @@ OccluderNode::~OccluderNode()
 }
 
 //==============================================================================
-Error OccluderNode::init(const CString& name, const CString& meshFname)
+Error OccluderNode::init(const CString& meshFname)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	// Load mesh
 	MeshLoader loader(&getSceneGraph().getResourceManager());
 	ANKI_CHECK(loader.load(meshFname));

+ 3 - 3
src/anki/scene/OccluderNode.h

@@ -20,14 +20,14 @@ class OccluderNode : public SceneNode
 	friend class OccluderMoveFeedbackComponent;
 
 public:
-	OccluderNode(SceneGraph* scene)
-		: SceneNode(scene)
+	OccluderNode(SceneGraph* scene, CString name)
+		: SceneNode(scene, name)
 	{
 	}
 
 	~OccluderNode();
 
-	ANKI_USE_RESULT Error init(const CString& name, const CString& meshFname);
+	ANKI_USE_RESULT Error init(const CString& meshFname);
 
 private:
 	DynamicArray<Vec3> m_vertsL; ///< Verts in local space.

+ 3 - 4
src/anki/scene/ParticleEmitter.cpp

@@ -260,8 +260,8 @@ public:
 //==============================================================================
 
 //==============================================================================
-ParticleEmitter::ParticleEmitter(SceneGraph* scene)
-	: SceneNode(scene)
+ParticleEmitter::ParticleEmitter(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -281,9 +281,8 @@ ParticleEmitter::~ParticleEmitter()
 }
 
 //==============================================================================
-Error ParticleEmitter::init(const CString& name, const CString& filename)
+Error ParticleEmitter::init(const CString& filename)
 {
-	ANKI_CHECK(SceneNode::init(name));
 	SceneComponent* comp;
 
 	// Load resource

+ 2 - 2
src/anki/scene/ParticleEmitter.h

@@ -163,11 +163,11 @@ class ParticleEmitter : public SceneNode, private ParticleEmitterProperties
 	friend class MoveFeedbackComponent;
 
 public:
-	ParticleEmitter(SceneGraph* scene);
+	ParticleEmitter(SceneGraph* scene, CString name);
 
 	~ParticleEmitter();
 
-	ANKI_USE_RESULT Error init(const CString& name, const CString& filename);
+	ANKI_USE_RESULT Error init(const CString& filename);
 
 	/// @name SceneNode virtuals
 	/// @{

+ 3 - 5
src/anki/scene/PlayerNode.cpp

@@ -126,8 +126,8 @@ public:
 //==============================================================================
 
 //==============================================================================
-PlayerNode::PlayerNode(SceneGraph* scene)
-	: SceneNode(scene)
+PlayerNode::PlayerNode(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -137,10 +137,8 @@ PlayerNode::~PlayerNode()
 }
 
 //==============================================================================
-Error PlayerNode::init(const CString& name, const Vec4& position)
+Error PlayerNode::init(const Vec4& position)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	// Create physics object
 	PhysicsPlayerControllerInitInfo init;
 	init.m_position = position;

+ 2 - 2
src/anki/scene/PlayerNode.h

@@ -21,11 +21,11 @@ class PlayerNode : public SceneNode
 	friend class PlayerNodeFeedbackComponent;
 
 public:
-	PlayerNode(SceneGraph* scene);
+	PlayerNode(SceneGraph* scene, CString name);
 
 	~PlayerNode();
 
-	ANKI_USE_RESULT Error init(const CString& name, const Vec4& position);
+	ANKI_USE_RESULT Error init(const Vec4& position);
 
 private:
 	PhysicsPlayerControllerPtr m_player;

+ 1 - 3
src/anki/scene/ReflectionProbe.cpp

@@ -57,12 +57,10 @@ ReflectionProbe::~ReflectionProbe()
 }
 
 //==============================================================================
-Error ReflectionProbe::init(const CString& name, F32 radius)
+Error ReflectionProbe::init(F32 radius)
 {
 	SceneComponent* comp;
 
-	ANKI_CHECK(SceneNode::init(name));
-
 	// Move component first
 	comp = getSceneAllocator().newInstance<MoveComponent>(this);
 	addComponent(comp, true);

+ 3 - 3
src/anki/scene/ReflectionProbe.h

@@ -25,14 +25,14 @@ public:
 	const F32 FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
 	const F32 EFFECTIVE_DISTANCE = 256.0;
 
-	ReflectionProbe(SceneGraph* scene)
-		: SceneNode(scene)
+	ReflectionProbe(SceneGraph* scene, CString name)
+		: SceneNode(scene, name)
 	{
 	}
 
 	~ReflectionProbe();
 
-	ANKI_USE_RESULT Error init(const CString& name, F32 radius);
+	ANKI_USE_RESULT Error init(F32 radius);
 
 	U getCubemapArrayIndex() const
 	{

+ 1 - 3
src/anki/scene/ReflectionProxy.cpp

@@ -46,10 +46,8 @@ public:
 //==============================================================================
 
 //==============================================================================
-Error ReflectionProxy::init(const CString& name, const CString& proxyMesh)
+Error ReflectionProxy::init(const CString& proxyMesh)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	// Move component first
 	SceneComponent* comp = getSceneAllocator().newInstance<MoveComponent>(this);
 	addComponent(comp, true);

+ 3 - 3
src/anki/scene/ReflectionProxy.h

@@ -21,8 +21,8 @@ class ReflectionProxy : public SceneNode
 	friend class ReflectionProxyMoveFeedbackComponent;
 
 public:
-	ReflectionProxy(SceneGraph* scene)
-		: SceneNode(scene)
+	ReflectionProxy(SceneGraph* scene, CString name)
+		: SceneNode(scene, name)
 	{
 	}
 
@@ -33,7 +33,7 @@ public:
 
 	/// Create the proxy. The points form a quad and they should be in local
 	/// space.
-	ANKI_USE_RESULT Error init(const CString& name, const CString& proxyMesh);
+	ANKI_USE_RESULT Error init(const CString& proxyMesh);
 
 private:
 	DynamicArray<Array<Vec4, 4>> m_quadsLSpace; ///< Quads in local space.

+ 2 - 3
src/anki/scene/SceneGraph.h

@@ -244,14 +244,13 @@ template<typename Node, typename... Args>
 inline Error SceneGraph::newSceneNode(
 	const CString& name, Node*& node, Args&&... args)
 {
-	ANKI_ASSERT(!name.isEmpty());
 	Error err = ErrorCode::NONE;
 	SceneAllocator<Node> al = m_alloc;
 
-	node = al.template newInstance<Node>(this);
+	node = al.template newInstance<Node>(this, name);
 	if(node)
 	{
-		err = node->init(name, std::forward<Args>(args)...);
+		err = node->init(std::forward<Args>(args)...);
 	}
 	else
 	{

+ 5 - 8
src/anki/scene/SceneNode.cpp

@@ -10,10 +10,14 @@ namespace anki
 {
 
 //==============================================================================
-SceneNode::SceneNode(SceneGraph* scene)
+SceneNode::SceneNode(SceneGraph* scene, CString name)
 	: m_scene(scene)
 	, m_uuid(scene->getNewSceneNodeUuid())
 {
+	if(name)
+	{
+		m_name.create(getSceneAllocator(), name);
+	}
 }
 
 //==============================================================================
@@ -37,13 +41,6 @@ SceneNode::~SceneNode()
 	m_components.destroy(alloc);
 }
 
-//==============================================================================
-Error SceneNode::init(const CString& name)
-{
-	m_name.create(getSceneAllocator(), name);
-	return ErrorCode::NONE;
-}
-
 //==============================================================================
 void SceneNode::setMarkedForDeletion()
 {

+ 5 - 6
src/anki/scene/SceneNode.h

@@ -30,16 +30,15 @@ class SceneNode : public Hierarchy<SceneNode>,
 public:
 	using Base = Hierarchy<SceneNode>;
 
-	/// The one and only constructor
-	SceneNode(SceneGraph* scene);
+	/// The one and only constructor.
+	/// @param scene The owner scene.
+	/// @param name The unique name of the node. If it's empty the the node
+	///             is not searchable.
+	SceneNode(SceneGraph* scene, CString name);
 
 	/// Unregister node
 	virtual ~SceneNode();
 
-	/// @param name The unique name of the node. If it's nullptr the the node
-	///             is not searchable.
-	ANKI_USE_RESULT Error init(const CString& name);
-
 	SceneGraph& getSceneGraph()
 	{
 		return *m_scene;

+ 6 - 9
src/anki/scene/Sector.cpp

@@ -70,11 +70,8 @@ PortalSectorBase::~PortalSectorBase()
 }
 
 //==============================================================================
-Error PortalSectorBase::init(
-	const CString& name, const CString& meshFname, Bool isSector)
+Error PortalSectorBase::init(const CString& meshFname, Bool isSector)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	// Create move component
 	SceneComponent* comp = getSceneAllocator().newInstance<MoveComponent>(this);
 	addComponent(comp, true);
@@ -161,9 +158,9 @@ Portal::~Portal()
 }
 
 //==============================================================================
-Error Portal::init(const CString& name, const CString& meshFname)
+Error Portal::init(const CString& meshFname)
 {
-	ANKI_CHECK(Base::init(name, meshFname, false));
+	ANKI_CHECK(Base::init(meshFname, false));
 	return ErrorCode::NONE;
 }
 
@@ -272,9 +269,9 @@ Sector::~Sector()
 }
 
 //==============================================================================
-Error Sector::init(const CString& name, const CString& meshFname)
+Error Sector::init(const CString& meshFname)
 {
-	ANKI_CHECK(PortalSectorBase::init(name, meshFname, true));
+	ANKI_CHECK(PortalSectorBase::init(meshFname, true));
 	return ErrorCode::NONE;
 }
 
@@ -719,4 +716,4 @@ void SectorGroup::findVisibleNodes(const FrustumComponent& frc,
 	ctx.m_visibleNodes = WeakArray<SceneNode*>(visibleNodesMem, nodesCount);
 }
 
-} // end namespace anki
+} // end namespace anki

+ 9 - 10
src/anki/scene/Sector.h

@@ -54,15 +54,14 @@ class PortalSectorBase : public SceneNode
 	friend class Sector;
 
 public:
-	PortalSectorBase(SceneGraph* scene)
-		: SceneNode(scene)
+	PortalSectorBase(SceneGraph* scene, CString name)
+		: SceneNode(scene, name)
 	{
 	}
 
 	~PortalSectorBase();
 
-	ANKI_USE_RESULT Error init(
-		const CString& name, const CString& modelFname, Bool isSector);
+	ANKI_USE_RESULT Error init(const CString& modelFname, Bool isSector);
 
 	const CollisionShape& getBoundingShape() const
 	{
@@ -99,14 +98,14 @@ class Portal : public PortalSectorBase
 public:
 	using Base = PortalSectorBase;
 
-	Portal(SceneGraph* scene)
-		: PortalSectorBase(scene)
+	Portal(SceneGraph* scene, CString name)
+		: PortalSectorBase(scene, name)
 	{
 	}
 
 	~Portal();
 
-	ANKI_USE_RESULT Error init(const CString& name, const CString& modelFname);
+	ANKI_USE_RESULT Error init(const CString& modelFname);
 
 	ANKI_USE_RESULT Error frameUpdate(
 		F32 prevUpdateTime, F32 crntTime) override;
@@ -132,14 +131,14 @@ public:
 	using Base = PortalSectorBase;
 
 	/// Default constructor
-	Sector(SceneGraph* scene)
-		: PortalSectorBase(scene)
+	Sector(SceneGraph* scene, CString name)
+		: PortalSectorBase(scene, name)
 	{
 	}
 
 	~Sector();
 
-	ANKI_USE_RESULT Error init(const CString& name, const CString& modelFname);
+	ANKI_USE_RESULT Error init(const CString& modelFname);
 
 	void tryAddPortal(Portal* portal);
 	void tryRemovePortal(Portal* portal);

+ 4 - 5
src/anki/scene/StaticCollisionNode.cpp

@@ -14,8 +14,8 @@ namespace anki
 {
 
 //==============================================================================
-StaticCollisionNode::StaticCollisionNode(SceneGraph* scene)
-	: SceneNode(scene)
+StaticCollisionNode::StaticCollisionNode(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -25,9 +25,8 @@ StaticCollisionNode::~StaticCollisionNode()
 }
 
 //==============================================================================
-Error StaticCollisionNode::init(const CString& name,
-	const CString& resourceFname,
-	const Transform& transform)
+Error StaticCollisionNode::init(
+	const CString& resourceFname, const Transform& transform)
 {
 	// Load resource
 	ANKI_CHECK(getResourceManager().loadResource(resourceFname, m_rsrc));

+ 3 - 5
src/anki/scene/StaticCollisionNode.h

@@ -19,17 +19,15 @@ namespace anki
 class StaticCollisionNode : public SceneNode
 {
 public:
-	StaticCollisionNode(SceneGraph* scene);
+	StaticCollisionNode(SceneGraph* scene, CString name);
 
 	~StaticCollisionNode();
 
 	/// Initialize the node.
-	/// @param[in] name The name of the node.
 	/// @param[in] resourceFname The file to load. It points to a .ankicl file.
 	/// @param[in] transform The transformation. That cannot change.
-	ANKI_USE_RESULT Error init(const CString& name,
-		const CString& resourceFname,
-		const Transform& transform);
+	ANKI_USE_RESULT Error init(
+		const CString& resourceFname, const Transform& transform);
 
 private:
 	CollisionResourcePtr m_rsrc;

+ 8 - 15
src/anki/scene/StaticGeometryNode.cpp

@@ -37,8 +37,9 @@ public:
 //==============================================================================
 
 //==============================================================================
-StaticGeometryPatchNode::StaticGeometryPatchNode(SceneGraph* scene)
-	: SceneNode(scene)
+StaticGeometryPatchNode::StaticGeometryPatchNode(
+	SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -48,13 +49,11 @@ StaticGeometryPatchNode::~StaticGeometryPatchNode()
 }
 
 //==============================================================================
-Error StaticGeometryPatchNode::init(
-	const CString& name, const ModelPatch* modelPatch)
+Error StaticGeometryPatchNode::init(const ModelPatch* modelPatch)
 {
 	ANKI_ASSERT(modelPatch);
 
 	m_modelPatch = modelPatch;
-	ANKI_CHECK(SceneNode::init(name));
 
 	// Create spatial components
 	for(U i = 1; i < m_modelPatch->getSubMeshesCount(); i++)
@@ -124,8 +123,8 @@ Error StaticGeometryPatchNode::buildRendering(RenderingBuildInfo& data) const
 //==============================================================================
 
 //==============================================================================
-StaticGeometryNode::StaticGeometryNode(SceneGraph* scene)
-	: SceneNode(scene)
+StaticGeometryNode::StaticGeometryNode(SceneGraph* scene, CString name)
+	: SceneNode(scene, name)
 {
 }
 
@@ -135,22 +134,16 @@ StaticGeometryNode::~StaticGeometryNode()
 }
 
 //==============================================================================
-Error StaticGeometryNode::init(const CString& name, const CString& filename)
+Error StaticGeometryNode::init(const CString& filename)
 {
-	ANKI_CHECK(SceneNode::init(name));
-
 	ANKI_CHECK(getResourceManager().loadResource(filename, m_model));
 
 	U i = 0;
 	for(const ModelPatch* patch : m_model->getModelPatches())
 	{
-		StringAuto newname(getFrameAllocator());
-
-		newname.sprintf("%s_%u", &name[0], i);
-
 		StaticGeometryPatchNode* node;
 		ANKI_CHECK(getSceneGraph().newSceneNode<StaticGeometryPatchNode>(
-			newname.toCString(), node, patch));
+			CString(), node, patch));
 
 		++i;
 	}

+ 4 - 5
src/anki/scene/StaticGeometryNode.h

@@ -22,12 +22,11 @@ class StaticGeometryPatchNode : public SceneNode
 	friend class StaticGeometryRenderComponent;
 
 public:
-	StaticGeometryPatchNode(SceneGraph* scene);
+	StaticGeometryPatchNode(SceneGraph* scene, CString name);
 
 	~StaticGeometryPatchNode();
 
-	ANKI_USE_RESULT Error init(
-		const CString& name, const ModelPatch* modelPatch);
+	ANKI_USE_RESULT Error init(const ModelPatch* modelPatch);
 
 private:
 	const ModelPatch* m_modelPatch;
@@ -39,11 +38,11 @@ private:
 class StaticGeometryNode : public SceneNode
 {
 public:
-	StaticGeometryNode(SceneGraph* scene);
+	StaticGeometryNode(SceneGraph* scene, CString name);
 
 	~StaticGeometryNode();
 
-	ANKI_USE_RESULT Error init(const CString& name, const CString& filename);
+	ANKI_USE_RESULT Error init(const CString& filename);
 
 private:
 	ModelResourcePtr m_model;

+ 0 - 2
src/anki/util/String.h

@@ -70,14 +70,12 @@ public:
 	CString(const Char* ptr)
 		: m_ptr(ptr)
 	{
-		checkInit();
 	}
 
 	/// Copy constructor.
 	CString(const CString& b)
 		: m_ptr(b.m_ptr)
 	{
-		checkInit();
 	}
 
 	/// Copy.

+ 28 - 32
tools/texture/create_atlas.py

@@ -5,7 +5,7 @@
 # Code licensed under the BSD License.
 # http://www.anki3d.org/LICENSE
 
-import optparse
+import argparse
 from PIL import Image, ImageDraw
 from math import *
 import os
@@ -56,39 +56,30 @@ def printi(msg):
 def parse_commandline():
 	""" Parse the command line arguments """
 
-	parser = optparse.OptionParser(usage = "usage: %prog [options]", \
-			description = "This program a texture atlas ")
+	parser = argparse.ArgumentParser(
+			description = "This program creates a texture atlas",
+			formatter_class = argparse.ArgumentDefaultsHelpFormatter)
 
-	parser.add_option("-i", "--input", dest = "inp",
-			type = "string", help = "specify the image(s) to convert. " \
-			"Seperate with space")
+	parser.add_argument("-i", "--input", nargs = "+", required = True,
+			help = "specify the image(s) to convert. Seperate with space")
 
-	parser.add_option("-o", "--output", dest = "out",
-			type = "string", help = "specify output PNG image.")
+	parser.add_argument("-o", "--output", default = "atlas.png",
+			help = "specify output PNG image.")
 
-	parser.add_option("-m", "--margin", dest = "margin",
-			type = "int", action = "store", default = 0,
+	parser.add_argument("-m", "--margin", type = int, default = 0,
 			help = "specify the margin.")
 
-	parser.add_option("-b", "--background-color", dest = "bg",
-			type = "string", help = "specify background of empty areas",
+	parser.add_argument("-b", "--background-color", 
+			help = "specify background of empty areas",
 			default = "ff00ff00")
 
-	# Add the default value on each option when printing help
-	for option in parser.option_list:
-		if option.default != ("NO", "DEFAULT"):
-			option.help += (" " if option.help else "") + "[default: %default]"
-
-	(options, args) = parser.parse_args()
-
-	if not options.inp or not options.out:
-		parser.error("argument is missing")
+	args = parser.parse_args()
 
 	ctx = Context()
-	ctx.in_files = options.inp.split(":")
-	ctx.out_file = options.out
-	ctx.margin = options.margin
-	ctx.bg_color = int(options.bg, 16)
+	ctx.in_files = args.input
+	ctx.out_file = args.output
+	ctx.margin = args.margin
+	ctx.bg_color = int(args.background_color, 16)
 
 	if len(ctx.in_files) < 2:
 		parser.error("Not enough images")
@@ -229,25 +220,30 @@ def shrink_atlas(ctx):
 		width = max(width, sub_image.atlas_x + sub_image.width + ctx.margin)
 		height = max(height, sub_image.atlas_y + sub_image.height + ctx.margin)
 
-	ctx.atlas_width = width
-	ctx.atlas_height = height
+	ctx.atlas_width = next_power_of_two(width)
+	ctx.atlas_height = next_power_of_two(height)
 
 def create_atlas(ctx):
 	""" Create and populate the atlas """
 
-	bg_color = 0
+	# Change the color to something PIL can understand
+	bg_color = (ctx.bg_color >> 24)
+	bg_color |= (ctx.bg_color >> 8) & 0xFF00
+	bg_color |= (ctx.bg_color << 8) & 0xFF0000
+	bg_color |= (ctx.bg_color << 24) & 0xFF000000
+
+	mode = "RGB"
 	if ctx.mode == "RGB":
 		color_space = (255, 255, 255)
-		bg_color = (ctx.bg_color >> 24) | (ctx.bg_color >> 16) \
-			| (ctx.bg_color >> 0)
 	else:
+		mode = "RGBA"
 		color_space = (255, 255, 255, 255)
 
-	atlas_img = Image.new('RGB', \
+	atlas_img = Image.new(mode, \
 			(int(ctx.atlas_width), int(ctx.atlas_height)), color_space)
 
 	draw = ImageDraw.Draw(atlas_img)
-	draw.rectangle((0, 0, ctx.atlas_width, ctx.atlas_height), ctx.bg_color)
+	draw.rectangle((0, 0, ctx.atlas_width, ctx.atlas_height), bg_color)
 
 	for sub_image in ctx.sub_images:
 		assert sub_image.atlas_x != 0xFFFFFFFF and \