aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/samples/SampleBase/scene/Scene.h
blob: be8b5a1a76325ca7a326fbfd7ec947ee33bc96da (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* Copyright (c) 2008-2017, NVIDIA CORPORATION.  All rights reserved.
*
* NVIDIA CORPORATION and its licensors retain all intellectual property
* and proprietary rights in and to this software, related documentation
* and any modifications thereto.  Any use, reproduction, disclosure or
* distribution of this software and related documentation without an express
* license agreement from NVIDIA CORPORATION is strictly prohibited.
*/

#ifndef SCENE_H
#define SCENE_H

#include <vector>
#include <map>
#include "scene/SceneController.h"
#include "foundation/PxMat44.h"
#include <functional>
namespace nv
{
	namespace cloth
	{
		class Factory;
		class Solver;
		class Cloth;
		class Fabric;
	}
}

class Scene;
struct SceneFactory
{
	SceneFactory(Scene* (*create)(SceneController*), const char* name):Create(create), mName(name) {}
	Scene* (*Create)(SceneController*);
	const char* mName;
};

#define DECLARE_SCENE_NAME(classname, name) static int classname##id = Scene::AddSceneFactory([](SceneController* c) {return static_cast<Scene*>(new classname(c)); }, name);
#define DECLARE_SCENE(classname) DECLARE_SCENE_NAME(classname,#classname)

class Scene
{
public:

	Scene(SceneController* sceneController):mSceneController(sceneController) {}
	virtual ~Scene();

	virtual void Animate(double dt) { doSimulationStep(dt); }
	void UpdateParticleDragging(float dt);
	virtual bool HandleEvent(UINT uMsg, WPARAM wParam, LPARAM lParam);
	bool HandlePickingEvent(UINT uMsg, WPARAM wParam, LPARAM lParam, physx::PxMat44 viewProjectionMatrix);
	virtual void drawUI();
	virtual bool drawSubScenes() { return false; } //returns true if scene needs to be reinitialized
	virtual void drawStatsUI() {}
	virtual void drawDebugVisualization();
	bool debugVisualizationUpdateRequested() const;

	virtual void onInitialize() = 0;
	virtual void onTerminate() { autoDeinitialize(); }

	SceneController* getSceneController() { return mSceneController; }

	static int AddSceneFactory(Scene* (*create)(SceneController*), const char* name) { sSceneFactories.push_back(SceneFactory(create, name)); return (int)sSceneFactories.size(); }
	static Scene* CreateScene(int index, SceneController* controller) { return sSceneFactories[index].Create(controller); }
	static const char* GetSceneName(int index) { return sSceneFactories[index].mName; }
	static int GetSceneCount() { return (int)sSceneFactories.size(); }

protected:
	//Helper functions to enable automatic deinitialize
	//Tracking an object will delete it when autoDeinitialize is called
	//Untracking can be used if you delete it sooner than autoDeinitialize
	void trackClothActor(ClothActor* clothActor);
	void untrackClothActor(ClothActor* clothActor);

	void trackSolver(nv::cloth::Solver* solver);
	void untrackSolver(nv::cloth::Solver* solver);

	void trackFabric(nv::cloth::Fabric* fabric);
	void untrackFabric(nv::cloth::Fabric* fabric);

	//Help to detach cloths from solver at AutoDeinit.
	void addClothToSolver(ClothActor* clothActor, nv::cloth::Solver* solver); 
	void addClothsToSolver(nv::cloth::Range<ClothActor*> clothActors, nv::cloth::Solver* solver); 

	void trackRenderable(Renderable* renderMesh);
	void untrackRenderable(Renderable* renderMesh);

	//add a callback that is run at the end of autoDeinitialize
	void trackCleanupCallback(std::function<void(void)> cleanupCallback);

	void autoDeinitialize();


	void doSimulationStep(float dt);
	void startSimulationStep(float dt);
	void waitForSimulationStep();
	void updateSimulationGraphics();

private:
	Scene& operator= (Scene&); // not implemented

	physx::PxMat44 GetDebugDrawTransform(const ClothActor& actor);
	void DebugRenderDistanceConstraints();
	void DebugRenderTethers();
	void DebugRenderConstraints();
	void DebugRenderConstraintStiffness();
	void DebugRenderConstraintError();
	void DebugRenderPositionDelta();
	void DebugRenderBoundingBox();

private:
	SceneController* mSceneController;

	std::vector<ClothActor*> mClothList;
	std::vector<nv::cloth::Solver*> mSolverList;
	std::map<nv::cloth::Solver*, MultithreadedSolverHelper> mSolverHelpers;
	std::vector<nv::cloth::Fabric*> mFabricList;
	std::map<ClothActor*, nv::cloth::Solver*> mClothSolverMap;
	std::vector<Renderable*> mRenderableList;
	std::vector<std::function<void(void)>> mCleanupCallbackList;

	static std::vector<SceneFactory> sSceneFactories;

	enum
	{
		DEBUG_VIS_DISTANCE_CONSTRAINTS = 1,
		DEBUG_VIS_TETHERS = 2,
		DEBUG_VIS_CONSTRAINTS = 4,
		DEBUG_VIS_CONSTRAINTS_STIFFNESS = 8,
		DEBUG_VIS_NORMALS = 16,
		DEBUG_VIS_TANGENTS = 32,
		DEBUG_VIS_BITANGENTS = 64,
		DEBUG_VIS_CONSTRAINT_ERROR = 128,
		DEBUG_VIS_POSITION_DELTA = 256,
		DEBUG_VIS_ACCELERATION = 512,
		DEBUG_VIS_BOUNDING_BOX = 1024,
		DEBUG_VIS_LAST
	};

	static unsigned int mDebugVisualizationFlags;
	static bool mDebugVisualizationUpdateRequested;

	struct SceneDebugRenderParams
	{
		//Constraint render params
		int mVisiblePhaseRangeBegin;
		int mVisiblePhaseRangeEnd;
	};

	static SceneDebugRenderParams sSceneDebugRenderParams;

	//Particle dragging
	struct DraggingParticle
	{
		DraggingParticle() { mTrackedCloth = nullptr; }
		ClothActor* mTrackedCloth;
		float mDist;
		float mOffset;
		int mParticleIndex;
	};
	DraggingParticle mDraggingParticle;
};


#endif