Bezier3 with more special cases handled and lookAt rotation

This commit is contained in:
Lingis
2020-01-26 17:22:25 -05:00
parent 88b7dbe3eb
commit c1c96cd81d
2 changed files with 40 additions and 8 deletions

View File

@@ -104,23 +104,26 @@ Bezier3Curve::Bezier3Curve(CameraState& start, CameraState& end) {
glm::dvec3 startNodePos = sceneGraphNode(start.referenceNode)->worldPosition();
glm::dvec3 startDirection = start.position - startNodePos;
double startRadius = sceneGraphNode(start.referenceNode)->boundingSphere();
double endRadius = sceneGraphNode(end.referenceNode)->boundingSphere();
glm::dvec3 endNodePos = sceneGraphNode(end.referenceNode)->worldPosition();
glm::dvec3 endDirection = end.position - endNodePos;
glm::dvec3 nodePosDiff = endNodePos - startNodePos;
double cosStartAngle = glm::dot(normalize(startDirection), normalize(nodePosDiff));
double cosEndAngle = glm::dot(normalize(endDirection), normalize(nodePosDiff));
// TODO: Test with raycaster, value can vary depending on how close we are to surface!!
// TODO: Test with raycaster, test is dependent on start position
bool TARGET_BEHIND_STARTNODE = cosStartAngle < -0.8;
bool TARGET_IN_OPPOSITE_DIRECTION = cosStartAngle > 0.8;
bool TARGET_ON_BACKSIDE = cosEndAngle > 0.8;
bool TARGET_IN_OPPOSITE_DIRECTION = cosStartAngle > 0.7;
// SET CONTROL POINTS
_points.push_back(start.position);
_points.push_back(start.position + 2.0 * startRadius * normalize(startDirection));
if (TARGET_BEHIND_STARTNODE)
if ( TARGET_BEHIND_STARTNODE )
{
glm::dvec3 parallell = normalize(nodePosDiff) * glm::dot(startDirection, normalize(nodePosDiff));
glm::dvec3 orthogonal = normalize(startDirection - parallell);
@@ -133,7 +136,32 @@ Bezier3Curve::Bezier3Curve(CameraState& start, CameraState& end) {
_points.push_back(extraKnot + parallell);
}
_points.push_back(end.position + 2.0 * endDirection);
if (TARGET_IN_OPPOSITE_DIRECTION && ! TARGET_ON_BACKSIDE) {
glm::dvec3 parallell = normalize(nodePosDiff * glm::dot(startDirection, normalize(nodePosDiff)));
glm::dvec3 orthogonal = normalize(normalize(startDirection) - parallell);
// Distant middle point
double dist = 0.5 * length(nodePosDiff);
glm::dvec3 extraKnot = startNodePos - dist * parallell + 3.0 * dist * orthogonal;
_points.push_back(extraKnot - 0.5 * dist * parallell);
_points.push_back(extraKnot);
_points.push_back(extraKnot + 0.5 * dist * parallell);
}
if (TARGET_ON_BACKSIDE)
{
glm::dvec3 parallell = normalize(nodePosDiff) * glm::dot(endDirection, normalize(nodePosDiff));
glm::dvec3 orthogonal = normalize(endDirection - parallell);
//Point on the side of start node
double dist = 5.0 * endRadius;
glm::dvec3 extraKnot = endNodePos + dist * orthogonal;
_points.push_back(extraKnot - parallell);
_points.push_back(extraKnot);
_points.push_back(extraKnot + parallell);
}
_points.push_back(end.position + 2.0 * endRadius * normalize(endDirection));
_points.push_back(end.position);
}

View File

@@ -95,19 +95,23 @@ const glm::vec3 PathSegment::getPositionAt(double t) const {
}
const glm::dquat PathSegment::getRotationAt(double t) const {
double tRot = helpers::shiftAndScale(t, 0.1, 0.9);
tRot = easingfunctions::cubicEaseInOut(tRot);
double tSlerp = helpers::shiftAndScale(t, 0.1, 0.9);
tSlerp = easingfunctions::cubicEaseInOut(tSlerp);
double tLookAt = helpers::shiftAndScale(t, 0.2, 0.8);
tLookAt = easingfunctions::cubicEaseInOut(tLookAt);
switch (_curveType) {
case Linear2:
case Bezier3:
return getLookAtRotation(
tRot,
tLookAt,
getPositionAt(t),
global::navigationHandler.camera()->lookUpVectorWorldSpace()
);
break;
default:
return glm::slerp(_start.rotation, _end.rotation, tRot);
return glm::slerp(_start.rotation, _end.rotation, tSlerp);
}
}