In BGE, I have a simple mesh, say, a cube that has been subdivided a few times to give it more than 8 vertices, like so:
What I'd like to do, generically speaking, is find the shortest distance from the surface, or alternately the bounding box, of that mesh a given location.
To be more specific, I want to find the distance from the camera (player) to the mesh. I would then pass that information into a text field on a HUD (which I already know how to do). Think of it like a range-finder, where the player always sees the distance from him/herself to the target object. I've found a few methods that work using the object's origin, but that doesn't work for me. I need the distance to the closest vertex on the object's mesh. Or alternately, at least the closest point on the object's bounding box.
I know how to get the camera's current location with object.worldPosition
. I've tested that successfully.
Here's what else I've found so far, none of which works for me:
- closest_point_on_mesh, an object property in BPY. This seems like it would work perfectly - I'd find the closest point, and find the distance from that point to the camera's location. Except that it's only for BPY, which doesn't help me for BGE.
- Ray casting in BGE, from this similar object property list for BGE. I'm not quite understanding how ray casting works here or how I would use it to find the nearest point to my origin point (the camera location). Note, I already know what mesh I want to "hit" (the cube), I just need to find the closest vertex or closest point on its surface.
- This StackExchange answer that relates to BPY. Again, I need a BGE-workable solution.
- This other StackExchange answer that is in BGE, but it is only for the distance between two objects' origins. I need the distance from one point, to the closest point on the object. Not the origin-to-origin distance.
Finally, here's what I've tried to implement. Since object.closest_point_on_mesh
from the first bullet above seems to be the closest to what I want, I decided why not try it in BGE and see if it works after all. It didn't.
import bge
from math import sqrt
#There's a bunch of other code in here that I won't repeat,
#but one of them is getHUDfield(), which retrieves the text
#objects in the HUD scene so that their text can be updated
def RangeUpdate():
#Have this actuated by "Always" and reside on the camera
#Find camera location
cam_loc = bge.logic.getCurrentController().owner.worldPosition
print(cam_loc) #for debugging - this works, successfully gives me the cam's location in the console
#Find the cube object and find the closest point on its mesh
objects = bge.logic.getCurrentScene().objects
bounding_cube = objects["Cube_00"]
loc, norm, idx = bounding_cube.closest_point_on_mesh(cam_loc)
#^^^Right now the problem is here: closest_point_on_mesh might not work in BGE?
#Find the distance between cam's location and this location
dist = sqrt((loc[0]-cam_loc[0])**2 + (loc[1]-cam_loc[1])**2 + (loc[2]-cam_loc[2])**2)
#Display it on the HUDfield called RangeLabel
allhudfields = getHUDfield()
hudfield = allhudfields["RangeLabel"]
hudfield["Text"] = str(dist) + " blender units"
The code fails at bounding_cube.closest_point_on_mesh(cam_loc)
. The console output says AttributeError: 'KX_GameObject' object has no attribute 'closest_point_on_mesh'
For the curious or skeptical, the part where it updates the hud field's text DOES work (if I feed it a dummy value). Clearly the failure is in finding the point on the mesh closest to the given location.
So does anyone know either how I can do something similar to calling the property closest_point_on_mesh
, but in BGE instead of BPY? Or, is there a totally different method or a work-around that works in BGE? To reiterate, my objective is to find the shortest possible distance from an arbitrary point (the camera's location), to the surface of a specified object/mesh (or at least the nearest vertex on the mesh, or the closest point on its bounding box).