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

FEAT: Add Points component #47

Merged
merged 2 commits into from
Nov 18, 2021
Merged

Conversation

JackDra
Copy link
Contributor

@JackDra JackDra commented Nov 7, 2021

Summary

Adds Points in threejs as a component.
https://threejs.org/docs/#api/en/objects/Points

Works very similar to how Mesh works.
Just copied and pasted Mesh.svelte into Points.svelte and replaced mesh with points.

With one addition to allow the material to be PointsMaterial
https://threejs.org/docs/#api/en/materials/PointsMaterial

Example

example

@vatro
Copy link
Owner

vatro commented Nov 9, 2021

Cool! 🙂 Is it working? 😉
Could you provide a simple code example for faster check? Thanks!

<!-- App.svelte -->
<script> ... </script>

@JackDra
Copy link
Contributor Author

JackDra commented Nov 9, 2021

For some reason, I could only get it working using a fresh sveltekit app, but not a regular svelte app....

<script lang="ts">
    import {
        Canvas,
        Scene,
        PerspectiveCamera,
        Points,
        DirectionalLight,
        PointsMaterial,
        BufferGeometry,
        WebGLRenderer,
        AmbientLight,
        Vector3,
        MathUtils,
        Float32BufferAttribute,
    } from "svelthree";

    import gsap from "gsap";

    const vertices = [];

    for (let i = 0; i < 3000; i++) {
        const x = MathUtils.randFloatSpread(1000);
        const y = MathUtils.randFloatSpread(1000);
        const z = MathUtils.randFloatSpread(1000);

        vertices.push(x, y, z);
    }

    const geometry = new BufferGeometry();
    geometry.setAttribute("position", new Float32BufferAttribute(vertices, 3));

    const material = new PointsMaterial({
        color: 0x888888,
        size: 10,
        sizeAttenuation: true,
    });

    function handleScroll(e) {
        let obj = getPoints();
        gsap.to(obj.scale, {
            duration: 1,
            x: obj.scale.x + e.deltaY / 500,
            y: obj.scale.y + e.deltaY / 500,
            z: obj.scale.z + e.deltaY / 500,
            ease: "elastic.out",
        });
    }

    function onPointerMove(e) {
        let obj = e.detail.target;

        let unpr = new Vector3().copy(e.detail.unprojected);
        let unprwtl = obj.worldToLocal(unpr).add(new Vector3(0, 0, 100));
        obj.lookAt(unprwtl);
    }
    let getPoints;
</script>

<main on:wheel={handleScroll}>
    <Canvas let:sti w={800} h={600} interactive>
        <Scene {sti} let:scene id="scene1" props={{ background: 0xedf2f7 }}>
            <PerspectiveCamera
                {scene}
                id="cam1"
                props={{ position: [0, 0, 2000], lookAt: [0, 0, 0] }}
            />

            <DirectionalLight {scene} />

            <AmbientLight {scene} props={{ color: 0xffffff, intensity: 1 }} />

            <Points
                {scene}
                {geometry}
                {material}
                mat={{ color: 0xff3e00 }}
                pos={[0, 0, 0]}
                interact
                on:pointermove={onPointerMove}
                bind:getPoints
            />
        </Scene>

        <WebGLRenderer
            {sti}
            sceneId="scene1"
            camId="cam1"
            config={{ antialias: true, alpha: false }}
        />
    </Canvas>
</main>

@JackDra
Copy link
Contributor Author

JackDra commented Nov 9, 2021

Now that I think about it, orbit controls seems much more fitting....

<script lang="ts">
    import {
        Canvas,
        Scene,
        PerspectiveCamera,
        Points,
        DirectionalLight,
        PointsMaterial,
        BufferGeometry,
        WebGLRenderer,
        AmbientLight,
        MathUtils,
        Float32BufferAttribute,
        OrbitControls,
    } from "svelthree";

    import gsap from "gsap";

    const vertices = [];

    for (let i = 0; i < 3000; i++) {
        const x = MathUtils.randFloatSpread(1000);
        const y = MathUtils.randFloatSpread(1000);
        const z = MathUtils.randFloatSpread(1000);

        vertices.push(x, y, z);
    }

    const geometry = new BufferGeometry();
    geometry.setAttribute("position", new Float32BufferAttribute(vertices, 3));

    const material = new PointsMaterial({
        color: 0x888888,
        size: 10,
        sizeAttenuation: true,
    });

    function handleScroll(e) {
        let obj = getPoints();
        gsap.to(obj.scale, {
            duration: 1,
            x: obj.scale.x + e.deltaY / 500,
            y: obj.scale.y + e.deltaY / 500,
            z: obj.scale.z + e.deltaY / 500,
            ease: "elastic.out",
        });
    }

    let getPoints;
</script>

<main on:wheel={handleScroll}>
    <Canvas let:sti w={800} h={600} interactive>
        <Scene {sti} let:scene id="scene1" props={{ background: 0xedf2f7 }}>
            <PerspectiveCamera
                {scene}
                id="cam1"
                props={{ position: [0, 0, 2000], lookAt: [0, 0, 0] }}
            />

            <DirectionalLight {scene} />

            <AmbientLight {scene} props={{ color: 0xffffff, intensity: 1 }} />

            <Points
                {scene}
                {geometry}
                {material}
                mat={{ color: 0xff3e00 }}
                pos={[0, 0, 0]}
                interact
                bind:getPoints
            />
            <OrbitControls {scene} autoRotate enableDamping />
        </Scene>

        <WebGLRenderer
            {sti}
            sceneId="scene1"
            camId="cam1"
            config={{ antialias: true, alpha: false }}
        />
    </Canvas>
</main>

@vatro vatro merged commit ae1fbd5 into vatro:major-refactor Nov 18, 2021
@vatro
Copy link
Owner

vatro commented Nov 28, 2021

Hi @JackDra!

To be honest I'm having a bit of a hard time getting back on track 😕 ... I wasn't even able to compile your example yet 😬, it would be cool if you could describe your setup a bit, especially concerning Vite configuration etc. Did you change something concerning svelthree setup? I tried a fresh SvelteKit-App like you, but I'm getting the <Scene> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules error. I've updated all svelthree-dependencies before trying, maybe that's causing the problem? 🤔 Hm... Any hint would be much appreciated! Thanks!

@vatro
Copy link
Owner

vatro commented Nov 28, 2021

I had the brilliant 😉 idea to build the project instead of just hitting dev 😬 ... and voila! I can see it! 🥳

image

Ok, so dev-mode has to be checked / fixed.

@JackDra
Copy link
Contributor Author

JackDra commented Nov 28, 2021

Is the ssr issue just with my changes? Or is it happening with any 3d scene?
I can check tomorrow.

@vatro
Copy link
Owner

vatro commented Nov 28, 2021

Is the ssr issue just with my changes? Or is it happening with any 3d scene? I can check tomorrow.

No, it doesn't have to do anything with your changes, the SvelteKit app build process has to be properly configured for external dependencies which have to be compiled (means svelthree), so that in the standard SvelteKit-App-SSR-dev-mode they're also compiled with ssr: true. I'm currently looking for more info on how to achieve that., see e.g. How do I fix the error I'm getting trying to include a package?.

other sources found:
sveltejs/kit#904

@JackDra
Copy link
Contributor Author

JackDra commented Nov 28, 2021

maybe we can just copy some of the stuff from svelte-cubed?
https://github.com/Rich-Harris/svelte-cubed/blob/main/svelte.config.js
Maybe the ssr part

@vatro
Copy link
Owner

vatro commented Nov 29, 2021

After hours of trying this and that with no success 🤷‍♂️, I've created a new issue concerning the SSR problem.

My current SvelteKit-App dev-mode workaround is to add:

<!-- index.svelte -->

<script context="module" lang="ts">
	export const ssr = false;
</script>

to the top of the component / page using svelthree.

@JackDra : Thank you very much for contributing! 🙂👍

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