1
0

Compare commits

..

9 Commits

Author SHA1 Message Date
0e70a06e05 add tokyo 2025-11-21 13:08:09 +09:00
f706e9a14e gh-actions 2025-11-21 13:07:54 +09:00
11d667c65e ignore 2025-11-21 13:07:42 +09:00
206d1a16ef fix ignore 2025-11-21 10:06:36 +09:00
46030ca87d update readme 2025-11-21 10:05:20 +09:00
a43d3366e5 add cname 2025-11-21 07:06:57 +09:00
53655fce76 fix fly motion 2025-11-21 07:04:10 +09:00
06946dd203 clean first 2025-11-21 07:04:09 +09:00
cb720251e7 add atmosphere 2025-11-21 07:04:08 +09:00
18 changed files with 56 additions and 73 deletions

View File

@@ -6,10 +6,6 @@ on:
- main
environment: gh-pages
env:
GITEA_MAIL: ${{ secrets.GITEA_MAIL }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
jobs:
build-deploy:
runs-on: ubuntu-latest
@@ -18,24 +14,25 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 25
ref: main
submodules: true
fetch-depth: 0
- run: |
cd atmosphere/
npm i
rm -rf dist/vrma
git clone https://syu:${GITEA_TOKEN}@git.syui.ai/ai/vrma
cp -rf ./vrma/model/ai.vrm public/
cp -rf ./vrma/anime/idle.vrma public/
working-directory: min-react/
- name: Build
env:
TZ: "Asia/Tokyo"
run: npm run build
working-directory: min-react/
VITE_GOOGLE_MAP_API_KEY: ${{ secrets.VITE_GOOGLE_MAP_API_KEY }}
run: |
cd atmosphere/
npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./min-react/dist
publish_dir: ./atmosphere/dist
user_name: 'ai[bot]'
user_email: '138105980+yui-syui-ai[bot]@users.noreply.github.com'

4
.gitignore vendored
View File

@@ -1,4 +1,5 @@
node_modules
*package-lock.json
example
*yarn.lock
**DS_Store
@@ -10,6 +11,3 @@ dist
three-geospatial
**.env
.env
.env.production
**.vrm
**.vrma

View File

@@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="referrer" content="strict-origin-when-cross-origin" />
<title>VRM Animation Preview</title>
<style>
html, body, #root { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }

View File

@@ -22,6 +22,6 @@
},
"devDependencies": {
"@vitejs/plugin-react": "^4.2.1",
"vite": "^7.2.7"
"vite": "^5.1.0"
}
}

BIN
atmosphere/public/ai.vrm Normal file

Binary file not shown.

BIN
atmosphere/public/fly.vrma Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
atmosphere/public/idle.vrma Normal file

Binary file not shown.

BIN
atmosphere/public/run.vrma Normal file

Binary file not shown.

View File

@@ -27,13 +27,16 @@ import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
const BASE_URL = import.meta.env.BASE_URL;
const VRM_URL = `${BASE_URL}ai.vrm`;
const VRMA_URL = `${BASE_URL}fly_sky.vrma`;
const VRMA_URL = `${BASE_URL}fly.vrma`;
const EARTH_RADIUS = 6378137;
// 天気変更の間隔 (ms) - 5分
const WEATHER_INTERVAL = 5 * 60 * 1000;
// 時間の進行速度 (倍率)
const TIME_SCALE = 100;
// 初期時刻: 正午 (12:00)
const INITIAL_DATE = new Date('2024-06-21T12:00:00');
// --- Weather Presets (天候設定) ---
@@ -67,17 +70,19 @@ const WEATHER_PRESETS = [
}
];
// --- Locations ---
// --- Locations ---
const LOCATIONS = [
{ name: 'Tokyo', longitude: 139.7671, latitude: 35.6812, heading: 180, pitch: -5, distance: 1100 },
{ name: 'Fuji', longitude: 138.7278, latitude: 35.3206, heading: 0, pitch: -10, distance: 4000 },
{ name: 'Space', longitude: 139.7671, latitude: 35.6812, heading: 0, pitch: -90, distance: 100000 },
{ name: 'Tokyo', longitude: 139.7671, latitude: 35.6812, heading: 180, pitch: -5, distance: 300 },
{ name: 'Fuji', longitude: 138.7278, latitude: 35.3606, heading: 0, pitch: -10, distance: 4000 },
{ name: 'Space', longitude: 139.7671, latitude: 35.6812, heading: 0, pitch: -90, distance: 10000000 },
];
// --- Shared State for Synchronization ---
// 複数のCanvas間で状態を共有するための簡易ストア
const worldState = {
// 世界座標 (Atmosphere内での位置 - ECEF)
position: new Vector3(0, EARTH_RADIUS + 100000, 0),
position: new Vector3(0, EARTH_RADIUS + 2000, 0),
// ローカル回転 (AvatarLayerでの回転 - Y-up)
// Note: This is treated as the "Local" quaternion.
quaternion: new Quaternion(),
@@ -231,55 +236,40 @@ function AtmosphereScene() {
}, []);
// 3. 時間進行と太陽移動 (Canvas内なのでuseFrameが使える)
//useFrame((state, delta) => {
// const currentDate = dateRef.current;
// const elapsedMs = delta * TIME_SCALE * 1000;
// currentDate.setTime(currentDate.getTime() + elapsedMs);
// if (atmosphereRef.current) {
// atmosphereRef.current.updateByDate(currentDate);
// }
// if (sunRef.current) {
// const hours = currentDate.getHours() + currentDate.getMinutes() / 60 + currentDate.getSeconds() / 3600;
// const sunAngle = MathUtils.mapLinear(hours, 6, 18, 0, Math.PI);
// const sunX = -Math.cos(sunAngle);
// const sunY = Math.sin(sunAngle);
// if (hours < 6 || hours > 18) {
// sunRef.current.position.set(0, -1, 0);
// sunRef.current.intensity = 10.0;
// } else {
// sunRef.current.position.set(sunX, sunY, 0.2);
// sunRef.current.intensity = MathUtils.lerp(0.5, 3.0, sunY);
// }
// }
//});
useFrame((state, delta) => {
// 時間を進める
const currentDate = dateRef.current;
const elapsedMs = delta * TIME_SCALE * 1000;
currentDate.setTime(currentDate.getTime() + elapsedMs);
// Atmosphere更新
if (atmosphereRef.current) {
atmosphereRef.current.updateByDate(currentDate);
const sunDirection = atmosphereRef.current.sunDirection;
if (sunRef.current && sunDirection) {
sunRef.current.position.copy(sunDirection);
sunRef.current.intensity = 3.0; // 強度は固定で、時間帯による調整はAtmosphereが担当
if (sunDirection.y < -0.1) {
sunRef.current.intensity = 0.1;
}
// 太陽移動
if (sunRef.current) {
const hours = currentDate.getHours() + currentDate.getMinutes() / 60 + currentDate.getSeconds() / 3600;
const sunAngle = MathUtils.mapLinear(hours, 6, 18, 0, Math.PI);
const sunX = -Math.cos(sunAngle);
const sunY = Math.sin(sunAngle);
if (hours < 6 || hours > 18) {
sunRef.current.position.set(0, -1, 0);
sunRef.current.intensity = 0.0;
} else {
sunRef.current.position.set(sunX, sunY, 0.2);
sunRef.current.intensity = MathUtils.lerp(0.5, 3.0, sunY);
}
}
});
return (
<>
{/* Camera is controlled by FollowCamera component */}
<PerspectiveCamera
makeDefault
near={10}
near={1}
far={10000000}
fov={45}
/>
@@ -307,7 +297,7 @@ function AtmosphereScene() {
/>
))}
</Clouds>
<AerialPerspective sky />
<AerialPerspective sky sunLight skyLight />
<ToneMapping mode={ToneMappingMode.AGX} />
</EffectComposer>
</Atmosphere>
@@ -349,7 +339,7 @@ function VrmCharacter() {
// Load all animations
const [vrmaFly, vrmaFlyStop, vrmaFlyIdle] = useLoader(GLTFLoader, [
`${BASE_URL}fly_sky.vrma`,
`${BASE_URL}fly.vrma`,
`${BASE_URL}fly_stop.vrma`,
`${BASE_URL}fly_idle.vrma`
], (loader) => {
@@ -569,7 +559,7 @@ function CameraSync() {
function AvatarLayer() {
return (
<Canvas gl={{ alpha: true, antialias: true }}>
<PerspectiveCamera makeDefault position={[0, 1.5, 3]} fov={40} />
<PerspectiveCamera makeDefault position={[0, 1.5, 3]} fov={30} />
<CameraSync />
<directionalLight position={[-1, 1, 1]} intensity={1.5} />
@@ -630,7 +620,7 @@ function LocationUI() {
function AtmosphereLayer() {
// Canvasが親となり、その中にロジックコンポーネント(AtmosphereScene)を入れる
return (
<Canvas gl={{ alpha: true, antialias: true }}>
<Canvas>
<AtmosphereScene />
</Canvas>
);

View File

@@ -2,7 +2,7 @@ import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
//base: '/',
base: '/pkg/atmosphere/',
plugins: [react()]
plugins: [react()],
base: '/',
//base: '/pkg/atmosphere/',
})

View File

@@ -1 +0,0 @@
vrm.syui.ai

BIN
min-react/public/ai.vrm Normal file

Binary file not shown.

BIN
min-react/public/idle.vrma Normal file

Binary file not shown.

View File

@@ -19,7 +19,7 @@
"@types/three": "^0.167.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "^0.0.0",
"react-scripts": "5.0.1",
"three": "^0.167.1",
"three-stdlib": "^2.30.5",
"typescript": "^4.9.5",

View File

@@ -27,6 +27,6 @@
"globals": "^15.9.0",
"typescript": "^5.5.3",
"typescript-eslint": "^8.3.0",
"vite": "^7.2.7"
"vite": "^5.4.2"
}
}