blob: cae09fa84146d0ea723a6af4f8d659f4d1fe5bd8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pierre Allard,
* Regent L'Archeveque - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.addons.vehicle.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.vecmath.Matrix4d;
import org.eclipse.apogy.addons.vehicle.ClosestNeighbourIteratorProvider;
import org.eclipse.apogy.addons.vehicle.MeshExtent2D;
import org.eclipse.apogy.addons.vehicle.WheelVehicleUtilities;
import org.eclipse.apogy.common.geometry.data3d.CartesianAxis;
import org.eclipse.apogy.common.geometry.data3d.CartesianPolygon;
import org.eclipse.apogy.common.geometry.data3d.CartesianPositionCoordinates;
import org.eclipse.apogy.common.geometry.data3d.CartesianTriangle;
import org.eclipse.apogy.common.geometry.data3d.CartesianTriangularMesh;
import org.eclipse.apogy.common.geometry.data3d.Geometry3DUtilities;
import org.eclipse.apogy.common.math.Matrix4x4;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyFacade;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.addons.dynamics.PhysicalBody;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.traverse.BreadthFirstIterator;
public abstract class ContactProviderCustomImpl extends ContactProviderImpl {
/*
* Stores the last triangle were a contact was made for each mesh and each
* wheel. A null triangle indicates that no intersection was found for the
* wheel.
*/
protected Map<CartesianTriangularMesh, Map<Integer, CartesianTriangle>> meshToWheelToLastTriangleMap = new HashMap<CartesianTriangularMesh, Map<Integer, CartesianTriangle>>();
protected CartesianPositionCoordinates[] getProjectionAlongAxisOnToPolygon(CartesianAxis axis,
List<CartesianPositionCoordinates> points, CartesianTriangularMesh mesh) {
CartesianPositionCoordinates[] intersections = new CartesianPositionCoordinates[points.size()];
ClosestNeighbourIteratorProvider closestNeighbourIteratorProvider = getVehiclePoseCorrector()
.getClosestNeighbourIteratorProvider(mesh);
MeshExtent2D meshExtent2D = getVehiclePoseCorrector().getMeshExtent2D(mesh);
Map<Integer, CartesianTriangle> wheelToLastTriangleMap = this.meshToWheelToLastTriangleMap.get(mesh);
if (wheelToLastTriangleMap == null) {
wheelToLastTriangleMap = new HashMap<Integer, CartesianTriangle>();
this.meshToWheelToLastTriangleMap.put(mesh, wheelToLastTriangleMap);
}
// Process each of wheels.
for (int i = 0; i < points.size(); i++) {
CartesianPositionCoordinates point = points.get(i);
Integer wheelIndex = new Integer(i);
// If the point falls within the mesh extent.
if (WheelVehicleUtilities.INSTANCE.isWithin(point.asPoint3d(), meshExtent2D)) {
CartesianTriangle startTriangle = wheelToLastTriangleMap.get(wheelIndex);
BreadthFirstIterator<CartesianTriangle, DefaultEdge> it = closestNeighbourIteratorProvider
.createBreadthFirstIterator(startTriangle);
CartesianPositionCoordinates projection = null;
while (it.hasNext() && projection == null) {
CartesianPolygon polygon = it.next();
projection = Geometry3DUtilities.getProjectionAlongAxisOnToPolygon(CartesianAxis.Z, point, polygon);
if (projection != null) {
wheelToLastTriangleMap.put(wheelIndex, (CartesianTriangle) polygon);
}
}
intersections[i] = projection;
}
}
return intersections;
}
/*
* Gets the matrix that expresses the pose of a PhysicalBody relative to a
* ContentNode.
*
* @param originalPose The original, uncorrected pose of the system.
*
* @param body The PhysicalBody.
*
* @param node The node containing the mesh.
*
* @return The matrix.
*/
protected Matrix4d getBodyToMeshTransform(Matrix4x4 originalPose, PhysicalBody body, Node node) {
// Gets the body to System transform
Matrix4d bodyToSystemTransform = getFootToSystemTransform(body);
// Gets the body in the world origin.
Matrix4d bodyToWorldTransform = new Matrix4d(originalPose.asMatrix4d());
bodyToWorldTransform.mul(bodyToSystemTransform);
// Gets the mesh to world transform.
Matrix4d meshToWorldTransform = ApogyCommonTopologyFacade.INSTANCE.expressNodeInRootFrame(node);
// Gets the bodyToMeshTransform
meshToWorldTransform.invert();
bodyToWorldTransform.mul(meshToWorldTransform);
return bodyToWorldTransform;
}
/*
* Gets the matrix that expresses the pose of a PhysicalBody relative to the
* current System.
*
* @param body The PhysicalBody.
*
* @return The matrix.
*/
protected Matrix4d getFootToSystemTransform(PhysicalBody body) {
Node root = getVehiclePoseCorrector().getSystemRootNode();
Matrix4d transform = ApogyCommonTopologyFacade.INSTANCE.expressInFrame(body, root);
return transform;
}
} // ContactProviderImpl