Skip to content

Commit

Permalink
fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
aamir1995 committed Oct 2, 2023
1 parent 61d226d commit f23ea7e
Show file tree
Hide file tree
Showing 22 changed files with 169 additions and 74 deletions.
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,26 @@
"editor.tabSize": 4,
"cSpell.words": [
"Barebone",
"blue'ish",
"clsx",
"colour",
"Drawio",
"drawkind",
"Farger",
"fontawesome",
"fortawesome",
"frontmost",
"getdrawobjectfrompoints",
"gltf",
"gray'ish",
"halfspace",
"halfspaces",
"HDRI",
"importmap",
"JSCAD",
"linestrip",
"measurescene",
"modheader",
"MSAA",
"MSAL",
"Naviswork",
Expand All @@ -31,6 +38,7 @@
"Quadtree",
"stackblitz",
"tonemapping",
"trackpad",
"transformative",
"webgl"
],
Expand Down
2 changes: 2 additions & 0 deletions docs/guides/camera_controllers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Camera controllers"
sidebar_position: 5
description: "How to use and configure camera controllers."
keywords: ["novorender api docs", "webgl api", "clipping volumes"]
pagination_next: null
pagination_prev: null
---

Before we dive into camera controllers, let's examine what they control exactly.
Expand Down
2 changes: 2 additions & 0 deletions docs/guides/clipping_volumes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Clipping Volumes"
sidebar_position: 10
description: "How to apply clipping planes and volumes to view only part of a scene."
keywords: ["novorender api docs", "webgl api", "clipping volumes"]
pagination_next: null
pagination_prev: null
---

Clipping allows you to render only part of a scene.
Expand Down
2 changes: 2 additions & 0 deletions docs/guides/drawing2D.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
title: "Draw measure objects and results"
description: "Draw measure entity or results into a 2D canvas using Measure module."
keywords: ["novorender api docs", "measure module", "2D drawing"]
pagination_next: null
pagination_prev: null
---


Expand Down
8 changes: 5 additions & 3 deletions docs/guides/dynamic_objects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Dynamic Objects"
sidebar_position: 11
description: "Add dynamic 3D objects into the view."
keywords: ["novorender api docs", "webgl api", "gltf", "dynamic objects"]
pagination_next: null
pagination_prev: null
---

;
Expand Down Expand Up @@ -41,7 +43,7 @@ The glTF loader is not magic.
It returns render state that you can generate yourself in code.
The dynamic object render state <CodeLink type="interface" name="RenderStateDynamicObject"/> is quite rich and complex, similar to that of glTF.
Procedural geometry is intended for experienced 3D programmers.
Thus, this guide will not delwe into the complexities of geometry and materials, but rather explain how to get started.
Thus, this guide will not delve into the complexities of geometry and materials, but rather explain how to get started.
For more detail, see the [glTF 2.0 specification](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html) or [Learn OpenGL](https://learnopengl.com/).

Let's create a triangle from scratch.
Expand Down Expand Up @@ -160,7 +162,7 @@ Ultimately, a scene graph is a mere convenience and trivial to implement yoursel

Nodes loaded from glTF will have their matrices converted into world space and made into a flat list.
If you wish to animate things, you will have to do so yourself.
In general, we discourage lenghty/constant animations.
In general, we discourage lengthy/constant animations.
This is because whenever the render state changes, the frame has to be completely re-rendered, which costs energy.
Also, progressive post effects and high-res rendering are often only applied after a small period of inaction.
Short animation sequences of seconds or less are fine, however, and may help the user to better understand function and context.
Expand All @@ -178,7 +180,7 @@ To enable picking, you must assign a value to <CodeLink type="interface" name="R
Since static scenes starts at id `0`, you should pick a high value to avoid clashes.
The object id is an unsigned 32 bit integer, so `0xf000_0000` seem like a good choice.

Each instance will be assgined an id from the base id value, thusly: `instance_object_id = baseObjectId + instance_index`.
Each instance will be assigned an id from the base id value, thusly: `instance_object_id = baseObjectId + instance_index`.
In this example we only have one instance, so the base id becomes the only id we need to test for.
If you click on the cube, it should grow by 10%.
If you click outside the cube, it should shrink by 10%.
Expand Down
4 changes: 3 additions & 1 deletion docs/guides/interactive_examples.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
title: "Using interactive examples"
sidebar_position: 1
description: "How to use the interacive code examples."
description: "How to use the interactive code examples."
keywords: ["novorender api docs", "examples"]
pagination_next: null
pagination_prev: null
---

import Link from "@docusaurus/Link";
Expand Down
2 changes: 2 additions & 0 deletions docs/guides/loading_scenes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Loading scenes"
sidebar_position: 4
description: "Loading scenes via Data JS API or Data REST API."
keywords: ["novorender api docs", "web api", "data js api", "loading scenes"]
pagination_next: null
pagination_prev: null
---


Expand Down
2 changes: 2 additions & 0 deletions docs/guides/measure_line.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
title: "Drawing Measure Line"
description: "Drawing a measure line or polygon using measure module"
keywords: ["novorender web api docs", "web api", "measure line strip"]
pagination_next: null
pagination_prev: null
---


Expand Down
2 changes: 2 additions & 0 deletions docs/guides/object_groups.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Object groups"
sidebar_position: 9
description: "Creating or modifying or isolating object groups."
keywords: ["novorender api docs", "web api", "data js api", "creating object groups", "isolating object groups"]
pagination_next: null
pagination_prev: null
---


Expand Down
2 changes: 2 additions & 0 deletions docs/guides/object_metadata.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ tags:
- Move to
- Fly to
keywords: ["novorender api docs", "web api", "data js api", "object metadata"]
pagination_next: null
pagination_prev: null
---


Expand Down
2 changes: 2 additions & 0 deletions docs/guides/object_selection.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Object Selection"
sidebar_position: 6
description: "Highlighting sets of objects using the web api."
keywords: ["novorender api docs", "web api", "object selection"]
pagination_next: null
pagination_prev: null
---


Expand Down
2 changes: 2 additions & 0 deletions docs/guides/parametric_measure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
title: "Parametric measure"
description: "Fetch parametric data based on real world position, and calculate measurements between 2 objects using Web API's Measure module."
keywords: ["novorender api docs", "web api", "measure module", "parametric measure"]
pagination_next: null
pagination_prev: null
---


Expand Down
6 changes: 4 additions & 2 deletions docs/guides/render_state.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Render state"
sidebar_position: 3
description: "How to treat and modify immutable render state."
keywords: ["novorender api docs", "render state"]
pagination_next: null
pagination_prev: null
---


Expand Down Expand Up @@ -93,7 +95,7 @@ if (prevObj !== newObj) {
```

Yes, copying is slower than mutation, but that cost is easily recovered by the efficiency of basic reference comparisons to detect changes.
Immutable style of coding may feel a bit awkward and alien to you at first, but it signficantly reduces to potential for mistakes.
Immutable style of coding may feel a bit awkward and alien to you at first, but it significantly reduces to potential for mistakes.
Not to mention the simplicity of understanding, use, implementation and a host of other benefits.

## How to modify render state.
Expand Down Expand Up @@ -214,7 +216,7 @@ interface MyObject {
}
```

We strive to do this everywhere, except where the intention is explictly that of mutation.
We strive to do this everywhere, except where the intention is explicitly that of mutation.
When mutation is possible, such as on [camera controller properties](camera_controllers#properties), it's usually backed up by some logic to handle it gracefully.

You may find typescript [const assertions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) useful for making members readonly implicitly.
Expand Down
2 changes: 2 additions & 0 deletions docs/guides/searching.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Searching"
sidebar_position: 8
description: "Search using Novorender."
keywords: ["novorender web api docs", "web api", "searching"]
pagination_next: null
pagination_prev: null
---


Expand Down
4 changes: 3 additions & 1 deletion docs/guides/spaces_and_linear_algebra.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Spaces and linear algebra."
sidebar_position: 2
description: "A brief introduction to world and camera space as well as some linear algebra."
keywords: ["novorender api docs", "spaces", "spaces", "matrix", "vector", "quaternion"]
pagination_next: null
pagination_prev: null
---

import Drawio from '@theme/Drawio'
Expand Down Expand Up @@ -88,7 +90,7 @@ This is a fairly common coordinate system in the CAD world, but unlike that of m

:::info
We changed our coordinate system from positive z-axis pointing up to positive y-axis pointing up.
This currently not true for the `core3D` module, which still uses the classic opengl coordinate system.
This currently not true for the `core3D` module, which still uses the classic OpenGL coordinate system.
The `View` class flips the render state for you, so unless you're using the core3D module directly, you don't have to worry about it.
:::

Expand Down
16 changes: 9 additions & 7 deletions docs/guides/views.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: "Render view"
sidebar_position: 2
description: "Learn how to create and modify render views."
keywords: ["novorender api docs", "view"]
pagination_next: null
pagination_prev: null
---


Expand Down Expand Up @@ -81,15 +83,15 @@ Most of the guides on bundling will simply copy or map `node_modules/@novorender
If you followed this recipe, you can simply set the <CodeLink type="type" name="ViewImportmap.baseUrl"/> property of the import map as below.

```typescript
const baseUrl = new URL("/public/novorender/api/", import.meta.url);
const baseUrl = new URL("/public/novorender/api/", window.location.origin);
const imports = await View.downloadImports({baseUrl});
```

You could of course give the full URL with domain and port number, but this could make it hard to share the same code for `localhost` debugging and production, hence the `import.meta.url` base url.
You could of course give the full URL with domain and port number, but this could make it hard to share the same code for `localhost` debugging and production, hence the `location.origin` base url.

:::tip
[`import.meta.url`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta) will only work inside ESM modules.
If your code is not running as ESM, you can use [`document.currentScript.src`](https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript) instead.
You can also use [`import.meta.url`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta) for base URL but this will only work inside ESM modules.
If your code is not running as ESM or `import.meta.url` doesn't work, you can keep using [`window.location.origin`](https://developer.mozilla.org/en-US/docs/Web/API/Location/origin).
:::

For any other variants, you'll have to manually specify the url and/or reference to each resource, making sure you get the exact url the bundler generated, e.g. including hash etc.
Expand All @@ -109,7 +111,7 @@ await view.run();
```

Note that <CodeLink type="class" name="View.run"/> is an async function.
It will run a render loop indefintively, relinquishing control back to the browser after each frame is completed.
It will run a render loop infinitely, relinquishing control back to the browser after each frame is completed.
This means the browser won't kill it for timing out, like a synchronous loop would.
Behind the scenes it uses [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame).
Every frame it will check if there has been any changes to the render state, and if so, render that new state.
Expand Down Expand Up @@ -156,7 +158,7 @@ Animations will drain batteries quickly. Use with moderation!
:::

If you want to composite your own 2D content into the canvas after the frame has actually been rendered, you should assign/override the <CodeLink type="class" name="View.render"/> function.
Since this function is called after all render state changes has been resolved and commited for a frame, you may inspect it for your own purposes.
Since this function is called after all render state changes has been resolved and committed for a frame, you may inspect it for your own purposes.

```typescript
view.render = () => {
Expand All @@ -179,7 +181,7 @@ For compositing you must create a new canvas and overlay with alpha blending.
We used image based lighting ([IBL](https://en.wikipedia.org/wiki/Image-based_lighting)) to light and shade the geometry.
Most of our examples use the default environment, which is a boring 6-pixel cube map with subtle shades of gray.
Such a simple environment doesn't do the engine any justice.
It's just there to provde at least some light out of the box.
It's just there to provide at least some light out of the box.
Otherwise the output would be completely black by default.

To use a proper environment map, we need to download a set of HDRI cube texture maps with pre-convoluted radiance and irradiance information.
Expand Down
10 changes: 8 additions & 2 deletions docs/tutorial/getting_started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ It is **highly recommended** to get yourself familiar with these fundamental con

In this introductory tutorial, we will explore the process of configuring the Novorender Web API by developing a plain & simple web application.

While we've only provided tutorials for [Vite](https://vitejs.dev/) and [Webpack](https://webpack.js.org/), the setup process should be similar for other bundlers/frameworks, with some minor modifications or adjustments as needed. You can adapt the provided instructions to your specific development environment to seamlessly integrate Novorender into your project.

## Using Vite or Webpack?

<BundlerCard />

## Others
While we've only provided tutorials for [Vite](https://vitejs.dev/) and [Webpack](https://webpack.js.org/), the setup process should be similar for other bundlers/frameworks, with some minor modifications or adjustments as needed. We encourage you to follow one of the above tutorials and try adapt the provided instructions to your specific development environment to seamlessly integrate Novorender Web API into your project.

You can also explore the [examples repository](https://github.com/novorender/novorender-examples), which contains sample applications that utilize various module bundlers and frameworks. This resource can be valuable for gaining insights and understanding how Novorender Web API can be integrated into different development setups.

If you're still encountering any issues while trying to integrate the Novorender Web API into your development environment, don't hesitate to reach out by opening an issue [here](https://github.com/novorender/novorender-examples/issues). We're here to help and will do our utmost to assist you!

export const BundlerCard = () => (
<div style={{ display: "flex", gap: 50, justifyContent: "center", alignItems: "center" }}>
{['Vite', 'Webpack'].map((v) => <div key={v} style={{width: 200}} className="card">
Expand Down
31 changes: 29 additions & 2 deletions docs/tutorial/vite_getting_started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ export default {
}
```

<details>
<summary>Adding headers via <b>ModHeader</b></summary>


If the above method of adding headers doesn't work or you don't have access to the build configuration, you can utilize the [ModHeader](https://modheader.com/) browser extension. This extension allows you to modify HTTP request and response headers, providing an alternative way to address header-related issues.

![ModHeader usage demonstration gif](/img/modheader.gif)

</details>

:::info
It's important to note that the method described above for enabling Cross-Origin headers is primarily intended for development mode. When transitioning to a production environment, you will need to configure these headers on your server. The specific implementation will depend on the server you are using, so please consult the relevant documentation for detailed instructions.
:::
Expand Down Expand Up @@ -200,10 +210,27 @@ const deviceProfile = getDeviceProfile(gpuTier);
```typescript title="main.ts"
import { View } from "@novorender/api";

const baseUrl = new URL("/novorender/api/", location.origin);
const baseUrl = new URL("/novorender/api/", window.location.origin);
const imports = await View.downloadImports({ baseUrl });
```

<details>
<summary>Getting Error: `Cannot find module '/novorender/api/shaders.js`</summary>
<div>In certain build environments or bundlers, you might encounter complaints about `shaders.js` not being found. In such cases, you will need to provide the `shaders` separately to resolve this issue.</div>

```typescript
// @ts-expect-error
import { shaders } from "@novorender/api/public/shaders";

const imports = await View.downloadImports({ baseUrl, shaders });
```

:::info
`// @ts-expect-error` is essential because TypeScript might incorrectly assume that the `@novorender/api` doesn't expose this module, even though it does and this will tell TypeScript to suppress that error from being reported.
:::

</details>

### Creating View
With all the necessary components in place, we can proceed to create and run our view:
```typescript title="main.ts"
Expand All @@ -227,7 +254,7 @@ const canvas = document.getElementById("canvas") as HTMLCanvasElement;
async function main(canvas: HTMLCanvasElement) {
const gpuTier = 2;
const deviceProfile = getDeviceProfile(gpuTier);
const baseUrl = new URL("/novorender/api/", location.origin);
const baseUrl = new URL("/novorender/api/", window.location.origin);
const imports = await View.downloadImports({ baseUrl });
const view = new View(canvas, deviceProfile, imports);
await view.run();
Expand Down
Loading

0 comments on commit f23ea7e

Please sign in to comment.