summaryrefslogtreecommitdiff
path: root/Runtime/Dynamics/Joint.h
blob: e632116fa652a7ed61110c8bb651fc55f7971504 (plain)
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
#ifndef JOINT_H
#define JOINT_H

#include "Runtime/BaseClasses/GameObject.h"
#include "Runtime/Math/Vector3.h"
#include "RigidBody.h"
#include "JointDescriptions.h"
class Rigidbody;
class NxJointDesc;
class NxJoint;

namespace Unity
{

class Joint : public Component
{
	public:
	
	REGISTER_DERIVED_ABSTRACT_CLASS (Joint, Component)
	
	Joint (MemLabelId label, ObjectCreationMode mode);
	// virtual ~Joint (); declared-by-macro
	
	Vector3f GetAxis () const { return m_Axis; }
	virtual void SetAxis (const Vector3f& axis);
	
	Vector3f GetAnchor () const { return m_Anchor; }
	virtual void SetAnchor (const Vector3f& axis);

	Vector3f GetConnectedAnchor () const { return m_ConnectedAnchor; }
	virtual void SetConnectedAnchor (const Vector3f& axis);

	bool GetAutoConfigureConnectedAnchor () const { return m_AutoConfigureConnectedAnchor; }
	virtual void SetAutoConfigureConnectedAnchor (bool anchor);

	void SetBreakForce (float force);
	float GetBreakForce () const;
	void SetBreakTorque (float torque);
	float GetBreakTorque () const;
		
	void SetConnectedBody (PPtr<Rigidbody> body);
	PPtr<Rigidbody> GetConnectedBody () const { return m_ConnectedBody; }

	virtual void CalculateGlobalHingeSpace (Vector3f& globalAnchor, Vector3f& globalAxis, Vector3f& globalNormal) const;
	Vector3f CalculateGlobalConnectedAnchor (bool autoConfigureConnectedFrame);

	virtual void AwakeFromLoad (AwakeFromLoadMode awakeMode);
	
	virtual void Deactivate (DeactivateOperation operation);
	virtual void Reset ();
	
	virtual void CheckConsistency();
	
	void NullJoint () { m_Joint = NULL; }
	
	protected:
	
	/// SUB CLASSES OVERRIDE THIS	
	virtual void Create () = 0;
	virtual void ApplySetupAxesToDesc (int option) = 0;
	
	template<class TransferFunction>
	void JointTransferPre (TransferFunction& transfer)
	{
		Super::Transfer (transfer);

		TRANSFER_SIMPLE (m_ConnectedBody);
		TRANSFER_SIMPLE (m_Anchor);
		TRANSFER_SIMPLE (m_Axis);
		TRANSFER_SIMPLE (m_AutoConfigureConnectedAnchor);
		transfer.Align();
		TRANSFER_SIMPLE (m_ConnectedAnchor);
		
	}

	template<class TransferFunction>
	void JointTransferPreNoAxis (TransferFunction& transfer)
	{
		Super::Transfer (transfer);

		TRANSFER_SIMPLE (m_ConnectedBody);
		TRANSFER_SIMPLE (m_Anchor);
		TRANSFER_SIMPLE (m_AutoConfigureConnectedAnchor);
		transfer.Align();
		TRANSFER_SIMPLE (m_ConnectedAnchor);
	}

	template<class TransferFunction>
	void JointTransferPost (TransferFunction& transfer)
	{
		TRANSFER (m_BreakForce);
		TRANSFER (m_BreakTorque);
	}
	
	void FinalizeCreateImpl (NxJointDesc& desc, bool swapActors = false);

	NxJoint*         m_Joint;
	bool			 m_AutoConfigureConnectedAnchor;
	Vector3f         m_Anchor;
	Vector3f		 m_ConnectedAnchor;
	Vector3f         m_Axis;

	enum { kChangeAxis = 1 << 0, kChangeAnchor = 1 << 1 };
	void SetupAxes (NxJointDesc& desc, int options = kChangeAnchor|kChangeAxis);

	private:

	void Cleanup ();
	
	bool             m_DidSetupAxes; 

	float            m_BreakForce;///< Maximum force the joint can withstand before breaking. Infinity means unbreakable. range { 0.001, infinity }
	float            m_BreakTorque;	///< Maximum torque the joint can withstand before breaking. Infinity means unbreakable. range { 0.001, infinity }

	protected:
	PPtr<Rigidbody> m_ConnectedBody;
	
	friend class ::Rigidbody;
};

/// We need to to know the type of the desc so unfortunately this function must be inside the subclasses.
/// For reuse of code we do it with macros
#define IMPLEMENT_AXIS_ANCHOR(klass,nxdesc)\
void klass::ApplySetupAxesToDesc (int option)\
{\
	if (IsActive () && m_Joint)\
	{\
		nxdesc desc;\
		AssertIf (m_Joint->getState () == NX_JS_BROKEN);\
		GET_JOINT()->saveToDesc (desc);\
		SetupAxes (desc, option);\
		GET_JOINT()->loadFromDesc (desc);\
		AssertIf (m_Joint->getState () == NX_JS_BROKEN);\
	}\
}\
	
#define FINALIZE_CREATE(desc, type)\
	FinalizeCreateImpl (desc);\
	if (GET_JOINT ())\
		GET_JOINT ()->loadFromDesc (desc);\
	else\
		m_Joint = GetDynamicsScene ().createJoint (desc);\
	AssertIf (m_Joint && m_Joint->getState () == NX_JS_BROKEN);\
	Assert (!GetGameObject().IsDestroying ());

}

#endif