CocosCreator 物理引擎中的碰撞平面的法线

kingbook 2020-12-18

栏目: 类库 ·

来源: kingbook

作者:kingbook

简介  这篇文章主要介绍了CocosCreator 物理引擎中的碰撞平面的法线以及相关的经验技巧,文章约3152字,浏览量527,点赞数1,值得参考!

CocosCreator使用的是box2d.js物理引擎,碰撞平面法线方向必须取反

private onBeginContact(contact:cc.PhysicsContact,selfCollider:cc.PhysicsCollider,otherCollider:cc.PhysicsCollider):void{
	let normal=contact.getWorldManifold().normal;
	normal.mulSelf(-1);//CocosCreator中,normal的方向是由selfCollider指向otherCollider,所以正确的碰撞平台法线是相反的方向
	cc.log(normal);
}

注意:在AS3版的Box2d中,只有当前刚体和contact的刚体A不同时,法线的方向才需要取反。
此问题应该是AS3版Box2d的Bug,查看AS3版的Box2DCollision2WorldManifold.as的Initialize方法的以下代码:

case b2Manifold.e_faceB:{
	//normal = b2Math.b2MulMV(xfB.R, manifold.m_localPlaneNormal);
	tMat = xfB.R;
	tVec = manifold.m_localPlaneNormal;
	normalX = tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
	normalY = tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
	
	//planePoint = b2Math.b2MulX(xfB, manifold.m_localPoint);
	tMat = xfB.R;
	tVec = manifold.m_localPoint;
	planePointX = xfB.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
	planePointY = xfB.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
	
	//此代码应放置到for循环之后
	// Ensure normal points from A to B
	m_normal.x = -normalX;
	m_normal.y = -normalY;
	//
	for (i = 0; i < manifold.m_pointCount; i++)
	{
		//clipPoint = b2Math.b2MulX(xfA, manifold.m_points[i].m_localPoint);
		tMat = xfA.R;
		tVec = manifold.m_points[i].m_localPoint;
		clipPointX = xfA.position.x + tMat.col1.x * tVec.x + tMat.col2.x * tVec.y;
		clipPointY = xfA.position.y + tMat.col1.y * tVec.x + tMat.col2.y * tVec.y;
		
		//b2Vec2 cA = clipPoint - radiusA * normal;
		//b2Vec2 cB = clipPoint + (radiusB - b2Dot(clipPoint - planePoint, normal)) * normal;
		//m_points[i] = 0.5f * (cA + cB);
		m_points[i].x = clipPointX + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA ) * normalX;
		m_points[i].y = clipPointY + 0.5 * (radiusB - (clipPointX - planePointX) * normalX - (clipPointY - planePointY) * normalY - radiusA ) * normalY;
		
	}
}

JS版的Box2d,b2WorldManifold的Initialize方法:

case exports.b2ManifoldType.e_faceB: {
	b2Rot.MulRV(xfB.q, manifold.localNormal, this.normal);
	var planePoint = b2Transform.MulXV(xfB, manifold.localPoint, b2WorldManifold.Initialize_s_planePoint);
	for (var i = 0; i < manifold.pointCount; ++i) {
		var clipPoint = b2Transform.MulXV(xfA, manifold.points[i].localPoint, b2WorldManifold.Initialize_s_clipPoint);
		var s = radiusB - b2Vec2.DotVV(b2Vec2.SubVV(clipPoint, planePoint, b2Vec2.s_t0), this.normal);
		var cB = b2Vec2.AddVMulSV(clipPoint, s, this.normal, b2WorldManifold.Initialize_s_cB);
		var cA = b2Vec2.SubVMulSV(clipPoint, radiusA, this.normal, b2WorldManifold.Initialize_s_cA);
		b2Vec2.MidVV(cA, cB, this.points[i]);
		this.separations[i] = b2Vec2.DotVV(b2Vec2.SubVV(cA, cB, b2Vec2.s_t0), this.normal); // b2Dot(cA - cB, normal);
	}
	// Ensure normal points from A to B.
	this.normal.SelfNeg();
	break;
}

AS3版:

// Ensure normal points from A to B
m_normal.x = -normalX;
m_normal.y = -normalY;

JS版:

// Ensure normal points from A to B.
this.normal.SelfNeg();

两个版本的反转法线的代码位置不一致,导致以上问题



以上就是本文的全部内容,希望对大家的学习有所帮助,本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文地址:https://www.cnblogs.com/kingBook/p/13344897.html

相关文章

Unity的物理引擎是如何实现碰撞的呢?

cocos creator基础-(二十)物理引擎碰撞检测(示例代码)

SpriteKit物理引擎碰撞中5个重要信息(示例代码)

Unity之碰撞体组件(示例代码)

【Unity 3D】学习笔记三十六:物理引擎——刚体(示例代码)

物理引擎接口(示例代码)

(转)CocosCreator零基础制作游戏《极限跳跃》制作游戏障碍物实现碰撞检测(示例代码)

cocos2d-x之物理引擎之碰撞监测(示例代码)