Browse Source

Shape:setDensity no longer needs Body:resetMassData unless the Body already has custom mass data.

Add Body:hasCustomMassData.
If the Body has custom mass data, attaching a Shape to it doesn't automatically reset its mass data.
Sasha Szpakowski 1 year ago
parent
commit
112a09ceb7

+ 5 - 0
src/modules/physics/box2d/Body.cpp

@@ -39,6 +39,7 @@ namespace box2d
 
 Body::Body(World *world, b2Vec2 p, Body::Type type)
 	: world(world)
+	, hasCustomMass(false)
 {
 	b2BodyDef def;
 	def.position = Physics::scaleDown(p);
@@ -249,6 +250,7 @@ void Body::setLinearDamping(float d)
 void Body::resetMassData()
 {
 	body->ResetMassData();
+	hasCustomMass = false;
 }
 
 void Body::setMassData(float x, float y, float m, float i)
@@ -258,6 +260,7 @@ void Body::setMassData(float x, float y, float m, float i)
 	massData.mass = m;
 	massData.I = Physics::scaleDown(Physics::scaleDown(i));
 	body->SetMassData(&massData);
+	hasCustomMass = true;
 }
 
 void Body::setMass(float m)
@@ -266,6 +269,7 @@ void Body::setMass(float m)
 	body->GetMassData(&data);
 	data.mass = m;
 	body->SetMassData(&data);
+	hasCustomMass = true;
 }
 
 void Body::setInertia(float i)
@@ -275,6 +279,7 @@ void Body::setInertia(float i)
 	massData.mass = body->GetMass();
 	massData.I = Physics::scaleDown(Physics::scaleDown(i));
 	body->SetMassData(&massData);
+	hasCustomMass = true;
 }
 
 void Body::setGravityScale(float scale)

+ 4 - 0
src/modules/physics/box2d/Body.h

@@ -137,6 +137,8 @@ public:
 	 **/
 	int getMassData(lua_State *L);
 
+	bool hasCustomMassData() const { return hasCustomMass; }
+
 	/**
 	 * Gets the Body's angular damping.
 	 **/
@@ -433,6 +435,8 @@ private:
 	// unowned?
 	World *world;
 
+	bool hasCustomMass;
+
 	// Reference to arbitrary data.
 	Reference* ref = nullptr;
 

+ 10 - 1
src/modules/physics/box2d/Shape.cpp

@@ -47,9 +47,16 @@ Shape::Shape(Body *body, const b2Shape &shape)
 		b2FixtureDef def;
 		def.shape = &shape;
 		def.userData.pointer = (uintptr_t)this;
-		def.density = 1.0f;
+
+		// 0 density stops CreateFixture from calling b2Body::ResetMassData().
+		def.density = body->hasCustomMassData() ? 0.0f : 1.0f;
+
 		fixture = body->body->CreateFixture(&def);
 		this->shape = fixture->GetShape();
+
+		if (body->hasCustomMassData())
+			setDensity(1.0f);
+
 		retain(); // Shape::destroy does the release().
 	}
 	else
@@ -188,6 +195,8 @@ void Shape::setDensity(float density)
 {
 	throwIfFixtureNotValid();
 	fixture->SetDensity(density);
+	if (!body->hasCustomMassData())
+		body->resetMassData();
 }
 
 void Shape::setSensor(bool sensor)

+ 8 - 0
src/modules/physics/box2d/wrap_Body.cpp

@@ -162,6 +162,13 @@ int w_Body_getMassData(lua_State *L)
 	return t->getMassData(L);
 }
 
+int w_Body_hasCustomMassData(lua_State *L)
+{
+	Body *t = luax_checkbody(L, 1);
+	luax_pushboolean(L, t->hasCustomMassData());
+	return 1;
+}
+
 int w_Body_getAngularDamping(lua_State *L)
 {
 	Body *t = luax_checkbody(L, 1);
@@ -688,6 +695,7 @@ static const luaL_Reg w_Body_functions[] =
 	{ "getMass", w_Body_getMass },
 	{ "getInertia", w_Body_getInertia },
 	{ "getMassData", w_Body_getMassData },
+	{ "hasCustomMassData", w_Body_hasCustomMassData },
 	{ "getAngularDamping", w_Body_getAngularDamping },
 	{ "getLinearDamping", w_Body_getLinearDamping },
 	{ "getGravityScale", w_Body_getGravityScale },

+ 1 - 5
src/modules/physics/box2d/wrap_Physics.cpp

@@ -262,11 +262,7 @@ int w_newFixture(lua_State *L)
 	float density = (float)luaL_optnumber(L, 3, 1.0f);
 
 	Shape *newShape;
-	luax_catchexcept(L, [&]() {
-		newShape = instance()->newAttachedShape(body, shape, density);
-		newShape->setDensity(density);
-		body->resetMassData();
-	});
+	luax_catchexcept(L, [&]() { newShape = instance()->newAttachedShape(body, shape, density); });
 
 	luax_pushshape(L, newShape);
 	newShape->release();

+ 0 - 1
src/scripts/nogame.lua

@@ -3042,7 +3042,6 @@ function love.nogame()
 			link.body:setAngularDamping(0.5)
 			link.shape = love.physics.newCircleShape(link.body, link.radius)
 			link.shape:setDensity(0.1 / i)
-			link.body:resetMassData()
 			link.state = State(link.body)
 
 			-- Note: every link must also be attached to the Duckloon. Otherwise the

+ 0 - 2
src/scripts/nogame.lua.h

@@ -11620,8 +11620,6 @@ const unsigned char nogame_lua[] =
 	0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x29, 0x0a,
 	0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x73, 0x68, 0x61, 0x70, 0x65, 0x3a, 0x73, 0x65, 0x74, 0x44, 
 	0x65, 0x6e, 0x73, 0x69, 0x74, 0x79, 0x28, 0x30, 0x2e, 0x31, 0x20, 0x2f, 0x20, 0x69, 0x29, 0x0a,
-	0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x3a, 0x72, 0x65, 0x73, 0x65, 0x74, 
-	0x4d, 0x61, 0x73, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x0a,
 	0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x53, 0x74, 
 	0x61, 0x74, 0x65, 0x28, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x0a,
 	0x0a,