Thread Tools Display Modes
10-25-13, 02:36 PM   #21
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by Resike View Post
I was trying to make a workaround for models with model:HasCustomCamera() == false, but i failed.
HasCustomCamera always returns false until you SetCustomCamera doesn't it? If you mean SetUnit not working with it then you can set a regular model first and then the unit and still use the custom camera stuff.
  Reply With Quote
10-26-13, 12:59 AM   #22
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Vrul View Post
HasCustomCamera always returns false until you SetCustomCamera doesn't it? If you mean SetUnit not working with it then you can set a regular model first and then the unit and still use the custom camera stuff.
Nope if if HasCustomCamera() returns false, then you can't use SetCameraPosition(x, y, z) which needs the SetCustomCamera(1).

Like here is this model: "Creature/Lostisles_carnivorousplant/lostisles_carnivorousplant01_creature_redspitter.m2" i couln't use SetCameraPosition(x, y, z) on this one.
  Reply With Quote
10-26-13, 03:05 AM   #23
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Hmm Ok. What models do work?
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote
10-26-13, 11:42 AM   #24
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by zork View Post
Hmm Ok. What models do work?
Well if model:HasCustomCamera() returns true then you can tilt it. I'm not sure whats the requirements but mostly passivedoodads and doodads can't have custom camera, creature and player models can have.

Last edited by Resike : 10-26-13 at 12:40 PM.
  Reply With Quote
10-27-13, 03:49 AM   #25
pelf
Sentient Plasmoid
 
pelf's Avatar
Premium Member
Join Date: May 2008
Posts: 133
I know it's not exactly in the spirit of DIY, but have you checked out how Examiner does this stuff? You can "inspect" anything that can be targeted. If the target isn't a player, then you just get a window with a model in it. (LeftMouse drag = rotate, RightMouse drag = pan, MouseWheel = zoom) If it is a player, you get the same, but with the inspection UI on top.

Also, the Dungeon Journal UI has a "show model" button for bosses, and I think you can rotate in there, too.
  Reply With Quote
10-27-13, 04:20 AM   #26
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
That is not what we want. Wo do not want to pan the model, we want to tilt it.

Examiner is just using the default ModelFrame functions.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote
10-27-13, 04:25 AM   #27
pelf
Sentient Plasmoid
 
pelf's Avatar
Premium Member
Join Date: May 2008
Posts: 133
Originally Posted by zork View Post
That is not what we want. Wo do not want to pan the model, we want to tilt it.

Examiner is just using the default ModelFrame functions.
I wouldn't have confused "tilting" with "panning". Though, is there a difference between "tilt" and "rotate"? If there is, I may have confused those two.

The only difference I can think of is that a tilt might involve rotation about an axis/point that is outside the model.
  Reply With Quote
10-27-13, 04:41 AM   #28
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Yes that is what we want.

Rotation on the model ifself rotates the model on its axis from 0-360°.
Tilting will allow moving the camera that is looking at the model up and down while at the same allows adjustment of the camera facing angle.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote
10-27-13, 05:05 AM   #29
pelf
Sentient Plasmoid
 
pelf's Avatar
Premium Member
Join Date: May 2008
Posts: 133
Got it. DIY it is, then .
  Reply With Quote
10-27-13, 05:10 AM   #30
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Btw thanks Vrul for the function set. Works perfectly.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote
10-27-13, 06:38 AM   #31
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
I updated Vrul's code a bit the problem was i wouldn't update the model when the pitch value was HALF_PI/-HALF_PI. aka top and bottom view.

Lua Code:
  1. local function OnUpdate(self, elapsed)
  2.     local x, y = GetCursorPosition()
  3.     local yaw = self.yaw + (x - self.x) * INCREMENT_RATIO
  4.     local pitch = self.pitch + (y - self.y) * INCREMENT_RATIO
  5.     if pitch > HALF_PI then
  6.         pitch = HALF_PI - 0.05
  7.     elseif pitch < - HALF_PI then
  8.         pitch = - HALF_PI + 0.05
  9.     end
  10.     self:SetOrientation(self.distance, yaw, pitch)
  11.     self.x, self.y = x, y
  12. end
  Reply With Quote
10-27-13, 08:18 AM   #32
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Yeah, cos(pi / 2) is 0 so any changes don't show while at that point. I have a similar change in the code I'm playing with. Basically the same thing:
Code:
local PITCH_LIMIT = PI / 2 - 0.05

local function OnUpdate(self, elapsed)
    local x, y = GetCursorPosition()
    local yaw = self.yaw + (x - self.x) * INCREMENT_RATIO
    local pitch = self.pitch + (y - self.y) * INCREMENT_RATIO
    if pitch > PITCH_LIMIT then
        pitch = PITCH_LIMIT
    elseif pitch < -PITCH_LIMIT then
        pitch = -PITCH_LIMIT
    end
    self:SetOrientation(self.distance, yaw, pitch)
    self.x, self.y = x, y
end
Edit: Updated initial code to reflect the changes so far.

Last edited by Vrul : 10-27-13 at 10:06 AM.
  Reply With Quote
10-27-13, 11:05 AM   #33
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Vrul View Post
Yeah, cos(pi / 2) is 0 so any changes don't show while at that point. I have a similar change in the code I'm playing with. Basically the same thing:
Code:
local PITCH_LIMIT = PI / 2 - 0.05

local function OnUpdate(self, elapsed)
    local x, y = GetCursorPosition()
    local yaw = self.yaw + (x - self.x) * INCREMENT_RATIO
    local pitch = self.pitch + (y - self.y) * INCREMENT_RATIO
    if pitch > PITCH_LIMIT then
        pitch = PITCH_LIMIT
    elseif pitch < -PITCH_LIMIT then
        pitch = -PITCH_LIMIT
    end
    self:SetOrientation(self.distance, yaw, pitch)
    self.x, self.y = x, y
end
Edit: Updated initial code to reflect the changes so far.
My other tought to fix it was when "pitch >= math.pi / 2" or "pitch <= math.pi / 2" then rotate the model instead of changing the camera's location, i had no time to test it yet tho.

Last edited by Resike : 10-27-13 at 02:06 PM.
  Reply With Quote
10-27-13, 03:12 PM   #34
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Some preview of my half-ready model tilting functions:

http://www.youtube.com/watch?v=3lrO-ua6yEo
  Reply With Quote
10-27-13, 03:48 PM   #35
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
That looks awesome, good job
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
10-28-13, 08:09 AM   #36
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Resike View Post
My other tought to fix it was when "pitch >= math.pi / 2" or "pitch <= math.pi / 2" then rotate the model instead of changing the camera's location, i had no time to test it yet tho.
I tried this method now, and i think this is the smoothest way to solve this stuck issue. Here is the updated OnUpdate function (degree precisely):

Lua Code:
  1. local function OnUpdate(self, elapsed)
  2.     local x, y = GetCursorPosition()
  3.     local limit = false
  4.     local pitch = self.pitch + (y - self.y) * INCREMENT_RADIAL
  5.     if pitch > PITCH_LIMIT or pitch < - PITCH_LIMIT then
  6.         limit = true
  7.     end
  8.     if limit then
  9.         local rotation = format("%.0f", math.abs(math.deg(((x - self.x) / 64 + model:GetFacing())) % 360))
  10.         if rotation ~= format("%.0f", math.abs(math.deg(model:GetFacing()) % 360)) then
  11.             model:SetRotation(math.rad(rotation))
  12.         end
  13.     else
  14.         local yaw = self.yaw + (x - self.x) * INCREMENT_RADIAL
  15.         self:SetOrientation(self.distance, yaw, pitch)
  16.     end
  17.     self.x, self.y = x, y
  18. end

Last edited by Resike : 10-28-13 at 08:47 AM.
  Reply With Quote
10-28-13, 10:54 AM   #37
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
I put every fuction together now.

Alt + LeftClick - Move frame
LeftClick + horizontal/vertical mouse movement - Tilt X, Tilt Z
RightClick + horizontal/vertical mouse movement - Move Y, Move Z
Alt + RightClick + vertical mouse movement - Move X
MiddleClick + horizontal mouse movement - Rotate
MouseWheel - Zoom camera (0.1)
Ctrl + MouseWheel - Zoom camera (0.5)
Alt + MouseWheel - Zoom camera (1)

Alt + MiddleMouse - Reset to default

Only Y Tilting is missing atm.

Lua Code:
  1. local format, math, pi, halfpi = format, math, math.pi, math.pi / 2
  2.  
  3. local frame = CreateFrame("Frame", nil, UIParent)
  4. frame:SetPoint("Center")
  5. frame:SetSize(512, 512)
  6. frame:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", insets = {left = 0, top = 0, right = 0, bottom = 0}, tile = true,})
  7. frame:SetBackdropColor(0, 0.4, 0, 1)
  8. frame:SetMovable(false)
  9.  
  10. local model = CreateFrame("PlayerModel", nil, frame)
  11. model:SetModel("Creature\\Alexstrasza\\LadyAlexstrasa.m2")
  12. model:SetAllPoints(frame)
  13. model:SetSize(512, 512)
  14. model:SetMovable(false)
  15. model:EnableMouse(true)
  16. model:EnableMouseWheel(true)
  17.  
  18. local function OnDragStart(self)
  19.     self:SetMovable(true)
  20.     self:StartMoving()
  21. end
  22.  
  23. local function OnDragStop(self)
  24.     self:StopMovingOrSizing()
  25.     self:SetMovable(false)
  26.     local x = math.floor(self:GetLeft() + (self:GetWidth() - UIParent:GetWidth()) / 2 + 0.5)
  27.     local y = math.floor(self:GetTop() - (self:GetHeight() + UIParent:GetHeight()) / 2 + 0.5)
  28.     self:ClearAllPoints()
  29.     self:SetPoint("Center", x, y)
  30. end
  31.  
  32. local function OnUpdate(self, elapsed)
  33.     local x, y = GetCursorPosition()
  34.     local pitch = model.pitch + (y - self.y) * pi / 256
  35.     local limit = false
  36.     if pitch > halfpi - 0.05 or pitch < - halfpi + 0.05 then
  37.         limit = true
  38.     end
  39.     if limit then
  40.         local rotation = format("%.0f", math.abs(math.deg(((x - self.x) / 64 + self:GetFacing())) % 360))
  41.         if rotation ~= format("%.0f", math.abs(math.deg(self:GetFacing()) % 360)) then
  42.             self:SetRotation(math.rad(rotation))
  43.         end
  44.     else
  45.         local yaw = self.yaw + (x - self.x) * pi / 256
  46.         self:SetOrientation(self.distance, yaw, pitch)
  47.     end
  48.     self.x, self.y = x, y
  49. end
  50.  
  51. local function RightButtonOnUpdate(self, elapsed)
  52.     local x, y = GetCursorPosition()
  53.     local px, py, pz = self:GetPosition()
  54.     if IsAltKeyDown() then
  55.         local mx = format("%.2f", (px + (y - self.y) / 64))
  56.         if format("%.2f", px) ~= mx then
  57.             self:SetPosition(mx, py, pz)
  58.         end
  59.     else
  60.         local my = format("%.2f", (py + (x - self.x) / 64))
  61.         local mz = format("%.2f", (pz + (y - self.y) / 64))
  62.         if format("%.2f", py) ~= my or format("%.2f", pz) ~= mz then
  63.             self:SetPosition(px, my, mz)
  64.         end
  65.     end
  66.     self.x, self.y = x, y
  67. end
  68.  
  69. local function MiddleButtonOnUpdate(self, elapsed)
  70.     local x, y = GetCursorPosition()
  71.     local rotation = format("%.0f", math.abs(math.deg(((x - self.x) / 84 + self:GetFacing())) % 360))
  72.     if rotation ~= format("%.0f", math.abs(math.deg(self:GetFacing()) % 360)) then
  73.         self:SetRotation(math.rad(rotation))
  74.     end
  75.     self.x, self.y = x, y
  76. end
  77.  
  78. local function OnMouseDown(self, button)
  79.     if button == "LeftButton" then
  80.         if IsAltKeyDown() then
  81.             OnDragStart(frame)
  82.         else
  83.             self.x, self.y = GetCursorPosition()
  84.             self:SetScript("OnUpdate", OnUpdate)
  85.         end
  86.     elseif button == "RightButton" then
  87.         self.x, self.y = GetCursorPosition()
  88.         self:SetScript("OnUpdate", RightButtonOnUpdate)
  89.     elseif button == "MiddleButton" then
  90.         if IsAltKeyDown() then
  91.             self:Reset()
  92.         else
  93.             self.x, self.x = GetCursorPosition()
  94.             self:SetScript("OnUpdate", MiddleButtonOnUpdate)
  95.         end
  96.     end
  97. end
  98.  
  99. local function OnMouseUp(self, button)
  100.     OnDragStop(frame)
  101.     if button == "LeftButton" then
  102.         self:SetScript("OnUpdate", nil)
  103.     elseif button == "RightButton" then
  104.         self:SetScript("OnUpdate", nil)
  105.     elseif button == "MiddleButton" then
  106.         self:SetScript("OnUpdate", nil)
  107.     end
  108. end
  109.  
  110. local function OnMouseWheel(self, delta)
  111.     local zoom = 0.1
  112.     if IsControlKeyDown() then
  113.         zoom = 0.5
  114.     elseif IsAltKeyDown() then
  115.         zoom = 1
  116.     end
  117.     local distance = model.distance - delta * zoom
  118.     if distance > 40 then
  119.         distance = 40
  120.     elseif distance < zoom then
  121.         distance = zoom
  122.     end
  123.     self:SetOrientation(distance, model.yaw, model.pitch)
  124. end
  125.  
  126. function model:SetOrientation(distance, yaw, pitch)
  127.     if self:HasCustomCamera() then
  128.         self.distance, self.yaw, self.pitch = distance, yaw, pitch
  129.         local x = distance * math.cos(yaw) * math.cos(pitch)
  130.         local y = distance * math.sin(- yaw) * math.cos(pitch)
  131.         local z = (distance * math.sin(- pitch))
  132.         self:SetCameraPosition(x, y, z)
  133.     end
  134. end
  135.  
  136. local x, y, z, px, py, pz, rot
  137.  
  138. function model:Reset()
  139.     self:SetCustomCamera(1)
  140.     self:SetCameraPosition(x, y, z)
  141.     self:SetPosition(px, py, pz)
  142.     self:SetRotation(rot)
  143.     self:SetCameraTarget(0, 0, pi / 5)
  144.     self:SetOrientation(math.sqrt(x * x + y * y + z * z), - math.atan(y / x), - math.atan(z / x))
  145. end
  146.  
  147. function model:Initialize()
  148.     self:SetCustomCamera(1)
  149.     x, y, z = self:GetCameraPosition()
  150.     px, py, pz = self:GetPosition()
  151.     rot = self:GetFacing()
  152.     self:SetCameraTarget(0, 0, pi / 5)
  153.     self:SetOrientation(math.sqrt(x * x + y * y + z * z), - math.atan(y / x), - math.atan(z / x))
  154. end
  155.  
  156. model:SetScript("OnKeyUp", OnKeyUp)
  157. model:SetScript("OnDragStart", OnDragStart)
  158. model:SetScript("OnDragStop", OnDragStop)
  159. model:SetScript("OnMouseDown", OnMouseDown)
  160. model:SetScript("OnMouseUp", OnMouseUp)
  161. model:SetScript("OnMouseWheel", OnMouseWheel)
  162.  
  163. model:Initialize()

I think it's quite lightweigth but optimizations can always be done.

Last edited by Resike : 10-28-13 at 12:49 PM.
  Reply With Quote
10-29-13, 07:55 AM   #38
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Soo what you guys think about it?
  Reply With Quote
11-12-13, 06:30 AM   #39
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Preview v2:

http://www.youtube.com/watch?v=egzorLE4h8E
  Reply With Quote
11-12-13, 10:10 AM   #40
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
It looks awesome, great job!
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Model tilting

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off