Skip to content

Commit

Permalink
auto-scale tape pins, annotation types
Browse files Browse the repository at this point in the history
  • Loading branch information
framefactory committed May 4, 2019
1 parent b3d06f1 commit 7270e44
Show file tree
Hide file tree
Showing 12 changed files with 220 additions and 43 deletions.
2 changes: 1 addition & 1 deletion libs/ff-graph
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import AnnotationSprite, { Annotation, AnnotationElement } from "./AnnotationSpr

////////////////////////////////////////////////////////////////////////////////

export default class PinSprite extends AnnotationSprite
export default class BalloonSprite extends AnnotationSprite
{
protected pin: THREE.Mesh;

Expand Down Expand Up @@ -58,19 +58,19 @@ export default class PinSprite extends AnnotationSprite
return null; //super.renderHTMLElement(container, camera, this.pin);
}

updateHTMLElement(element: PinAnnotation)
updateHTMLElement(element: BalloonAnnotation)
{
//element.performUpdate();
}

protected createHTMLElement(): PinAnnotation
protected createHTMLElement(): BalloonAnnotation
{
return null; //new PinAnnotation(this);
}
}

@customElement("sv-pin-annotation")
class PinAnnotation extends AnnotationElement
@customElement("sv-balloon-annotation")
class BalloonAnnotation extends AnnotationElement
{
protected firstConnected()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import AnnotationSprite, { Annotation, AnnotationElement } from "./AnnotationSpr
const _quadrantClasses = [ "sv-q0", "sv-q1", "sv-q2", "sv-q3" ];


export default class BeamSprite extends AnnotationSprite
export default class ExtendedSprite extends AnnotationSprite
{
protected beam: THREE.Line;
protected quadrant = -1;
Expand Down Expand Up @@ -64,7 +64,7 @@ export default class BeamSprite extends AnnotationSprite

renderHTMLElement(container: HTMLElement, camera: THREE.Camera)
{
const element = super.renderHTMLElement(container, camera, this.beam) as BeamAnnotation;
const element = super.renderHTMLElement(container, camera, this.beam) as ExtendedAnnotation;

const angleOpacity = math.scaleLimit(this.viewAngle * math.RAD2DEG, 90, 100, 1, 0);
const opacity = angleOpacity * element.getOpacity();
Expand All @@ -84,21 +84,21 @@ export default class BeamSprite extends AnnotationSprite
return element;
}

updateHTMLElement(element: BeamAnnotation)
updateHTMLElement(element: ExtendedAnnotation)
{
element.performUpdate();
}

protected createHTMLElement(): BeamAnnotation
protected createHTMLElement(): ExtendedAnnotation
{
return new BeamAnnotation(this);
return new ExtendedAnnotation(this);
}
}

////////////////////////////////////////////////////////////////////////////////

@customElement("sv-beam-annotation")
class BeamAnnotation extends AnnotationElement
@customElement("sv-extended-annotation")
class ExtendedAnnotation extends AnnotationElement
{
protected titleElement: HTMLDivElement;
protected contentElement: HTMLDivElement;
Expand Down
136 changes: 136 additions & 0 deletions source/client/annotations/StandardSprite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* 3D Foundation Project
* Copyright 2019 Smithsonian Institution
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as THREE from "three";

import math from "@ff/core/math";

import { customElement, PropertyValues, html, render } from "@ff/ui/CustomElement";
import Button from "@ff/ui/Button";

import AnnotationSprite, { Annotation, AnnotationElement } from "./AnnotationSprite";

////////////////////////////////////////////////////////////////////////////////

const _quadrantClasses = [ "sv-q0", "sv-q1", "sv-q2", "sv-q3" ];


export default class StandardSprite extends AnnotationSprite
{
protected beam: THREE.Line;
protected quadrant = -1;

constructor(annotation: Annotation)
{
super(annotation);

const geo = new THREE.Geometry();
geo.vertices.push(new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, 1, 0));
const mat = new THREE.LineBasicMaterial({ color: "#009cde" });
mat.transparent = true;

this.beam = new THREE.Line(geo, mat);
this.beam.frustumCulled = false;
this.beam.matrixAutoUpdate = false;
this.add(this.beam);

this.update();
}

update()
{
const annotation = this.annotation.data;

this.beam.scale.setScalar(5 * annotation.scale);
this.beam.position.y = annotation.offset;
this.beam.updateMatrix();

super.update();
}

renderHTMLElement(container: HTMLElement, camera: THREE.Camera)
{
const element = super.renderHTMLElement(container, camera, this.beam) as StandardAnnotation;

const angleOpacity = math.scaleLimit(this.viewAngle * math.RAD2DEG, 90, 100, 1, 0);
const opacity = angleOpacity * element.getOpacity();

element.style.opacity = opacity.toString();
this.beam.material["opacity"] = opacity;

element.style.visibility = opacity ? "visible" : "hidden";

// update quadrant/orientation
if (this.orientationQuadrant !== this.quadrant) {
element.classList.remove(_quadrantClasses[this.quadrant]);
element.classList.add(_quadrantClasses[this.orientationQuadrant]);
this.quadrant = this.orientationQuadrant;
}

return element;
}

updateHTMLElement(element: StandardAnnotation)
{
element.performUpdate();
}

protected createHTMLElement(): StandardAnnotation
{
return new StandardAnnotation(this);
}
}

////////////////////////////////////////////////////////////////////////////////

@customElement("sv-standard-annotation")
class StandardAnnotation extends AnnotationElement
{
protected titleElement: HTMLDivElement;
protected currentOpacity = 0;
protected targetOpacity = 0;

constructor(sprite: AnnotationSprite)
{
super(sprite);

this.titleElement = this.appendElement("div");
this.titleElement.classList.add("sv-content", "sv-title");
}

getOpacity()
{
this.currentOpacity = this.targetOpacity;
return this.currentOpacity;
}

protected firstConnected()
{
super.firstConnected();
this.classList.add("sv-beam-annotation");
}

protected update(changedProperties: PropertyValues): void
{
super.update(changedProperties);

const annotation = this.sprite.annotation.data;

this.titleElement.innerText = annotation.title;
this.targetOpacity = annotation.visible ? 1 : 0;
}
}
28 changes: 17 additions & 11 deletions source/client/components/CVAnnotationView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@

import { Dictionary } from "@ff/core/types";

import { Node, ITypedEvent, types } from "@ff/graph/Component";
import { ITypedEvent, Node, types } from "@ff/graph/Component";

import Viewport, { IViewportDisposeEvent } from "@ff/three/Viewport";
import HTMLSpriteGroup, { HTMLSprite } from "@ff/three/HTMLSpriteGroup";

import CObject3D, { IPointerEvent, IRenderContext } from "@ff/scene/components/CObject3D";

import CVModel2 from "./CVModel2";
import CVMeta from "./CVMeta";
import CVReader from "./CVReader";

import { IAnnotation } from "client/schema/model";
import Annotation, { EAnnotationStyle } from "../models/Annotation";

import AnnotationSprite, { IAnnotationClickEvent, IAnnotationLinkEvent } from "../annotations/AnnotationSprite";

import PinSprite from "../annotations/PinSprite";
import BeamSprite from "../annotations/BeamSprite";
import CVMeta from "./CVMeta";
import CVReader from "./CVReader";
import StandardSprite from "../annotations/StandardSprite";
import ExtendedSprite from "../annotations/ExtendedSprite";
import BalloonSprite from "../annotations/BalloonSprite";

////////////////////////////////////////////////////////////////////////////////

Expand All @@ -49,7 +49,7 @@ const _inputs = {
unitScale: types.Number("Transform.UnitScale", { preset: 1, precision: 5 }),
title: types.String("Annotation.Title"),
lead: types.String("Annotation.Lead"),
style: types.Enum("Annotation.Style", EAnnotationStyle, EAnnotationStyle.Default),
style: types.Enum("Annotation.Style", EAnnotationStyle, EAnnotationStyle.Standard),
scale: types.Scale("Annotation.Scale", 1),
offset: types.Number("Annotation.Offset"),
article: types.Option("Annotation.Article", []),
Expand Down Expand Up @@ -106,7 +106,7 @@ export default class CVAnnotationView extends CObject3D
const ins = this.ins;
ins.title.setValue(annotation ? annotation.data.title : "", true);
ins.lead.setValue(annotation ? annotation.data.lead : "", true);
ins.style.setValue(annotation ? annotation.data.style : EAnnotationStyle.Default, true);
ins.style.setValue(annotation ? annotation.data.style : EAnnotationStyle.Standard, true);
ins.scale.setValue(annotation ? annotation.data.scale : 1, true);
ins.offset.setValue(annotation ? annotation.data.offset : 0, true);
ins.tilt.setValue(annotation ? annotation.data.tilt : 0, true);
Expand Down Expand Up @@ -349,12 +349,18 @@ export default class CVAnnotationView extends CObject3D

let sprite;
switch(annotation.data.style) {
case EAnnotationStyle.Pin:
sprite = new BalloonSprite(annotation);
break;
case EAnnotationStyle.Balloon:
sprite = new PinSprite(annotation);
sprite = new BalloonSprite(annotation);
break;
case EAnnotationStyle.Extended:
sprite = new ExtendedSprite(annotation);
break;
case EAnnotationStyle.Line:
case EAnnotationStyle.Standard:
default:
sprite = new BeamSprite(annotation);
sprite = new StandardSprite(annotation);
break;
}

Expand Down
3 changes: 2 additions & 1 deletion source/client/components/CVGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export default class CVGrid extends CObject3D
get grid() {
return this.object3D as ThreeGrid;
}
get rootScene() {

protected get rootScene() {
return this.getGraphComponent(CVScene);
}

Expand Down
2 changes: 2 additions & 0 deletions source/client/components/CVOrbitNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ export default class CVOrbitNavigation extends CVNavigation
get settingProperties() {
return [
this.ins.enabled,
this.ins.orbit,
this.ins.offset,
this.ins.autoZoom,
this.ins.autoRotation,
this.ins.lightsFollowCamera,
Expand Down
9 changes: 7 additions & 2 deletions source/client/components/CVScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import * as THREE from "three";

import { IComponentEvent, types } from "@ff/graph/Component";
import { IComponentEvent, ITypedEvent, types } from "@ff/graph/Component";

import { EUnitType, TUnitType } from "client/schema/common";
import { IDocument, IScene } from "client/schema/document";
Expand All @@ -27,6 +27,11 @@ import CVModel2 from "./CVModel2";

////////////////////////////////////////////////////////////////////////////////

export interface IBoundingBoxEvent extends ITypedEvent<"bounding-box">
{
boundingBox: THREE.Box3;
}

/**
* Manages the scene and the nodes in the scene tree.
*
Expand Down Expand Up @@ -119,6 +124,6 @@ export default class CVScene extends CVNode
box.makeEmpty();

this.models.forEach(model => box.expandByObject(model.object3D));
this.emit("bounding-box");
this.emit<IBoundingBoxEvent>({ type: "bounding-box", boundingBox: box });
}
}
Loading

0 comments on commit 7270e44

Please sign in to comment.