Compare commits
12 Commits
69c874e106
...
5dd99a1195
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dd99a1195 | ||
|
|
532b39f02d | ||
|
|
65d5e08f36 | ||
|
|
11e62d47d4 | ||
|
|
6577f53390 | ||
|
|
0ff96ffe0f | ||
|
|
4bb59ce3a6 | ||
|
|
6157f3fff5 | ||
|
|
d90246e834 | ||
|
|
4bdecc600a | ||
|
|
25ee09a60f | ||
|
|
e5b459a729 |
@@ -80,18 +80,30 @@ struct Node {
|
||||
|
||||
### 4. Enhanced Rendering (`bridge/src/lib.rs` - `reify()`)
|
||||
|
||||
**Implemented type-specific rendering:**
|
||||
**Implemented type-specific wireframe rendering:**
|
||||
|
||||
- **Box entities (type 1):** Colored wireframe cubes using entity color
|
||||
- **Sphere entities (type 2):** Three orthogonal wireframe circles (XY, XZ, YZ planes) in entity color
|
||||
- **Model entities (type 3):** Distinctive octahedron wireframe (placeholder for actual model loading)
|
||||
The current implementation uses wireframe visualizations for all entity types, providing a lightweight and performant rendering solution that works with the Stardust Lines API:
|
||||
|
||||
- **Box entities (type 1):** Colored wireframe cubes (12 edges) using entity color and dimensions
|
||||
- **Sphere entities (type 2):** Three orthogonal wireframe circles (XY, XZ, YZ planes) forming a sphere visualization
|
||||
- **Model entities (type 3):** Distinctive octahedron wireframe (12 edges) as a placeholder for 3D models
|
||||
- **Unknown types:** Gray wireframe cube as fallback
|
||||
|
||||
**Features:**
|
||||
- Respects entity dimensions for accurate sizing
|
||||
- Uses entity-specific colors
|
||||
- Uses entity-specific RGB colors with alpha transparency
|
||||
- Applies proper transforms (position, rotation, scale)
|
||||
- Maintains visual distinction between entity types
|
||||
- Lightweight rendering using the Stardust Lines element
|
||||
|
||||
**Note on 3D Model Support:**
|
||||
Full 3D model rendering with textures requires:
|
||||
1. Downloading Overte model assets (typically GLTF/GLB format)
|
||||
2. Caching them locally
|
||||
3. Using `Model::direct(PathBuf)` with local file paths
|
||||
4. The current implementation uses wireframe placeholders as Overte model URLs are HTTP-based and require asset pipeline integration
|
||||
|
||||
Future enhancement: Implement a background asset downloader that fetches Overte models and textures, caches them locally, and dynamically updates the scene graph to replace wireframe placeholders with actual 3D models.
|
||||
|
||||
### 5. StardustBridge C++ Interface (`StardustBridge.hpp/.cpp`)
|
||||
|
||||
|
||||
259
README.md
259
README.md
@@ -1,45 +1,244 @@
|
||||
# Starworld (StardustXR + Overte client)
|
||||
# Starworld (StardustXR + Overte Client)
|
||||
|
||||
[](https://gitea.example.com/yourusername/starworld/actions)
|
||||
|
||||
## Rust bridge (optional)
|
||||
This project can load a Rust bridge shared library exposing a C ABI to the StardustXR client. Build it with:
|
||||
## Overview
|
||||
|
||||
Starworld is an Overte client that renders virtual world entities inside the StardustXR compositor. It bridges Overte's entity protocol with Stardust's spatial computing environment, allowing you to view and interact with Overte domains in XR.
|
||||
|
||||
**Current Status:** Wireframe rendering with full transform, color, and dimension support. See [RENDERING_FIX_SUMMARY.md](RENDERING_FIX_SUMMARY.md) for details on the rendering pipeline.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
- CMake 3.15+
|
||||
- C++20 compiler (GCC/Clang)
|
||||
- Rust toolchain (for the bridge)
|
||||
- StardustXR server running
|
||||
- Required libraries: glm, OpenSSL, zlib, libcurl
|
||||
|
||||
### Build Everything
|
||||
```bash
|
||||
./build_and_test.sh
|
||||
```
|
||||
|
||||
Or manually:
|
||||
|
||||
```bash
|
||||
# 1. Build Rust bridge
|
||||
cd bridge
|
||||
cargo build --release
|
||||
cd ..
|
||||
|
||||
# 2. Build C++ client
|
||||
mkdir -p build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
### Run with Simulation Mode
|
||||
Test the rendering without connecting to an Overte server:
|
||||
|
||||
```bash
|
||||
export STARWORLD_SIMULATE=1
|
||||
export STARWORLD_BRIDGE_PATH=./bridge/target/release
|
||||
./build/stardust-overte-client
|
||||
```
|
||||
|
||||
This creates three demo entities (red cube, green sphere, blue octahedron).
|
||||
|
||||
### Connect to Overte Server
|
||||
```bash
|
||||
export STARWORLD_BRIDGE_PATH=./bridge/target/release
|
||||
./build/stardust-overte-client ws://domain.example.com:40102
|
||||
```
|
||||
|
||||
Or use domain discovery:
|
||||
```bash
|
||||
export STARWORLD_BRIDGE_PATH=./bridge/target/release
|
||||
./build/stardust-overte-client --discover
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Overte Server (UDP) → OverteClient (C++) → SceneSync → StardustBridge (C++)
|
||||
↓ (dlopen C-ABI)
|
||||
Rust Bridge
|
||||
↓
|
||||
Stardust Server
|
||||
```
|
||||
|
||||
The Rust bridge provides the StardustXR client implementation, exposing a C ABI for the C++ code to use.
|
||||
|
||||
## Entity Rendering
|
||||
|
||||
Starworld currently renders entities using **wireframe visualizations**:
|
||||
|
||||
- **Box** (type 1): 12-edge cube wireframe
|
||||
- **Sphere** (type 2): 3 orthogonal circles forming a sphere
|
||||
- **Model** (type 3): Octahedron wireframe (placeholder)
|
||||
- **Unknown**: Default cube wireframe
|
||||
|
||||
All entities respect:
|
||||
- Position, rotation, scale (full transform matrix)
|
||||
- RGB color with alpha transparency
|
||||
- Dimensions (xyz size in meters)
|
||||
|
||||
For details on the rendering implementation and future 3D model support, see [ENTITY_RENDERING_ENHANCEMENTS.md](ENTITY_RENDERING_ENHANCEMENTS.md).
|
||||
|
||||
## Rust Bridge
|
||||
|
||||
The bridge (required for proper StardustXR integration) is a Rust shared library that:
|
||||
- Connects to the Stardust compositor via fusion client
|
||||
- Manages the spatial scene graph
|
||||
- Handles entity creation, updates, and removal
|
||||
- Renders entities using the asteroids element API
|
||||
|
||||
Build it with:
|
||||
```bash
|
||||
cd bridge
|
||||
cargo build
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
This produces `bridge/target/debug/libstardust_bridge.so`. The app will try to load it automatically at startup. You can also set an explicit path:
|
||||
This produces `bridge/target/release/libstardust_bridge.so`, which the C++ client loads at runtime.
|
||||
|
||||
### Bridge Path Configuration
|
||||
The client tries these locations in order:
|
||||
1. `STARWORLD_BRIDGE_PATH` environment variable
|
||||
2. `./bridge/target/debug/libstardust_bridge.so`
|
||||
3. `libstardust_bridge.so` (system library path)
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Environment Variables
|
||||
- `STARWORLD_BRIDGE_PATH`: Path to bridge .so directory
|
||||
- `STARWORLD_SIMULATE`: Set to `1` for simulation mode (no Overte connection)
|
||||
- `STARDUSTXR_SOCKET`: Override Stardust compositor socket path
|
||||
- `OVERTE_URL`: Override Overte server URL
|
||||
- `OVERTE_DISCOVER`: Enable domain discovery (`1` or `true`)
|
||||
- `OVERTE_DISCOVER_PROBE`: Enable/disable domain reachability probing
|
||||
- `OVERTE_DISCOVER_INDEX`: Manual domain selection index
|
||||
- `OVERTE_USERNAME`: Set username for Overte authentication
|
||||
|
||||
### Command-Line Options
|
||||
- `--socket=/path/to.sock`: Legacy socket override
|
||||
- `--abstract=name`: Use abstract socket namespace
|
||||
- `--overte=ws://host:port`: Overte server WebSocket URL
|
||||
- `--discover`: Enable Overte domain discovery
|
||||
|
||||
## Development
|
||||
|
||||
### Project Structure
|
||||
```
|
||||
Starworld/
|
||||
├── src/ # C++ source files
|
||||
│ ├── main.cpp
|
||||
│ ├── StardustBridge.cpp
|
||||
│ ├── OverteClient.cpp
|
||||
│ ├── SceneSync.cpp
|
||||
│ └── ...
|
||||
├── bridge/ # Rust bridge
|
||||
│ ├── src/lib.rs
|
||||
│ └── Cargo.toml
|
||||
├── tests/ # Test harness
|
||||
└── tools/ # Python utilities
|
||||
```
|
||||
|
||||
### Debugging
|
||||
Enable verbose logging:
|
||||
```bash
|
||||
export RUST_LOG=debug
|
||||
export LOG_LEVEL=debug
|
||||
./build/stardust-overte-client
|
||||
```
|
||||
|
||||
### Vendoring StardustXR Crates
|
||||
For deterministic builds, clone dependencies into `third_party/`:
|
||||
|
||||
```bash
|
||||
export STARWORLD_BRIDGE_PATH=./bridge/target/debug/libstardust_bridge.so
|
||||
cd third_party
|
||||
git clone https://github.com/StardustXR/asteroids.git
|
||||
git clone https://github.com/StardustXR/core.git
|
||||
```
|
||||
|
||||
If the bridge is not present, the app falls back to a stub and (previously) attempted raw sockets; with the bridge present it will initialize via the official client crates.
|
||||
Then update `bridge/Cargo.toml`:
|
||||
```toml
|
||||
[dependencies.stardust-xr-asteroids]
|
||||
path = "../third_party/asteroids"
|
||||
|
||||
## Overte
|
||||
Overte connectivity is optional; if unreachable, the client runs in offline mode and logs a warning.
|
||||
|
||||
## CLI
|
||||
- `--socket=/path/to.sock` (legacy attempt)
|
||||
- `--abstract=name` (legacy abstract socket attempt)
|
||||
|
||||
Prefer using the Rust bridge.
|
||||
|
||||
## Vendoring StardustXR crates (recommended for deep integration)
|
||||
For fuller control and inspection of the StardustXR client pipeline, clone the `asteroids` and `core` (fusion) repositories into `third_party/` and switch the bridge's `Cargo.toml` to `path` dependencies. See `third_party/README.md` for details.
|
||||
|
||||
Benefits:
|
||||
- Deterministic builds (no moving `dev` branch)
|
||||
- Ability to patch or instrument crate internals without forking remote
|
||||
- Easier to expose new C ABI functions (input, health queries, node data extraction)
|
||||
|
||||
After vendoring:
|
||||
```bash
|
||||
sed -i 's/git = .*/path = "..\/third_party\/asteroids"/' bridge/Cargo.toml
|
||||
sed -i 's/git = .*/path = "..\/third_party\/core"/' bridge/Cargo.toml
|
||||
cargo build -p stardust_bridge
|
||||
[dependencies.stardust-xr-fusion]
|
||||
path = "../third_party/core"
|
||||
```
|
||||
|
||||
If you do not vendor, please provide commit SHAs to pin; I can update `Cargo.toml` accordingly.
|
||||
This allows you to:
|
||||
- Lock to specific commits
|
||||
- Patch client internals
|
||||
- Debug client crate issues
|
||||
- Add custom C ABI exports
|
||||
|
||||
## Known Limitations
|
||||
|
||||
1. **Wireframe-only rendering**: Full 3D models require asset download pipeline (see roadmap)
|
||||
2. **No texture support**: Material/texture application needs model loading
|
||||
3. **UDP only**: WebSocket transport not yet implemented
|
||||
4. **Entity types**: Limited to basic primitives (box, sphere, model placeholder)
|
||||
|
||||
## Roadmap
|
||||
|
||||
### Phase 1: Rendering ✅ (Current)
|
||||
- [x] Wireframe entity visualization
|
||||
- [x] Transform, color, dimension support
|
||||
- [x] Entity type differentiation
|
||||
|
||||
### Phase 2: Assets (Planned)
|
||||
- [ ] HTTP model downloader
|
||||
- [ ] Local asset cache
|
||||
- [ ] GLTF/GLB model loading
|
||||
- [ ] Dynamic model replacement
|
||||
- [ ] Texture application
|
||||
|
||||
### Phase 3: Interaction
|
||||
- [ ] Input forwarding (pointer, hand tracking)
|
||||
- [ ] Avatar representation
|
||||
- [ ] Audio spatial rendering
|
||||
|
||||
### Phase 4: Advanced Features
|
||||
- [ ] Script integration
|
||||
- [ ] Zone/environment support
|
||||
- [ ] Particle effects
|
||||
- [ ] Lighting
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Failed to connect to StardustXR compositor"
|
||||
- Ensure Stardust server is running
|
||||
- Check `STARDUSTXR_SOCKET` environment variable
|
||||
- Try: `ss -lx | grep stardust` to find the socket
|
||||
|
||||
### "Rust bridge present but start() failed"
|
||||
- Rebuild the bridge: `cd bridge && cargo build --release`
|
||||
- Check library exists: `ls -lh bridge/target/release/libstardust_bridge.so`
|
||||
- Verify RPATH: `ldd build/stardust-overte-client`
|
||||
|
||||
### "Could not connect to Overte"
|
||||
- Verify server URL/port
|
||||
- Check network connectivity
|
||||
- Try `--discover` to find public domains
|
||||
- Use simulation mode: `export STARWORLD_SIMULATE=1`
|
||||
|
||||
### Nothing renders in VR
|
||||
- Check Stardust server logs for errors
|
||||
- Verify entities have non-zero dimensions
|
||||
- Enable debug logging: `RUST_LOG=debug`
|
||||
- Look for "[bridge/reify]" log messages
|
||||
|
||||
## Contributing
|
||||
|
||||
See [ENTITY_RENDERING_ENHANCEMENTS.md](ENTITY_RENDERING_ENHANCEMENTS.md) for implementation details.
|
||||
|
||||
For CI/test setup, see [CI_SETUP_SUMMARY.md](CI_SETUP_SUMMARY.md).
|
||||
|
||||
## License
|
||||
|
||||
[Add your license here]
|
||||
|
||||
216
RENDERING_FIX_SUMMARY.md
Normal file
216
RENDERING_FIX_SUMMARY.md
Normal file
@@ -0,0 +1,216 @@
|
||||
# Starworld Rendering Pipeline Fix Summary
|
||||
|
||||
## Problem Diagnosis
|
||||
|
||||
The Starworld project stopped rendering entities after attempting to implement 3D model and texture support. The root cause was using incorrect Stardust API patterns that don't exist in the current version:
|
||||
|
||||
### Issues Found:
|
||||
|
||||
1. **Incorrect Model API Usage**
|
||||
- Used `Model::namespaced("fusion", "tex_cube")` which doesn't exist
|
||||
- Attempted to use `ModelPart::new()` and `.mat_param()` which are server-side APIs, not available in the client asteroids library
|
||||
|
||||
2. **API Mismatch**
|
||||
- Confused server-side Model implementation with client-side asteroids Elements
|
||||
- The `Model` element in asteroids requires a file path via `Model::direct(PathBuf)`
|
||||
- Material parameters are not directly accessible from client code
|
||||
|
||||
3. **Asset Pipeline Missing**
|
||||
- Overte provides model URLs (HTTP), but Stardust's `Model::direct()` expects local file paths
|
||||
- No asset download/caching mechanism was implemented
|
||||
|
||||
## Solution Implemented
|
||||
|
||||
### 1. **Switched to Wireframe Rendering**
|
||||
|
||||
Instead of trying to use non-existent model APIs, the fix implements proper wireframe visualizations using the Stardust `Lines` element, which is well-supported and documented:
|
||||
|
||||
```rust
|
||||
// Box entities - 12-edge cube wireframe
|
||||
let cube_lines = create_wireframe_cube(node_color, 0.005);
|
||||
Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(Lines::new(cube_lines).build())
|
||||
|
||||
// Sphere entities - 3 orthogonal circles
|
||||
let sphere_lines = create_wireframe_sphere(node_color, 0.005);
|
||||
Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(Lines::new(sphere_lines).build())
|
||||
|
||||
// Model entities - octahedron placeholder
|
||||
let oct_lines = create_octahedron_wireframe(node_color, 0.005);
|
||||
Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(Lines::new(oct_lines).build())
|
||||
```
|
||||
|
||||
### 2. **Cleaned Up Dependencies**
|
||||
|
||||
Removed unused imports:
|
||||
- `Model` and `ModelPart` from asteroids (not needed for wireframe approach)
|
||||
- `Transform` (already using fully qualified path)
|
||||
- `MaterialParameter` (not available in client API)
|
||||
- `ResourceID` (not needed for current implementation)
|
||||
|
||||
### 3. **Updated Cargo Configuration**
|
||||
|
||||
Changed from path-based dependency (non-existent local asteroids) to git-based:
|
||||
```toml
|
||||
[dependencies.stardust-xr-asteroids]
|
||||
git = "https://github.com/StardustXR/asteroids.git"
|
||||
branch = "dev"
|
||||
```
|
||||
|
||||
## Current Rendering Capabilities
|
||||
|
||||
✅ **Working:**
|
||||
- Box entities render as colored wireframe cubes
|
||||
- Sphere entities render as 3-circle wireframe spheres
|
||||
- Model entities render as octahedron wireframes (distinct placeholder)
|
||||
- All entities respect:
|
||||
- Position, rotation, scale (transform)
|
||||
- RGB color with alpha
|
||||
- Dimensions (xyz size)
|
||||
- Entity type differentiation
|
||||
|
||||
❌ **Not Yet Implemented:**
|
||||
- Loading actual 3D models from Overte URLs
|
||||
- Applying textures to surfaces
|
||||
- Solid surface rendering
|
||||
|
||||
## Build Status
|
||||
|
||||
✅ **Bridge compiles successfully** (warnings resolved)
|
||||
```bash
|
||||
cd bridge
|
||||
cargo build
|
||||
# Output: Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.01s
|
||||
```
|
||||
|
||||
## How to Test
|
||||
|
||||
### 1. Build the Bridge
|
||||
```bash
|
||||
cd /home/mayatheshy/stardust/Starworld
|
||||
cd bridge
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
### 2. Build the C++ Client
|
||||
```bash
|
||||
cd /home/mayatheshy/stardust/Starworld
|
||||
mkdir -p build && cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
### 3. Run with Simulation Mode
|
||||
```bash
|
||||
export STARWORLD_SIMULATE=1
|
||||
export STARWORLD_BRIDGE_PATH=/home/mayatheshy/stardust/Starworld/bridge/target/debug
|
||||
./stardust-overte-client
|
||||
```
|
||||
|
||||
This will create three demo entities:
|
||||
- **CubeA**: Red wireframe cube (20cm)
|
||||
- **SphereB**: Green wireframe sphere (15cm)
|
||||
- **ModelC**: Blue octahedron (25cm)
|
||||
|
||||
### 4. Connect to Real Overte Server
|
||||
```bash
|
||||
export STARWORLD_BRIDGE_PATH=/home/mayatheshy/stardust/Starworld/bridge/target/debug
|
||||
./stardust-overte-client ws://domain.example.com:40102
|
||||
```
|
||||
|
||||
## Path to Full 3D Model Support
|
||||
|
||||
To implement true 3D model rendering, you would need:
|
||||
|
||||
### Phase 1: Asset Management
|
||||
1. **Model Downloader Service**
|
||||
- Background thread/async task to download models from Overte URLs
|
||||
- Cache to local filesystem (e.g., `~/.cache/starworld/models/`)
|
||||
- Track download progress and completion
|
||||
|
||||
2. **URL to Path Mapping**
|
||||
- Hash Overte URLs to generate cache filenames
|
||||
- Maintain a registry: `HashMap<String, PathBuf>` (URL -> local path)
|
||||
- Handle re-downloads on cache miss
|
||||
|
||||
### Phase 2: Dynamic Scene Updates
|
||||
3. **Placeholder → Model Replacement**
|
||||
- Initially render wireframe placeholder
|
||||
- When model download completes, update the scene:
|
||||
```rust
|
||||
if let Some(local_path) = model_cache.get(&node.model_url) {
|
||||
Model::direct(local_path)
|
||||
.transform(transform)
|
||||
.build()
|
||||
} else {
|
||||
// Wireframe placeholder while downloading
|
||||
Lines::new(octahedron_lines).build()
|
||||
}
|
||||
```
|
||||
|
||||
4. **Texture Application**
|
||||
- Download textures to cache similarly
|
||||
- Use model part API to apply materials (requires deeper asteroids integration)
|
||||
|
||||
### Phase 3: Format Conversion (if needed)
|
||||
5. **Overte → GLTF Conversion**
|
||||
- If Overte uses proprietary formats, implement converter
|
||||
- Or use Overte's existing export capabilities
|
||||
|
||||
## Example: Working Model Loading Pattern
|
||||
|
||||
From the Armillary project (reference implementation):
|
||||
```rust
|
||||
match Model::direct(&self.model_path) {
|
||||
Ok(model_elem) => {
|
||||
model = Some(
|
||||
model_elem
|
||||
.pos([0.0, model_info.height_offset, 0.0])
|
||||
.build()
|
||||
.identify(&model_info.uuid),
|
||||
)
|
||||
}
|
||||
Err(e) => {
|
||||
// Fallback to error text display
|
||||
model_error = Some(
|
||||
Text::new(format!("Model Error:\n{e}"))
|
||||
.character_height(0.025)
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**Key takeaway:** `Model::direct()` requires a valid local `PathBuf`, not a URL.
|
||||
|
||||
## Conclusion
|
||||
|
||||
The rendering pipeline is now **functional and stable** with wireframe visualizations. This provides:
|
||||
- Immediate feedback during development
|
||||
- Low overhead for debugging entity positions/transforms
|
||||
- Clear visual distinction between entity types
|
||||
- Foundation for future 3D model integration
|
||||
|
||||
To enable full 3D models, implement the asset pipeline described above. The wireframe approach will continue to work as a fallback for failed downloads or unsupported model formats.
|
||||
|
||||
## Files Modified
|
||||
|
||||
1. **bridge/src/lib.rs** - Fixed `reify()` implementation to use Lines instead of non-existent Model APIs
|
||||
2. **bridge/Cargo.toml** - Changed asteroids dependency from path to git
|
||||
3. **ENTITY_RENDERING_ENHANCEMENTS.md** - Updated documentation to reflect wireframe approach
|
||||
|
||||
## Build Artifacts
|
||||
|
||||
After building, the bridge library will be at:
|
||||
- Debug: `bridge/target/debug/libstardust_bridge.so`
|
||||
- Release: `bridge/target/release/libstardust_bridge.so`
|
||||
|
||||
The C++ client will dynamically load this at runtime.
|
||||
1
bridge/Cargo.lock
generated
1
bridge/Cargo.lock
generated
@@ -2419,6 +2419,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "stardust-xr-asteroids"
|
||||
version = "2.0.0"
|
||||
source = "git+https://github.com/StardustXR/asteroids.git?branch=dev#38ec7d047076626396f6d5cde56ee8ff19eda8ee"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"derive-where",
|
||||
|
||||
@@ -16,7 +16,8 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
|
||||
[dependencies.stardust-xr-asteroids]
|
||||
path = "../third_party/asteroids"
|
||||
git = "https://github.com/StardustXR/asteroids.git"
|
||||
branch = "dev"
|
||||
|
||||
[dependencies.stardust-xr-fusion]
|
||||
git = "https://github.com/StardustXR/core.git"
|
||||
|
||||
@@ -10,16 +10,13 @@ use glam::Mat4;
|
||||
use stardust_xr_asteroids as ast; // alias for brevity
|
||||
use stardust_xr_asteroids::{
|
||||
client::ClientState,
|
||||
elements::{PlaySpace, Spatial, Lines, Model, ModelPart},
|
||||
elements::{PlaySpace, Spatial, Lines},
|
||||
Migrate, Reify, CustomElement, Projector, Context,
|
||||
};
|
||||
use stardust_xr_molecules::accent_color::AccentColor;
|
||||
use stardust_xr_fusion::objects::connect_client as fusion_connect_client;
|
||||
use stardust_xr_fusion::node::NodeType;
|
||||
use stardust_xr_fusion::root::RootAspect;
|
||||
use stardust_xr_fusion::spatial::Transform;
|
||||
use stardust_xr_fusion::drawable::MaterialParameter;
|
||||
use stardust_xr_fusion::values::ResourceID;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
#[derive(Clone, serde::Serialize, serde::Deserialize)]
|
||||
@@ -104,6 +101,59 @@ impl Reify for BridgeState {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
fn create_wireframe_sphere(color_val: stardust_xr_fusion::values::Color, thickness: f32) -> Vec<Line> {
|
||||
let segments = 32;
|
||||
let r = 0.5; // radius
|
||||
let mut lines = Vec::new();
|
||||
|
||||
// Create 3 orthogonal circles (XY, XZ, YZ planes)
|
||||
for axis in 0..3 {
|
||||
let mut points = Vec::new();
|
||||
for i in 0..=segments {
|
||||
let angle = (i as f32 / segments as f32) * std::f32::consts::TAU;
|
||||
let (sin, cos) = angle.sin_cos();
|
||||
let point = match axis {
|
||||
0 => Vector3 { x: cos * r, y: sin * r, z: 0.0 }, // XY plane
|
||||
1 => Vector3 { x: cos * r, y: 0.0, z: sin * r }, // XZ plane
|
||||
_ => Vector3 { x: 0.0, y: cos * r, z: sin * r }, // YZ plane
|
||||
};
|
||||
points.push(LinePoint { point, thickness, color: color_val });
|
||||
}
|
||||
lines.push(Line { points, cyclic: true });
|
||||
}
|
||||
lines
|
||||
}
|
||||
|
||||
fn create_octahedron_wireframe(color_val: stardust_xr_fusion::values::Color, thickness: f32) -> Vec<Line> {
|
||||
let r = 0.5;
|
||||
// 6 vertices of octahedron
|
||||
let verts = [
|
||||
Vector3 { x: 0.0, y: r, z: 0.0 }, // top
|
||||
Vector3 { x: r, y: 0.0, z: 0.0 }, // +X
|
||||
Vector3 { x: 0.0, y: 0.0, z: r }, // +Z
|
||||
Vector3 { x: -r, y: 0.0, z: 0.0 }, // -X
|
||||
Vector3 { x: 0.0, y: 0.0, z: -r }, // -Z
|
||||
Vector3 { x: 0.0, y: -r, z: 0.0 }, // bottom
|
||||
];
|
||||
|
||||
// 12 edges
|
||||
let edges = [
|
||||
(0, 1), (0, 2), (0, 3), (0, 4), // top pyramid
|
||||
(5, 1), (5, 2), (5, 3), (5, 4), // bottom pyramid
|
||||
(1, 2), (2, 3), (3, 4), (4, 1), // equator
|
||||
];
|
||||
|
||||
edges.iter().map(|(a, b)| {
|
||||
Line {
|
||||
points: vec![
|
||||
LinePoint { point: verts[*a], thickness, color: color_val },
|
||||
LinePoint { point: verts[*b], thickness, color: color_val },
|
||||
],
|
||||
cyclic: false,
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
let children = self.nodes.iter().filter_map(|(id, node)| {
|
||||
let dims = glam::Vec3::from(node.dimensions);
|
||||
if dims.length() < 0.001 {
|
||||
@@ -120,55 +170,49 @@ impl Reify for BridgeState {
|
||||
let scale_array = [vis_scale.x, vis_scale.y, vis_scale.z];
|
||||
let transform = stardust_xr_fusion::spatial::Transform::from_translation_rotation_scale(trans_array, rot_array, scale_array);
|
||||
|
||||
// Create appropriate visual based on entity type - wrap all in Spatial for type consistency
|
||||
// Create appropriate visual based on entity type
|
||||
match node.entity_type {
|
||||
1 => {
|
||||
// Box - use cube model with color
|
||||
eprintln!("[bridge/reify] Creating box model for node {}", id);
|
||||
// Box - use wireframe cube with color
|
||||
eprintln!("[bridge/reify] Creating box (wireframe) for node {}", id);
|
||||
let cube_lines = create_wireframe_cube(node_color, 0.005);
|
||||
Some((*id, Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(
|
||||
Model::namespaced("fusion", "tex_cube")
|
||||
.part(
|
||||
ModelPart::new("Cube")
|
||||
.mat_param("color", MaterialParameter::Color(node_color))
|
||||
).build()
|
||||
)))
|
||||
.child(Lines::new(cube_lines).build())))
|
||||
}
|
||||
2 => {
|
||||
// Sphere - use sphere model with color
|
||||
eprintln!("[bridge/reify] Creating sphere model for node {}", id);
|
||||
// Sphere - use wireframe sphere with color
|
||||
eprintln!("[bridge/reify] Creating sphere (wireframe) for node {}", id);
|
||||
let sphere_lines = create_wireframe_sphere(node_color, 0.005);
|
||||
Some((*id, Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(
|
||||
Model::namespaced("fusion", "tex_sphere")
|
||||
.part(
|
||||
ModelPart::new("Sphere")
|
||||
.mat_param("color", MaterialParameter::Color(node_color))
|
||||
).build()
|
||||
)))
|
||||
.child(Lines::new(sphere_lines).build())))
|
||||
}
|
||||
3 => {
|
||||
// Model - use model URL if available, fallback to cube
|
||||
eprintln!("[bridge/reify] Creating gyro model for node {}", id);
|
||||
// For now, use a fallback model since we can't load arbitrary URLs yet
|
||||
// TODO: Implement model loading and caching
|
||||
Some((*id, Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(
|
||||
Model::namespaced("fusion", "gyro")
|
||||
.part(
|
||||
ModelPart::new("Gem")
|
||||
.mat_param("color", MaterialParameter::Color(node_color))
|
||||
).build()
|
||||
)))
|
||||
// Model - attempt to load from URL if provided, fallback to wireframe
|
||||
if !node.model_url.is_empty() {
|
||||
eprintln!("[bridge/reify] Creating model for node {} from URL: {}", id, node.model_url);
|
||||
// For now, we can't easily load arbitrary HTTP URLs in the Overte format
|
||||
// Fall back to wireframe octahedron as a distinct placeholder
|
||||
let oct_lines = create_octahedron_wireframe(node_color, 0.005);
|
||||
Some((*id, Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(Lines::new(oct_lines).build())))
|
||||
} else {
|
||||
eprintln!("[bridge/reify] Creating model placeholder for node {} (no URL)", id);
|
||||
let oct_lines = create_octahedron_wireframe(node_color, 0.005);
|
||||
Some((*id, Spatial::default()
|
||||
.transform(transform)
|
||||
.build()
|
||||
.child(Lines::new(oct_lines).build())))
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Unknown or unsupported type - render as wireframe
|
||||
eprintln!("[bridge/reify] Creating wireframe for node {} type={}", id, node.entity_type);
|
||||
// Unknown or unsupported type - render as wireframe cube
|
||||
eprintln!("[bridge/reify] Creating wireframe for unknown node {} type={}", id, node.entity_type);
|
||||
let cube_lines = create_wireframe_cube(node_color, 0.003);
|
||||
Some((*id, Spatial::default()
|
||||
.transform(transform)
|
||||
@@ -353,7 +397,7 @@ pub extern "C" fn sdxr_start(app_id: *const std::os::raw::c_char) -> i32 {
|
||||
}
|
||||
};
|
||||
|
||||
let dbus_connection = match stardust_xr_fusion::objects::connect_client().await {
|
||||
let _dbus_connection = match stardust_xr_fusion::objects::connect_client().await {
|
||||
Ok(conn) => conn,
|
||||
Err(_) => {
|
||||
eprintln!("[bridge] Failed to connect to D-Bus, using fallback");
|
||||
|
||||
59
build_and_test.sh
Executable file
59
build_and_test.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
# Quick build and test script for Starworld
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
echo "=== Starworld Build & Test Script ==="
|
||||
echo
|
||||
|
||||
# 1. Build the Rust bridge
|
||||
echo "[1/3] Building Rust bridge..."
|
||||
cd "$SCRIPT_DIR/bridge"
|
||||
cargo build --release
|
||||
echo "✓ Rust bridge built successfully"
|
||||
echo
|
||||
|
||||
# 2. Build the C++ client
|
||||
echo "[2/3] Building C++ client..."
|
||||
cd "$SCRIPT_DIR"
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
make -j$(nproc)
|
||||
echo "✓ C++ client built successfully"
|
||||
echo
|
||||
|
||||
# 3. Verify the bridge library exists
|
||||
echo "[3/3] Verifying build artifacts..."
|
||||
BRIDGE_PATH="$SCRIPT_DIR/bridge/target/release/libstardust_bridge.so"
|
||||
if [ -f "$BRIDGE_PATH" ]; then
|
||||
echo "✓ Bridge library found: $BRIDGE_PATH"
|
||||
ls -lh "$BRIDGE_PATH"
|
||||
else
|
||||
echo "✗ Bridge library not found at: $BRIDGE_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_PATH="$SCRIPT_DIR/build/stardust-overte-client"
|
||||
if [ -f "$CLIENT_PATH" ]; then
|
||||
echo "✓ Client executable found: $CLIENT_PATH"
|
||||
ls -lh "$CLIENT_PATH"
|
||||
else
|
||||
echo "✗ Client executable not found at: $CLIENT_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=== Build Complete! ==="
|
||||
echo
|
||||
echo "To test with simulation mode:"
|
||||
echo " export STARWORLD_SIMULATE=1"
|
||||
echo " export STARWORLD_BRIDGE_PATH=$SCRIPT_DIR/bridge/target/release"
|
||||
echo " $SCRIPT_DIR/build/stardust-overte-client"
|
||||
echo
|
||||
echo "To connect to an Overte server:"
|
||||
echo " export STARWORLD_BRIDGE_PATH=$SCRIPT_DIR/bridge/target/release"
|
||||
echo " $SCRIPT_DIR/build/stardust-overte-client ws://domain.example.com:40102"
|
||||
echo
|
||||
Reference in New Issue
Block a user