Experimental engine agnostic 3D CSG library for game development written in Rust. Started as a port of csg.js to Rust.

Related tags

Command-line brusher
Overview

brusher

Experimental engine agnostic 3D CSG library for game development written in Rust. Started as a port of csg.js to Rust.

ultimate goal

My hope is that it can essentially provide an API that can be used to create an editor like Trenchbroom, GTKRadiant, Hammer, etc by providing easy to use public methods for creating and manipulating 3D "brushes" (solids) that can be used to create levels for games.

For things like curves, I'm considering adding curvo by @mattatz as a dependency to provide a way to create curves like pipes & arches.

features & todo

2024-08-14.10-05-27.mov
  • union
  • intersect
  • subtract
  • knife (WIP)
    • handle maintaining materials per surface
  • serialization
  • extrude
  • bevel
    • technically already possible manually by using knife but just needs a helper function
  • construct Brushlet from Vec<Polygons>
  • construct Brushlet from Vec<Surface>
    • allows you to define a convex solid by defining its surfaces (planes)
  • smooth normals with configurable angle tolerance
  • editor API (WIP)

example (Bevy)

cargo run --release --features bevy --example realtime_basic

usage

    use brusher::prelude::*;

    // Helper enum to map materials to indices
    enum MyMaterials {
        ProtoGrey = 0,
        ProtoGreen = 1,
    }

    impl From<MyMaterials> for usize {
        fn from(material: MyMaterials) -> usize {
            material as usize
        }
    }

    // Create a brush that will combine two rooms
    let mut brush = Brush::new("Rooms");

    // Create a brushlet for the first room
    brush.add_brushlet(Brushlet::from_cuboid(
        brusher::primitives::Cuboid {
            origin: DVec3::new(0.0, 0.0, 0.0),
            width: 8.0,
            height: 4.0,
            depth: 8.0,
            material_indices: CuboidMaterialIndices {
                front: MyMaterials::ProtoGrey.into(),
                back: MyMaterials::ProtoGreen.into(),
                left: MyMaterials::ProtoGreen.into(),
                right: MyMaterials::ProtoGrey.into(),
                top: MyMaterials::ProtoGrey.into(),
                bottom: MyMaterials::ProtoGrey.into(),
            },
        },
        BrushletSettings {
            name: "Room 1".to_string(),
            operation: BooleanOp::Subtract,
            // Cut the brushlet with a knife
            knives: vec![Knife {
                normal: DVec3::new(-1.0, -1.0, -1.0),
                distance_from_origin: 4.0,
                material_index: MyMaterials::ProtoGreen.into(),
            }],
            inverted: true,
        },
    ));

    // Create a brushlet for the second room
    brush.add_brushlet(Brushlet::from_cuboid(
        brusher::primitives::Cuboid {
            origin: DVec3::new(4.0, 0.0, 4.0),
            width: 8.0,
            height: 4.0,
            depth: 8.0,
            material_indices: CuboidMaterialIndices {
                front: MyMaterials::ProtoGreen.into(),
                back: MyMaterials::ProtoGreen.into(),
                left: MyMaterials::ProtoGreen.into(),
                right: MyMaterials::ProtoGreen.into(),
                top: MyMaterials::ProtoGreen.into(),
                bottom: MyMaterials::ProtoGreen.into(),
            },
        },
        BrushletSettings {
            name: "Room 2".to_string(),
            operation: BooleanOp::Union,
            knives: vec![],
            inverted: false,
        },
    ));

    // Cut at the brush level with a knife to cut both rooms at once
    brush.settings.knives = vec![Knife {
        normal: DVec3::new(1.0, 1.0, 0.0),
        distance_from_origin: 4.0,
        material_index: MyMaterials::ProtoGrey.into(),
    }];

    let mesh_data = brush.to_mesh_data();

construct meshes from a brush

This example uses bevy, but you should be able to adapt it to any engine that supports meshes.

    // Helper enum to map materials to indices
    enum MyMaterials {
        ProtoGrey = 0,
        ProtoGreen = 1,
    }

    impl From<MyMaterials> for usize {
        fn from(material: MyMaterials) -> usize {
            material as usize
        }
    }

    // Create a brush (see above example)
    // ...

    // Define some materials
    let material_proto_grey = materials.add(Color::rgb(0.5, 0.5, 0.5).into());
    let material_proto_green = materials.add(Color::rgb(0.2, 0.8, 0.2).into());

    // Get the mesh data from the brush and convert it to bevy meshes
    let meshes_with_materials = brush.to_mesh_data().to_bevy_meshes();

    // Spawn the meshes and assign materials based on the material index
    for (mesh, material_index) in meshes_with_materials {
        let material = match material_index {
            MyMaterials::ProtoGrey => material_proto_grey.clone(),
            MyMaterials::ProtoGreen => material_proto_green.clone(),
            _ => material_proto_grey.clone(),
        };

        commands.spawn(PbrBundle {
            mesh: meshes.add(mesh),
            material,
            transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)),
            ..default()
        });
    }

special thanks

  • Thank you to csg.js by @evanw for the original csg.js library! Your work has done some serious heavy lifting for this project and I am grateful for it.
  • Thank you to shambler by @shfty for the inspiration to start this project.
You might also like...
An experimental GUI library for Rust 🦀

guee 🚧 Nothing to see here 🚧 ... But if you insist: This is an experimental UI library I'm working on for Blackjack. The idea is to find a very prag

png_defringe_rs is a port of Immorpher's PNG Defringe program written in Rust to achieve easier installation and faster performance.

png_defringe_rs png_defringe_rs is a port of Immorpher's PNG Defringe program written in Rust to achieve easier installation and faster performance. U

🐚+🦞 Ultra-portable Rust game engine suited for offline 2D games powered by WebAssembly

pagurus 🐚 + 🦞 Ultra-portable Rust game engine suited for offline 2D games powered by WebAssembly. Examples Snake Traditional snake game: examples/sn

AI-powered game engine for dynamic, personalized experiences in evolving worlds. Ethical, accessible, inclusive.

ARCADIA: Advanced and Responsive Computational Architecture for Dynamic Interactive Ai: A Whitepaper By Reuven Cohen (rUv) Introduction Imagine a futu

A set of demo projects for the Fyrox Game Engine.

Fyrox Demo Projects A set of demo projects for the Fyrox Game Engine. Most of the projects located in this repository in the respective folders. Navig

Nexa programming language. A language for game developers by a game developer
Nexa programming language. A language for game developers by a game developer

NexaLang Nexa programming language. A language for game developers by a game developer. Features High-Level: Nexa is an easy high level language Two M

Windows shellcode development in Rust
Windows shellcode development in Rust

Write Windows Shellcode in Rust Project overview Windows shellcode project is located in shellcode/, it can build into a PE file with only .text secti

A Rust command line tool to simplify embedded development and deployment.

Bobbin-CLI bobbin-cli is a tool designed to make it easy to build, deploy, test and debug embedded devices using a unified CLI. bobbin-cli understands

Are we lang yet? A simple website providing information about the status of Rust's language development ecosystem.

Are We Lang Yet This project answers the question "Is the Rust ecosystem ready to use for language development yet?". arewelangyet.com What is this? C

Owner
Brian Howard
Game Developer, Web Developer, I do a bit of everything. - Netcode - Gameplay - Art
Brian Howard
Prisma2D - Fast, API agnostic, software only 2D graphics crate in pure Rust.

Prisma2D: Ultra-fast CPU 2D graphics Prisma2D is a blazingly fast, efficient yet minimal crate for basic 2D graphics on the CPU. for Rust. With Prisma

Aggelos Tselios 4 Nov 30, 2023
🧮 Boolean expression evaluation engine. A Rust port of boolrule.

coolrule My blog post: Porting Boolrule to Rust Boolean expression evaluation engine (a port of boolrule to Rust). // Without context let expr = coolr

Andrew Healey 3 Aug 21, 2023
This is a command line port of the game Wordle in Rust

Wordle.rs Welcome to Wordle.rs! This is a command line port of the game Wordle in Rust. I built this in order to get more familiar with programming in

Brock Herion 5 Apr 8, 2022
Fyrox - 3D and 2D game engine written in Rust

Fyrox - a modern Rust game engine A feature-rich, production-ready, general purpose 2D/3D game engine written in Rust with a scene editor. Formerly kn

Fyrox Engine 5.3k Dec 30, 2022
Email test server for development, written in Rust

MailCrab Email test server for development, written in Rust. Inspired by MailHog and MailCatcher. MailCrab was created as an exercise in Rust, trying

Tweede golf 30 Feb 7, 2023
An experimental real-time operating system (RTOS) written in Rust

An experimental real-time operating system (RTOS) written in Rust

null 0 Nov 14, 2022
Cuprate, an upcoming experimental, modern & secure monero node. Written in Rust

Cuprate an upcoming experimental, modern & secure monero node. Written in Rust (there is nothing working at the moment, stay tuned if you want to see

Someone Else 16 Feb 20, 2023
🛠️ An experimental functional systems programming language, written in Rust and powered by LLVM as a backend.

An experimental functional systems programming language, written in Rust, and powered by LLVM as a backend. ?? Goal: The intent is to create a program

codex 3 Nov 15, 2023
An experimental project for rust version of Hertz written by GPT4.

Ryze: An experimental Rust Web Framework Ryze is a minimal web framework for Rust inspired by Hertz and written by GPT4. Example Here is a simple exam

Wenju Gao 3 Nov 28, 2023
Experimental Rust UI library for Audulus. "rui" is a temporary name.

Experimental Rust UI library for Audulus. "rui" is a temporary name.

Audulus LLC 1.1k Dec 28, 2022