add MCG without Jacobi preconditioning, delegate cloth solver to another class, ignore positive separation, improve contact handling, support different shapes
Specially, see b3SpringSolver.cpp for details.
This commit is contained in:
		| @@ -20,13 +20,14 @@ | ||||
| #define B3_SPRING_CLOTH_H | ||||
|  | ||||
| #include <bounce/common/math/mat33.h> | ||||
| #include <bounce/collision/shapes/sphere.h> | ||||
|  | ||||
| #define B3_CLOTH_SPHERE_CAPACITY 32 | ||||
| #define B3_CLOTH_SHAPE_CAPACITY 32 | ||||
|  | ||||
| class b3StackAllocator; | ||||
| class b3Draw; | ||||
|  | ||||
| class b3Shape; | ||||
|  | ||||
| struct b3Mesh; | ||||
|  | ||||
| struct b3SpringClothDef | ||||
| @@ -94,13 +95,13 @@ enum b3MassType | ||||
| 	e_dynamicMass | ||||
| }; | ||||
|  | ||||
| // This structure represents an acceleration constraint. | ||||
| struct b3MassCollision | ||||
| //  | ||||
| struct b3MassContact | ||||
| { | ||||
| 	b3Vec3 n, t1, t2; | ||||
| 	float32 Fn, Ft1, Ft2; | ||||
| 	u32 j; | ||||
| 	float32 s; | ||||
| 	b3Vec3 n; | ||||
| 	bool active; | ||||
| 	bool lockOnSurface, slideOnSurface; | ||||
| }; | ||||
|  | ||||
| // Time step statistics | ||||
| @@ -136,7 +137,13 @@ public: | ||||
| 	b3MassType GetType(u32 i) const; | ||||
|  | ||||
| 	// | ||||
| 	b3Sphere* CreateSphere(const b3Vec3& center, float32 radius); | ||||
| 	void AddShape(b3Shape* shape); | ||||
|  | ||||
| 	//  | ||||
| 	u32 GetShapeCount() const; | ||||
|  | ||||
| 	//  | ||||
| 	b3Shape** GetShapes(); | ||||
|  | ||||
| 	//  | ||||
| 	const b3SpringClothStep& GetStep() const; | ||||
| @@ -150,11 +157,16 @@ public: | ||||
| 	// | ||||
| 	void Draw(b3Draw* draw) const; | ||||
| protected: | ||||
| 	void UpdateCollisions() const; | ||||
| 	friend class b3SpringSolver; | ||||
| 	 | ||||
| 	// Update contacts.  | ||||
| 	// This is where some contacts might be initiated or terminated. | ||||
| 	void UpdateContacts(); | ||||
| 	 | ||||
| 	b3StackAllocator* m_allocator; | ||||
|  | ||||
| 	b3Mesh* m_mesh; | ||||
| 	float32 m_r; | ||||
|  | ||||
| 	b3Vec3 m_gravity; | ||||
|  | ||||
| @@ -163,17 +175,16 @@ protected: | ||||
| 	b3Vec3* m_f; | ||||
| 	float32* m_inv_m; | ||||
| 	b3Vec3* m_y; | ||||
| 	b3MassType* m_massTypes; | ||||
| 	b3MassCollision* m_collisions; | ||||
| 	b3MassType* m_types; | ||||
| 	u32 m_massCount; | ||||
|  | ||||
| 	b3MassContact* m_contacts; | ||||
| 	 | ||||
| 	b3Spring* m_springs; | ||||
| 	u32 m_springCount; | ||||
|  | ||||
| 	float32 m_r; | ||||
|  | ||||
| 	b3Sphere m_spheres[B3_CLOTH_SPHERE_CAPACITY]; | ||||
| 	u32 m_sphereCount; | ||||
| 	b3Shape* m_shapes[B3_CLOTH_SHAPE_CAPACITY]; | ||||
| 	u32 m_shapeCount; | ||||
|  | ||||
| 	b3SpringClothStep m_step; | ||||
| }; | ||||
| @@ -191,13 +202,23 @@ inline void b3SpringCloth::SetGravity(const b3Vec3& gravity) | ||||
| inline b3MassType b3SpringCloth::GetType(u32 i) const | ||||
| { | ||||
| 	B3_ASSERT(i < m_massCount); | ||||
| 	return m_massTypes[i]; | ||||
| 	return m_types[i]; | ||||
| } | ||||
|  | ||||
| inline void b3SpringCloth::SetType(u32 i, b3MassType type) | ||||
| { | ||||
| 	B3_ASSERT(i < m_massCount); | ||||
| 	m_massTypes[i] = type; | ||||
| 	m_types[i] = type; | ||||
| } | ||||
|  | ||||
| inline u32 b3SpringCloth::GetShapeCount() const | ||||
| { | ||||
| 	return m_shapeCount; | ||||
| } | ||||
|  | ||||
| inline b3Shape** b3SpringCloth::GetShapes()  | ||||
| { | ||||
| 	return m_shapes; | ||||
| } | ||||
|  | ||||
| inline const b3SpringClothStep& b3SpringCloth::GetStep() const | ||||
|   | ||||
							
								
								
									
										93
									
								
								include/bounce/dynamics/cloth/spring_solver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								include/bounce/dynamics/cloth/spring_solver.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| /* | ||||
| * Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net | ||||
| * | ||||
| * This software is provided 'as-is', without any express or implied | ||||
| * warranty.  In no event will the authors be held liable for any damages | ||||
| * arising from the use of this software. | ||||
| * Permission is granted to anyone to use this software for any purpose, | ||||
| * including commercial applications, and to alter it and redistribute it | ||||
| * freely, subject to the following restrictions: | ||||
| * 1. The origin of this software must not be misrepresented; you must not | ||||
| * claim that you wrote the original software. If you use this software | ||||
| * in a product, an acknowledgment in the product documentation would be | ||||
| * appreciated but is not required. | ||||
| * 2. Altered source versions must be plainly marked as such, and must not be | ||||
| * misrepresented as being the original software. | ||||
| * 3. This notice may not be removed or altered from any source distribution. | ||||
| */ | ||||
|  | ||||
| #ifndef B3_SPRING_SOLVER_H | ||||
| #define B3_SPRING_SOLVER_H | ||||
|  | ||||
| #include <bounce/common/math/vec3.h> | ||||
| #include <bounce/common/math/mat33.h> | ||||
|  | ||||
| class b3SpringCloth; | ||||
| class b3StackAllocator; | ||||
|  | ||||
| struct b3MassContact; | ||||
| struct b3Spring; | ||||
|  | ||||
| enum b3MassType; | ||||
|  | ||||
| struct b3SpringSolverDef | ||||
| { | ||||
| 	b3SpringCloth* cloth; | ||||
| 	float32 dt; | ||||
| }; | ||||
|  | ||||
| class b3SpringSolver | ||||
| { | ||||
| public: | ||||
| 	b3SpringSolver(const b3SpringSolverDef& def); | ||||
|  | ||||
| 	~b3SpringSolver(); | ||||
|  | ||||
| 	void Solve(b3Vec3* constraintForces); | ||||
|  | ||||
| 	u32 GetIterations() const; | ||||
| private: | ||||
| 	// Apply internal forces and store their unique derivatives. | ||||
| 	void InitializeSpringForces(); | ||||
|  | ||||
| 	// Initialize b, from Ax = b | ||||
| 	void Compute_b(b3Vec3* b) const; | ||||
|  | ||||
| 	// Solve Ax = b using the Modified Conjugate Gradient (MCG).  | ||||
| 	// Output x and the residual error f. | ||||
| 	void Solve_MCG(b3Vec3* x, b3Vec3* f, u32& iterations, const b3Vec3* b) const; | ||||
|  | ||||
| 	// Solve Ax = b using MCG with Jacobi preconditioning. | ||||
| 	// Output x and the residual error f. | ||||
| 	// This method is slower than MCG because we have to compute the preconditioning  | ||||
| 	// matrix P, but it can improve convergence. | ||||
| 	void Solve_MPCG(b3Vec3* x, b3Vec3* f, u32& iterations, const b3Vec3* b) const; | ||||
|  | ||||
| 	b3SpringCloth * m_cloth; | ||||
| 	float32 m_h; | ||||
| 	b3Mat33* m_Jx; | ||||
| 	b3Mat33* m_Jv; | ||||
| 	u32 m_iterations; | ||||
|  | ||||
| 	b3StackAllocator* m_allocator; | ||||
|  | ||||
| 	b3Vec3* m_x; | ||||
| 	b3Vec3* m_v; | ||||
| 	b3Vec3* m_f; | ||||
| 	float32* m_inv_m; | ||||
| 	b3Vec3* m_y; | ||||
| 	b3MassType* m_types; | ||||
| 	u32 m_massCount; | ||||
|  | ||||
| 	b3MassContact* m_contacts; | ||||
| 	 | ||||
| 	b3Spring* m_springs; | ||||
| 	u32 m_springCount; | ||||
| }; | ||||
|  | ||||
| inline u32 b3SpringSolver::GetIterations() const | ||||
| { | ||||
| 	return m_iterations; | ||||
| } | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user