# How to direct a character parallel to the ground?

I try

``````if (RaycastDown(hitPos, hitDrawable, normal))
{
node.rotation = Quaternion(normal.x, node.rotation.yaw, normal.z);
}``````

Do I understand correctly that normal is not calculated really ?

``````void Drawable::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQueryResult>& results)
{
float distance = query.ray_.HitDistance(GetWorldBoundingBox());
if (distance < query.maxDistance_)
{
RayQueryResult result;
result.position_ = query.ray_.origin_ + distance * query.ray_.direction_;
result.normal_ = -query.ray_.direction_;  // <------------------------------------------------------------
result.distance_ = distance;
result.drawable_ = this;
result.node_ = GetNode();
result.subObject_ = M_MAX_UNSIGNED;
results.Push(result);
}
}
``````

That is in the base class, which doesnâ€™t actually understand the geometry. E.g. StaticModel raycast should return the normal correctly.

If Iâ€™m not mistaken, thereâ€™s already a snippet from Vehicle or Water Demo which demonstrates actual placement (or something similar) of objects (mushrooms) parallel from Terrain. Maybe you could derive something from that exampleâ€¦

Oh, thanks. It works

``````if (RaycastDown(hitPos, hitDrawable, normal))
{
Quaternion grndTilt = Quaternion(Vector3(0.0f, 1.0f, 0.0f), normal);
node.rotation = grndTilt * Quaternion(0.0f, node.rotation.yaw, 0.0f);
}``````

Another method from answers.unity3d.com/questions/16 â€¦ ormal.html
It gives smoother results.

``````        Vector3 corner1 = node.position + Vector3(-1.0f, 0.0f, -1.0f);
Vector3 corner2 = node.position + Vector3(1.0f, 0.0f, -1.0f);
Vector3 corner3 = node.position + Vector3(1.0f, 0.0f, 1.0f);
Vector3 corner4 = node.position + Vector3(-1.0f, 0.0f, 1.0f);

Vector3 hit1, hit2, hit3, hit4;

bool b1 = RaycastDown(corner1, hit1, hitDrawable);
bool b2 = RaycastDown(corner2, hit2, hitDrawable);
bool b3 = RaycastDown(corner3, hit3, hitDrawable);
bool b4 = RaycastDown(corner4, hit4, hitDrawable);

if (!b1) log.Warning("b1");
if (!b2) log.Warning("b2");
if (!b3) log.Warning("b3");
if (!b4) log.Warning("b4"); // fix it case

Vector3 normal = hit1.CrossProduct(hit2) + hit2.CrossProduct(hit3) +
hit3.CrossProduct(hit4) + hit4.CrossProduct(hit1);
normal.Normalize();
normal = -normal;

Quaternion grndTilt = Quaternion(Vector3(0.0f, 1.0f, 0.0f), normal);
node.rotation = grndTilt * Quaternion(0.0f, node.rotation.yaw, 0.0f);

...

bool RaycastDown(Vector3 from, Vector3& hitPos, Drawable@& hitDrawable)
{
hitDrawable = null;
Ray ray(from + Vector3(0.0f, 1.0f, 0.0f), Vector3(0.0f, -1.0f, 0.0f));
RayQueryResult result = scene.octree.RaycastSingle(ray, RAY_TRIANGLE, 1000, DRAWABLE_GEOMETRY, 1);

if (result.drawable is null)
return false;

hitPos = result.position;
hitDrawable = result.drawable;
return true;
}``````