zoukankan      html  css  js  c++  java
  • CocosCreator 物理引擎中的碰撞平面的法线

    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();
    

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

  • 相关阅读:
    ASP.NET 表单验证 Part.1(理解表单验证)
    Silverlight 简介 Part.3(设计 Siverlight 页面)
    ASP.NET 成员资格 Part.3(LoginStatus、LoginView、PasswordRecovery)
    ASP.NET 网站部署 Part.1(安装IIS、复制文件部署网站)
    ASP.NET Dynamic Data Part.1(创建动态数据应用程序)
    ASP.NET 安全模型 Part.2(SSL)
    ASP.NET MVC Part.2(扩展基本的 MVC 应用程序)
    ASP.NET 网站部署 Part.2(使用 Web 部署)
    开发高级 Web 部件
    创建 Web 部件(WebPart 类、简单的 Web 部件)
  • 原文地址:https://www.cnblogs.com/kingBook/p/13344897.html
Copyright © 2011-2022 走看看