Getting an angle relative to an entity from a normal?

Hi I am trying to make a floating ship entity but have come across a problem.

Doing tr.HitNormal:Angle() returns a pretty useless angle that I can’t understand how to translate into an angle I can use to try and go towards.

Here is my physics simulate code so far, I haven’t done much work on it yet but I wanted to start :slight_smile:

[lua]
function ENT:PhysicsSimulate(p,d)
self.vAng = Vector(0,0,0)
self.vLin = Vector(0,0,0)

self.l_vel = self.Entity:WorldToLocal(self.Entity:GetVelocity()+self.Entity:GetPos())

local hover_damp = Vector(0,0,self.l_vel.z * -5)

local ang = Angle(0,0,0)

for k,v in pairs(self:GetTracePoints()) do
	local trc = {}
	trc.start = self:LocalToWorld(v)
	trc.endpos = trc.start + self:GetUp() * -50
	trc.filter = self
	
	local tr = util.TraceLine(trc)
	if tr.Hit then
		debugoverlay.Cross(tr.HitPos, 10, d * 2)
		local force = Vector(0,0,(tr.Fraction - 0.5) * -100000)
		self.vLin = self.vLin + force + hover_damp
		
		//self:SetAngles(tr.HitNormal:Angle() + Angle(90,0,0))
	end
end

return self.vAng, self.vLin, SIM_LOCAL_ACCELERATION

end
[/lua]

Would appreciate any help I am not the best person with vector math.

[lua]tr.Normal:Angle()[/lua]

Is this what you are after?

No sorry. That just returns the original trace direction. tr.HitNormal is no good either in its ‘raw’ form either only modifies the pitch value so it doesn’t translate into my ships at all.

Look at this slope. (sorry for large images) (HitNormal being first three numbers)

http://dl.dropbox.com/u/3715122/gm_construct0001.jpg

Entity facing one direction pitch value is at 23.

http://dl.dropbox.com/u/3715122/gm_construct0002.jpg

Entity facing other direction pitch value unchanged.

I don’t know then sorry, I obviously misunderstood your question :smile:

[editline]06:48PM[/editline]

In fact, try rotating the angle around the entities right axis by 90 degrees.

[editline]06:49PM[/editline]

[lua]local ang = tr.HitNormal:Angle()
ang:RotateAroundAxis(self:GetRight(), 90)[/lua]

Hmm that corrects the pitch but then the roll goes completely off.

I had an idea of somehow getting the angle the rectangle the white crosses make and mirroring that but that sounds far too complicated.

Perhaps it would be easier to figure out how much angular force is required to make it so each of the traces I do has a similar distance therefore mimicking the surface exactly.

In my old ships I used this function: local forcelinear, forceangular = p:CalculateForceOffset(force, center)
but now I am using local vectors and that function returns global vectors.

WorldToLocal?

Hmm I think I got it working. Let me know if there is a better solution, not looking for the angle anymore just trying to mimick the rectangle the four crosses make.

[lua]
function ENT:PhysicsSimulate(p,d)
self.vAng = Vector(0,0,0)
self.vLin = Vector(0,0,0)

self.l_vel = self.Entity:WorldToLocal(self.Entity:GetVelocity()+self.Entity:GetPos())

local hover_damp = Vector(0,0,self.l_vel.z * -5)

local ang = Angle(0,0,0)

for k,v in pairs(self:GetTracePoints()) do
	local trc = {}
	trc.start = self:LocalToWorld(v)
	trc.endpos = trc.start + self:GetUp() * -50
	trc.filter = self
	
	local tr = util.TraceLine(trc)
	if tr.Hit then
		debugoverlay.Cross(tr.HitPos, 10, d * 2)
		local force = Vector(0,0,(tr.Fraction - 0.5) * -100000)
		self.vLin = self.vLin + force + hover_damp
		local ang = self:LocalToWorld(tr.HitNormal + self:GetPos())
		self.vAng = self.vAng + (v * force.z / 10000)
	end
end
local temp = Vector(self.vAng.x,self.vAng.y,self.vAng.z)
self.vAng.y = temp.x * -1
self.vAng.x = temp.y
debugoverlay.Text(self:GetPos(), self.vAng.x.."      "..self.vAng.y.."      "..self.vAng.z, d * 2)
return self.vAng, self.vLin, SIM_LOCAL_ACCELERATION

end
[/lua]

Anyone got any better ideas my maths is always hacky.