let´s say, i want to place the reflection on the sphere a little bit to the right, on this exemple i can simply move the reflection plane to the right, but on more complex objects it can be a little bit tricky,
so, the plan is, to cast a ray on to the object and reflect it, so we can retrieve a location to put the white plane on.
i´m not a good python scripter (the other reason that im trying to do this, is to learn python ), I found this function ray_cast(star, end), that returns a location, the normal, and the face index that the ray casted on.
the code i wrote:
ob = bpy.data.objects[‘Mesh’]
s = [0,0,0] # start location
e = [-5,0,0] # end location
@scorpius:
Yes, I know about the object space stuff, after some research i found out what those numbers were,
the first output (with plane rotated 45º) the “error” occur because the ray did´nt hit the face, the solution for that is to extrapolate the ray´s lenght, and the “weird” normal output is the X,Y,Z where the normal has the lenght of 1 unit
now, i only need help finding out the reflected vector (where the reflected plane is, or will be), we can use the AngleBetweenVecs() function, but them we need to rotate the inicial vector somehow using eulers rotation (no idea if this is right, I´m not a good math guy)
or we can use the reflection() function, look´s like this method is more apropriate (dãr) but it retuns some weird numbers, that apparently is not a reflection =(
@Hoverkraftt
Glad to see you are interested, Im not a good coder/math guy, so this script is a realy good learning resource, at least for me =]
so thanks in advance!
Wings has a similar function for placing highlights: you select a light and a face, then it reorients the light so that it reflects off of the face and into the camera. Is this what you are trying to do?
I’m not 100% sure, but I’d guess the the reflection() function is the way to go. How do you know it’s not returning the reflected vector?
yes, thats exactly what I´m trying to do, without repositioning a lamp, only showing a line where that position is, but that´s a small detail.
here´s an exemple of the output from start.reflected(nor):
ps1 : nor = the normal output from the ray_cast()
the object center is set at (0,0,0) and no rotation, scale is applied to the obj, so object space = world space (right?).
Now look at the point that the reflection() function returned = (1, -1.4142, -1), looks like the opposite from what it “should” return, =(
here is the script that i used to calculate that:
import Mathutils
import math
from Mathutils import Vector
print(“-----------------------”)
starVec = Vector(2,0,0)
endVec = Vector(-6,0,0)
print(starVec,endVec)
ob = bpy.data.objects[‘Mesh.001’]
ray = ob.ray_cast(starVec, endVec)
col = Vector(ray[0][0],ray[0][1],ray[0][2])
nor = Vector(ray[1][0],ray[1][1],ray[1][2])
I think it would be best to have the reflected line displayed, as Hperigo said. That way you can place whatever you want in the reflection, be it a white plane to accent the surface or for example to frame up a character in the reflection of a car. Very useful I think.
Actually it looks like you are using Blender 2.5 …
In that case I think you forgot to add the reflect_vector to your hit_point.
A reflect vector is a direction from the origin [0,0,0], for you need to “move” it to the hit position to visualize it properly.
(as scorpius said to draw the 3D elements - rays, points - helps A LOT)
so, i tried to use the “custom” function from here and it worked!
well kind of, the result had the Y, and Z axis mirrored, so i multiplyed those by -1, and it kind of worked, still a litle bit wrong, but its an improvement!
here are some pics:
as you can see, the reflection its pretty close, but still a little bit off the place it shoud be…
and the code:
import Mathutils as M
import bpy, math
from Mathutils import Vector
begin the reflected ray calculation
def Ray_calc():
starVec = Vector(2,0,0)
endVec = Vector(-6,0,0)
#print(starVec,endVec)
ob = bpy.context.active_object
ray = ob.ray_cast(starVec, endVec)
col = Vector(ray[0][0],ray[0][1],ray[0][2]) #gets the coalision vector
nor = Vector(ray[1][0],ray[1][1],ray[1][2]) #gets the normal vector
newVec = Vector(vec_reflect_py(starVec, nor)) #reflects
newVec += col #adding the coalinsion vector to the result vector
newVec = Vector(newVec[0],newVec[1]*-1,newVec[2]*-1) #weird Y, Z axis flipin
return starVec, col, newVec
#begin reflect function
def vec_reflect_py(vec, mirror):
reflect = [0.0, 0.0, 0.0]
# normalizing
length = 0.0
for i in range(3):
length += mirror[i] * mirror[i]
length = float(math.sqrt(length))
for i in range(3):
mirror[i] /= length
dot2 = 2 * (vec[0]*mirror[0]+vec[1]*mirror[1]+vec[2]*mirror[2])
reflect[0] = vec[0] - (dot2 * mirror[0])
reflect[1] = vec[1] - (dot2 * mirror[1])
reflect[2] = vec[2] - (dot2 * mirror[2])
return reflect
#begin to draw the calculated ray
def Ray_draw(v0,v1,v2):
verts_loc = []
a = 0
b = 0
c = 0
while a < 3:
verts_loc.append(v0[a])
a += 1
while b < 3:
verts_loc.append(v1[b])
b += 1
while c < 3:
verts_loc.append(v2[c])
c += 1
Ray_calc() #executes the reflection
Ray_draw(Ray_calc()[0],Ray_calc()[1],Ray_calc()[2]) #draws the reflection
ps1: the ray starts at (2,0,0), and ends at (-6,0,0) OBJECT SPACE, so a good idea is to place the mesh center at (0,0,0) global space, with applied rotation, scale, so that the coordinates don´t get mixed up.
ps2: the Ray_draw function creates a new object with 3 vertices, if no face is hited by the ray, a ZeroDivisionError will occur