Skip to content

Commit

Permalink
Fix/1716/labels not connected with lines (#1948)
Browse files Browse the repository at this point in the history
* Fix issue, update line position according to view angle #1716

* Refactoring

* Update tests for new label-line behaviour #1716

* Add tests, Remove dead code, Some refactoring #1716

* Update Changelog

* Run prettier

* Fix bug

* Fix line interaction #1716

* Apply Changes request

* Apply REview Suggestions #1716
  • Loading branch information
RomanenkoVladimir committed Apr 27, 2021
1 parent 0325fdb commit d1fa1c8
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/)

## [unreleased] (Added 🚀 | Changed | Removed 🗑 | Fixed 🐞 | Chore 👨‍💻 👩‍💻)

### Fixed 🐞

- Fix labels and lines missing a connection in some cases([#1716](https://github.com/MaibornWolff/codecharta/issues/1716))

## [1.72.0] - 2021-04-22

### Added 🚀
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,15 @@ describe("CodeMapLabelService", () => {
codeMapLabelService.addLabel(otherSampleLeaf, { showNodeName: true, showNodeMetric: false })
threeSceneService.labels.children = generateSceneLabelChild(4)

threeSceneService["highlightedLineIndex"] = 5
threeSceneService["highlightedLine"] = new Object3D()
codeMapLabelService.clearTemporaryLabel(sampleLeaf)

expect(codeMapLabelService.dispose).toBeCalledWith(threeSceneService.labels.children)
expect(threeSceneService.labels.children.length).toEqual(2)
expect(codeMapLabelService["labels"][0].node).toEqual(otherSampleLeaf)
expect(threeSceneService["highlightedLineIndex"]).toEqual(-1)
expect(threeSceneService["highlightedLine"]).toEqual(null)
})

it("should not clear if no label exists for a given node", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export class CodeMapLabelService implements CameraChangeSubscriber {
this.labels.splice(index, 1)
this.dispose(this.threeSceneService.labels.children)
this.threeSceneService.labels.children.length -= 2
this.threeSceneService.resetLineHighlight()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { setIdToNode } from "../../state/store/lookUp/idToNode/idToNode.actions"
import { klona } from "klona"
import { CodeMapLabelService } from "./codeMap.label.service"
import { CodeMapMesh } from "./rendering/codeMapMesh"
import { Material, Object3D, Raycaster, Vector3 } from "three"
import { Geometry, Material, Object3D, Raycaster, Vector3 } from "three"
import { CodeMapPreRenderService } from "./codeMap.preRender.service"
import { LazyLoader } from "../../util/lazyLoader"

Expand Down Expand Up @@ -352,15 +352,19 @@ describe("codeMapMouseEventService", () => {
const resultPosition = new Vector3(0.5, 0.5, 0)

const labels = []
const labelLine = new Object3D()
const placeholderLine = new Object3D()
const labelNode = new Object3D()
label["material"] = new Material()
const rayCaster = new Raycaster(new Vector3(10, 10, 0), new Vector3(1, 1, 1))

labelNode.translateX(-4)
labelNode.translateY(5)

labels.push(label, labelLine, labelNode, labelLine)
const lineGeometry = new Geometry()
lineGeometry.vertices.push(new Vector3(2, 2, 2), new Vector3(1, 1, 1))
placeholderLine["geometry"] = lineGeometry

labels.push(label, placeholderLine, labelNode, placeholderLine)

threeSceneService.animateLabel(label, rayCaster, labels)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ export class CodeMapMouseEventService

updateHovering() {
if (this.hasMouseMoved(this.oldMouse)) {
const labels = this.threeSceneService.labels?.children

if (this.isGrabbing || this.isMoving) {
this.threeSceneService.resetLabel()
this.clearTemporaryLabel()
Expand All @@ -187,7 +189,6 @@ export class CodeMapMouseEventService

const mouseCoordinates = this.transformHTMLToSceneCoordinates()
const camera = this.threeCameraService.camera
const labels = this.threeSceneService.labels?.children

const mapMesh = this.threeSceneService.getMapMesh()
let nodeNameHoveredLabel = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { CodeMapNode } from "../../../codeCharta.model"
import { setIdToBuilding } from "../../../state/store/lookUp/idToBuilding/idToBuilding.actions"
import { setIdToNode } from "../../../state/store/lookUp/idToNode/idToNode.actions"
import { setScaling } from "../../../state/store/appSettings/scaling/scaling.actions"
import { Box3, Matrix4, Object3D, Raycaster, Vector3 } from "three"
import { Box3, Geometry, Group, Material, Matrix4, Object3D, Raycaster, Vector3 } from "three"

describe("ThreeSceneService", () => {
let threeSceneService: ThreeSceneService
Expand Down Expand Up @@ -260,25 +260,30 @@ describe("ThreeSceneService", () => {

describe("animateLabel", () => {
let labels = null
let labelLine = null
let otherNode = null
let label = null
let rayCaster = null
let placeholderLine = null
let lineGeometry = null

beforeEach(() => {
labels = []
labelLine = new Object3D()
otherNode = new Object3D()
label = new Object3D()
placeholderLine = new Object3D()
lineGeometry = new Geometry()

rayCaster = new Raycaster(new Vector3(10, 10, 0), new Vector3(1, 1, 1))
lineGeometry.vertices.push(new Vector3(2, 2, 2), new Vector3(1, 1, 1))
placeholderLine["geometry"] = lineGeometry
})

it("should animate the label by moving it 20% on the viewRay if it has no intersection", () => {
otherNode.translateX(-4)
otherNode.translateY(5)
const resultPosition = new Vector3(0.5, 0.5, 0)

labels.push(label, labelLine, otherNode, labelLine)
labels.push(label, placeholderLine, otherNode, placeholderLine)

threeSceneService.animateLabel(label, rayCaster, labels)
expect(threeSceneService["highlightedLabel"]).toEqual(label)
Expand All @@ -290,7 +295,7 @@ describe("ThreeSceneService", () => {

const resultPosition = new Vector3(0.5, 0.5, 0)

labels.push(label, labelLine, otherNode, labelLine)
labels.push(label, placeholderLine, otherNode, placeholderLine)

threeSceneService.animateLabel(label, rayCaster, labels)
expect(threeSceneService["highlightedLabel"]).toEqual(label)
Expand All @@ -303,14 +308,91 @@ describe("ThreeSceneService", () => {
unObstructingNode.applyMatrix4(new Matrix4().makeTranslation(0.5, 0.5, 0))

label.userData = CODE_MAP_BUILDING
labels.push(label, labelLine, otherNode, labelLine, unObstructingNode, labelLine)
labels.push(label, placeholderLine, otherNode, placeholderLine, unObstructingNode, placeholderLine)

threeSceneService.animateLabel(label, rayCaster, labels)
expect(threeSceneService["highlightedLabel"]).toEqual(label)
expect(label.position).toEqual(unObstructingNode.position)
})
})

describe("resetLineHighlight", () => {
it("should reset line highlighting", () => {
threeSceneService["highlightedLineIndex"] = 5
threeSceneService["highlightedLine"] = new Object3D()

threeSceneService.resetLineHighlight()

expect(threeSceneService["highlightedLineIndex"]).toEqual(-1)
expect(threeSceneService["highlightedLine"]).toEqual(null)
})
})

describe("getHoveredLabelLineIndex", () => {
it("should return index+1 if found", () => {
const labels = []
const label1 = new Object3D()
const label2 = new Object3D()
const label3 = new Object3D()
labels.push(label1, label2, label3)

const indexIncrement = threeSceneService.getHoveredLabelLineIndex(labels, label2)

expect(indexIncrement).toEqual(2)
})
})

describe("toggleLineAnimation", () => {
let highlightedLabel = null
let hoveredLabel = null
let highlightedLine = null
let lineGeometry = null
let labels = null
let labelsGroup = null

beforeEach(() => {
highlightedLine = new Object3D()
lineGeometry = new Geometry()
lineGeometry.vertices.push(new Vector3(3, 3, 3), new Vector3(3, 3, 3))
highlightedLine["geometry"] = lineGeometry
highlightedLine.material = new Material()

labels = []
labels.push(new Object3D(), new Object3D(), new Object3D())

labelsGroup = new Group()
labelsGroup.children = labels
threeSceneService.labels = labelsGroup

hoveredLabel = new Object3D()
hoveredLabel.position.set(2, 2, 2)

highlightedLabel = new Object3D()
highlightedLabel.position.set(1, 1, 1)
highlightedLabel.material = new Material()

threeSceneService["highlightedLineIndex"] = 1
threeSceneService["highlightedLabel"] = highlightedLabel
threeSceneService["highlightedLine"] = highlightedLine
threeSceneService["normedTransformVector"] = new Vector3(0, 0, 0)
})

it("should set endpoint to given hoveredLabel coordinates if not in reset mode", () => {
threeSceneService.toggleLineAnimation(hoveredLabel)

expect(threeSceneService.labels.children[1]["geometry"].vertices[0]).toEqual(new Vector3(3, 3, 3))
expect(threeSceneService.labels.children[1]["geometry"].vertices[1]).toEqual(new Vector3(2, 2, 2))
})

it("should set endpoint to highlightedLabel if in reset mode", () => {
threeSceneService.resetLabel()

expect(threeSceneService.labels.children[1]["geometry"].vertices[0]).toEqual(new Vector3(3, 3, 3))
expect(threeSceneService.labels.children[1]["geometry"].vertices[1]).toEqual(new Vector3(1, 1, 1))
expect(threeSceneService["highlightedLabel"]).toEqual(null)
})
})

describe("scaleHeight", () => {
it("should update mapGeometry scaling to new vector", () => {
const scaling = new Vector3(1, 2, 3)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AmbientLight, DirectionalLight, Scene, Group, Material, Raycaster, Vector3, Object3D, Box3 } from "three"
import { AmbientLight, DirectionalLight, Scene, Group, Material, Raycaster, Vector3, Object3D, Box3, Line, Geometry } from "three"
import { CodeMapMesh } from "../rendering/codeMapMesh"
import { CodeMapBuilding } from "../rendering/codeMapBuilding"
import { CodeMapPreRenderServiceSubscriber, CodeMapPreRenderService } from "../codeMap.preRender.service"
Expand Down Expand Up @@ -44,6 +44,8 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
private rayPoint = new Vector3(0, 0, 0)
private normedTransformVector = new Vector3(0, 0, 0)
private highlightedLabel = null
private highlightedLineIndex = -1
private highlightedLine = null
private mapLabelColors = this.storeService.getState().appSettings.mapColors.labelColorAndAlpha

constructor(private $rootScope: IRootScopeService, private storeService: StoreService) {
Expand Down Expand Up @@ -85,12 +87,6 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
}
}

highlightBuildingsAfterSelect() {
// TODO dead code? Remove it please.
const state = this.storeService.getState()
this.getMapMesh().highlightBuilding(this.highlighted, this.selected, state, this.constantHighlight)
}

private selectMaterial(materials: Material[]) {
const selectedMaterial = materials.find(({ userData }) => userData.id === this.selected.node.id)
selectedMaterial?.["color"].setHex(this.numberSelectionColor)
Expand Down Expand Up @@ -179,6 +175,9 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map
hoveredLabel["material"].opacity = 1
}

this.highlightedLineIndex = this.getHoveredLabelLineIndex(labels, hoveredLabel)
this.highlightedLine = labels[this.highlightedLineIndex]

this.rayPoint = new Vector3()
this.rayPoint.subVectors(raycaster.ray.origin, hoveredLabel.position)

Expand All @@ -191,18 +190,49 @@ export class ThreeSceneService implements CodeMapPreRenderServiceSubscriber, Map

hoveredLabel.position.add(this.normedTransformVector)

this.toggleLineAnimation(hoveredLabel)

this.highlightedLabel = hoveredLabel
}
}

resetLineHighlight() {
this.highlightedLineIndex = -1
this.highlightedLine = null
}

resetLabel() {
if (this.highlightedLabel !== null) {
this.highlightedLabel.position.sub(this.normedTransformVector)
this.highlightedLabel.material.opacity = this.mapLabelColors.alpha

if (this.highlightedLine) {
this.toggleLineAnimation(this.highlightedLabel)
}

this.highlightedLabel = null
}
}

getHoveredLabelLineIndex(labels: Object3D[], label: Object3D) {
const index = labels.findIndex(({ uuid }) => uuid === label.uuid)

if (index >= 0) {
return index + 1
}
}

toggleLineAnimation(hoveredLabel: Object3D) {
const geometry = new Geometry()
const endPoint = new Vector3(hoveredLabel.position.x, hoveredLabel.position.y, hoveredLabel.position.z)

geometry.vertices.push(this.highlightedLine.geometry.vertices[0], endPoint)

const newLineForHighlightedLabel = new Line(geometry, this.highlightedLine.material)

this.labels.children.splice(this.highlightedLineIndex, 1, newLineForHighlightedLabel)
}

getLabelForHoveredNode(hoveredBuilding: CodeMapBuilding, labels: Object3D[]) {
if (labels == null) {
return null
Expand Down

0 comments on commit d1fa1c8

Please sign in to comment.