MiMoEngine ASM: x86-64 MASM汇编+C混合架构游戏引擎
核心热路径(数学/内存/字符串/性能分析)用MASM汇编(SSE/AVX2) 外围系统(窗口/渲染/ECS/音频/UI/脚本)用C语言 含自研编辑器、VisualScript积木编程、中文渲染(glyph_atlas)
This commit is contained in:
commit
2d56cb3bc9
91 files changed
+9988
No files matched your search
@@ -0,0 +1,202 @@
|
||||
#include "physics.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
PhysicsWorld* physics_create(void) {
|
||||
PhysicsWorld* w = (PhysicsWorld*)calloc(1, sizeof(PhysicsWorld));
|
||||
w->gravity_enabled = 1;
|
||||
w->gravity = (Vec3){0, -9.81f, 0};
|
||||
return w;
|
||||
}
|
||||
|
||||
void physics_destroy(PhysicsWorld* world) {
|
||||
free(world);
|
||||
}
|
||||
|
||||
uint32_t physics_add_aabb(PhysicsWorld* world, uint32_t entity, Vec3 min, Vec3 max) {
|
||||
uint32_t idx = world->collider_count++;
|
||||
Collider* c = &world->colliders[idx];
|
||||
c->entity_id = entity;
|
||||
c->type = COLLIDER_AABB;
|
||||
c->aabb.min = min;
|
||||
c->aabb.max = max;
|
||||
c->is_trigger = 0;
|
||||
c->is_static = 0;
|
||||
return idx;
|
||||
}
|
||||
|
||||
uint32_t physics_add_sphere(PhysicsWorld* world, uint32_t entity, Vec3 center, float radius) {
|
||||
uint32_t idx = world->collider_count++;
|
||||
Collider* c = &world->colliders[idx];
|
||||
c->entity_id = entity;
|
||||
c->type = COLLIDER_SPHERE;
|
||||
c->sphere.center = center;
|
||||
c->sphere.radius = radius;
|
||||
return idx;
|
||||
}
|
||||
|
||||
uint32_t physics_add_plane(PhysicsWorld* world, uint32_t entity, Vec3 normal, float distance) {
|
||||
uint32_t idx = world->collider_count++;
|
||||
Collider* c = &world->colliders[idx];
|
||||
c->entity_id = entity;
|
||||
c->type = COLLIDER_PLANE;
|
||||
vec3_normalize(&normal, &c->plane.normal);
|
||||
c->plane.distance = distance;
|
||||
c->is_static = 1;
|
||||
return idx;
|
||||
}
|
||||
|
||||
void physics_remove_collider(PhysicsWorld* world, uint32_t index) {
|
||||
if (index < world->collider_count) {
|
||||
world->colliders[index] = world->colliders[--world->collider_count];
|
||||
}
|
||||
}
|
||||
|
||||
void physics_update_collider(PhysicsWorld* world, uint32_t index, Vec3 position) {
|
||||
Collider* c = &world->colliders[index];
|
||||
if (c->type == COLLIDER_SPHERE) {
|
||||
c->sphere.center = position;
|
||||
}
|
||||
}
|
||||
|
||||
static int aabb_vs_aabb(const Collider* a, const Collider* b, Vec3* normal, float* depth) {
|
||||
Vec3 diff;
|
||||
Vec3 centerA = {(a->aabb.min.x + a->aabb.max.x) * 0.5f, (a->aabb.min.y + a->aabb.max.y) * 0.5f, (a->aabb.min.z + a->aabb.max.z) * 0.5f};
|
||||
Vec3 centerB = {(b->aabb.min.x + b->aabb.max.x) * 0.5f, (b->aabb.min.y + b->aabb.max.y) * 0.5f, (b->aabb.min.z + b->aabb.max.z) * 0.5f};
|
||||
vec3_sub(¢erA, ¢erB, &diff);
|
||||
Vec3 half_a, half_b, size;
|
||||
vec3_sub(&a->aabb.max, &a->aabb.min, &half_a);
|
||||
vec3_scale(&half_a, 0.5f, &half_a);
|
||||
vec3_sub(&b->aabb.max, &b->aabb.min, &half_b);
|
||||
vec3_scale(&half_b, 0.5f, &half_b);
|
||||
|
||||
float dx = fabsf(diff.x) - (half_a.x + half_b.x);
|
||||
float dy = fabsf(diff.y) - (half_a.y + half_b.y);
|
||||
float dz = fabsf(diff.z) - (half_a.z + half_b.z);
|
||||
|
||||
if (dx < 0 && dy < 0 && dz < 0) {
|
||||
*depth = -fmaxf(fmaxf(dx, dy), dz);
|
||||
if (dx > dy && dx > dz) normal = &(Vec3){copysignf(1, diff.x), 0, 0};
|
||||
else if (dy > dz) { normal->x = 0; normal->y = copysignf(1, diff.y); normal->z = 0; }
|
||||
else { normal->x = 0; normal->y = 0; normal->z = copysignf(1, diff.z); }
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sphere_vs_sphere(const Collider* a, const Collider* b, Vec3* normal, float* depth) {
|
||||
Vec3 diff;
|
||||
vec3_sub(&a->sphere.center, &b->sphere.center, &diff);
|
||||
float dist = vec3_length(&diff);
|
||||
float radii = a->sphere.radius + b->sphere.radius;
|
||||
|
||||
if (dist < radii) {
|
||||
*depth = radii - dist;
|
||||
if (dist > 0.0001f) {
|
||||
vec3_normalize(&diff, normal);
|
||||
} else {
|
||||
*normal = (Vec3){0, 1, 0};
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sphere_vs_aabb(const Collider* sphere, const Collider* aabb, Vec3* normal, float* depth) {
|
||||
Vec3 closest;
|
||||
closest.x = fmaxf(aabb->aabb.min.x, fminf(sphere->sphere.center.x, aabb->aabb.max.x));
|
||||
closest.y = fmaxf(aabb->aabb.min.y, fminf(sphere->sphere.center.y, aabb->aabb.max.y));
|
||||
closest.z = fmaxf(aabb->aabb.min.z, fminf(sphere->sphere.center.z, aabb->aabb.max.z));
|
||||
|
||||
Vec3 diff;
|
||||
vec3_sub(&sphere->sphere.center, &closest, &diff);
|
||||
float dist_sq = vec3_dot(&diff, &diff);
|
||||
|
||||
if (dist_sq < sphere->sphere.radius * sphere->sphere.radius) {
|
||||
float dist = sqrtf(dist_sq);
|
||||
*depth = sphere->sphere.radius - dist;
|
||||
if (dist > 0.0001f) {
|
||||
vec3_normalize(&diff, normal);
|
||||
} else {
|
||||
*normal = (Vec3){0, 1, 0};
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sphere_vs_plane(const Collider* sphere, const Collider* plane, Vec3* normal, float* depth) {
|
||||
float dist = vec3_dot(&sphere->sphere.center, &plane->plane.normal) - plane->plane.distance;
|
||||
if (dist < sphere->sphere.radius) {
|
||||
*depth = sphere->sphere.radius - dist;
|
||||
*normal = plane->plane.normal;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int physics_check_collision(const Collider* a, const Collider* b, Vec3* normal, float* depth) {
|
||||
if (a->type == COLLIDER_AABB && b->type == COLLIDER_AABB)
|
||||
return aabb_vs_aabb(a, b, normal, depth);
|
||||
if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_SPHERE)
|
||||
return sphere_vs_sphere(a, b, normal, depth);
|
||||
if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_AABB)
|
||||
return sphere_vs_aabb(a, b, normal, depth);
|
||||
if (a->type == COLLIDER_AABB && b->type == COLLIDER_SPHERE) {
|
||||
int hit = sphere_vs_aabb(b, a, normal, depth);
|
||||
if (hit) { normal->x = -normal->x; normal->y = -normal->y; normal->z = -normal->z; }
|
||||
return hit;
|
||||
}
|
||||
if (a->type == COLLIDER_SPHERE && b->type == COLLIDER_PLANE)
|
||||
return sphere_vs_plane(a, b, normal, depth);
|
||||
if (a->type == COLLIDER_PLANE && b->type == COLLIDER_SPHERE) {
|
||||
int hit = sphere_vs_plane(b, a, normal, depth);
|
||||
if (hit) { normal->x = -normal->x; normal->y = -normal->y; normal->z = -normal->z; }
|
||||
return hit;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int physics_raycast(PhysicsWorld* world, Vec3 origin, Vec3 direction, float max_dist,
|
||||
uint32_t* hit_entity, Vec3* hit_point, Vec3* hit_normal) {
|
||||
vec3_normalize(&direction, &direction);
|
||||
float closest_t = max_dist;
|
||||
int hit = 0;
|
||||
|
||||
for (uint32_t i = 0; i < world->collider_count; i++) {
|
||||
Collider* c = &world->colliders[i];
|
||||
if (c->type == COLLIDER_SPHERE) {
|
||||
Vec3 oc;
|
||||
vec3_sub(&origin, &c->sphere.center, &oc);
|
||||
float a = vec3_dot(&direction, &direction);
|
||||
float b = 2.0f * vec3_dot(&oc, &direction);
|
||||
float cc = vec3_dot(&oc, &oc) - c->sphere.radius * c->sphere.radius;
|
||||
float disc = b * b - 4 * a * cc;
|
||||
if (disc >= 0) {
|
||||
float t = (-b - sqrtf(disc)) / (2 * a);
|
||||
if (t > 0 && t < closest_t) {
|
||||
closest_t = t;
|
||||
*hit_entity = c->entity_id;
|
||||
Vec3 scaled;
|
||||
vec3_scale(&direction, t, &scaled);
|
||||
vec3_add(&origin, &scaled, hit_point);
|
||||
vec3_sub(hit_point, &c->sphere.center, hit_normal);
|
||||
vec3_normalize(hit_normal, hit_normal);
|
||||
hit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
void physics_step(PhysicsWorld* world, float dt) {
|
||||
(void)world;
|
||||
(void)dt;
|
||||
}
|
||||
|
||||
void physics_set_gravity(PhysicsWorld* world, Vec3 gravity) {
|
||||
world->gravity = gravity;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
// ============================================================================
|
||||
// physics.h - 物理引擎 (碰撞检测, 调用ASM数学)
|
||||
// ============================================================================
|
||||
|
||||
#include "../include/engine_api.h"
|
||||
#include "../ASM/math_c_fallback.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_COLLIDERS 1024
|
||||
|
||||
typedef enum {
|
||||
COLLIDER_AABB,
|
||||
COLLIDER_SPHERE,
|
||||
COLLIDER_PLANE,
|
||||
} ColliderType;
|
||||
|
||||
typedef struct {
|
||||
uint32_t entity_id;
|
||||
ColliderType type;
|
||||
union {
|
||||
struct { Vec3 min; Vec3 max; } aabb;
|
||||
struct { Vec3 center; float radius; } sphere;
|
||||
struct { Vec3 normal; float distance; } plane;
|
||||
};
|
||||
int is_trigger;
|
||||
int is_static;
|
||||
} Collider;
|
||||
|
||||
typedef struct {
|
||||
Vec3 velocity;
|
||||
Vec3 acceleration;
|
||||
float mass;
|
||||
float restitution;
|
||||
float friction;
|
||||
int is_kinematic;
|
||||
} RigidBody;
|
||||
|
||||
typedef struct {
|
||||
Collider colliders[MAX_COLLIDERS];
|
||||
uint32_t collider_count;
|
||||
int gravity_enabled;
|
||||
Vec3 gravity;
|
||||
} PhysicsWorld;
|
||||
|
||||
// 碰撞回调
|
||||
typedef void (*CollisionCallback)(uint32_t entity_a, uint32_t entity_b, Vec3 normal, float depth);
|
||||
|
||||
// 创建/销毁
|
||||
PhysicsWorld* physics_create(void);
|
||||
void physics_destroy(PhysicsWorld* world);
|
||||
|
||||
// 碰撞体
|
||||
uint32_t physics_add_aabb(PhysicsWorld* world, uint32_t entity, Vec3 min, Vec3 max);
|
||||
uint32_t physics_add_sphere(PhysicsWorld* world, uint32_t entity, Vec3 center, float radius);
|
||||
uint32_t physics_add_plane(PhysicsWorld* world, uint32_t entity, Vec3 normal, float distance);
|
||||
void physics_remove_collider(PhysicsWorld* world, uint32_t index);
|
||||
void physics_update_collider(PhysicsWorld* world, uint32_t index, Vec3 position);
|
||||
|
||||
// 碰撞检测
|
||||
int physics_check_collision(const Collider* a, const Collider* b, Vec3* normal, float* depth);
|
||||
int physics_raycast(PhysicsWorld* world, Vec3 origin, Vec3 direction, float max_dist,
|
||||
uint32_t* hit_entity, Vec3* hit_point, Vec3* hit_normal);
|
||||
|
||||
// 模拟
|
||||
void physics_step(PhysicsWorld* world, float dt);
|
||||
void physics_set_gravity(PhysicsWorld* world, Vec3 gravity);
|
||||
Reference in new issue
Block a user