sceneview-mcp 3.6.2 → 3.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -0
- package/dist/analyze-project.js +500 -0
- package/dist/auth.js +84 -0
- package/dist/billing.js +137 -0
- package/dist/convert-platform.js +302 -0
- package/dist/debug-issue.js +2 -2
- package/dist/explain-api.js +245 -0
- package/dist/extra-guides.js +1 -1
- package/dist/generate-animation.js +576 -0
- package/dist/generate-environment.js +483 -0
- package/dist/generate-gesture.js +532 -0
- package/dist/generate-physics.js +570 -0
- package/dist/generate-scene.js +4 -4
- package/dist/generated/llms-txt.js +6 -0
- package/dist/guides.js +8 -8
- package/dist/index.js +54 -1111
- package/dist/migration.js +2 -2
- package/dist/optimize-scene.js +173 -0
- package/dist/platform-setup.js +11 -11
- package/dist/samples.js +64 -64
- package/dist/search-models.js +214 -0
- package/dist/telemetry.js +120 -0
- package/dist/tiers.js +100 -0
- package/dist/tools/definitions.js +467 -0
- package/dist/tools/handler.js +791 -0
- package/dist/tools/index.js +18 -0
- package/dist/tools/types.js +8 -0
- package/dist/validator.js +1 -1
- package/llms.txt +24 -1
- package/package.json +7 -18
package/dist/migration.js
CHANGED
|
@@ -8,8 +8,8 @@ SceneView 3.0 is a full rewrite from Android Views to **Jetpack Compose**. Nearl
|
|
|
8
8
|
|
|
9
9
|
| 2.x | 3.0 |
|
|
10
10
|
|-----|-----|
|
|
11
|
-
| \`io.github.sceneview:sceneview:2.x.x\` | \`io.github.sceneview:sceneview:3.6.
|
|
12
|
-
| \`io.github.sceneview:arsceneview:2.x.x\` | \`io.github.sceneview:arsceneview:3.6.
|
|
11
|
+
| \`io.github.sceneview:sceneview:2.x.x\` | \`io.github.sceneview:sceneview:3.6.2\` |
|
|
12
|
+
| \`io.github.sceneview:arsceneview:2.x.x\` | \`io.github.sceneview:arsceneview:3.6.2\` |
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* optimize-scene.ts
|
|
3
|
+
*
|
|
4
|
+
* Analyzes SceneView code and suggests performance optimizations.
|
|
5
|
+
*/
|
|
6
|
+
export function optimizeScene(code) {
|
|
7
|
+
const suggestions = [];
|
|
8
|
+
const lines = code.split("\n");
|
|
9
|
+
// ── Check for multiple engine instances ──
|
|
10
|
+
const engineCount = (code.match(/rememberEngine\(\)/g) || []).length;
|
|
11
|
+
if (engineCount > 1) {
|
|
12
|
+
suggestions.push({
|
|
13
|
+
severity: "high",
|
|
14
|
+
category: "Memory",
|
|
15
|
+
issue: `${engineCount} Engine instances detected. Each Engine allocates significant GPU memory.`,
|
|
16
|
+
suggestion: "Create ONE engine at the top level and pass it down to all Scene composables.",
|
|
17
|
+
codeExample: `// At top-level composable:\nval engine = rememberEngine()\n// Pass to all scenes:\nScene(engine = engine) { ... }`,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// ── Check for per-frame allocations ──
|
|
21
|
+
if (/onFrame\s*=\s*\{/.test(code)) {
|
|
22
|
+
if (/Position\(/.test(code) && /onFrame/.test(code)) {
|
|
23
|
+
suggestions.push({
|
|
24
|
+
severity: "medium",
|
|
25
|
+
category: "Performance",
|
|
26
|
+
issue: "Potential per-frame Position allocation inside onFrame callback.",
|
|
27
|
+
suggestion: "Reuse mutable position objects instead of creating new Position instances every frame.",
|
|
28
|
+
codeExample: `// Before (bad): onFrame = { node.position = Position(x, y, z) }\n// After (good):\nval pos = remember { MutablePosition() }\nonFrame = { pos.set(x, y, z); node.position = pos }`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ── Check for large environment files ──
|
|
33
|
+
if (/4k\.hdr|4K\.hdr|8k\.hdr|8K\.hdr/.test(code)) {
|
|
34
|
+
suggestions.push({
|
|
35
|
+
severity: "high",
|
|
36
|
+
category: "Memory",
|
|
37
|
+
issue: "Large HDR environment file detected (4K or 8K).",
|
|
38
|
+
suggestion: "Use 2K HDR files for mobile. 4K+ wastes GPU memory with minimal visual improvement on small screens.",
|
|
39
|
+
codeExample: `// Use 2K: "environments/sky_2k.hdr"\n// NOT: "environments/sky_4k.hdr"`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// ── Check for missing post-processing flag ──
|
|
43
|
+
if (/SceneView\s*\(/.test(code) && !/postProcessing/.test(code)) {
|
|
44
|
+
suggestions.push({
|
|
45
|
+
severity: "low",
|
|
46
|
+
category: "Performance",
|
|
47
|
+
issue: "Post-processing is enabled by default (bloom, SSAO, tone mapping).",
|
|
48
|
+
suggestion: "If you don't need post-processing effects, disable them to save ~2ms per frame.",
|
|
49
|
+
codeExample: `SceneView(\n engine = engine,\n postProcessing = false // saves ~2ms/frame\n) { ... }`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// ── Check for too many concurrent model loads ──
|
|
53
|
+
const modelLoadCount = (code.match(/rememberModelInstance/g) || []).length;
|
|
54
|
+
if (modelLoadCount > 4) {
|
|
55
|
+
suggestions.push({
|
|
56
|
+
severity: "medium",
|
|
57
|
+
category: "Memory",
|
|
58
|
+
issue: `${modelLoadCount} concurrent model loads detected. Loading many models simultaneously spikes memory.`,
|
|
59
|
+
suggestion: "Limit to 3-4 concurrent loads. Use pagination or lazy loading for large model lists.",
|
|
60
|
+
codeExample: `// Load only visible models:\nval visibleItems = items.take(4)\nvisibleItems.forEach { item ->\n rememberModelInstance(modelLoader, item.path)\n}`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// ── Check for missing scaleToUnits ──
|
|
64
|
+
if (/ModelNode\s*\(/.test(code) && !/scaleToUnits/.test(code)) {
|
|
65
|
+
suggestions.push({
|
|
66
|
+
severity: "low",
|
|
67
|
+
category: "Quality",
|
|
68
|
+
issue: "ModelNode without scaleToUnits — model may render at unexpected size.",
|
|
69
|
+
suggestion: "Use scaleToUnits to normalize model size. Without it, the model uses its original units which vary by source.",
|
|
70
|
+
codeExample: `ModelNode(\n modelInstance = instance,\n scaleToUnits = 1.0f // normalizes to 1 meter\n)`,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// ── Check for multiple shadow-casting lights ──
|
|
74
|
+
const shadowLights = (code.match(/castShadows\s*\(\s*true\s*\)/g) || []).length;
|
|
75
|
+
if (shadowLights > 2) {
|
|
76
|
+
suggestions.push({
|
|
77
|
+
severity: "high",
|
|
78
|
+
category: "Performance",
|
|
79
|
+
issue: `${shadowLights} shadow-casting lights detected. Each adds a depth render pass.`,
|
|
80
|
+
suggestion: "Limit to 1-2 shadow-casting lights on mobile. Disable shadows on secondary lights.",
|
|
81
|
+
codeExample: `// Primary light with shadows:\nLightNode(apply = { castShadows(true) })\n// Fill light without shadows:\nLightNode(apply = { castShadows(false) })`,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// ── Check for texture compression hints ──
|
|
85
|
+
if (/\.png|\.jpg|\.jpeg/.test(code) && /Texture|texture|bitmap/i.test(code)) {
|
|
86
|
+
suggestions.push({
|
|
87
|
+
severity: "medium",
|
|
88
|
+
category: "Memory",
|
|
89
|
+
issue: "Uncompressed texture format (PNG/JPG) detected.",
|
|
90
|
+
suggestion: "Use KTX2 with Basis Universal compression for textures. 4-6x memory reduction on GPU.",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// ── Check for Dispatchers.IO with Filament calls ──
|
|
94
|
+
if (/Dispatchers\.(IO|Default)/.test(code) && /(modelLoader|materialLoader|engine\.)/.test(code)) {
|
|
95
|
+
suggestions.push({
|
|
96
|
+
severity: "high",
|
|
97
|
+
category: "Correctness",
|
|
98
|
+
issue: "Filament JNI calls detected near background dispatcher.",
|
|
99
|
+
suggestion: "ALL Filament calls must run on the main thread. Use rememberModelInstance in composables or wrap in withContext(Dispatchers.Main).",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
// ── Check for missing environment/IBL ──
|
|
103
|
+
if (/SceneView\s*\(/.test(code) && !/environment|createHDR|rememberEnvironment/.test(code) && /ModelNode/.test(code)) {
|
|
104
|
+
suggestions.push({
|
|
105
|
+
severity: "medium",
|
|
106
|
+
category: "Quality",
|
|
107
|
+
issue: "No environment/IBL detected. Metallic surfaces will appear black without image-based lighting.",
|
|
108
|
+
suggestion: "Add an HDR environment for physically-correct reflections on PBR materials.",
|
|
109
|
+
codeExample: `SceneView(\n environment = rememberEnvironment(environmentLoader) {\n environmentLoader.createHDREnvironment("environments/sky_2k.hdr")\n ?: createEnvironment(environmentLoader)\n }\n)`,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
// ── Check for missing Modifier.fillMaxSize ──
|
|
113
|
+
if (/SceneView\s*\(/.test(code) && !/fillMaxSize/.test(code)) {
|
|
114
|
+
suggestions.push({
|
|
115
|
+
severity: "low",
|
|
116
|
+
category: "Quality",
|
|
117
|
+
issue: "SceneView may have zero size without Modifier.fillMaxSize().",
|
|
118
|
+
suggestion: "Add modifier = Modifier.fillMaxSize() to ensure the 3D view is visible.",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
// Calculate score
|
|
122
|
+
const highCount = suggestions.filter((s) => s.severity === "high").length;
|
|
123
|
+
const mediumCount = suggestions.filter((s) => s.severity === "medium").length;
|
|
124
|
+
const lowCount = suggestions.filter((s) => s.severity === "low").length;
|
|
125
|
+
const score = Math.max(0, 100 - highCount * 20 - mediumCount * 10 - lowCount * 5);
|
|
126
|
+
let summary;
|
|
127
|
+
if (score >= 90) {
|
|
128
|
+
summary = "Excellent! This code follows SceneView best practices with minimal optimization opportunities.";
|
|
129
|
+
}
|
|
130
|
+
else if (score >= 70) {
|
|
131
|
+
summary = "Good code with some optimization opportunities. Address the high-severity items for best performance.";
|
|
132
|
+
}
|
|
133
|
+
else if (score >= 50) {
|
|
134
|
+
summary = "Several optimization opportunities found. Focus on high-severity items first for the biggest impact.";
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
summary = "Significant performance issues detected. Address the high-severity items immediately to avoid crashes and poor performance.";
|
|
138
|
+
}
|
|
139
|
+
return { suggestions, score, summary };
|
|
140
|
+
}
|
|
141
|
+
export function formatOptimizationReport(report) {
|
|
142
|
+
const parts = [
|
|
143
|
+
`## Scene Optimization Report`,
|
|
144
|
+
``,
|
|
145
|
+
`**Score:** ${report.score}/100`,
|
|
146
|
+
`**Summary:** ${report.summary}`,
|
|
147
|
+
``,
|
|
148
|
+
];
|
|
149
|
+
if (report.suggestions.length === 0) {
|
|
150
|
+
parts.push("No optimization suggestions. Your code looks well-optimized!");
|
|
151
|
+
return parts.join("\n");
|
|
152
|
+
}
|
|
153
|
+
const severityIcon = { high: "!!!", medium: "!!", low: "!" };
|
|
154
|
+
const severityLabel = { high: "HIGH", medium: "MEDIUM", low: "LOW" };
|
|
155
|
+
// Group by severity
|
|
156
|
+
for (const sev of ["high", "medium", "low"]) {
|
|
157
|
+
const items = report.suggestions.filter((s) => s.severity === sev);
|
|
158
|
+
if (items.length === 0)
|
|
159
|
+
continue;
|
|
160
|
+
parts.push(`### ${severityIcon[sev]} ${severityLabel[sev]} Priority (${items.length})\n`);
|
|
161
|
+
for (const item of items) {
|
|
162
|
+
parts.push(`**[${item.category}] ${item.issue}**`);
|
|
163
|
+
parts.push(`> ${item.suggestion}`);
|
|
164
|
+
if (item.codeExample) {
|
|
165
|
+
parts.push("```kotlin");
|
|
166
|
+
parts.push(item.codeExample);
|
|
167
|
+
parts.push("```");
|
|
168
|
+
}
|
|
169
|
+
parts.push(``);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return parts.join("\n");
|
|
173
|
+
}
|
package/dist/platform-setup.js
CHANGED
|
@@ -12,7 +12,7 @@ const ANDROID_3D = `## SceneView Android — 3D Setup
|
|
|
12
12
|
\`\`\`kotlin
|
|
13
13
|
// build.gradle.kts (app module)
|
|
14
14
|
dependencies {
|
|
15
|
-
implementation("io.github.sceneview:sceneview:3.6.
|
|
15
|
+
implementation("io.github.sceneview:sceneview:3.6.2")
|
|
16
16
|
}
|
|
17
17
|
\`\`\`
|
|
18
18
|
|
|
@@ -87,7 +87,7 @@ const ANDROID_AR = `## SceneView Android — AR Setup
|
|
|
87
87
|
\`\`\`kotlin
|
|
88
88
|
// build.gradle.kts (app module)
|
|
89
89
|
dependencies {
|
|
90
|
-
implementation("io.github.sceneview:arsceneview:3.6.
|
|
90
|
+
implementation("io.github.sceneview:arsceneview:3.6.2")
|
|
91
91
|
// arsceneview includes sceneview transitively
|
|
92
92
|
}
|
|
93
93
|
\`\`\`
|
|
@@ -177,7 +177,7 @@ In Xcode: **File > Add Package Dependencies** > paste:
|
|
|
177
177
|
\`\`\`
|
|
178
178
|
https://github.com/sceneview/sceneview
|
|
179
179
|
\`\`\`
|
|
180
|
-
Set version rule to **"from: 3.6.
|
|
180
|
+
Set version rule to **"from: 3.6.2"**.
|
|
181
181
|
|
|
182
182
|
Or in Package.swift:
|
|
183
183
|
\`\`\`swift
|
|
@@ -188,7 +188,7 @@ let package = Package(
|
|
|
188
188
|
name: "MyApp",
|
|
189
189
|
platforms: [.iOS(.v18), .macOS(.v15), .visionOS(.v1)],
|
|
190
190
|
dependencies: [
|
|
191
|
-
.package(url: "https://github.com/sceneview/sceneview", from: "3.6.
|
|
191
|
+
.package(url: "https://github.com/sceneview/sceneview", from: "3.6.2")
|
|
192
192
|
],
|
|
193
193
|
targets: [
|
|
194
194
|
.executableTarget(
|
|
@@ -273,7 +273,7 @@ const IOS_AR = `## SceneViewSwift — iOS AR Setup
|
|
|
273
273
|
### 1. SPM Dependency
|
|
274
274
|
|
|
275
275
|
\`\`\`swift
|
|
276
|
-
.package(url: "https://github.com/sceneview/sceneview", from: "3.6.
|
|
276
|
+
.package(url: "https://github.com/sceneview/sceneview", from: "3.6.2")
|
|
277
277
|
\`\`\`
|
|
278
278
|
|
|
279
279
|
### 2. Info.plist — Camera Permission (Required)
|
|
@@ -417,7 +417,7 @@ SceneView Flutter uses **PlatformView** to embed native SceneView (Android: Fila
|
|
|
417
417
|
\`\`\`yaml
|
|
418
418
|
# pubspec.yaml
|
|
419
419
|
dependencies:
|
|
420
|
-
sceneview_flutter: ^3.6.
|
|
420
|
+
sceneview_flutter: ^3.6.2
|
|
421
421
|
\`\`\`
|
|
422
422
|
|
|
423
423
|
### 2. Android Setup
|
|
@@ -476,7 +476,7 @@ const FLUTTER_AR = `## SceneView Flutter — AR Setup
|
|
|
476
476
|
|
|
477
477
|
\`\`\`yaml
|
|
478
478
|
dependencies:
|
|
479
|
-
sceneview_flutter: ^3.6.
|
|
479
|
+
sceneview_flutter: ^3.6.2
|
|
480
480
|
\`\`\`
|
|
481
481
|
|
|
482
482
|
### 2. Android Manifest
|
|
@@ -632,7 +632,7 @@ plugins {
|
|
|
632
632
|
|
|
633
633
|
dependencies {
|
|
634
634
|
implementation(compose.desktop.currentOs)
|
|
635
|
-
implementation("io.github.sceneview:sceneview-desktop:3.6.
|
|
635
|
+
implementation("io.github.sceneview:sceneview-desktop:3.6.2") // when published
|
|
636
636
|
}
|
|
637
637
|
\`\`\`
|
|
638
638
|
|
|
@@ -683,7 +683,7 @@ SceneView on Android TV uses the same Filament renderer as mobile Android, with
|
|
|
683
683
|
|
|
684
684
|
\`\`\`kotlin
|
|
685
685
|
dependencies {
|
|
686
|
-
implementation("io.github.sceneview:sceneview:3.6.
|
|
686
|
+
implementation("io.github.sceneview:sceneview:3.6.2")
|
|
687
687
|
implementation("androidx.leanback:leanback:1.0.0")
|
|
688
688
|
implementation("androidx.tv:tv-foundation:1.0.0-alpha10")
|
|
689
689
|
}
|
|
@@ -748,14 +748,14 @@ const SETUPS = {
|
|
|
748
748
|
android: {
|
|
749
749
|
name: "Android (Jetpack Compose)",
|
|
750
750
|
renderer: "Filament (OpenGL ES / Vulkan)",
|
|
751
|
-
status: "Stable (v3.6.
|
|
751
|
+
status: "Stable (v3.6.2)",
|
|
752
752
|
guide3d: ANDROID_3D,
|
|
753
753
|
guideAr: ANDROID_AR,
|
|
754
754
|
},
|
|
755
755
|
ios: {
|
|
756
756
|
name: "iOS / macOS / visionOS (SwiftUI)",
|
|
757
757
|
renderer: "RealityKit (Metal)",
|
|
758
|
-
status: "Alpha (v3.6.
|
|
758
|
+
status: "Alpha (v3.6.2)",
|
|
759
759
|
guide3d: IOS_3D,
|
|
760
760
|
guideAr: IOS_AR,
|
|
761
761
|
},
|