oldschool-toontown/libotp/nametag/Nametag3d.py

399 lines
14 KiB
Python

import math
from panda3d.core import *
from . import NametagGlobals
from .Nametag import Nametag
from ._constants import *
class Nametag3d(Nametag, PandaNode):
def __init__(self):
Nametag.__init__(self, 10.5)
PandaNode.__init__(self, 'unnamed')
self.m_np_360 = None
self.m_np_372 = None
self.m_np_balloon = None
# self.setCullCallback()
# safe_to_flatten_below: 0
self.cbNode = CallbackNode(self.getName() + '-cbNode')
self.cbNode.setCullCallback(PythonCallbackObject(self.cullCallback))
self.addChild(self.cbNode)
self.m_billboard_offset = 3.0
self.m_np_top = NodePath.anyPath(PandaNode('top'))
self.m_is_3d = 1
self.m_field_396 = 0
self.m_name_frame = Vec4(0, 0, 0, 0)
self.m_chat_contents = None
self.setBounds(BoundingSphere((0, 0, 0), 2.0))
def setBillboardOffset(self, billboard_offset):
self.m_billboard_offset = billboard_offset
def getBillboardOffset(self):
return self.m_billboard_offset
def cullCallback(self, traverse_data):
if self.isGroupManaged():
# sort = CullBinManager.getGlobalPtr().getBinSort(traverse_data._state.getBinIndex())
# np = traverse_data._node_path.getNodePath()
traverser = traverse_data.getTrav()
np = NodePath.anyPath(self)
sort = CullBinManager.getGlobalPtr().getBinSort(traverser.getInitialState().getBinIndex())
self.adjustToCamera(np, sort)
def manage(self, manager):
self.m_np_top.reparentTo(NodePath.anyPath(self))
self.updateContents()
def unmanage(self, manager):
self.m_np_top.detachNode()
Nametag.unmanage(self, manager)
def updateContents(self):
self.stopFlash()
if self.m_has_draw_order:
bin = config.GetString('nametag-fixed-bin', 'fixed')
self.m_np_top.setBin(bin, self.m_draw_order)
else:
self.m_np_top.clearBin()
if self.m_group:
self.setName(self.m_group.getName())
else:
self.setName('unnamed')
if self.m_np_360:
self.m_np_360.removeNode()
if self.m_np_372:
self.m_np_372.removeNode()
if self.m_np_balloon:
self.m_np_balloon.removeNode()
self.m_np_top.node().removeAllChildren()
self.m_chat_contents = self.determineContents()
if self.isGroupManaged():
if self.m_chat_contents & 2:
self.generateChat(NametagGlobals._speech_balloon_3d)
elif self.m_chat_contents & 4:
self.generateChat(NametagGlobals._thought_balloon_3d)
elif self.m_chat_contents & 1:
self.generateName()
def release(self, arg):
if arg.getButton() == MouseButton.one():
self.setState(PGButton.SRollover)
if self.m_group:
self.m_group.click()
def generateChat(self, balloon):
v5 = self.getState()
text_color = Vec4(NametagGlobals.getChatFg(self.m_group.getColorCode(), v5))
balloon_color = Vec4(NametagGlobals.getChatBg(self.m_group.getColorCode(), v5))
if self.m_group.m_chat_flags & CFQuicktalker:
balloon_color = Vec4(self.m_group.getQtColor())
text = self.m_group.getChat()
has_page_button = False
has_quit_button = False
if not self.m_group.m_has_timeout:
has_page_button = self.m_group.m_chat_flags & CFPageButton
if self.m_group.getPageNumber() >= self.m_group.getNumChatPages() - 1:
if self.m_group.m_chat_flags & CFQuitButton:
has_page_button = False
has_quit_button = True
page_button = None
if has_page_button:
page_button = NametagGlobals.getPageButton(v5)
elif has_quit_button:
page_button = NametagGlobals.getQuitButton(v5)
reversed = self.m_group.m_chat_flags & CFReversed
new_button = [None]
balloon_result = balloon.generate(text, self.m_group.getChatFont(), self.m_wordwrap,
text_color, balloon_color, self.m_is_3d,
self.m_has_draw_order, self.m_draw_order,
page_button, self.m_group.willHaveButton(),
reversed, new_button)
self.m_np_balloon = self.m_np_top.attachNewNode(balloon_result)
if new_button[0]:
self.startFlash(new_button[0])
self.m_name_frame = balloon.m_text_frame
self.m_field_396 = 1
def generateName(self):
v4 = self.getState()
v56 = Vec4(NametagGlobals.getNameFg(self.m_group.getColorCode(), v4))
v54 = Vec4(NametagGlobals.getNameBg(self.m_group.getColorCode(), v4))
self.m_name_frame = Vec4(*self.m_group.getNameFrame())
self.m_name_frame[0] -= NametagGlobals._card_pad[0]
self.m_name_frame[1] += NametagGlobals._card_pad[1]
self.m_name_frame[2] -= NametagGlobals._card_pad[2]
self.m_name_frame[3] += NametagGlobals._card_pad[3]
self.m_field_396 = 1
v47 = None
if v54[3] != 0.0:
card = CardMaker('nametag')
card.setFrame(self.m_name_frame)
card.setColor(v54)
if NametagGlobals._nametag_card:
card.setSourceGeometry(NametagGlobals._nametag_card.node(),
NametagGlobals._nametag_card_frame)
self.m_np_372 = self.m_np_top.attachNewNode(card.generate())
self.m_np_372.setTransparency(1)
v47 = self.m_np_372.find('**/+GeomNode')
label86 = False
if self.m_is_3d:
if self.m_group.m_name_icon:
self.m_group.m_name_icon.instanceTo(self.m_np_top)
if v47:
self.m_np_360 = self.m_group.copyNameTo(v47)
self.m_np_360.setDepthWrite(0)
self.m_np_360.setY(-0.01) # Panda3D 1.10 hack to prevent z-fighting.
v47.node().setEffect(DecalEffect.make())
else:
label86 = True
else:
label86 = True
if label86:
self.m_np_360 = self.m_group.copyNameTo(self.m_np_top)
if self.m_has_draw_order:
bin = config.GetString('nametag-fixed-bin', 'fixed')
self.m_name_icon.setBin(bin, self.m_draw_order + 1)
self.m_np_360.setBin(bin, self.m_draw_order + 2)
self.m_np_360.setColor(v56)
if v56[3] != 1.0:
self.m_np_360.setTransparency(1)
def adjustToCamera(self, np, sort):
if self.m_is_3d:
lens = NametagGlobals._camera.node().getLens(0)
if self.m_avatar or not self.m_group:
v131 = self.m_avatar
else:
v131 = self.m_group.m_avatar
v130 = NametagGlobals._camera.getTransform(np)
v25 = v130.getMat()
v204 = v25.xformVec(Vec3.up())
v203 = v25.xformVec(Vec3.forward())
v193 = Mat3()
lookAt(v193, Vec3(v203), Vec3(v204))
v177 = Mat4(v193)
v177_3_0 = v177[3][0]
v177_3_1 = v177[3][1]
a3 = np.getTransform(NametagGlobals._camera).getMat()
v122 = a3[3][1]
v30 = max(v122, 0.1)
v31 = v30 * 0.02
v121 = (v31 ** 0.5) * NametagGlobals.getGlobalNametagScale() * 0.56
if self.m_billboard_offset == 0.0:
v42 = 0
else:
v32 = v25[0][1]
v33 = v25[0][0]
v136 = v25[0][2]
v134 = v33
v127 = self.m_billboard_offset
v144 = math.sqrt(v136 * v136 + v32 * v32 + v134 * v134)
v129 = self.m_billboard_offset / v144
if v122 > 0.0:
if isinstance(lens, PerspectiveLens):
v37 = lens.getNear() + 0.001
if v122 - v129 < v37:
v129 = v122 - v37
v127 = v129 * v144
v121 = (v122 - v129) / v122 * v121
v38 = v25[3][0]
v39 = v25[3][1]
v126 = v25[3][2]
v125 = v39
v129 = v126 * v126 + v39 * v39 + v38 * v38
if v129 == 0.0:
v125 = 0.0
v38 = 0.0
v126 = 0.0
else:
v40 = v129 - 1.0
if abs(v40) > 0.0: # if ( v40 >= 1.0e-12 || v40 <= -1.0e-12 ) NOT ALMOST ZERO
v41 = 1.0 / math.sqrt(v129)
v38 *= v41
v125 *= v41
v126 *= v41
v126 *= v127
v177_3_0 = v38 * v127
v177_3_1 = v125 * v127
v42 = v126
v205 = Mat4(v177[0][0] * v121, v177[0][1] * v121, v177[0][2] * v121, v177[0][3] * v121,
v177[1][0] * v121, v177[1][1] * v121, v177[1][2] * v121, v177[1][3] * v121,
v177[2][0] * v121, v177[2][1] * v121, v177[2][2] * v121, v177[2][3] * v121,
v177_3_0, v177_3_1, v42, v177[3][3])
self.m_np_top.setMat(v205)
v51 = 0
if self.displayAsActive():
if not self.m_chat_contents & (2 | 4):
v51 = 1
elif not self.m_group:
v51 = 1
elif self.m_group.m_has_timeout:
v51 = 1
elif not self.m_group.willHaveButton():
v51 = 1
elif self.m_group.getPageNumber() >= self.m_group.getNumChatPages() - 1:
v51 = 1
v123 = 0
sorta = 0
frame = Vec4(0, 0, 0, 0)
v150 = lens.getProjectionMat()
if v51:
v138, v139, v140 = v205.xformVec(Vec3(-2.5, 0.0, 1.0))
v124, v125, v126 = v205.xformVec(Vec3(2.5, 0.0, 1.0))
v121 = np.getTransform(v131)
if v121.isInvalid():
return
v64 = v121.getMat()
v138, v139, v140 = v64.xformPoint(Point3(v138, v139, v140))
v124, v125, v126 = v64.xformPoint(Point3(v124, v125, v126))
v122 = v131.getTransform(NametagGlobals._camera)
if v122.isInvalid():
return
v124, v125, v126 = v122.getMat().xformPoint(Point3(v124, v125, v126))
v134, v135, v136 = v122.getMat().xformPoint(Point3(v138, v139, 0.0))
a2 = v150.xform(Vec4(v124, v125, v126, 1.0))
frame = v150.xform(Vec4(v134, v135, v136, 1.0))
if a2[3] <= 0.0 or frame[3] <= 0.0:
self.m_group.m_nametag3d_flag &= (self.m_group.m_nametag3d_flag <= 0) - 1
self.deactivate()
return
v123 = 1
v133 = 1.0 / frame[3]
v128 = 1.0 / a2[3]
frame = Vec4(frame[0] * v133, a2[0] * v128, frame[1] * v133, a2[1] * v128)
v89 = 0
if self.m_field_396:
v124, v125, v126 = v205.xformPoint(Point3(self.m_name_frame[0] - 0.5, 0.0, self.m_name_frame[2] - 1.0))
v138, v139, v140 = v205.xformPoint(Point3(self.m_name_frame[1] + 0.5, 0.0, self.m_name_frame[3] + 1.0))
v124, v125, v126 = a3.xformPoint(Point3(v124, v125, v126))
v138, v139, v140 = a3.xformPoint(Point3(v138, v139, v140))
a2 = v150.xform(Vec4(v138, v139, v140, 1.0))
v134, v135, v136, v137 = v150.xform(Vec4(v124, v125, v126, 1.0))
if v137 <= 0.0 or a2[3] <= 0.0:
v89 = 1
else:
v133 = 1.0 / v137
v109 = 1.0 / a2[3]
v110 = v109 * a2[1]
v127 = v133 * v135
v131 = v109 * a2[0]
v111 = v133 * v134
v146 = v111
if v111 < -1.0 or v131 > 1.0 or v127 < -1.0 or v110 > 1.0:
v89 = 1
if v123:
if frame[3] > v110:
v110 = frame[3]
if frame[2] >= v127:
v115 = v127
else:
v115 = frame[2]
if frame[1] <= v131:
v116 = v131
else:
v116 = frame[1]
if frame[0] >= v146:
frame[0] = v146
frame[1] = v116
frame[2] = v115
else:
frame[0] = v146
frame[1] = v131
frame[2] = v127
v123 = 1
frame[3] = v110
sorta = int(v125 * -100.0)
if v123 and self.displayAsActive():
self.setRegion(frame, sorta)
v118 = self.m_group.m_nametag3d_flag
if v89:
v118 = max(v118, 1)
elif v118 <= 2:
v118 = 2
self.m_group.setNametag3dFlag(v118)
return
self.m_group.incrementNametag3dFlag(2)
if not self.displayAsActive():
return
if not self.m_field_396:
return
v12 = np.getNetTransform().getMat()
v124 = v12.xformPoint(Point3(self.m_name_frame[0] - 0.5, 0, self.m_name_frame[2] - 1.0))
v16 = v12.xformPoint(Point3(self.m_name_frame[1] + 0.5, 0, self.m_name_frame[3] + 1.0))
v131 = Vec4(v124[0], v16[0], v124[2], v16[2])
self.setRegion(v131, sort)