init commit
This commit is contained in:
13
src/app.d.ts
vendored
Normal file
13
src/app.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
12
src/app.html
Normal file
12
src/app.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
7
src/index.test.ts
Normal file
7
src/index.test.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
describe('sum test', () => {
|
||||
it('adds 1 + 2 to equal 3', () => {
|
||||
expect(1 + 2).toBe(3);
|
||||
});
|
||||
});
|
11
src/lib/components/App.svelte
Normal file
11
src/lib/components/App.svelte
Normal file
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
import { Canvas } from '@threlte/core'
|
||||
import Scene from './Scene.svelte'
|
||||
import { World } from '@threlte/rapier';
|
||||
</script>
|
||||
|
||||
<Canvas>
|
||||
<World gravity={[0, 0, 0]}>
|
||||
<Scene />
|
||||
</World>
|
||||
</Canvas>
|
109
src/lib/components/RandomMeshes.svelte
Normal file
109
src/lib/components/RandomMeshes.svelte
Normal file
@@ -0,0 +1,109 @@
|
||||
<script
|
||||
lang="ts"
|
||||
context="module"
|
||||
>
|
||||
const geometry = new SphereGeometry(1)
|
||||
const material = new MeshBasicMaterial({ color: '#339933' })
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { T } from '@threlte/core'
|
||||
import { HTML } from '@threlte/extras'
|
||||
import { Attractor, Collider, RigidBody } from '@threlte/rapier'
|
||||
import { BoxGeometry, MeshBasicMaterial, MeshStandardMaterial, SphereGeometry, Vector3 } from 'three'
|
||||
|
||||
export let range: number = 10
|
||||
export let position: [number, number, number] = [0, 0, 0]
|
||||
let isHovering = false
|
||||
let isPointerDown = false
|
||||
let contactVec = new Vector3()
|
||||
const bodyPositions = [
|
||||
new Vector3(position[0] - range, position[0] - range, position[0] - range).toArray(),
|
||||
new Vector3(position[1] + (range / 2), position[1] + range, position[1] + range).toArray(),
|
||||
new Vector3(position[2] + range, position[2] - (range / 2), position[2] + range).toArray()
|
||||
]
|
||||
|
||||
const getId = () => {
|
||||
return Math.random().toString(16).slice(2)
|
||||
}
|
||||
|
||||
const getRandomSize = (): number => {
|
||||
return (Math.random() / 4) + 0.25
|
||||
}
|
||||
|
||||
const generateBodies = (c: number) => {
|
||||
return Array(c)
|
||||
.fill('x')
|
||||
.map((_, index) => {
|
||||
return {
|
||||
id: getId(),
|
||||
position: bodyPositions[index],
|
||||
size: getRandomSize()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const onClick = () => {
|
||||
console.log('clicked')
|
||||
|
||||
}
|
||||
|
||||
$: bodies = generateBodies(3)
|
||||
</script>
|
||||
|
||||
<HTML
|
||||
position.x={position[0]}
|
||||
position.y={position[1]}
|
||||
position.z={position[2]}
|
||||
|
||||
>
|
||||
<button
|
||||
on:pointerenter={() => (isHovering = true)}
|
||||
on:pointerleave={() => {
|
||||
isPointerDown = false
|
||||
isHovering = false
|
||||
}}
|
||||
on:pointerdown={() => (isPointerDown = true)}
|
||||
on:pointerup={() => (isPointerDown = false)}
|
||||
on:pointercancel={() => {
|
||||
isPointerDown = false
|
||||
isHovering = false
|
||||
}}
|
||||
on:click={onClick}
|
||||
class="rounded-full bg-orange-500 px-3 text-white hover:opacity-90 active:opacity-70"
|
||||
>
|
||||
Hello!
|
||||
</button>
|
||||
</HTML>
|
||||
|
||||
<Attractor
|
||||
position.x={position[0]}
|
||||
position.y={position[1]}
|
||||
position.z={position[2]}
|
||||
range={200}
|
||||
strength={isHovering ? 1 : 0.1}
|
||||
gravityType={"linear"}
|
||||
/>
|
||||
|
||||
{#each bodies as body (body.id)}
|
||||
<T.Group position={body.position}>
|
||||
<RigidBody>
|
||||
<Collider
|
||||
shape="ball"
|
||||
args={[body.size]}
|
||||
mass={body.size}
|
||||
/>
|
||||
<Attractor
|
||||
range={50}
|
||||
strength={1}
|
||||
gravityType={"newtonian"}
|
||||
/>
|
||||
<T.Mesh
|
||||
scale={[body.size, body.size, body.size]}
|
||||
|
||||
{geometry}
|
||||
{material}
|
||||
/>
|
||||
</RigidBody>
|
||||
</T.Group>
|
||||
{/each}
|
64
src/lib/components/Scene.svelte
Normal file
64
src/lib/components/Scene.svelte
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import { T } from '@threlte/core'
|
||||
import { ContactShadows, Float, Grid, OrbitControls } from '@threlte/extras'
|
||||
import { Attractor, RigidBody } from '@threlte/rapier';
|
||||
import RandomMeshes from './RandomMeshes.svelte';
|
||||
|
||||
const size = 100
|
||||
const count = 500
|
||||
|
||||
const positions = new Float32Array(count * 3)
|
||||
|
||||
// randomly distribute points in a cube
|
||||
for (let i = 0; i < count; i++) {
|
||||
positions[i * 3 + 0] = (Math.random() - 0.5) * size
|
||||
positions[i * 3 + 1] = (Math.random() - 0.5) * size
|
||||
positions[i * 3 + 2] = (Math.random() - 0.5) * size
|
||||
}
|
||||
</script>
|
||||
|
||||
<T.PerspectiveCamera
|
||||
position.y={15}
|
||||
position.z={25}
|
||||
makeDefault
|
||||
fov={70}
|
||||
far={10000}
|
||||
>
|
||||
<OrbitControls
|
||||
enableZoom={false}
|
||||
enablePan={false}
|
||||
enableRotate={false}
|
||||
enableDamping
|
||||
target.y={0}
|
||||
autoRotate
|
||||
/>
|
||||
</T.PerspectiveCamera>
|
||||
|
||||
<T.DirectionalLight
|
||||
intensity={0.8}
|
||||
position.x={5}
|
||||
position.y={10}
|
||||
/>
|
||||
|
||||
|
||||
<T.Points>
|
||||
<T.BufferGeometry>
|
||||
<T.BufferAttribute
|
||||
args={[positions, 3]}
|
||||
attach={(parent, self) => {
|
||||
parent.setAttribute('position', self)
|
||||
return () => {
|
||||
// cleanup function called when ref changes or the component unmounts
|
||||
// https://threlte.xyz/docs/reference/core/t#attach
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</T.BufferGeometry>
|
||||
<T.PointsMaterial size={0.1} />
|
||||
</T.Points>
|
||||
|
||||
<RandomMeshes
|
||||
position={[0, 0, 0]}
|
||||
range={10}
|
||||
/>
|
||||
|
5
src/lib/components/models/README.md
Normal file
5
src/lib/components/models/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Threlte Model Pipeline Components
|
||||
|
||||
This directory holds automatically generated Threlte components from GLTF models.
|
||||
|
||||
Place your models in `static/models` and run `npm run model-pipeline:run` to generate the components.
|
1
src/lib/index.ts
Normal file
1
src/lib/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
// place files you want to import through the `$lib` alias in this folder.
|
28
src/routes/+page.svelte
Normal file
28
src/routes/+page.svelte
Normal file
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
import App from '$lib/components/App.svelte'
|
||||
import type { PageData } from './$types';
|
||||
export let data: PageData;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#each data.models as model}
|
||||
<span>{model.title}</span>
|
||||
{/each}
|
||||
<App />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgb(0, 36, 6);
|
||||
background: linear-gradient(180deg, rgba(0, 36, 6, 1) 0%, rgba(0, 0, 0, 1) 100%);
|
||||
display: absolute;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
15
src/routes/+page.ts
Normal file
15
src/routes/+page.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
const models: Model[] = [
|
||||
{ title: 'Model 1' },
|
||||
{ title: 'Model 2' },
|
||||
{ title: 'Model 3' }
|
||||
];
|
||||
|
||||
export type Model = { title: string}
|
||||
|
||||
export function load(): { models: Model[] } {
|
||||
return {
|
||||
models: models.map((model) => ({
|
||||
title: model.title
|
||||
}))
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user