Keeping a child entity at a location respective to its parent
8 replies, posted
I'm making an oil drill and tank, and I'm nearly finished except for this very minor flaw. The Oil tank itself is the metal phx frame, while the "oil" is a black phx cube that is stretched on the z-axis and moved up to imitate liquid oil being pumped into the tank. This is a lot to read and if you're down to help me out please read carefully.
Because SetModelScale now scales on all axes, I had to use the [url=http://wiki.garrysmod.com/page/Entity/EnableMatrix]EnableMatrix[/url] trick to resize the z-axis independently. This works, but scales the model up 50% and down 50% of the value you give it. To fix this I created a formula that takes this into account and moves the cube up on the z-axis so it appears that the cube is only growing in one direction (up) instead of two (up and down). Here is how the cube of oil is being drawn.
[lua]
function ENT:Draw()
// The NWInt Oil is the amount of oil ranging from 0 (empty) to 100 (full) a tank has
if self:GetNWInt("Oil") > 0 then //If there's no oil then the cube won't be drawn
self:DrawModel()
end
local scale = Vector( 1.6, 1.6, self:GetNWInt("Oil") / 25 ) // Stretch the cube to fill the tank wireframe, from the wiki
local mat = Matrix()
mat:Scale( scale )
self:EnableMatrix( "RenderMultiply", mat )
if IsValid(self:GetNWEntity("Tank")) then
local tankpos = self:GetNWEntity("Tank"):GetPos() //The wireframe phx
// This is the formula I made that correctly places the cube on the z axis. It's the x and y axes that are the problem
self:SetRenderOrigin( ( Vector( tankpos.x, tankpos.y, tankpos.z - ( (self:GetNWInt("Oil") * -0.45) + 70 ) ) ) )
end
end
[/lua]
What I need is the cube to be completely aligned with the wireframe on the x and y axes at any angle. As you can see in the video below, rotating it will throw it off center.
Please note, I am not having trouble with the z axis, only placement on the x and y axes. The formula I made works perfectly when placing the oil on the z-axis.
I've got a hunch that this can be fixed with LocalToWorld or WorldToLocal, but I've never used these functions before so a demonstration would be nice if that's the fix.
Here's a video of the tank as of right now:
[video=youtube;QW4JPA3BmyM]http://www.youtube.com/watch?v=QW4JPA3BmyM[/video]
Thanks for your help, I hope it's an easy fix.
Use either LocalToWorld or ent:GetForward()/ent:GetRight()/ent:GetUp() to position your black box.
[QUOTE=Robotboy655;43464861]Use either LocalToWorld or ent:GetForward()/ent:GetRight()/ent:GetUp() to position your black box.[/QUOTE]
I've tried using LocalToWorld for a good amount of time, but with no results. Could you go more in depth with that or give an example?
I can't really give you any code without testing it myself in this case, basically what you want to do is figureout local position of your black box from the origin of phx prop, then do
local blackboxpos = self:LocalToWorld( localboxpos )
[QUOTE=Robotboy655;43465476]I can't really give you any code without testing it myself in this case, basically what you want to do is figureout local position of your black box from the origin of phx prop, then do
local blackboxpos = self:LocalToWorld( localboxpos )[/QUOTE]
Found a semi-solution, on the tank's Initialize function I created the black cube and set its parent to the tank, then set the cube's positions relative to the tank's position.
[lua]
//self is the corresponding tank entity (phx wireframe)
self.OilCube = ents.Create("machinery_oil")
local pos = self:GetPos()
self.OilCube:SetPos( Vector( pos.x + 23, pos.y, pos.z - 70 ) )
self.OilCube:SetParent( self )
self.OilCube:SetModel("models/hunter/blocks/cube05x05x05.mdl")
self.OilCube:SetColor( Color( 0, 0, 0, 180 ) )
[/lua]
This works perfectly at any angle or position, however there's one problem.
[video=youtube;ODoaRhgao4A]http://www.youtube.com/watch?v=ODoaRhgao4A[/video]
As I said in the op, when stretching an entity using EnableMatrix it stretches the entity in both positive and negative directions on the axis, so the black cube grows up and down, when I only need it growing up. I was combating this with a formula that would change the cube's z position accordingly, but that was what was messing it all up.
Basically, is there any way to use EnableMatrix to stretch the cube upwards only?
You can use Entity:SetLocalPos if you have parent to set the Z pos, try it.
[code]
child:SetPos(parent:LocalToWorld(Vector(offsetx, offsety, offsetz)));
--it is also the same as...
child:SetPos(Vector(offsetx, offsety, offsetz) + parent:GetPos())
[/code]
where offsetx offsety and offsetz is the offset of the parent:GetPos()
also since it is growing both ways on the z axis, it would make sense that it would do 50 / 50 %, so with that logic you could get the total z width and multiply it by the scale you want and subtract it from the default z widt, divide by two, and add it / subtract it from the offsetz
Would it not be better to use a clientside model?
[QUOTE=Robotboy655;43501331]You can use Entity:SetLocalPos if you have parent to set the Z pos, try it.[/QUOTE]
Awesome, thanks man. You're a real godsend for this dev forum.
[QUOTE=mdeceiver79;43501451]Would it not be better to use a clientside model?[/QUOTE]
That was initially the plan, but the CModel acted exactly as the entity I was creating when I tried it. I'll see if I can apply the fix to the CModel now.
Sorry, you need to Log In to post a reply to this thread.