Thread: Model tilting
View Single Post
10-24-13, 10:56 PM   #17
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Vrul View Post
The custom camera seems to be limited to keeping the model upright, that's what's causing the sudden flipping. You may just need to cap the pitch to +/- 90 degrees (+/- pi / 2 radians). Here is what I came up with from playing around with the camera stuff today (along with many client crashes):
Code:
local MODEL = "Creature/LasherSunflower/lasher_sunflower.m2"
local MODEL_SIZE = 256
local INCREMENT_ZOOM, MAX_ZOOM, MIN_ZOOM = 0.5, 20, 1

local atan, cos, sin, sqrt, PI = math.atan, math.cos, math.sin, math.sqrt, math.pi
local HALF_PI, INCREMENT_RATIO = PI / 2, PI / MODEL_SIZE

local frame = CreateFrame('Frame', nil, UIParent)
frame:SetPoint('CENTER', UIParent:GetWidth() / 4, UIParent:GetHeight() / 4)
frame:SetSize(MODEL_SIZE + 8, MODEL_SIZE + 8)
frame:SetBackdrop({
    bgFile = [[Interface\BUTTONS\WHITE8X8]],
    edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
    tileSize = 16, tile = true,
    insets = { left = 3, right = 3, top = 3, bottom = 3 }
})
frame:SetBackdropColor(0.05, 0.1, 0.15, 1)
frame:SetBackdropBorderColor(1, 1, 1, 1)
frame:EnableMouse(true)

local model = CreateFrame('PlayerModel', nil, frame)
model:SetPoint('CENTER')
model:SetSize(MODEL_SIZE, MODEL_SIZE)

local function OnMouseWheel(self, delta)
    local distance = self.distance - delta * INCREMENT_ZOOM
    if distance > MAX_ZOOM then
        distance = MAX_ZOOM
    elseif distance < MIN_ZOOM then
        distance = MIN_ZOOM
    end
    self:SetOrientation(distance, self.yaw, self.pitch)
end

local function OnUpdate(self, elapsed)
    local x, y = GetCursorPosition()
    local yaw = (x - self.x) * INCREMENT_RATIO
    if yaw > PI then
        yaw = PI
    elseif yaw < -PI then
        yaw = -PI
    end
    local pitch = (y - self.y) * INCREMENT_RATIO
    if pitch > HALF_PI then
        pitch = HALF_PI
    elseif pitch < -HALF_PI then
        pitch = -HALF_PI
    end
    self:SetOrientation(self.distance, yaw, pitch)
end

local function OnMouseDown(self, button)
    if button ~= 'LeftButton' then return end
    self.x, self.y = GetCursorPosition()
    self:SetScript('OnUpdate', OnUpdate)
end

local function OnMouseUp(self, button)
    self:SetScript('OnUpdate', nil)
    if button == 'MiddleButton' then
        self:SetOrientation(self._distance, self._yaw, self._pitch)
    end
end

function model:Initialize()
    self:EnableMouse(true)
    self:EnableMouseWheel(true)
    self:SetScript('OnMouseDown', OnMouseDown)
    self:SetScript('OnMouseUp', OnMouseUp)
    self:SetScript('OnMouseWheel', OnMouseWheel)
    self:SetScript('OnUpdate', nil)
end

function model:LoadModel(file)
    self:SetModel(file)
    self:SetCustomCamera(1)
    self:SetCameraDistance(1)
    local x, y, z = self:GetCameraPosition()
    self:SetCameraTarget(0, y, z)
    self._distance = sqrt(x * x + y * y + z * z)
    self._yaw = -atan(y / x)
    self._pitch = -atan(z / x)
    self:SetOrientation(self._distance, self._yaw, self._pitch)
end

function model:SetOrientation(distance, yaw, pitch)
    if self:HasCustomCamera() then
        self.distance, self.yaw, self.pitch = distance, yaw, pitch
        local x = distance * cos(yaw) * cos(pitch)
        local y = distance * sin(-yaw) * cos(pitch)
        local z = distance * sin(-pitch)
        self:SetCameraPosition(x, y, z)
    end
end

model:Initialize()
model:LoadModel(MODEL)
Quick question what does the SetOrientation do?

Thats actually really good, any chance to save the positions on mouseup and continue from there in the next click?
Also you could add the model:SetPosition(x, y, z) function to right clicking, then you have pretty much all the model functions in it.

Last edited by Resike : 10-24-13 at 11:04 PM.
  Reply With Quote