Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First Helper functions for Basis and Transform #208

Closed
wants to merge 1 commit into from

Conversation

tom-leys
Copy link
Contributor

A quite messy PR which adds some basic Transform and Basis methods. I have been using these so that I can set a simple transform up in my code.

I would appreciate if you could help get these into a state where they are suitable to merge. I really wanted to share them.

I am using code like this to instance a mesh, set up a transform and place it in the world

    pub unsafe fn place_mesh(&mut self, pos: Vector3, scale: f32, rot: f32) -> Spatial {
        let mut instance = self.instance_tile();
        instance.set_name(GodotString::from_str(format!("({}, {})", pos.x as i32, pos.y as i32)));

        let transform =
            Transform3D::create_scale(scale, scale, scale)
                .post_rotate(0.0, 1.0, 0.0, Angle::degrees(rot))
                .post_translate(pos);

//        let transform = Transform

        instance.set_transform(Transform::from_transform(&transform));

        instance
    }

My process was to go to the relevant C++ code in the engine, port the code to Rust and put it in the object.

@karroffel
Copy link
Member

PR #207 was merged, if you could rebase this PR it would make reviewing a bit easier :)

@tom-leys
Copy link
Contributor Author

PR #207 was merged, if you could rebase this PR it would make reviewing a bit easier :)

Hi @karroffel - I've finally done this rebase. Check it out now please :)

@karroffel
Copy link
Member

There seems to be issues on CI which make it fail 😅

@tom-leys
Copy link
Contributor Author

I needed to update my code to support newest Euclid with units.

Here's some more (updated) example code

pub struct InShipSpace;
pub struct WorldSpace;
pub type InShipLoc3 = euclid::Vector3D<f32, InShipSpace>;

    pub unsafe fn place_tile(&mut self, pos: ShipBox) -> Spatial {
        let mut instance : Spatial = self.instance_tile();
        instance.set_name(GodotString::from_str(format!("({}, {})", pos.left, pos.top)));

        let top_left = vec2(f32::from(pos.left), f32::from(pos.top));
        let mut distance : Vector2D::<f32, InShipSpace> = vec2(f32::from(pos.right), f32::from(pos.bottom)) - top_left;
        let centre = top_left + (distance / 2.0);
        let compensation = vec2(1.0, 1.0);

        distance += compensation;
//        distance *= vec2(1/self.mesh_size.0, 1/self.mesh_size.1);
        let (mesh_x, mesh_y) = (f32::from(self.mesh_size.0), f32::from(self.mesh_size.1));

        let avg_size = (distance.x/mesh_x + distance.y/mesh_y) / 2.0;
        let rot = (((centre.x + centre.y * 31.0) / avg_size) % 4.0).trunc();

        let transform =
            Transform3D::<_, InShipSpace, InShipSpace>::create_scale(
                distance.x/mesh_x, avg_size, distance.y/mesh_y)
                .post_rotate(0.0, 1.0, 0.0, Angle::degrees(90.0 * rot))
                .post_translate(vec3(centre.x, 0.0, centre.y));

//        let transform = Transform

        instance.set_transform(Transform::from_transform(&transform));

        instance
    }

    pub unsafe fn place_mesh(&mut self, pos: InShipLoc3, scale: f32, rot: f32) -> Spatial {
        let mut instance = self.instance_tile();
        instance.set_name(GodotString::from_str(format!("({}, {})", pos.x as i32, pos.z as i32)));

        let transform =
            Transform3D::<_, InShipSpace, InShipSpace>::create_scale(scale, scale, scale)
                .post_rotate(0.0, 1.0, 0.0, Angle::degrees(rot))
                .post_translate(pos);

//        let transform = Transform

        instance.set_transform(Transform::from_transform(&transform));

        instance
    }

    pub unsafe fn instance_tile(&mut self) -> Spatial {
        let instance = if self.placed_count < self.parent_children {
            let existing_instance = self.parent.get_child(self.placed_count).unwrap();
            existing_instance.cast::<Spatial>().unwrap()
        } else {
            let mut instance = MeshInstance::new();
            instance.set_mesh(Some(self.template.clone()));
            self.parent.add_child(instance.cast::<Node>(), false);
            instance.cast::<Spatial>().unwrap()
        };
        self.placed_count += 1;

        instance
    }

@tom-leys
Copy link
Contributor Author

If you check out my blog:

https://medium.com/@recallsingularity/rendering-a-2d-game-in-3d-bd24ddbee6eb

image

The floor meshes are placed using place_tile and the conveyors by using place_mesh.

@ghost
Copy link

ghost commented Dec 10, 2019

@tom-leys It seems like this is duplicated in #254. Could you update this PR with the latest code, so we can review / merge the feature first?

@tom-leys
Copy link
Contributor Author

tom-leys commented Feb 7, 2020

#288 (Now duplicates this one)

@tom-leys tom-leys closed this Feb 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants