Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions common/include/zen-common/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ int zn_vec3_to_array(vec3 vec, struct wl_array *array);
*/
int zn_array_to_versor(struct wl_array *array, versor vec);

/**
* @return 0 if successful, -1 otherwise
*/
int zn_array_to_float(struct wl_array *array, float *value);

#ifdef __cplusplus
}
#endif
10 changes: 10 additions & 0 deletions common/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,13 @@ zn_array_to_versor(struct wl_array *array, versor vec)

return 0;
}

int
zn_array_to_float(struct wl_array *array, float *value)
{
if (sizeof(float) != array->size) return -1;

memcpy(value, array->data, sizeof(float));

return 0;
}
7 changes: 7 additions & 0 deletions zgnroot/include/zgnr/intersection.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@
*/
float zgnr_intersection_ray_obb(
vec3 origin, vec3 direction, vec3 aabb_half_size, mat4 transform);

/**
* @return the distance from the origin to the intersection, or FLT_MAX if not
* intersecting
*/
float zgnr_intersection_ray_sphere(
vec3 origin, vec3 direction, vec3 center, float radius);
4 changes: 4 additions & 0 deletions zgnroot/include/zgnr/region/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@

struct zgnr_region_node {
struct wl_list cuboid_list; // zgnr_cuboid_region::link
struct wl_list sphere_list; // zgnr_sphere_region::link
};

/**
* @param transform : translation & rotation only
*/
float zgnr_region_node_ray_cast(
struct zgnr_region_node *self, mat4 transform, vec3 origin, vec3 direction);
11 changes: 11 additions & 0 deletions zgnroot/include/zgnr/region/sphere.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <cglm/types.h>
#include <wayland-server-core.h>

struct zgnr_sphere_region {
vec3 center;
float radius;

struct wl_list link;
};
1 change: 1 addition & 0 deletions zgnroot/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ _zgnr_srcs = [
'src/region.c',
'src/region/node.c',
'src/region/cuboid.c',
'src/region/sphere.c',
'src/rendering-unit.c',
'src/seat.c',
'src/seat-ray.c',
Expand Down
26 changes: 26 additions & 0 deletions zgnroot/src/intersection.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,29 @@ zgnr_intersection_ray_obb(

return t_min;
}

float
zgnr_intersection_ray_sphere(
vec3 origin, vec3 direction, vec3 center, float radius)
{
float t; // intersection point is (origin + t * direction)

vec3 ray_origin;

// The center of the sphere is the origin of the coordinates.
glm_vec3_sub(origin, center, ray_origin);

// A t^2 + B t + C = 0
float A = glm_vec3_dot(direction, direction);
float B = 2 * glm_vec3_dot(ray_origin, direction);
float C = glm_vec3_dot(ray_origin, ray_origin) - radius * radius;
float D = B * B - 4 * A * C;

if (D < 0) return FLT_MAX;

t = (-B - sqrtf(D)) / (2 * A);

if (t <= 0) return FLT_MAX;

return t;
}
40 changes: 38 additions & 2 deletions zgnroot/src/region.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <zigen-protocol.h>

#include "region/cuboid.h"
#include "region/sphere.h"

static void zgnr_region_destroy(struct zgnr_region* self);

Expand All @@ -28,8 +29,6 @@ zgnr_region_protocol_add_cuboid(struct wl_client* client,
struct wl_resource* resource, struct wl_array* half_size_array,
struct wl_array* center_array, struct wl_array* quaternion_array)
{
UNUSED(client);

struct zgnr_region* self = wl_resource_get_user_data(resource);
struct zgnr_cuboid_region* cuboid;

Expand Down Expand Up @@ -60,16 +59,53 @@ zgnr_region_protocol_add_cuboid(struct wl_client* client,

cuboid = zgnr_cuboid_region_create(half_size, center, quaternion);
if (cuboid == NULL) {
wl_client_post_no_memory(client);
zn_error("Failed to creat a cuboid region");
return;
}

zgnr_region_node_add_cuboid(self->node, cuboid);
}

static void
zgnr_region_protocol_add_sphere(struct wl_client* client,
struct wl_resource* resource, struct wl_array* center_wl_array,
struct wl_array* radius_wl_array)
{
struct zgnr_region* self = wl_resource_get_user_data(resource);
struct zgnr_sphere_region* sphere;

vec3 center;
float radius;

if (zn_array_to_vec3(center_wl_array, center) != 0) {
wl_resource_post_error(resource, ZGN_COMPOSITOR_ERROR_WL_ARRAY_SIZE,
"center is expected vec3 (%ld bytes) but got %ld bytes", sizeof(vec3),
center_wl_array->size);
return;
}

if (zn_array_to_float(radius_wl_array, &radius) != 0) {
wl_resource_post_error(resource, ZGN_COMPOSITOR_ERROR_WL_ARRAY_SIZE,
"radius is expected float (%ld bytes) but got %ld bytes", sizeof(float),
radius_wl_array->size);
return;
}

sphere = zgnr_sphere_region_create(center, radius);
if (sphere == NULL) {
wl_client_post_no_memory(client);
zn_error("Failed to creat a sphere region");
return;
}

zgnr_region_node_add_sphere(self->node, sphere);
}

static const struct zgn_region_interface implementation = {
.destroy = zgnr_region_protocol_destroy,
.add_cuboid = zgnr_region_protocol_add_cuboid,
.add_sphere = zgnr_region_protocol_add_sphere,
};

struct zgnr_region*
Expand Down
31 changes: 29 additions & 2 deletions zgnroot/src/region/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ zgnr_region_node_ray_cast(struct zgnr_region_node* self, mat4 outer_transform,
vec3 origin, vec3 direction)
{
struct zgnr_cuboid_region* cuboid_region;
struct zgnr_sphere_region* sphere_region;

float min_distance = FLT_MAX;
wl_list_for_each (cuboid_region, &self->cuboid_list, link) {
float distance;
Expand All @@ -26,6 +28,18 @@ zgnr_region_node_ray_cast(struct zgnr_region_node* self, mat4 outer_transform,
if (distance < min_distance) min_distance = distance;
}

wl_list_for_each (sphere_region, &self->sphere_list, link) {
float distance;

vec3 center;
glm_mat4_mulv3(outer_transform, sphere_region->center, 1, center);

distance = zgnr_intersection_ray_sphere(
origin, direction, center, sphere_region->radius);

if (distance < min_distance) min_distance = distance;
}

return min_distance;
}

Expand All @@ -36,6 +50,13 @@ zgnr_region_node_add_cuboid(
wl_list_insert(&self->cuboid_list, &cuboid->link);
}

void
zgnr_region_node_add_sphere(
struct zgnr_region_node* self, struct zgnr_sphere_region* sphere)
{
wl_list_insert(&self->sphere_list, &sphere->link);
}

struct zgnr_region_node*
zgnr_region_node_create_copy(struct zgnr_region_node* self)
{
Expand Down Expand Up @@ -63,6 +84,7 @@ zgnr_region_node_create(void)
}

wl_list_init(&self->cuboid_list);
wl_list_init(&self->sphere_list);

return self;

Expand All @@ -73,11 +95,16 @@ zgnr_region_node_create(void)
void
zgnr_region_node_destroy(struct zgnr_region_node* self)
{
struct zgnr_cuboid_region *cuboid, *tmp;
struct zgnr_cuboid_region *cuboid, *tmp_cuboid;
struct zgnr_sphere_region *sphere, *tmp_sphere;

wl_list_for_each_safe (cuboid, tmp, &self->cuboid_list, link) {
wl_list_for_each_safe (cuboid, tmp_cuboid, &self->cuboid_list, link) {
zgnr_cuboid_region_destroy(cuboid);
}

wl_list_for_each_safe (sphere, tmp_sphere, &self->sphere_list, link) {
zgnr_sphere_region_destroy(sphere);
}

free(self);
}
4 changes: 4 additions & 0 deletions zgnroot/src/region/node.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
#pragma once

#include "cuboid.h"
#include "sphere.h"
#include "zgnr/region/node.h"

void zgnr_region_node_add_cuboid(
struct zgnr_region_node* self, struct zgnr_cuboid_region* cuboid);

void zgnr_region_node_add_sphere(
struct zgnr_region_node* self, struct zgnr_sphere_region* sphere);

struct zgnr_region_node* zgnr_region_node_create_copy(
struct zgnr_region_node* self);

Expand Down
33 changes: 33 additions & 0 deletions zgnroot/src/region/sphere.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "sphere.h"

#include <cglm/vec3.h>
#include <zen-common.h>

struct zgnr_sphere_region*
zgnr_sphere_region_create(vec3 center, float radius)
{
struct zgnr_sphere_region* self;

self = zalloc(sizeof *self);
if (self == NULL) {
zn_error("Failed to allocate memory");
goto err;
}

glm_vec3_copy(center, self->center);
self->radius = radius;

wl_list_init(&self->link);

return self;

err:
return NULL;
}

void
zgnr_sphere_region_destroy(struct zgnr_sphere_region* self)
{
wl_list_remove(&self->link);
free(self);
}
7 changes: 7 additions & 0 deletions zgnroot/src/region/sphere.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

#include "zgnr/region/sphere.h"

struct zgnr_sphere_region* zgnr_sphere_region_create(vec3 center, float radius);

void zgnr_sphere_region_destroy(struct zgnr_sphere_region* self);