top of page
Search
cedarcantab

pressurebody-jc

Updated: Apr 10


h


#ifndef _PRESSURE_BODY_H
#define _PRESSURE_BODY_H

#include "SpringBody.h"

namespace JellyPhysics 
{
	class PressureBody : public SpringBody
	{
	protected:
		float		mVolume;
		float		mGasAmount;
		Vector2*	mNormalList;
		
	public:
		PressureBody(World* w, const ClosedShape& s, float mpp,
					 float gasPressure, float shapeK, float shapeD,
					 float edgeK, float edgeD,
					 const Vector2& pos, float angleInRadians, const Vector2& scale,
					 bool kinematic) :
			SpringBody(w, s, mpp, shapeK, shapeD, edgeK, edgeD, pos, angleInRadians, scale, kinematic)
		{
			mGasAmount = gasPressure;
			mNormalList = new Vector2[mPointCount];
			mVolume = 0.0f;
		}
		
		~PressureBody();
		
		void setGasPressure( float val ) { mGasAmount = val; }
		float getGasPressure() { return mGasAmount; }
		
		float getVolume() { return mVolume; }
		
		void accumulateInternalForces();
		
	};
}


#endif	// _PRESSURE_BODY_H

cpp


#include "PressureBody.h"

namespace JellyPhysics 
{
	PressureBody::~PressureBody()
	{
		delete[] mNormalList;
		//delete[] mEdgeLengthList;
	}
	
	void PressureBody::accumulateInternalForces()
	{

		SpringBody::accumulateInternalForces();
		
		// internal forces based on pressure equations.  we need 2 loops to do this.  one to find the overall volume of the
		// body, and 1 to apply forces.  we will need the normals for the edges in both loops, so we will cache them and remember them.
		mVolume = 0.0f;
		
		for (int i = 0; i < mPointCount; i++)
		{
			int prev = (i > 0) ? i-1 : mPointCount-1;
			int next = (i < mPointCount - 1) ? i + 1 : 0;
			
			PointMass& pmP = mPointMasses[prev];
			PointMass& pmI = mPointMasses[i];
			PointMass& pmN = mPointMasses[next];
			
			// currently we are talking about the edge from i --> j.
			// first calculate the volume of the body, and cache normals as we go.
			Vector2 edge1N = pmI.Position - pmP.Position;
			edge1N.makePerpendicular();
			
			Vector2 edge2N = pmN.Position - pmI.Position;
			edge2N.makePerpendicular();
			
			Vector2 norm = edge1N + edge2N;
			
			norm.normalise();			
			float edgeL = mEdgeInfo[i].length; //edge2N.length();
			
			// cache normal and edge length
			mNormalList[i] = norm;
			//mEdgeLengthList[i] = edgeL;
			
			float xdist = absf(pmI.Position.X - pmN.Position.X);
			float normX = absf(norm.X);
			
			float volumeProduct = xdist * normX * edgeL;
			
			// add to volume
			mVolume += 0.5f * volumeProduct;
		}
		
		// now loop through, adding forces!
		float invVolume = 1.0f / mVolume;
		
		for (int i = 0; i < mPointCount; i++)
		{
			int j = (i < mPointCount - 1) ? i + 1 : 0;
			
			float pressureV = (invVolume * mEdgeInfo[i].length * mGasAmount);
			mPointMasses[i].Force += mNormalList[i] * pressureV;
			mPointMasses[j].Force += mNormalList[j] * pressureV;
		}
	}
}

8 views0 comments

Recent Posts

See All

p2 naive broadphase

var Broadphase = require('../collision/Broadphase'); module.exports = NaiveBroadphase; /** * Naive broadphase implementation. Does N^2...

sopiro motor constranit

import { Matrix2, Vector2 } from "./math.js"; import { RigidBody } from "./rigidbody.js"; import { Settings } from "./settings.js";...

Yorumlar


記事: Blog2_Post
bottom of page