Nachfrage: Diese Nachfrage ist ein dringender Bedarf! In einer U-Bahn-Szene muss ein Fluchtweg mit einem Pfeil angezeigt werden, der den Weg anzeigt. Ich habe nicht weniger als ein Dutzend Stunden gebraucht, um diesen Pfeil zu zeichnen, und ich war schließlich fertig, aber es gab noch ein Problem. Meine Anforderung an diesen Pfeil ist, dass er, egal ob in der Szene hinein- oder herausgezoomt wird, weder zu groß noch zu klein sein darf, um deutlich erkannt zu werden, und dass sich seine Form nicht ändern darf, da er sonst nicht wie ein Pfeil aussieht. Verwendet Line2.js von three.js und eine Open-Source-Bibliothek MeshLine.js Teil des Codes: DrawPath.js: /** * Zeichne eine Route */ importiere * als DREI aus „../build/three.module.js“; importiere { MeshLine, MeshLineMaterial, MeshLineRaycast } aus '../js.my/MeshLine.js'; importiere { Line2 } aus '../js/lines/Line2.js'; importiere { LineMaterial } aus '../js/lines/LineMaterial.js'; importiere { LineGeometry } aus '../js/lines/LineGeometry.js'; importiere { GeometryUtils } aus '../js/utils/GeometryUtils.js'; importiere { CanvasDraw } von '../js.my/CanvasDraw.js'; importiere { Utils } von '../js.my/Utils.js'; importiere { Msg } von '../js.my/Msg.js'; let DrawPath = Funktion () { lass _self = dies; let _canvasDraw = neues CanvasDraw(); Utils(); let msg = neue Msg(); dies._isDrawing = falsch; dieser._Pfad = []; diese._zeilen = []; diese._arrows = []; Lassen Sie _depthTest = true; lass _side = 0; let viewerContainerId = '#cc'; let viewerContainer = $(viewerContainerId)[0]; Objekte lassen; lass die Kamera; lass dich wenden; lass Szene; this.config = Funktion (Objekte_, Kamera_, Szene_, Drehung_) { Objekte = Objekte_; Kamera = Kamera_; drehen = drehen_; Szene = Szene_; this._oldDistance = 1; this._oldCameraPos = { x: Kamera.position.x, y: Kamera.position.y, z: Kamera.position.z } } dies.start = Funktion () { wenn (!this._isDrawing) { dies._isDrawing = wahr; viewerContainer.addEventListener('klicken', ray); viewerContainer.addEventListener('Maus nach unten', Maus nach unten); viewerContainer.addEventListener('Maus hoch', Maus hoch); } msg.show("Bitte klicken Sie auf den Boden, um die Linie zu zeichnen"); } dies.stop = Funktion () { wenn (this._isDrawing) { dies._isDrawing = falsch; viewerContainer.removeEventListener('klicken', ray); viewerContainer.addEventListener('Maus nach unten', Maus nach unten); viewerContainer.addEventListener('Maus hoch', Maus hoch); } msg.show("Linienzeichnung beenden"); } Funktion mousedown(params) { this._mousedownPosition = { x: Kamera.position.x, y: Kamera.position.y, z: Kamera.position.z } } Funktion mouseup(Parameter) { this._mouseupPosition = { x: Kamera.position.x, y: Kamera.position.y, z: Kamera.position.z } } Funktion Strahl(e) { schalte.unFocusButton(); let raycaster = createRaycaster(e.clientX, e.clientY); lass intersects = raycaster.intersectObjects(Objekte.alle); wenn (Schnittpunkt.Länge > 0) { lass Punkt = schneidet[0].Punkt; lass Abstand = utils.abstand(diese._mousedownPosition.x, diese._mousedownPosition.y, diese._mousedownPosition.z, diese._mouseupPosition.x, diese._mouseupPosition.y, diese._mouseupPosition.z); wenn (Abstand < 5) { _self._path.push({ x: Punkt.x, y: Punkt.y + 50, z: Punkt.z }); wenn (_self._path.length > 1) { lass Punkt1 = _self._Pfad[_self._Pfad.Länge - 2]; lass Punkt2 = _self._path[_self._path.length - 1]; zeichneLinie(Punkt1, Punkt2); zeichnePfeil(Punkt1, Punkt2); } } } } Funktion erstelleRaycaster(ClientX, ClientY) { sei x = (ClientX / $(viewerContainerId).width()) * 2 - 1; sei y = -(clientY / $(viewerContainerId).height()) * 2 + 1; sei Standardvektor = neuer DREI.Vektor3(x, y, 0,5); lass worldVector = standardVector.unproject(Kamera); lass ray = worldVector.sub(camera.position).normalize(); lass raycaster = neu THREE.Raycaster(Kameraposition, Strahl); Raycaster zurückgeben; } dies.refresh = Funktion () { wenn (_self._path.length > 1) { lass Abstand = utils.abstand(diese._alteKameraPos.x, diese._alteKameraPos.y, diese._alteKameraPos.z, Kamera.position.x, Kamera.position.y, Kamera.position.z); sei das Verhältnis = 1; wenn (this._oldDistance != 0) { Verhältnis = Math.abs((this._oldDistance - Entfernung) / this._oldDistance) } wenn (Abstand > 5 && Verhältnis > 0,1) { console.log("======= DrawPath-Aktualisierung= ... für (lass i = 0; i < _self._path.length - 1; i++) { lass Pfeil = _self._arrows[i]; lass Punkt1 = _self._Pfad[i]; lass Punkt2 = _self._Pfad[i + 1]; Pfeil aktualisieren(Punkt1, Punkt2, Pfeil); } this._oldDistance = Entfernung; this._oldCameraPos = { x: Kamera.position.x, y: Kamera.position.y, z: Kamera.position.z } } } } Funktion zeichneLinie(Punkt1, Punkt2) { const Positionen = []; Positionen.Push(Punkt1.x / 50, Punkt1.y / 50, Punkt1.z / 50); Positionen.Push(Punkt2.x / 50, Punkt2.y / 50, Punkt2.z / 50); let geometrie = neue LineGeometry(); geometrie.setPositions(Positionen); let matLine = neues Linienmaterial({ Farbe: 0x009900, Linienbreite: 0,003, // in Welteinheiten mit Größendämpfung, andernfalls Pixel gestrichelt: wahr, Tiefentest: _Tiefentest, Seite: _Seite }); lass Linie = neue Linie2(Geometrie, matLine); line.computeLineDistances(); Linie.Skala.Satz(50, 50, 50); Szene.Hinzufügen(Zeile); _self._lines.push(Zeile); } Funktion zeichnePfeil(Punkt1, Punkt2) { let arrowLine = _self.createArrowLine(punkt1, punkt2); var meshLine = Pfeillinie.meshLine; let canvasTexture = _canvasDraw.drawArrow(DREI, Renderer, 300, 100); //Pfeil var Material = neues MeshLineMaterial({ useMap: wahr, Karte: CanvasTexture, Farbe: neue THREE.Color(0x00f300), Deckkraft: 1, Auflösung: neuer THREE.Vector2($(viewerContainerId).width(), $(viewerContainerId).height()), Linienbreite: Pfeillinie.Linienbreite, Tiefentest: _Tiefentest, Seite: _Seite, Wiederholung: new THREE.Vector2(1, 1), transparent: wahr, GrößeDämpfung: 1 }); var mesh = neues THREE.Mesh(meshLine.geometry, material); mesh.scale.set(50, 50, 50); Szene.Hinzufügen(Netz); _self._arrows.push(Netz); } Funktion RefreshArrow(Punkt1, Punkt2, Pfeil) { let arrowLine = _self.createArrowLine(punkt1, punkt2); var meshLine = Pfeillinie.meshLine; let canvasTexture = _canvasDraw.drawArrow(DREI, Renderer, 300, 100); //Pfeil var Material = neues MeshLineMaterial({ useMap: wahr, Karte: CanvasTexture, Farbe: neue THREE.Color(0x00f300), Deckkraft: 1, Auflösung: neuer THREE.Vector2($(viewerContainerId).width(), $(viewerContainerId).height()), Linienbreite: Pfeillinie.Linienbreite, Tiefentest: _Tiefentest, Seite: _Seite, Wiederholung: new THREE.Vector2(1, 1), transparent: wahr, GrößeDämpfung: 1 }); Pfeil.Geometrie = MeshLine.Geometrie; Pfeil.Material = Material; } this.createArrowLine = Funktion (Punkt1, Punkt2) { lass centerPoint = { x: (punkt1.x + punkt2.x) / 2, y: (punkt1.y + punkt2.y) / 2, z: (punkt1.z + punkt2.z) / 2 }; let Abstand = utils.Abstand(Punkt1.x, Punkt1.y, Punkt1.z, Punkt2.x, Punkt2.y, Punkt2.z); var startPos = { x: (Punkt1.x + Punkt2.x) / 2 / 50, y: (Punkt1.y + Punkt2.y) / 2 / 50, z: (Punkt1.z + Punkt2.z) / 2 / 50 } sei d = utils.distance(centerPoint.x, centerPoint.y, centerPoint.z, Kameraposition.x, Kameraposition.y, Kameraposition.z); wenn (d < 2000) d = 2000; wenn (d > 10000) d = 10000; sei Zeilenbreite = 100 * d / 4000; //Konsole.log("d=", d); sei sc = 0,035; var endPos = { x: startPos.x + (punkt2.x - punkt1.x) * sc * d / Abstand / 50, y: startPos.y + (punkt2.y - punkt1.y) * sc * d / Abstand / 50, z: startPos.z + (punkt2.z - punkt1.z) * sc * d / Abstand / 50 } var Pfeillinienpunkte = []; : arrowLinePoints.push(startPos.x, startPos.y, startPos.z); : arrowLinePoints.push(endPos.x, endPos.y, endPos.z); var meshLine = neue MeshLine(); meshLine.setGeometry(arrowLinePoints); return { meshLine: meshLine, Linienbreite: Linienbreite }; } this.setDepthTest = Funktion (bl) { wenn (bl) { _depthTest = wahr; this._lines.map(Zeile => { Linie.Material.TiefenTest = true; Linie.Material.Seite = 0; }); diese._arrows.map(arrow => { Pfeil.Material.TiefenTest = true; Pfeil.Material.Seite = 0; }); } anders { _depthTest = falsch; this._lines.map(Zeile => { Linie.Material.TiefenTest = falsch; Linie.Material.Seite = DREI.Doppelseite; }); diese._arrows.map(arrow => { Pfeil.Material.TiefenTest = falsch; Pfeil.Material.Seite = DREI.Doppelseite; }); } } /** * Stornieren */ dies.undo = Funktion () { Szene.entfernen(this._lines[this._lines.length - 1]); Szene.entfernen(this._arrows[this._arrows.length - 1]); _self._path.splice(this._path.length - 1, 1); _self._lines.splice(this._lines.length - 1, 1); _self._arrows.splice(this._arrows.length - 1, 1); } } DrawPath.prototype.constructor = Zeichenpfad; exportiere { DrawPath } Teil des Codes in show.js: lass drawPath; //Zeichnen Sie die Linie drawPath = new DrawPath(); drawPath.config( Objekte, Kamera, Szene, drehen ); $("#rightContainer").anzeigen(); $("#line-start").on("click", Funktion (Ereignis) { zeichnePath.start(); }); $("#line-stop").on("click", Funktion (Ereignis) { zeichnePath.stop(); }); $("#line-undo").on("click", Funktion (Ereignis) { drawPath.undo(); }); $("#line-show").on("click", Funktion (Ereignis) { zeichnePath.refresh(); }); lassen Sie Tiefentest = true; $("#line-depthTest").on("click", Funktion (Ereignis) { if (Tiefentest) { drawPath.setDepthTest(false); Tiefentest = falsch; } anders { drawPath.setDepthTest(true); Tiefentest = wahr; } }); setzeIntervall(() => { Zeichenpfad und Zeichenpfad.refresh(); }, 100); Effektbild: Es gibt noch einige Probleme: Obwohl die Szene vergrößert ist und der Pfeil in dieser Darstellung etwas groß ist, wird die maximale Größe immer noch kontrolliert. Es gibt nur ein Problem mit der Form, das möglicherweise ein Perspektivproblem ist. Der von mir erwartete Effekt sollte etwa dieser sein, d. h., egal aus welchem Blickwinkel man ihn betrachtet, der Pfeil sollte nicht verformt sein: Dies ist das Ende dieses Artikels über die Verwendung von three.js zum Zeichnen dreidimensionaler Pfeillinien, der mein halbes Leben in Anspruch genommen hat. Weitere verwandte Inhalte zu dreidimensionalen Pfeillinien mit three.js finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Erfahren Sie, wie Sie saubere und standardmäßige HTML-Tags schreiben
>>: Eine kurze Diskussion des interessanten Boxmodells der CSS3-Boxgrößeneigenschaft
Es gibt viele Gründe, warum eine Anwendung langsa...
Hier sind einige Beispiele, wie ich diese Eigensch...
Dieser Artikel stellt ein interessantes Pseudoele...
Inhaltsverzeichnis 1. Objektmethoden definieren 2...
In diesem Artikelbeispiel wird der spezifische Co...
getElementById kann das Objekt nicht abrufen Beim...
XMeter API bietet einen umfassenden Online-Schnit...
Das META-Tag ist ein Hilfstag im Kopfbereich der ...
Erneutes Mounten des Datenträgers nach dem Initia...
Wenn ich das Formular eingabeunfähig machen möchte...
Inhaltsverzeichnis 1. Einleitung 2. Umweltvorbere...
HTML <dl> Tag #Definition und Verwendung Da...
Beginnen Sie vorsichtig mit der Reinigung! Auflis...
Inhaltsverzeichnis 1. Welche Inhalte müssen üblic...
Vue-Komponenten sind verbunden, daher ist es unve...