use of au.gov.asd.tac.constellation.utilities.graphics.Vector3f in project constellation by constellation-app.
the class FreeformSelectionPlugin method edit.
@Override
public void edit(final GraphWriteMethods graph, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException {
final float mix = camera.getMix();
final float inverseMix = 1.0F - mix;
final Vector3f centre = new Vector3f(camera.lookAtCentre);
final float left = box[0];
final float right = box[1];
final float top = box[2];
final float bottom = box[3];
// Look up all the required attributes.
int xAttr = VisualConcept.VertexAttribute.X.get(graph);
int yAttr = VisualConcept.VertexAttribute.Y.get(graph);
int zAttr = VisualConcept.VertexAttribute.Z.get(graph);
final int x2Attr = VisualConcept.VertexAttribute.X2.get(graph);
final int y2Attr = VisualConcept.VertexAttribute.Y2.get(graph);
final int z2Attr = VisualConcept.VertexAttribute.Z2.get(graph);
final int vxSelectedAttr = VisualConcept.VertexAttribute.SELECTED.get(graph);
final int txSelectedAttr = VisualConcept.TransactionAttribute.SELECTED.get(graph);
final int vxVisibilityAttr = VisualConcept.VertexAttribute.VISIBILITY.get(graph);
final int txVisibilityAttr = VisualConcept.TransactionAttribute.VISIBILITY.get(graph);
final SetBooleanValuesOperation selectVerticesOperation = new SetBooleanValuesOperation(graph, GraphElementType.VERTEX, vxSelectedAttr);
final SetBooleanValuesOperation selectTransactionsOperation = new SetBooleanValuesOperation(graph, GraphElementType.TRANSACTION, txSelectedAttr);
final float visibilityHigh = camera.getVisibilityHigh();
final float visibilityLow = camera.getVisibilityLow();
// Get a copy of the current rotation matrix.
final Vector3f diff = Vector3f.subtract(camera.lookAtEye, camera.lookAtCentre);
final float cameraDistance = diff.getLength();
// Get the inverse eye rotation to match the object frame rotation.
final Frame frame = new Frame(camera.lookAtEye, camera.lookAtCentre, camera.lookAtUp);
final Matrix44f objectFrameMatrix = new Matrix44f();
frame.getMatrix(objectFrameMatrix, true);
final Matrix44f rotationMatrixt = new Matrix44f();
objectFrameMatrix.getRotationMatrix(rotationMatrixt);
final Matrix44f rotationMatrixti = new Matrix44f();
rotationMatrixti.invert(rotationMatrixt);
final Matrix33f rotationMatrix = new Matrix33f();
rotationMatrixti.getRotationMatrix(rotationMatrix);
// Do the vertex positions need mixing?
boolean requiresMix = x2Attr != Graph.NOT_FOUND && y2Attr != Graph.NOT_FOUND && z2Attr != Graph.NOT_FOUND;
final boolean requiresVertexVisibility = vxVisibilityAttr != Graph.NOT_FOUND;
final boolean requiresTransactionVisibility = txVisibilityAttr != Graph.NOT_FOUND;
// If the mix value is either 0 or 1 then no mixing is required
if (requiresMix && mix == 0.0F) {
requiresMix = false;
} else if (requiresMix && mix == 1.0F) {
xAttr = x2Attr;
yAttr = y2Attr;
zAttr = z2Attr;
requiresMix = false;
} else {
// Do nothing
}
final BitSet vxIncluded = new BitSet();
final int vxCount = graph.getVertexCount();
// Select the correct vertices.
for (int position = 0; position != vxCount; position++) {
final int vxId = graph.getVertex(position);
if (requiresVertexVisibility) {
final float visibility = graph.getFloatValue(vxVisibilityAttr, vxId);
if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
continue;
}
}
// Get the main location of the vertex.
float x = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxId) : VisualGraphDefaults.getDefaultX(vxId);
float y = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxId) : VisualGraphDefaults.getDefaultY(vxId);
float z = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxId) : VisualGraphDefaults.getDefaultZ(vxId);
// If mixing is required then mix the main location with the alternative location.
boolean mixed = false;
if (requiresMix) {
x = inverseMix * x + mix * graph.getFloatValue(x2Attr, vxId);
y = inverseMix * y + mix * graph.getFloatValue(y2Attr, vxId);
z = inverseMix * z + mix * graph.getFloatValue(z2Attr, vxId);
mixed = true;
}
// Convert world coordinates to camera coordinates.
final Vector3f sceneLocation = convertWorldToScene(x, y, z, centre, rotationMatrix, cameraDistance);
final int rAttr = VisualConcept.VertexAttribute.NODE_RADIUS.get(graph);
final float r = graph.getFloatValue(rAttr, vxId);
if (sceneLocation.getZ() < 0) {
final float leftMostPoint = (sceneLocation.getX() - r) / -sceneLocation.getZ();
final float rightMostPoint = (sceneLocation.getX() + r) / -sceneLocation.getZ();
final float bottomMostPoint = (sceneLocation.getY() - r) / -sceneLocation.getZ();
final float topMostPoint = (sceneLocation.getY() + r) / -sceneLocation.getZ();
final boolean vertexLeftOfFreeform = rightMostPoint < left;
final boolean vertexRightOfFreeform = right < leftMostPoint;
final boolean vertexBelowFreeform = topMostPoint < bottom;
final boolean vertexAboveFreeform = top < bottomMostPoint;
if (!vertexLeftOfFreeform && !vertexRightOfFreeform && !vertexBelowFreeform && !vertexAboveFreeform && inFreeformPolygons(leftMostPoint, topMostPoint)) {
vxIncluded.set(vxId);
}
}
}
final BitSet txIncluded = new BitSet();
if (vxIncluded.isEmpty()) {
final int linkCount = graph.getLinkCount();
for (int position = 0; position < linkCount; position++) {
final int linkId = graph.getLink(position);
final int vxLo = graph.getLinkLowVertex(linkId);
final int vxHi = graph.getLinkHighVertex(linkId);
// Get the main location of the lo vertex.
float xLo = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxLo) : VisualGraphDefaults.getDefaultX(vxLo);
float yLo = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxLo) : VisualGraphDefaults.getDefaultY(vxLo);
float zLo = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxLo) : VisualGraphDefaults.getDefaultZ(vxLo);
// Get the main location of the lo vertex.
float xHi = xAttr != Graph.NOT_FOUND ? graph.getFloatValue(xAttr, vxHi) : VisualGraphDefaults.getDefaultX(vxHi);
float yHi = yAttr != Graph.NOT_FOUND ? graph.getFloatValue(yAttr, vxHi) : VisualGraphDefaults.getDefaultY(vxHi);
float zHi = zAttr != Graph.NOT_FOUND ? graph.getFloatValue(zAttr, vxHi) : VisualGraphDefaults.getDefaultZ(vxHi);
if (requiresMix) {
xLo = inverseMix * xLo + mix * graph.getFloatValue(x2Attr, vxLo);
yLo = inverseMix * yLo + mix * graph.getFloatValue(y2Attr, vxLo);
zLo = inverseMix * zLo + mix * graph.getFloatValue(z2Attr, vxLo);
xHi = inverseMix * xHi + mix * graph.getFloatValue(x2Attr, vxHi);
yHi = inverseMix * yHi + mix * graph.getFloatValue(y2Attr, vxHi);
zHi = inverseMix * zHi + mix * graph.getFloatValue(z2Attr, vxHi);
}
// Convert world coordinates to camera coordinates.
final Vector3f worldLocationLo = new Vector3f(xLo, yLo, zLo);
worldLocationLo.subtract(centre);
final Vector3f lo = new Vector3f();
lo.rotate(worldLocationLo, rotationMatrix);
lo.setZ(lo.getZ() - cameraDistance);
final Vector3f worldLocationHi = new Vector3f(xHi, yHi, zHi);
worldLocationHi.subtract(centre);
final Vector3f hi = new Vector3f();
hi.rotate(worldLocationHi, rotationMatrix);
hi.setZ(hi.getZ() - cameraDistance);
// If at least one of the end-points is in front of the eye...
if (lo.getZ() < 0 || hi.getZ() < 0) {
final float horizontalOffsetLo;
final float horizontalOffsetHi;
final float verticalOffsetLo;
final float verticalOffsetHi;
if (lo.getZ() < 0) {
final float loz = -Math.abs(lo.getZ());
horizontalOffsetLo = lo.getX() / -loz;
verticalOffsetLo = lo.getY() / -loz;
} else if (lo.getZ() > 0) {
horizontalOffsetLo = lo.getX() + (lo.getZ() * (hi.getX() - lo.getX())) / (lo.getZ() - hi.getZ());
verticalOffsetLo = lo.getY() + (lo.getZ() * (hi.getY() - lo.getY()) / (lo.getZ() - hi.getZ()));
} else {
horizontalOffsetLo = lo.getX();
verticalOffsetLo = lo.getY();
}
if (hi.getZ() < 0) {
final float hiz = -Math.abs(hi.getZ());
horizontalOffsetHi = hi.getX() / -hiz;
verticalOffsetHi = hi.getY() / -hiz;
} else if (hi.getZ() > 0) {
horizontalOffsetHi = lo.getX() + (lo.getZ() * (hi.getX() - lo.getX())) / (lo.getZ() - hi.getZ());
verticalOffsetHi = lo.getY() + (lo.getZ() * (hi.getY() - lo.getY()) / (lo.getZ() - hi.getZ()));
} else {
horizontalOffsetHi = hi.getX();
verticalOffsetHi = hi.getY();
}
final boolean intersects = lineSegmentIntersectsRectangle(horizontalOffsetLo, verticalOffsetLo, horizontalOffsetHi, verticalOffsetHi, left, bottom, right, top);
if (intersects) {
final int linkTxCount = graph.getLinkTransactionCount(linkId);
for (int linkPos = 0; linkPos < linkTxCount; linkPos++) {
final int txId = graph.getLinkTransaction(linkId, linkPos);
txIncluded.set(txId);
}
}
}
}
}
final int txCount = graph.getTransactionCount();
if (txIncluded.isEmpty()) {
if (isAdd) {
if (vxSelectedAttr != Graph.NOT_FOUND) {
for (int vxId = vxIncluded.nextSetBit(0); vxId >= 0; vxId = vxIncluded.nextSetBit(vxId + 1)) {
if (!graph.getBooleanValue(vxSelectedAttr, vxId)) {
selectVerticesOperation.setValue(vxId, true);
}
}
}
if (txSelectedAttr != Graph.NOT_FOUND) {
for (int position = 0; position < txCount; position++) {
final int txId = graph.getTransaction(position);
if (vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId)) && !graph.getBooleanValue(txSelectedAttr, txId)) {
if (requiresTransactionVisibility) {
final float visibility = graph.getFloatValue(txVisibilityAttr, txId);
if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
continue;
}
}
selectTransactionsOperation.setValue(txId, true);
}
}
}
} else if (isToggle) {
if (vxSelectedAttr != Graph.NOT_FOUND) {
for (int vertex = vxIncluded.nextSetBit(0); vertex >= 0; vertex = vxIncluded.nextSetBit(vertex + 1)) {
selectVerticesOperation.setValue(vertex, !graph.getBooleanValue(vxSelectedAttr, vertex));
}
}
if (txSelectedAttr != Graph.NOT_FOUND) {
for (int position = 0; position < txCount; position++) {
final int txId = graph.getTransaction(position);
if (vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId))) {
if (requiresTransactionVisibility) {
final float visibility = graph.getFloatValue(txVisibilityAttr, txId);
if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
continue;
}
}
selectTransactionsOperation.setValue(txId, !graph.getBooleanValue(txSelectedAttr, txId));
}
}
}
} else {
if (vxSelectedAttr != Graph.NOT_FOUND) {
for (int position = 0; position < vxCount; position++) {
final int vxId = graph.getVertex(position);
final boolean included = vxIncluded.get(vxId);
if (included != graph.getBooleanValue(vxSelectedAttr, vxId)) {
selectVerticesOperation.setValue(vxId, included);
}
}
}
if (txSelectedAttr != Graph.NOT_FOUND) {
for (int position = 0; position < txCount; position++) {
final int txId = graph.getTransaction(position);
boolean included = vxIncluded.get(graph.getTransactionSourceVertex(txId)) && vxIncluded.get(graph.getTransactionDestinationVertex(txId));
if (requiresTransactionVisibility) {
final float visibility = graph.getFloatValue(txVisibilityAttr, txId);
if (visibility <= 1.0F && (visibility > visibilityHigh || visibility < visibilityLow)) {
included = false;
}
}
if (included != graph.getBooleanValue(txSelectedAttr, txId)) {
selectTransactionsOperation.setValue(txId, included);
}
}
}
}
} else {
if (isAdd) {
if (txSelectedAttr != Graph.NOT_FOUND) {
for (int txId = txIncluded.nextSetBit(0); txId >= 0; txId = txIncluded.nextSetBit(txId + 1)) {
if (!graph.getBooleanValue(txSelectedAttr, txId)) {
selectTransactionsOperation.setValue(txId, true);
}
}
}
} else if (isToggle) {
if (txSelectedAttr != Graph.NOT_FOUND) {
for (int txId = txIncluded.nextSetBit(0); txId >= 0; txId = txIncluded.nextSetBit(txId + 1)) {
selectTransactionsOperation.setValue(txId, !graph.getBooleanValue(txSelectedAttr, txId));
}
}
} else {
if (txSelectedAttr != Graph.NOT_FOUND) {
for (int position = 0; position < txCount; position++) {
final int txId = graph.getTransaction(position);
final boolean included = txIncluded.get(txId);
if (included != graph.getBooleanValue(txSelectedAttr, txId)) {
selectTransactionsOperation.setValue(txId, included);
}
}
}
// Deselect any selected vertices.
if (vxSelectedAttr != Graph.NOT_FOUND) {
for (int position = 0; position < vxCount; position++) {
final int vxId = graph.getVertex(position);
final boolean selected = graph.getBooleanValue(vxSelectedAttr, vxId);
if (selected) {
selectVerticesOperation.setValue(vxId, false);
}
}
}
}
}
graph.executeGraphOperation(selectVerticesOperation);
graph.executeGraphOperation(selectTransactionsOperation);
}
use of au.gov.asd.tac.constellation.utilities.graphics.Vector3f in project constellation by constellation-app.
the class DefaultInteractionEventHandler method scheduleNewLineChangeOperation.
/**
* Schedule a {@link VisualOperation} to change the new line model, along
* with the camera if necessary, using an alternate EventState for current
* hit testing information.
*
* @param rg Read access to the graph, corresponding to the lock on which
* gestures are currently being processed.
* @param endPoint The updated end point for the new line
* @param camera The camera (which may or may not be updated) that this
* newline corresponds to
* @param cameraChange Whether or not to also schedule a camera change
* operation.
* @param newLineHitTestState The EventState giving the most recent
* information about hit testing with relation to the new line.
*/
private void scheduleNewLineChangeOperation(final GraphReadMethods rg, final Point endPoint, final Camera camera, final boolean cameraChange, final EventState newLineHitTestState) {
final NewLineModel updatedModel;
final Vector3f startPoint = VisualGraphUtilities.getVertexCoordinates(rg, eventState.getAddTransactionSourceVertex());
if (newLineHitTestState.getCurrentHitType().equals(HitType.VERTEX)) {
final int vertexId = newLineHitTestState.getCurrentHitId();
updatedModel = new NewLineModel(startPoint, VisualGraphUtilities.getVertexCoordinates(rg, vertexId), camera);
} else {
updatedModel = new NewLineModel(startPoint, endPoint == null ? startPoint : visualInteraction.windowToGraphCoordinates(VisualGraphUtilities.getCamera(rg), endPoint), camera);
}
final VisualOperation updateNewLineOperation = visualAnnotator.setNewLineModel(updatedModel);
if (cameraChange) {
scheduleCameraChangeOperation(updateNewLineOperation);
} else {
manager.addOperation(updateNewLineOperation);
}
}
use of au.gov.asd.tac.constellation.utilities.graphics.Vector3f in project constellation by constellation-app.
the class DefaultInteractionEventHandler method mouseWheelMoved.
@Override
public void mouseWheelMoved(final MouseWheelEvent event) {
queue.add(wg -> {
if (wg != null) {
final Camera camera = new Camera(VisualGraphUtilities.getCamera(wg));
final Point wheelPoint = event.getPoint();
// HACK_DPI: Don't need to scale the wheelPoint.
eventState.setClosestNode(visualInteraction.closestNodeCameraCoordinates(wg, camera, wheelPoint));
if (!eventState.isPoint(EventState.WHEEL_POINT) || !wheelPoint.equals(eventState.getPoint(EventState.WHEEL_POINT))) {
eventState.storePoint(wheelPoint, EventState.WHEEL_POINT);
}
final Vector3f zoomReferencePoint = eventState.hasClosestNode() ? eventState.getClosestNode() : CameraUtilities.getFocusVector(camera);
// reference point for further action, and in some cases simulate a drag.
if (eventState.isMousePressed() && !wheelPoint.equals(eventState.getPoint(EventState.REFERENCE_POINT))) {
final Point from;
switch(eventState.getCurrentAction()) {
case PANNING:
from = eventState.getFirstValidPoint(EventState.DRAG_POINT, EventState.REFERENCE_POINT);
final Vector3f translation = visualInteraction.convertTranslationToPan(from, wheelPoint, zoomReferencePoint);
CameraUtilities.pan(camera, translation.getX(), translation.getY());
break;
case DRAG_NODES:
from = eventState.getPoint(EventState.DRAG_POINT);
performDrag(wg, camera, from, wheelPoint);
break;
default:
break;
}
}
CameraUtilities.zoom(camera, -event.getWheelRotation(), visualInteraction.convertZoomPointToDirection(wheelPoint), zoomReferencePoint.getLength());
eventState.addEventName(ZOOM_ACTION_NAME);
if (eventState.isMousePressed()) {
eventState.setClosestNode(visualInteraction.closestNodeCameraCoordinates(wg, camera, wheelPoint));
eventState.storePoint(wheelPoint, EventState.REFERENCE_POINT, EventState.DRAG_POINT);
}
updateCameraAndNewLine(wg, wheelPoint, camera, true);
}
return STANDARD_DELAY;
});
}
use of au.gov.asd.tac.constellation.utilities.graphics.Vector3f in project constellation by constellation-app.
the class DefaultInteractionEventHandler method showContextMenu.
private void showContextMenu(final GraphReadMethods rg, final Camera camera, final Point screenLocation, final GraphElementType elementType, final int clickedId) {
final JPopupMenu popup = new JPopupMenu();
final Collection<? extends ContextMenuProvider> popups = Lookup.getDefault().lookupAll(ContextMenuProvider.class);
final Vector3f graphLocation = visualInteraction.windowToGraphCoordinates(camera, screenLocation);
for (final ContextMenuProvider pmp : popups) {
// Retrive list of item names to populate and optional list of icons to assign
// Icons will be added corresponding to an image if the icons list is not ull
// and a non null icon is provided with corresponding index.
final List<String> items = pmp.getItems(rg, elementType, clickedId);
final List<ImageIcon> icons = pmp.getIcons(rg, elementType, clickedId);
if (!items.isEmpty()) {
final List<String> menuPath = pmp.getMenuPath(elementType);
if (CollectionUtils.isEmpty(menuPath)) {
for (int idx = 0; idx < items.size(); idx++) {
final Icon icon = (icons != null && icons.size() > idx + 1) ? (Icon) icons.get(idx) : null;
final String item = items.get(idx);
if (icon == null) {
// No icon was found, add menu item without an icon
popup.add(new AbstractAction(item) {
@Override
public void actionPerformed(final ActionEvent event) {
PluginExecution.withPlugin(new SelectGraphItem(pmp, item, elementType, clickedId, graphLocation)).executeLater(null);
}
});
} else {
// An icon was found, add menu item containing the icon
popup.add(new AbstractAction(item, icon) {
@Override
public void actionPerformed(final ActionEvent event) {
PluginExecution.withPlugin(new SelectGraphItem(pmp, item, elementType, clickedId, graphLocation)).executeLater(null);
}
});
}
}
} else {
JComponent currentMenu = popup;
for (final String level : menuPath) {
int childCount = currentMenu.getComponentCount();
for (int i = 0; i < childCount; i++) {
final JComponent childComponent = (JComponent) currentMenu.getComponent(i);
if (childComponent instanceof JMenu) {
JMenu childMenu = (JMenu) childComponent;
if (childMenu.getText().equals(level)) {
currentMenu = childComponent;
break;
}
}
}
final JMenu childMenu = new JMenu(level);
currentMenu.add(childMenu);
currentMenu = childMenu;
}
for (int idx = 0; idx < items.size(); idx++) {
final Icon icon = (icons != null && icons.size() > idx) ? (Icon) icons.get(idx) : null;
final String item = items.get(idx);
if (icon == null) {
// No icon was found, add menu item without an icon
((JMenu) currentMenu).add(new AbstractAction(item) {
@Override
public void actionPerformed(final ActionEvent event) {
PluginExecution.withPlugin(new SelectGraphItem(pmp, item, elementType, clickedId, graphLocation)).executeLater(null);
}
});
} else {
// An icon was found, add menu item containing the icon
((JMenu) currentMenu).add(new AbstractAction(item, icon) {
@Override
public void actionPerformed(final ActionEvent event) {
PluginExecution.withPlugin(new SelectGraphItem(pmp, item, elementType, clickedId, graphLocation)).executeLater(null);
}
});
}
}
}
}
}
popup.show(manager.getVisualComponent(), screenLocation.x, screenLocation.y);
}
use of au.gov.asd.tac.constellation.utilities.graphics.Vector3f in project constellation by constellation-app.
the class GraphRendererDropTarget method drop.
@Override
public void drop(final DropTargetDropEvent dtde) {
BiConsumer<Graph, DropInfo> dropHandler = null;
// Accept the drop, work out whether any graph dropper will handle it, and if so mark the drop as complete.
dtde.acceptDrop(dtde.getDropAction());
final Collection<? extends GraphDropper> droppers = Lookup.getDefault().lookupAll(GraphDropper.class);
for (final GraphDropper dropper : droppers) {
dropHandler = dropper.drop(dtde);
if (dropHandler != null) {
break;
}
}
dtde.dropComplete(dropHandler != null);
// (Note this has to be in a new thread because hit testing is done on the EDT, which we need to wait for the results of, but we are already on the EDT).
if (dropHandler != null) {
BiConsumer<Graph, DropInfo> resultDropHandler = dropHandler;
final Thread computeDrop = new Thread(() -> {
final Vector3f dropGraphLocation = processor.windowToGraphCoordinates(processor.getDisplayCamera(), dropLocation);
final BlockingQueue<HitState> hitTestQueue = new ArrayBlockingQueue<>(1);
manager.addOperation(processor.hitTestPoint(dropLocation.x, dropLocation.y, hitTestQueue));
HitState hitState;
while (true) {
try {
hitState = hitTestQueue.take();
break;
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
final DropInfo dropInfo = new DropInfo(dropGraphLocation, hitState.getCurrentHitId(), hitState.getCurrentHitType().equals(HitType.VERTEX), hitState.getCurrentHitType().equals(HitType.TRANSACTION));
resultDropHandler.accept(graph, dropInfo);
});
computeDrop.setName("Graph Renderer Drop Target");
computeDrop.start();
}
}
Aggregations