首页 > 其他分享 >记录一个开源的物理引擎:Physac

记录一个开源的物理引擎:Physac

时间:2024-12-13 14:20:34浏览次数:3  
标签:body PhysicsBody Physac int void float 开源 引擎 physics

此篇文章在2023年7月27日被记录

1、Physac介绍

Physac是一个开源的物理引擎,所有代码实现在头文件中,仅仅有2100行代码,移植接口只需要一个画线函数,因此很容易移植到嵌入式设备等,GitHub地址为https://github.com/victorfisac/Physac

2、引擎接口

引擎具有以下特性:

  • 可以动态创建\销毁三种控件:圆形、多边形、四边形
  • 可以改变全局重力方向
  • 可以给控件添加力、角度力
  • 用爆炸力将多边形物理体破碎成小物理体

API接口如下:

// Initializes physics values, pointers and creates physics loop thread
void InitPhysics(void);

// Returns true if physics thread is currently enabled
bool IsPhysicsEnabled(void);

// Sets physics global gravity force
void SetPhysicsGravity(float x, float y);

// Creates a new circle physics body with generic parameters
PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density);

// Creates a new rectangle physics body with generic parameters
PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density);

// Creates a new polygon physics body with generic parameters
PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density);

// Adds a force to a physics body
void PhysicsAddForce(PhysicsBody body, Vector2 force);

// Adds a angular force to a physics body
void PhysicsAddTorque(PhysicsBody body, float amount);

// Shatters a polygon shape physics body to little physics bodies with explosion force
void PhysicsShatter(PhysicsBody body, Vector2 position, float force);

// Returns the current amount of created physics bodies
int GetPhysicsBodiesCount(void);

// Returns a physics body of the bodies pool at a specific index
PhysicsBody GetPhysicsBody(int index);

// Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
int GetPhysicsShapeType(int index);

// Returns the amount of vertices of a physics body shape
int GetPhysicsShapeVerticesCount(int index);

// Returns transformed position of a body shape (body position + vertex transformed position)
Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex);

// Sets physics body shape transform based on radians parameter
void SetPhysicsBodyRotation(PhysicsBody body, float radians);

// Unitializes and destroy a physics body
void DestroyPhysicsBody(PhysicsBody body);

// Unitializes physics pointers and closes physics loop thread
void ClosePhysics(void);

3、移植相关

正如上述所说,移植仅仅需要一个画线函数,就可以匹配所有的平台:X86、嵌入式等等,我制作了一个demo,具体表现为在屏幕上有一个旋转的长方块,随机落下圆形或者是随机多边形打在长方块上。

#include "physac.h"
InitPhysics();
PhysicsBody floor = CreatePhysicsBodyRectangle((Vector2){screenWidth / 2 , screenHeight / 2 + 50 }, screenWidth*0.75,screenHeight*0.1, 10);
floor->enabled = false;
    while(true)
    {
        QThread::usleep(30);
        if(flag1++>10)
        {
            flag1 = 0;
            Vector2 temp;
            temp.x = QRandomGenerator::global()->bounded(screenWidth/2-20,screenWidth/2+20);
            temp.y = QRandomGenerator::global()->bounded(10,20);
            CreatePhysicsBodyCircle(temp, QRandomGenerator::global()->bounded(10, 30), QRandomGenerator::global()->bounded(10, 30));

            temp.x = QRandomGenerator::global()->bounded(screenWidth/2-20,screenWidth/2+20);
            temp.y = QRandomGenerator::global()->bounded(10,20);
            CreatePhysicsBodyPolygon(temp, QRandomGenerator::global()->bounded(10, 30), QRandomGenerator::global()->bounded(3,8),QRandomGenerator::global()->bounded(10, 30));
        }
        if(flag2++>3)
        {
            flag2 = 0;
            angle++;
            angle = angle % 360 ;
            SetPhysicsBodyRotation((PhysicsBody)addr, angle*PHYSAC_DEG2RAD);
        }

        int bodiesCount = GetPhysicsBodiesCount();
        for (int i = bodiesCount - 1; i >= 0; i--)
        {
            PhysicsBody body = GetPhysicsBody(i);

            if ((body != NULL) && (body->position.y > screenHeight * 2))
                DestroyPhysicsBody(body);
        }
        RunPhysicsStep();
        bodiesCount = GetPhysicsBodiesCount();
        image.fill(Qt::white);
        for (int i = 0; i < bodiesCount; i++)
        {
            PhysicsBody body = GetPhysicsBody(i);

            if (body != NULL)
            {
                int vertexCount = GetPhysicsShapeVerticesCount(i);
                for (int j = 0; j < vertexCount; j++)
                {
                    // Get physics bodies shape vertices to draw lines
                    // Note: GetPhysicsShapeVertex() already calculates rotation transformations
                    Vector2 vertexA = GetPhysicsShapeVertex(body, j);

                    int jj = (((j + 1) < vertexCount) ? (j + 1) : 0); // Get next vertex or first to close the shape
                    Vector2 vertexB = GetPhysicsShapeVertex(body, jj);

                    QLineF line(vertexA.x, vertexA.y, vertexB.x, vertexB.y);// Draw a line between two vertex positions
                    Painter.drawLine(line);

                }
            }
        }

4、移植展示

QT5:

img

ESP32:

img

5、已知问题

代码简单也是有代价的,简单看了一下代码,计算复杂两是O(N^N),这就导致控件数量较多的时候,计算复杂度会大幅度上升(控件较多时,ESP32计算一帧甚至需要几十秒),并且涉及到大量的浮点运算,对单片机非常不友好!

标签:body,PhysicsBody,Physac,int,void,float,开源,引擎,physics
From: https://www.cnblogs.com/shumei52/p/18604868

相关文章

  • 开源分布式系统追踪技术系列
    分布式跟踪系列CATcatmonitor分布式监控CAT-是什么?catmonitor-02-分布式监控CAT埋点catmonitor-03-深度剖析开源分布式监控CATcatmonitor-04-cat服务端部署实战catmonitor-05-cat客户端集成实战catmonitor-06-cat消息存储skywalking监控-skywalking-01-APM......
  • 《安富莱嵌入式周报》第347期:分立元件自制14bit分辨率DAC,开源电池测试仪,大量位操作技
    周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 视频版https://www.bilibili.com/video/BV1SFq9YAE4j/目录:1、分立元件自制14bit分辨率DAC2、开源电池测试仪3、微软为VSCode制作的AIToolkit插件4、Zephyr相关(1)好消......
  • 开源一个多重响应集比较多的问卷-----玉溪市博物馆展览文本相关问卷调查
    最近期末了,大家做的问卷调查相关的课程都比较多,我来展示部分问卷分析,问卷主题是:玉溪市博物馆展览文本相关问卷调查问卷内主要是多重响应集合详细说一下spss多重相应的分析及python可视化部分一、多重相应集的定义:具体的路径就是 SPSS菜单栏-->分析-->多重响应--->定义......
  • 2024华为云开源开发者论坛召开,20+技术大咖解读开源生态发展
    12月7日,2024华为云开源开发者论坛在上海隆重举行,此次论坛以“开放创新,释放云上数字生产力”为主题,汇聚了来自全球的开源生态合作伙伴、企业、个人与高校开发者,围绕“开源生态前景剖析”,“开源技术解读”,“开源开发者支持与实践”等时下热点开源话题进行分享讨论,旨在帮助开发者基于......
  • 开源低代码平台-Microi吾码-接口引擎实战:MongoDB相关操作
    Microi吾码-接口引擎实战:MongoDB相关操作前言往MongoDB系统日志中插入数据新增数据(自定义数据库名、表名)修改数据删除数据查询数据列表查询单条数据Microi吾码-系列文档接口引擎实战-系列文档前言本篇介绍如何在接口引擎、后端V8事件中对MongoDB进行相关操作对Mongo......
  • 珠海先达数字化工厂:制造业转型的新引擎
    一、前言在智能制造的浪潮下,传统制造流程正经历着前所未有的重组与革新,其核心目标直指产品的全面智能化。这一转型过程中,个性化客户需求的精准捕捉与设计实现、供应商与制造商间的无缝信息对接、以及售后服务的即时响应,均成为数字化工厂构建中不可或缺的要素。随着企业对新兴技术......
  • 四个强大的 Salesforce 开源替方案(附成本对比)
    关于SalesforceSalesforce于1999年在美国旧金山创立,作为最早一批提供软件即服务(SaaS)的公司之一,Salesforce开创了基于云计算的商业应用模式。2000年代初:推出首个基于云的CRM产品,凭借其“无需安装、随时随地访问”的优势迅速吸引了大量用户。2004年:Salesforce在纽约证......
  • 一套以用户体验出发的.NET8 Web开源框架
    前言今天大姚给大家分享一套以用户体验出发的.NET8Web开源框架:YiFramework。项目介绍YiFramework是一个基于.NET8+Abp.vNext+SqlSugar的DDD领域驱动设计后端开源框架,前端使用Vue3,项目架构模式三层架构\DDD领域驱动设计,内置RBAC权限管理、BBS论坛社区系统以用户体验出发......
  • Web CAD工程应用程序图形引擎-HOOPS Communicator SDK 24.8
    适用于Web上的工程应用程序的图形引擎HOOPSCommunicator图形引擎可加速Web应用程序开发,提供高级3DWeb可视化功能,用于在Web浏览器中渲染大型3D模型。升级到HOOPSWeb平台可添加准确、快速的CAD数据导入。3D网络图形库HOOPSCommunicatorSDK为软件开发人......
  • 【免费大屏版】JeecgBoot v3.7.2 大屏版发布,开源低代码平台
    项目介绍JeecgBoot是一款企业级的低代码平台!前后端分离架构SpringBoot2.x,SpringCloud,AntDesign&Vue3,Mybatis-plus,Shiro,JWT支持微服务。强大的代码生成器让前后端代码一键生成!JeecgBoot引领低代码开发模式(OnlineCoding->代码生成->手工MERGE),帮助解决Java项目70%的重复......