180 lines
5.3 KiB
Zig
180 lines
5.3 KiB
Zig
const std = @import("std");
|
||
const rl = @import("raylib");
|
||
const cm = @import("Cam");
|
||
|
||
|
||
pub var is_object_dragging : bool = undefined; // drag işlemi için gerekli
|
||
pub var freeMode = false;
|
||
pub var count_id : usize = 0; // bu değişken anlık id'yi tutar
|
||
|
||
// ışın ve ışına bağlı çarpışma ray ve raycollison değişkenleri ile yapılır.
|
||
pub var selected_shape_index:?usize = 0;
|
||
|
||
pub const ShapeType = enum {
|
||
cube,
|
||
rectangle,
|
||
sphere,
|
||
cylinder,
|
||
}; //tipler
|
||
|
||
pub const Shape = struct {
|
||
id : usize = 0,
|
||
name : [:0]const u8,
|
||
position: rl.Vector3,
|
||
color: rl.Color,
|
||
|
||
data: union(enum) {
|
||
// 'box' terimi hem küpü hem de dikdörtgen prizmayı kapsar
|
||
cube: struct {
|
||
width: f32,
|
||
height: f32,
|
||
length: f32,
|
||
},
|
||
sphere: struct {
|
||
radius: f32,
|
||
},
|
||
cylinder: struct {
|
||
radius: f32,
|
||
height: f32,
|
||
},
|
||
},
|
||
|
||
pub fn initCube(position: rl.Vector3, color: rl.Color, width: f32, height: f32, length: f32) Shape {
|
||
count_id += 1;
|
||
return Shape{
|
||
.id = count_id,
|
||
.name = "count_id",
|
||
.position = position,
|
||
.color = color,
|
||
.data = .{ .cube = .{ .width = width, .height = height, .length = length } },
|
||
};
|
||
}
|
||
|
||
// Küre için özel init metodu
|
||
pub fn initSphere(position: rl.Vector3, color: rl.Color, radius: f32) Shape {
|
||
count_id += 1;
|
||
return Shape{
|
||
.id = count_id,
|
||
.name= "count_id",
|
||
.position = position,
|
||
.color = color,
|
||
.data = .{ .sphere = .{ .radius = radius } },
|
||
};
|
||
}
|
||
|
||
// Silindir için özel init metodu
|
||
pub fn initCylinder(position: rl.Vector3, color: rl.Color, radius: f32, height: f32) Shape {
|
||
count_id += 1;
|
||
return Shape{
|
||
.id = count_id,
|
||
.name = "count_id",
|
||
.position = position,
|
||
.color = color,
|
||
.data = .{ .cylinder = .{ .radius = radius, .height = height } },
|
||
};
|
||
}
|
||
};
|
||
|
||
|
||
pub fn findClosestHitObject(
|
||
mouse_position: rl.Vector2,
|
||
camera: rl.Camera3D,
|
||
shapes: *std.ArrayList(Shape),
|
||
) void {
|
||
// Fare tuşuna basılıyorsa kontrol et
|
||
if (!rl.isMouseButtonPressed(.left)) {
|
||
return;
|
||
}
|
||
|
||
const ray = rl.getScreenToWorldRay(mouse_position, camera);
|
||
|
||
var closest_hit_index: ?usize = null;
|
||
var closest_distance = std.math.floatMax(f32);
|
||
|
||
for (shapes.items, 0..) |shape, index| {
|
||
var hit_info = rl.RayCollision{.hit = false, .distance = 0.0,
|
||
.normal = rl.Vector3.init(0, 0, 0),
|
||
.point = rl.Vector3.init(0, 0, 0)};
|
||
|
||
switch (shape.data) {
|
||
.cube => |cube_data| {
|
||
const box = getBoundingBoxForCube(shape.position,
|
||
cube_data.width, cube_data.height, cube_data.length);
|
||
hit_info = rl.getRayCollisionBox(ray, box);
|
||
},
|
||
.sphere => |sphere_data| {
|
||
hit_info = rl.getRayCollisionSphere(ray, shape.position, sphere_data.radius);
|
||
},
|
||
.cylinder => |cylinder_data| {
|
||
// Performans için BoundingBox çarpışma testini kullan
|
||
const box = getBoundingBoxForCylinder(shape.position, cylinder_data.radius, cylinder_data.height);
|
||
hit_info = rl.getRayCollisionBox(ray, box);
|
||
},
|
||
}
|
||
|
||
if (hit_info.hit and hit_info.distance < closest_distance) {
|
||
closest_hit_index = index;
|
||
closest_distance = hit_info.distance;
|
||
}
|
||
}
|
||
|
||
selected_shape_index = closest_hit_index;
|
||
}
|
||
|
||
|
||
pub fn inputControls() void {
|
||
|
||
if (rl.isMouseButtonPressed(.right)) {
|
||
freeMode = !freeMode;
|
||
if (freeMode) {
|
||
rl.disableCursor();
|
||
} else {
|
||
rl.enableCursor();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
pub fn getBoundingBoxForCube(position: rl.Vector3, width: f32, height: f32, length: f32) rl.BoundingBox {
|
||
// Nesnenin boyutlarının yarısını hesapla
|
||
const half_width = width / 2.0;
|
||
const half_height = height / 2.0;
|
||
const half_length = length / 2.0;
|
||
|
||
// Minimum köşeyi (sol alt arka) hesapla
|
||
const min_x = position.x - half_width;
|
||
const min_y = position.y - half_height;
|
||
const min_z = position.z - half_length;
|
||
|
||
// Maksimum köşeyi (sağ üst ön) hesapla
|
||
const max_x = position.x + half_width;
|
||
const max_y = position.y + half_height;
|
||
const max_z = position.z + half_length;
|
||
|
||
return rl.BoundingBox{
|
||
.min = rl.Vector3.init(min_x, min_y, min_z),
|
||
.max = rl.Vector3.init(max_x, max_y, max_z),
|
||
};
|
||
}
|
||
|
||
|
||
pub fn getBoundingBoxForCylinder(position: rl.Vector3, radius: f32, height: f32) rl.BoundingBox {
|
||
// Yüksekliğin yarısını hesapla
|
||
const half_height = height / 2.0;
|
||
|
||
// Minimum köşe noktasını (min x, min y, min z) hesapla
|
||
const min_x = position.x - radius;
|
||
const min_y = position.y - half_height;
|
||
const min_z = position.z - radius;
|
||
|
||
// Maksimum köşe noktasını (max x, max y, max z) hesapla
|
||
const max_x = position.x + radius;
|
||
const max_y = position.y + half_height;
|
||
const max_z = position.z + radius;
|
||
|
||
// BoundingBox yapısını döndür
|
||
return rl.BoundingBox{
|
||
.min = rl.Vector3.init(min_x, min_y, min_z),
|
||
.max = rl.Vector3.init(max_x, max_y, max_z),
|
||
};
|
||
} |