Rick Posted July 6, 2013 Share Posted July 6, 2013 I have a plane model that I'm using for a gui widget. I want to have options to anchor these to top, bottom, left, right edges of the screen. I'm just testing top left (0,0) atm so I have the following code: local pos = self.camera:UnProject(Vec3(0, 0, 1)) -- always face the camera self.entity:SetPosition(self.camera:GetPosition()) self.entity:SetRotation(self.camera:GetRotation()) self.entity:Move((pos.x / 2), (pos.y / 2), 1, false) self.entity:Turn(270, 0, 0) However this doesn't align the plane exactly to the top left edge. For a screen resolution of 1024x768 if I change the Move() code to self.entity:Move((pos.x / 2) + .018, (pos.y / 2) - .15, 1) it lines up perfectly, but for other resolutions that doesn't line up. I'm using the plane model that comes with LE Models/Primitives/plane.mdl Why is self.camera:UnProject(Vec3(0, 0, 1)) not producing a point that would be exactly in the center of the plane at the 2D space 0,0? How can I do this to be more consistent with any resolution? Quote Link to comment Share on other sites More sharing options...
beo6 Posted July 6, 2013 Share Posted July 6, 2013 i don't know what you exactly try to achieve but if you wan't to have the plane center at the top left position of the screen local pos = self.camera:UnProject(Vec3(0, 0, 1)) -- always face the camera self.entity:SetPosition(pos) self.entity:SetRotation(self.camera:GetRotation()) self.entity:Turn(270, 0, 0) this works for me. Quote Link to comment Share on other sites More sharing options...
Rick Posted July 6, 2013 Author Share Posted July 6, 2013 That does work thanks. I'm a little confused though. If I unproject (800, 600, 1) then the center of the plane is in the bottom right. I guess I would expect then (0,0,1) would have the center of the plane in the top/left (since I'm guessing that's the center of the plane model), but it's not the center of the plane it's actually the top/left of the plane. Basically, I'm looking to anchor the plane to any edge of the 2D screen. Trying to do this against the right edges seems like I'll need to convert the scale of the plane to pixels on the screen so I can subtract that difference by what I send to UnProject? Not really sure how I'd do this. Man I wish I was better at math :/ Quote Link to comment Share on other sites More sharing options...
beo6 Posted July 6, 2013 Share Posted July 6, 2013 uhm. UnProject converts a pixel position on your screen from the camera to a global 3d position. So to attach it to the top right side you would only need to get the width of your context. local context=Context:GetCurrent() local pos = self.camera:UnProject(Vec3(context:GetWidth(), 0, 1)) Quote Link to comment Share on other sites More sharing options...
Rick Posted July 6, 2013 Author Share Posted July 6, 2013 That doesn't work for me. The center of the plane ends up in the top right corner. I would want the top right of the plane to be in the top right corner of the window. This is why I'm confused some why 0, 0 puts the top left corner of the plane at the top left corner of the window instead of the center of the plane at the top left corner of the window as I assume the local 0,0 of the plane would be it's center. If this was 2D you'd have to subtract the width of the image from the right edge to "anchor" it on the right side. However because it's a 3D plane I'm not sure how you'd do this. I think you'd have to convert width of the plane from 3D space to 2D space and then subtract that number by the context width before sending it to UnProject(). Not sure how to do that 3D to 2D conversion of a size. [edit] Actually I was incorrect. (0,0,1) does put the plane at the center point of the plane in the top/left instead of the top/left corner of the plane. So on all edges I'll have to account for 1/2 the plane width/height and adjust somehow. The texture I was using didn't make this obvious but I switched textures and now I can see that. Thinking out loud. Let's say we have a plane, 2 units in width, total, and 1 unit away from the camera. Would need to see how wide in pixels that is given the current screen resolution. Maybe I could get the scale and subtract 1/2 the scale from the position and unproject that value, then add 1/2 the scale to the position and unproject that value, then find the difference between those 2 values to get the size in pixels and then add that to the screen space I want to unproject. hmm will give it a go. Quote Link to comment Share on other sites More sharing options...
beo6 Posted July 6, 2013 Share Posted July 6, 2013 hmm. i don't know how we could get the actual screen pixels of the entity since it is also depending of the distance etc. The easiest would be to change the base of the entity. I think that would be possible in a 3d model editor. Another way could be to set a pivot at the position and parent your entity to it. Just like this: function Script:Start() self.pivot = Pivot:Create() local entityscale = self.entity:GetScale() local entityPos = self.entity:GetPosition() entityPos.x = entityPos.x + (entityscale.x/2) entityPos.z = entityPos.z + (entityscale.z/2) self.pivot:SetPosition(entityPos) self.entity:SetParent(self.pivot) end function Script:UpdateWorld() local context=Context:GetCurrent() local pos = self.camera:UnProject(Vec3(context:GetWidth(), 0, 1)) -- always face the camera self.pivot:SetPosition(pos) self.pivot:SetRotation(self.camera:GetRotation()) self.pivot:Turn(270, 0, 0) end Quote Link to comment Share on other sites More sharing options...
Rick Posted July 6, 2013 Author Share Posted July 6, 2013 The easiest would be to change the base of the entity. I think that would be possible in a 3d model editor. I don't think this would work as I want to be able to anchor to any side the same plane so setting the base at the top/left would work for the top/left screen but not the bottom/right is I want to anchor a widget plane there. I'd be in the same boat. Maybe there is a way to change this dynamically in LE though. Will check that out as that might be the easiest. I put in that code but got a funky result. Quote Link to comment Share on other sites More sharing options...
beo6 Posted July 6, 2013 Share Posted July 6, 2013 (edited) i tried my code and it works for me. Now i have the plane top right corner at the top left right of the screen. And you can change the pivot position if you wan't to attach the plane at another corner. Edited July 6, 2013 by beo6 Quote Link to comment Share on other sites More sharing options...
Rick Posted July 7, 2013 Author Share Posted July 7, 2013 Got it to work. My plane was rotated in the editor to start with which screwed it up. I got all of the edges anchorable now. I have a hard time thinking in 3D though. So anchoring on some other edges requires different combinations of positioning the pivot and what point is unprojected? Like I can unproject (0,0) or (contextWidth, 0) or (0, contextHeight) or (contextWidth, contextHeight), or even 1/2 contextWidth and height, etc? Thanks for the help and good idea of the pivot! Quote Link to comment Share on other sites More sharing options...
beo6 Posted July 7, 2013 Share Posted July 7, 2013 Nice that you got it to work. It was just a quick idea since I had no better idea. You can unproject any position on the screen. and the pivot is only the Anchor position of the entity. if you want to change the pivot on the fly it becomes a bit more complicated since you move your entity with the pivot because it is parented. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.