Skip to content
This repository has been archived by the owner on Jun 10, 2022. It is now read-only.

[SDK] Texture asset support #164

Merged
merged 5 commits into from
Feb 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions packages/functional-tests/src/tests/asset-preload-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,24 @@ export default class AssetPreloadTest extends Test {
await delay(1000);

label.text.contents = 'Preloading assets';
const [prefabs, mats] = await Promise.all([
const [monkey, uvgrid] = await Promise.all([
this.app.context.assetManager.loadGltf('monkey', this.baseUrl + '/monkey.glb'),
this.app.context.assetManager.loadGltf('uvgrid', this.generateMaterial())
]);
label.text.contents = `Assets preloaded:
${prefabs.prefabs.count + mats.prefabs.count} prefabs, ${prefabs.materials.count + mats.materials.count} materials`;
label.text.contents = "Assets preloaded:" +
`${monkey.prefabs.count + uvgrid.prefabs.count} prefabs, ` +
`${monkey.materials.count + uvgrid.materials.count} materials, ` +
`${monkey.textures.count + uvgrid.textures.count} textures`;
await delay(1000);

const monkeyPrefab = monkey.prefabs.byIndex(0);
const monkeyMat = monkey.materials.byIndex(0);
const uvgridMat = uvgrid.materials.byIndex(0);
const uvgridTex = uvgrid.textures.byIndex(0);

label.text.contents = 'Instantiating prefabs';
const head = await MRESDK.Actor.CreateFromPrefab(this.app.context, {
prefabId: prefabs.prefabs.byIndex(0).id,
prefabId: monkeyPrefab.id,
actor: {
transform: {
position: { x: -1, y: 1, z: 0 }
Expand All @@ -60,7 +67,7 @@ ${prefabs.prefabs.count + mats.prefabs.count} prefabs, ${prefabs.materials.count
radius: 1
},
actor: {
materialId: mats.materials.byIndex(0).id,
materialId: uvgridMat.id,
transform: {
position: { x: 1, y: 1, z: 0 }
}
Expand All @@ -75,12 +82,24 @@ ${prefabs.prefabs.count + mats.prefabs.count} prefabs, ${prefabs.materials.count
actor.children.forEach(c => assignMat(c, mat));
}

assignMat(head, mats.materials.byIndex(0));
assignMat(sphere, prefabs.materials.byIndex(0));
assignMat(head, uvgridMat);
assignMat(sphere, monkeyMat);
label.text.contents = 'Materials swapped';

await delay(3000);

monkeyMat.mainTexture = uvgridTex;
uvgridMat.mainTexture = null;
label.text.contents = 'Textures swapped';

await delay(3000);

monkeyMat.mainTexture = null;
uvgridMat.mainTexture = null;
label.text.contents = 'Textures cleared';

await delay(3000);

assignMat(head, null);
assignMat(sphere, null);
label.text.contents = 'Materials cleared';
Expand Down
69 changes: 40 additions & 29 deletions packages/functional-tests/src/tests/mutable-asset-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
* Licensed under the MIT License.
*/

import * as GltfGen from '@microsoft/gltf-gen';
import * as MRESDK from '@microsoft/mixed-reality-extension-sdk';
import App from '../app';
import Server from '../server';
import delay from '../utils/delay';
import destroyActors from '../utils/destroyActors';
import Test from './test';
Expand All @@ -18,46 +20,55 @@ export default class MutableAssetTest extends Test {
public async run(): Promise<boolean> {

const assets = await this.app.context.assetManager.loadGltf(
'assets', `${this.baseUrl}/monkey.glb`);
'assets', this.generateMaterial()
);

const monkey = MRESDK.Actor.CreateFromPrefab(this.app.context, {
prefabId: assets.prefabs.byIndex(0).id,
const mat = assets.materials.byIndex(0);
const box = await MRESDK.Actor.CreatePrimitive(this.app.context, {
definition: {
shape: MRESDK.PrimitiveShape.Box,
dimensions: {x: 1, y: 1, z: 1}
},
actor: {
name: 'monkey',
name: 'box',
materialId: mat.id,
transform: {
position: { x: 0, y: 1, z: 0 }
}
}
}).value;
});

const label = MRESDK.Actor.CreateEmpty(this.app.context, {
actor: {
name: 'label',
transform: {
position: { x: 0, y: 2, z: 0 }
},
text: {
contents: 'Original (pink)'
}
}
}).value;
label.lookAt(this.user, MRESDK.LookAtMode.TargetY);

await delay(3000);
for (let i = 0; i < 64; i++) {
mat.color.copyFrom( this.fromHSV(i / 32, 1, 1) );
mat.mainTextureOffset.set(i / 32, i / 32);
mat.mainTextureScale.set(1 - i / 32, 1 - i / 32);

const material = assets.materials.byIndex(0);
const origColor = material.color.clone();
material.color.set(0, 1, 0, 1);
label.text.contents = 'Green';
await delay(100);
}

await delay(3000);
destroyActors([box]);
return true;
}

material.color.copyFrom(origColor);
label.text.contents = 'Back to original';
private generateMaterial(): string {
const material = new GltfGen.Material({
metallicFactor: 0,
baseColorTexture: new GltfGen.Texture({
source: new GltfGen.Image({
uri: `${this.baseUrl}/uv-grid.png` // alternate form (don't embed)
})
})
});
const gltfFactory = new GltfGen.GltfFactory(null, null, [material]);

await delay(3000);
return Server.registerStaticBuffer('assets.glb', gltfFactory.generateGLTF());
}

destroyActors([monkey, label]);
return true;
private fromHSV(h: number, s: number, v: number): MRESDK.Color4 {
// from wikipedia: https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
function f(n: number, k = (n + h * 6) % 6) {
return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
}
return new MRESDK.Color4(f(5), f(3), f(1), 1);
}
}
6 changes: 3 additions & 3 deletions packages/gltf-gen/src/geometry/sphere.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the MIT License.
*/

import { MeshPrimitive, Vertex } from '..';
import { Material, MeshPrimitive, Vertex } from '..';
import { Vector2, Vector3 } from '@microsoft/mixed-reality-extension-sdk';

/**
Expand All @@ -17,8 +17,8 @@ export class Sphere extends MeshPrimitive {
* @param longLines The number of polar vertex rings
* @param latLines The number of equatorial vertex rings (not counting poles)
*/
public constructor(radius: number, longLines = 12, latLines = 8) {
super();
public constructor(radius: number, longLines = 12, latLines = 8, material: Material = null) {
super({material});

// generate north pole
const north = new Vertex({
Expand Down
2 changes: 2 additions & 0 deletions packages/sdk/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

// tslint:disable:variable-name

export const ZeroGuid = '00000000-0000-0000-0000-000000000000';

/** @hidden */
export const HTTPHeaders = {
SessionID: 'x-ms-mixed-reality-extension-sessionid',
Expand Down
20 changes: 18 additions & 2 deletions packages/sdk/src/math/vector2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ import { Epsilon, Matrix, Scalar, Vector3 } from '.';

// tslint:disable:member-ordering variable-name one-variable-per-declaration trailing-comma no-bitwise curly max-line-length

export interface Vector2Like {
x: number;
y: number;
}

/**
* Class representing a vector containing 2 coordinates
*/
export class Vector2 {
export class Vector2 implements Vector2Like {
stevenvergenz marked this conversation as resolved.
Show resolved Hide resolved

// Statics

Expand Down Expand Up @@ -300,7 +305,7 @@ export class Vector2 {
return {
x: this.x,
y: this.y,
};
} as Vector2Like;
}

/**
Expand Down Expand Up @@ -656,4 +661,15 @@ export class Vector2 {
public clone(): Vector2 {
return new Vector2(this.x, this.y);
}

/**
* Updates the Vector2 from the sparsely populated value.
* @param from The sparsely populated value to read from.
*/
public copy(from: Partial<Vector2Like>): this {
if (!from) { return this; }
if (from.x !== undefined) { this.x = from.x; }
if (from.y !== undefined) { this.y = from.y; }
return this;
}
}
15 changes: 9 additions & 6 deletions packages/sdk/src/types/runtime/actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
PrimitiveDefinition,
SetAnimationStateOptions
} from '../..';
import { ZeroGuid } from '../../constants';
import { log } from '../../log';
import observe from '../../utils/observe';
import readPath from '../../utils/readPath';
Expand Down Expand Up @@ -82,10 +83,10 @@ export class Actor implements ActorLike, Patchable<ActorLike> {
private _rigidBody?: RigidBody;
private _collider?: Collider;
private _text?: Text;
private _materialId?: string;
private _materialId = ZeroGuid;
// tslint:enable:variable-name

/**
/*
* PUBLIC ACCESSORS
*/

Expand Down Expand Up @@ -113,17 +114,19 @@ export class Actor implements ActorLike, Patchable<ActorLike> {
this._parentId = value;
this.actorChanged('parentId');
}

/** @returns A shared reference to this actor's material, or null if this actor has no material */
public get material() { return this._context.assetManager.assets[this._materialId] as Material; }
public set material(value) {
this.materialId = value && value.id || null;
this.materialId = value && value.id || ZeroGuid;
}
public get materialId() { return this._materialId; }
public set materialId(value) {
if (value && value.startsWith('0000')) {
value = null;
if (!value || value.startsWith('0000')) {
value = ZeroGuid;
}
if (!this.context.assetManager.assets[value]) {
value = null; // throw?
value = ZeroGuid; // throw?
}
this._materialId = value;
this.actorChanged('materialId');
Expand Down
Loading