Merge branch 'master' of github.com:Astron/panda3d
This commit is contained in:
commit
b34b44e894
|
|
@ -566,7 +566,7 @@ class Actor(DirectObject, NodePath):
|
|||
# and sort them every time somebody asks for the list
|
||||
self.__sortedLODNames = self.__partBundleDict.keys()
|
||||
# Reverse sort the doing a string->int
|
||||
def sortFunc(x, y):
|
||||
def sortKey(x):
|
||||
if not str(x).isdigit():
|
||||
smap = {'h':3,
|
||||
'm':2,
|
||||
|
|
@ -574,19 +574,16 @@ class Actor(DirectObject, NodePath):
|
|||
'f':0}
|
||||
|
||||
"""
|
||||
sx = smap.get(x[0],None)
|
||||
sy = smap.get(y[0],None)
|
||||
sx = smap.get(x[0], None)
|
||||
|
||||
if sx is None:
|
||||
self.notify.error('Invalid lodName: %s' % x)
|
||||
if sy is None:
|
||||
self.notify.error('Invalid lodName: %s' % y)
|
||||
"""
|
||||
return cmp(smap[y[0]], smap[x[0]])
|
||||
return smap[x[0]]
|
||||
else:
|
||||
return cmp (int(y), int(x))
|
||||
return int(x)
|
||||
|
||||
self.__sortedLODNames.sort(sortFunc)
|
||||
self.__sortedLODNames.sort(key=sortKey, reverse=True)
|
||||
|
||||
def getLODNames(self):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class DirectNotify:
|
|||
# we're running before ShowBase has finished initializing; and
|
||||
# we import it directly from libpandaexpress, in case we're
|
||||
# running before libpanda.dll is available.
|
||||
from libpandaexpress import ConfigVariableString
|
||||
from panda3d.core import ConfigVariableString
|
||||
|
||||
dconfigParam = ("notify-level-" + categoryName)
|
||||
cvar = ConfigVariableString(dconfigParam, "")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ for the programmer/user
|
|||
"""
|
||||
from LoggerGlobal import defaultLogger
|
||||
from direct.showbase import PythonUtil
|
||||
from libpandaexpress import ConfigVariableBool
|
||||
from panda3d.core import ConfigVariableBool
|
||||
import time
|
||||
import types
|
||||
import sys
|
||||
|
|
@ -18,7 +18,7 @@ class Notifier:
|
|||
# with the C++ notify system.
|
||||
streamWriter = None
|
||||
if ConfigVariableBool('notify-integrate', True):
|
||||
from libpandaexpress import StreamWriter, Notify
|
||||
from panda3d.core import StreamWriter, Notify
|
||||
streamWriter = StreamWriter(Notify.out(), False)
|
||||
|
||||
showTime = ConfigVariableBool('notify-timestamp', False)
|
||||
|
|
|
|||
|
|
@ -103,8 +103,6 @@ Section "${SMDIRECTORY}" SecCore
|
|||
File /r /x CVS /x Opt?-Win32 "${PSOURCE}\direct\filter\*.sha"
|
||||
SetOutPath $INSTDIR\direct
|
||||
File /r /x CVS /x Opt?-Win32 "${PSOURCE}\direct\*.py"
|
||||
SetOutPath $INSTDIR
|
||||
File "${PSOURCE}\panda3d.py"
|
||||
!else
|
||||
File /r /x CVS /x Opt?-Win32 "${PSOURCE}\direct\src\directscripts\*"
|
||||
SetOutPath $INSTDIR\direct\filter
|
||||
|
|
@ -112,11 +110,15 @@ Section "${SMDIRECTORY}" SecCore
|
|||
SetOutPath $INSTDIR\direct
|
||||
File /r /x CVS /x Opt?-Win32 "${PSOURCE}\direct\src\*.py"
|
||||
File "${PANDA}\tmp\__init__.py"
|
||||
SetOutPath $INSTDIR
|
||||
File "${PSOURCE}\direct\src\ffi\panda3d.py"
|
||||
!endif
|
||||
Delete "$INSTDIR\panda3d.py"
|
||||
Delete "$INSTDIR\panda3d.pyc"
|
||||
Delete "$INSTDIR\panda3d.pyo"
|
||||
SetOutPath $INSTDIR\pandac
|
||||
File /r "${PANDA}\pandac\*.py"
|
||||
SetOutPath $INSTDIR\panda3d
|
||||
File /r "${PANDA}\panda3d\*.py"
|
||||
File /r "${PANDA}\panda3d\*.pyd"
|
||||
SetOutPath $INSTDIR\python
|
||||
File /r "${PANDA}\python\*"
|
||||
RMDir /r "$SMPROGRAMS\${SMDIRECTORY}"
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ class SelectedNodePaths(DirectObject):
|
|||
break
|
||||
|
||||
# Get this pointer
|
||||
id = nodePath.id()
|
||||
id = nodePath.get_key()
|
||||
# First see if its already in the selected dictionary
|
||||
dnp = self.getSelectedDict(id)
|
||||
# If so, deselect it
|
||||
|
|
@ -104,7 +104,7 @@ class SelectedNodePaths(DirectObject):
|
|||
# Show its bounding box
|
||||
dnp.highlight(fRecompute = 0)
|
||||
# Add it to the selected dictionary
|
||||
self.selectedDict[dnp.id()] = dnp
|
||||
self.selectedDict[dnp.get_key()] = dnp
|
||||
self.selectedList.append(dnp) # [gjeon]
|
||||
|
||||
# And update last
|
||||
|
|
@ -117,7 +117,7 @@ class SelectedNodePaths(DirectObject):
|
|||
def deselect(self, nodePath):
|
||||
""" Deselect the specified node path """
|
||||
# Get this pointer
|
||||
id = nodePath.id()
|
||||
id = nodePath.get_key()
|
||||
# See if it is in the selected dictionary
|
||||
dnp = self.getSelectedDict(id)
|
||||
if dnp:
|
||||
|
|
@ -240,7 +240,7 @@ class SelectedNodePaths(DirectObject):
|
|||
|
||||
def getDirectNodePath(self, nodePath):
|
||||
# Get this pointer
|
||||
id = nodePath.id()
|
||||
id = nodePath.get_key()
|
||||
# First check selected dict
|
||||
dnp = self.getSelectedDict(id)
|
||||
if dnp:
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class AstronDatabaseInterface:
|
|||
"""
|
||||
|
||||
# Save the callback:
|
||||
ctx = self.air.contextAllocator.allocate()
|
||||
ctx = self.air.getContext()
|
||||
self._callbacks[ctx] = callback
|
||||
|
||||
# Pack up/count valid fields.
|
||||
|
|
@ -72,7 +72,6 @@ class AstronDatabaseInterface:
|
|||
self._callbacks[ctx](doId)
|
||||
|
||||
del self._callbacks[ctx]
|
||||
self.air.contextAllocator.free(ctx)
|
||||
|
||||
def queryObject(self, databaseId, doId, callback):
|
||||
"""
|
||||
|
|
@ -84,7 +83,7 @@ class AstronDatabaseInterface:
|
|||
"""
|
||||
|
||||
# Save the callback:
|
||||
ctx = self.air.contextAllocator.allocate()
|
||||
ctx = self.air.getContext()
|
||||
self._callbacks[ctx] = callback
|
||||
|
||||
# Generate and send the datagram:
|
||||
|
|
@ -138,7 +137,6 @@ class AstronDatabaseInterface:
|
|||
|
||||
finally:
|
||||
del self._callbacks[ctx]
|
||||
self.air.contextAllocator.free(ctx)
|
||||
|
||||
def updateObject(self, databaseId, doId, dclass, newFields, oldFields=None, callback=None):
|
||||
"""
|
||||
|
|
@ -192,7 +190,7 @@ class AstronDatabaseInterface:
|
|||
# Generate and send the datagram:
|
||||
dg = PyDatagram()
|
||||
if oldFields is not None:
|
||||
ctx = self.air.contextAllocator.allocate()
|
||||
ctx = self.air.getContext()
|
||||
self._callbacks[ctx] = callback
|
||||
if fieldCount == 1:
|
||||
dg.addServerHeader(databaseId, self.air.ourChannel,
|
||||
|
|
@ -235,6 +233,11 @@ class AstronDatabaseInterface:
|
|||
self._callbacks[ctx](None)
|
||||
return
|
||||
|
||||
if not di.getRemainingSize():
|
||||
# We failed due to other reasons.
|
||||
if self._callbacks[ctx]:
|
||||
return self._callbacks[ctx]({})
|
||||
|
||||
if multi:
|
||||
fieldCount = di.getUint16()
|
||||
else:
|
||||
|
|
@ -260,7 +263,6 @@ class AstronDatabaseInterface:
|
|||
|
||||
finally:
|
||||
del self._callbacks[ctx]
|
||||
self.air.contextAllocator.free(ctx)
|
||||
|
||||
def handleDatagram(self, msgType, di):
|
||||
if msgType == DBSERVER_CREATE_OBJECT_RESP:
|
||||
|
|
|
|||
|
|
@ -7,6 +7,80 @@ from ConnectionRepository import ConnectionRepository
|
|||
from PyDatagram import PyDatagram
|
||||
from PyDatagramIterator import PyDatagramIterator
|
||||
from AstronDatabaseInterface import AstronDatabaseInterface
|
||||
from NetMessenger import NetMessenger
|
||||
import collections
|
||||
|
||||
# Helper functions for logging output:
|
||||
def msgpack_length(dg, length, fix, maxfix, tag8, tag16, tag32):
|
||||
if length < maxfix:
|
||||
dg.addUint8(fix + length)
|
||||
elif tag8 is not None and length < 1<<8:
|
||||
dg.addUint8(tag8)
|
||||
dg.addUint8(length)
|
||||
elif tag16 is not None and length < 1<<16:
|
||||
dg.addUint8(tag16)
|
||||
dg.addBeUint16(length)
|
||||
elif tag32 is not None and length < 1<<32:
|
||||
dg.addUint8(tag32)
|
||||
dg.addBeUint32(length)
|
||||
else:
|
||||
raise ValueError('Value too big for MessagePack')
|
||||
|
||||
def msgpack_encode(dg, element):
|
||||
if element == None:
|
||||
dg.addUint8(0xc0)
|
||||
elif element == False:
|
||||
dg.addUint8(0xc2)
|
||||
elif element == True:
|
||||
dg.addUint8(0xc3)
|
||||
elif isinstance(element, (int, long)):
|
||||
if -32 <= element < 128:
|
||||
dg.addInt8(element)
|
||||
elif 128 <= element < 256:
|
||||
dg.addUint8(0xcc)
|
||||
dg.addUint8(element)
|
||||
elif 256 <= element < 65536:
|
||||
dg.addUint8(0xcd)
|
||||
dg.addBeUint16(element)
|
||||
elif 65536 <= element < (1<<32):
|
||||
dg.addUint8(0xce)
|
||||
dg.addBeUint32(element)
|
||||
elif (1<<32) <= element < (1<<64):
|
||||
dg.addUint8(0xcf)
|
||||
dg.addBeUint64(element)
|
||||
elif -128 <= element < -32:
|
||||
dg.addUint8(0xd0)
|
||||
dg.addInt8(element)
|
||||
elif -32768 <= element < -128:
|
||||
dg.addUint8(0xd1)
|
||||
dg.addBeInt16(element)
|
||||
elif -1<<31 <= element < -32768:
|
||||
dg.addUint8(0xd2)
|
||||
dg.addBeInt32(element)
|
||||
elif -1<<63 <= element < -1<<31:
|
||||
dg.addUint8(0xd3)
|
||||
dg.addBeInt64(element)
|
||||
else:
|
||||
raise ValueError('int out of range for msgpack: %d' % element)
|
||||
elif isinstance(element, dict):
|
||||
msgpack_length(dg, len(element), 0x80, 0x10, None, 0xde, 0xdf)
|
||||
for k,v in element.items():
|
||||
msgpack_encode(dg, k)
|
||||
msgpack_encode(dg, v)
|
||||
elif isinstance(element, list):
|
||||
msgpack_length(dg, len(element), 0x90, 0x10, None, 0xdc, 0xdd)
|
||||
for v in element:
|
||||
msgpack_encode(dg, v)
|
||||
elif isinstance(element, basestring):
|
||||
msgpack_length(dg, len(element), 0xa0, 0x20, 0xd9, 0xda, 0xdb)
|
||||
dg.appendData(element)
|
||||
elif isinstance(element, float):
|
||||
# Python does not distinguish between floats and doubles, so we send
|
||||
# everything as a double in MsgPack:
|
||||
dg.addUint8(0xcb)
|
||||
dg.addFloat64(element)
|
||||
else:
|
||||
raise TypeError('Encountered non-MsgPack-packable value: %r' % element)
|
||||
|
||||
class AstronInternalRepository(ConnectionRepository):
|
||||
"""
|
||||
|
|
@ -43,9 +117,12 @@ class AstronInternalRepository(ConnectionRepository):
|
|||
self.channelAllocator = UniqueIdAllocator(baseChannel, baseChannel+maxChannels-1)
|
||||
self._registeredChannels = set()
|
||||
|
||||
self.contextAllocator = UniqueIdAllocator(0, 100)
|
||||
self.__contextCounter = 0
|
||||
|
||||
self.netMessenger = NetMessenger(self)
|
||||
|
||||
self.dbInterface = AstronDatabaseInterface(self)
|
||||
self.__callbacks = {}
|
||||
|
||||
self.ourChannel = self.allocateChannel()
|
||||
|
||||
|
|
@ -61,6 +138,10 @@ class AstronInternalRepository(ConnectionRepository):
|
|||
|
||||
self.readDCFile(dcFileNames)
|
||||
|
||||
def getContext(self):
|
||||
self.__contextCounter = (self.__contextCounter + 1) & 0xFFFFFFFF
|
||||
return self.__contextCounter
|
||||
|
||||
def allocateChannel(self):
|
||||
"""
|
||||
Allocate an unused channel out of this AIR's configured channel space.
|
||||
|
|
@ -153,6 +234,11 @@ class AstronInternalRepository(ConnectionRepository):
|
|||
DBSERVER_OBJECT_SET_FIELD_IF_EQUALS_RESP,
|
||||
DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP):
|
||||
self.dbInterface.handleDatagram(msgType, di)
|
||||
elif msgType == DBSS_OBJECT_GET_ACTIVATED_RESP:
|
||||
self.handleGetActivatedResp(di)
|
||||
elif msgType >= 20000:
|
||||
# These messages belong to the NetMessenger:
|
||||
self.netMessenger.handle(msgType, di)
|
||||
else:
|
||||
self.notify.warning('Received message with unknown MsgType=%d' % msgType)
|
||||
|
||||
|
|
@ -211,6 +297,30 @@ class AstronInternalRepository(ConnectionRepository):
|
|||
do.delete()
|
||||
do.sendDeleteEvent()
|
||||
|
||||
def handleGetActivatedResp(self, di):
|
||||
ctx = di.getUint32()
|
||||
doId = di.getUint32()
|
||||
activated = di.getUint8()
|
||||
|
||||
if ctx not in self.__callbacks:
|
||||
self.notify.warning('Received unexpected DBSS_OBJECT_GET_ACTIVATED_RESP (ctx: %d)' %ctx)
|
||||
return
|
||||
|
||||
try:
|
||||
self.__callbacks[ctx](doId, activated)
|
||||
finally:
|
||||
del self.__callbacks[ctx]
|
||||
|
||||
def getActivated(self, doId, callback):
|
||||
ctx = self.getContext()
|
||||
self.__callbacks[ctx] = callback
|
||||
|
||||
dg = PyDatagram()
|
||||
dg.addServerHeader(doId, self.ourChannel, DBSS_OBJECT_GET_ACTIVATED)
|
||||
dg.addUint32(ctx)
|
||||
dg.addUint32(doId)
|
||||
self.send(dg)
|
||||
|
||||
def sendUpdate(self, do, fieldName, args):
|
||||
"""
|
||||
Send a field update for the given object.
|
||||
|
|
@ -403,7 +513,7 @@ class AstronInternalRepository(ConnectionRepository):
|
|||
self.eventSocket = SocketUDPOutgoing()
|
||||
self.eventSocket.InitToAddress(address)
|
||||
|
||||
def writeServerEvent(self, logtype, *args):
|
||||
def writeServerEvent(self, logtype, *args, **kwargs):
|
||||
"""
|
||||
Write an event to the central Event Logger, if one is configured.
|
||||
|
||||
|
|
@ -415,9 +525,16 @@ class AstronInternalRepository(ConnectionRepository):
|
|||
if self.eventSocket is None:
|
||||
return # No event logger configured!
|
||||
|
||||
log = collections.OrderedDict()
|
||||
log['type'] = logtype
|
||||
log['sender'] = self.eventLogId
|
||||
|
||||
for i,v in enumerate(args):
|
||||
# +1 because the logtype was _0, so we start at _1
|
||||
log['_%d' % (i+1)] = v
|
||||
|
||||
log.update(kwargs)
|
||||
|
||||
dg = PyDatagram()
|
||||
dg.addString(self.eventLogId)
|
||||
dg.addString(logtype)
|
||||
for arg in args:
|
||||
dg.addString(str(arg))
|
||||
msgpack_encode(dg, log)
|
||||
self.eventSocket.Send(dg.getMessage())
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ MsgName2Id = {
|
|||
# DBSS-backed-object messages:
|
||||
'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS': 2200,
|
||||
'DBSS_OBJECT_ACTIVATE_WITH_DEFAULTS_OTHER': 2201,
|
||||
'DBSS_OBJECT_GET_ACTIVATED': 2207,
|
||||
'DBSS_OBJECT_GET_ACTIVATED_RESP': 2208,
|
||||
'DBSS_OBJECT_DELETE_FIELD_DISK': 2230,
|
||||
'DBSS_OBJECT_DELETE_FIELDS_DISK': 2231,
|
||||
'DBSS_OBJECT_DELETE_DISK': 2232,
|
||||
|
|
@ -137,9 +139,7 @@ MsgName2Id = {
|
|||
MsgId2Names = invertDictLossless(MsgName2Id)
|
||||
|
||||
# put msg names in module scope, assigned to msg value
|
||||
for name, value in MsgName2Id.items():
|
||||
exec('%s = %s' % (name, value))
|
||||
del name, value
|
||||
globals().update(MsgName2Id)
|
||||
|
||||
# These messages are ignored when the client is headed to the quiet zone
|
||||
QUIET_ZONE_IGNORED_LIST = [
|
||||
|
|
|
|||
|
|
@ -26,6 +26,4 @@ MsgName2Id = {
|
|||
MsgId2Names = invertDictLossless(MsgName2Id)
|
||||
|
||||
# put msg names in module scope, assigned to msg value
|
||||
for name, value in MsgName2Id.items():
|
||||
exec('%s = %s' % (name, value))
|
||||
del name, value
|
||||
globals().update(MsgName2Id)
|
||||
|
|
|
|||
|
|
@ -6,26 +6,6 @@ from direct.distributed.PyDatagram import PyDatagram
|
|||
from direct.showbase.Messenger import Messenger
|
||||
|
||||
|
||||
# Messages do not need to be in the MESSAGE_TYPES list.
|
||||
# This is just an optimization. If the message is found
|
||||
# in this list, it is reduced to an integer index and
|
||||
# the message string is not sent. Otherwise, the message
|
||||
# string is sent in the datagram.
|
||||
MESSAGE_TYPES=(
|
||||
"avatarOnline",
|
||||
"avatarOffline",
|
||||
"create",
|
||||
"needUberdogCreates",
|
||||
"transferDo",
|
||||
)
|
||||
|
||||
# This is the reverse look up for the recipient of the
|
||||
# datagram:
|
||||
MESSAGE_STRINGS={}
|
||||
for i in zip(MESSAGE_TYPES, range(1, len(MESSAGE_TYPES)+1)):
|
||||
MESSAGE_STRINGS[i[0]]=i[1]
|
||||
|
||||
|
||||
class NetMessenger(Messenger):
|
||||
"""
|
||||
This works very much like the Messenger class except that messages
|
||||
|
|
@ -34,62 +14,101 @@ class NetMessenger(Messenger):
|
|||
"""
|
||||
notify = DirectNotifyGlobal.directNotify.newCategory('NetMessenger')
|
||||
|
||||
def __init__(self, air, channels):
|
||||
def __init__(self, air, baseChannel=20000, baseMsgType=20000):
|
||||
"""
|
||||
air is the AI Repository.
|
||||
channels is a list of channel IDs (uint32 values)
|
||||
baseChannel is the channel that the first message is sent on.
|
||||
baseMsgType is the MsgType of the same.
|
||||
"""
|
||||
assert self.notify.debugCall()
|
||||
Messenger.__init__(self)
|
||||
self.air=air
|
||||
self.channels=channels
|
||||
for i in self.channels:
|
||||
self.air.registerForChannel(i)
|
||||
self.baseChannel = baseChannel
|
||||
self.baseMsgType = baseMsgType
|
||||
|
||||
self.__message2type = {}
|
||||
self.__type2message = {}
|
||||
self.__message2channel = {}
|
||||
|
||||
def clear(self):
|
||||
assert self.notify.debugCall()
|
||||
for i in self.channels:
|
||||
self.air.unRegisterChannel(i)
|
||||
del self.air
|
||||
del self.channels
|
||||
Messenger.clear(self)
|
||||
|
||||
def send(self, message, sentArgs=[]):
|
||||
def register(self, code, message):
|
||||
assert self.notify.debugCall()
|
||||
channel = self.baseChannel + code
|
||||
msgType = self.baseMsgType + code
|
||||
|
||||
if message in self.__message2type:
|
||||
self.notify.error('Tried to register message %s twice!' % message)
|
||||
return
|
||||
|
||||
self.__message2type[message] = msgType
|
||||
self.__type2message[msgType] = message
|
||||
self.__message2channel[message] = channel
|
||||
|
||||
def prepare(self, message, sentArgs=[]):
|
||||
"""
|
||||
Send message to All AI and Uber Dog servers.
|
||||
Prepare the datagram that would get sent in order to send this message
|
||||
to its designated channel.
|
||||
"""
|
||||
assert self.notify.debugCall()
|
||||
|
||||
# Make sure the message is registered:
|
||||
if message not in self.__message2type:
|
||||
self.notify.error('Tried to send unregistered message %s!' % message)
|
||||
return
|
||||
|
||||
datagram = PyDatagram()
|
||||
# To:
|
||||
datagram.addUint8(1)
|
||||
datagram.addChannel(self.channels[0])
|
||||
datagram.addChannel(self.__message2channel[message])
|
||||
# From:
|
||||
datagram.addChannel(self.air.ourChannel)
|
||||
#if 1: # We send this just because the air expects it:
|
||||
# # Add an 'A' for AI
|
||||
# datagram.addUint8(ord('A'))
|
||||
|
||||
messageType=MESSAGE_STRINGS.get(message, 0)
|
||||
messageType=self.__message2type[message]
|
||||
datagram.addUint16(messageType)
|
||||
if messageType:
|
||||
datagram.addString(str(dumps(sentArgs)))
|
||||
else:
|
||||
datagram.addString(str(dumps((message, sentArgs))))
|
||||
self.air.send(datagram)
|
||||
datagram.addString(str(dumps(sentArgs)))
|
||||
|
||||
def handle(self, pickleData):
|
||||
return datagram
|
||||
|
||||
def accept(self, message, *args):
|
||||
if message not in self.__message2channel:
|
||||
self.notify.error('Tried to accept unregistered message %s!' % message)
|
||||
return
|
||||
|
||||
anyAccepting = bool(self.whoAccepts(message))
|
||||
if not anyAccepting:
|
||||
self.air.registerForChannel(self.__message2channel[message])
|
||||
|
||||
Messenger.accept(self, message, *args)
|
||||
|
||||
def send(self, message, sentArgs=[]):
|
||||
"""
|
||||
Send pickleData from the net on the local netMessenger.
|
||||
The internal data in pickleData should have a tuple of
|
||||
(messageString, sendArgsList).
|
||||
Send message to anything that's listening for it.
|
||||
"""
|
||||
assert self.notify.debugCall()
|
||||
messageType=self.air.getMsgType()
|
||||
if messageType:
|
||||
message=MESSAGE_TYPES[messageType-1]
|
||||
sentArgs=loads(pickleData)
|
||||
else:
|
||||
(message, sentArgs) = loads(pickleData)
|
||||
|
||||
datagram = self.prepare(message, sentArgs)
|
||||
self.air.send(datagram)
|
||||
Messenger.send(self, message, sentArgs=sentArgs)
|
||||
|
||||
def handle(self, msgType, di):
|
||||
"""
|
||||
Send data from the net on the local netMessenger.
|
||||
"""
|
||||
assert self.notify.debugCall()
|
||||
|
||||
if msgType not in self.__type2message:
|
||||
self.notify.warning('Received unknown message: %d' % msgType)
|
||||
return
|
||||
|
||||
message = self.__type2message[msgType]
|
||||
sentArgs=loads(di.getString())
|
||||
|
||||
if type(sentArgs) != list:
|
||||
self.notify.warning('Received non-list item in %s message: %r' %
|
||||
(message, sentArgs))
|
||||
return
|
||||
|
||||
Messenger.send(self, message, sentArgs=sentArgs)
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
# For iterating over children
|
||||
def getChildren(self):
|
||||
"""Returns a Python list of the egg node's children."""
|
||||
result = []
|
||||
child = self.getFirstChild()
|
||||
while (child != None):
|
||||
result.append(child)
|
||||
child = self.getNextChild()
|
||||
return result
|
||||
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
# For iterating over vertices
|
||||
def getVertices(self):
|
||||
"""Returns a Python list of the egg primitive's vertices."""
|
||||
result = []
|
||||
for i in range(self.getNumVertices()):
|
||||
result.append(self.getVertex(i))
|
||||
return result
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
|
||||
"""
|
||||
NodePathCollection-extensions module: contains methods to extend
|
||||
functionality of the NodePathCollection class
|
||||
"""
|
||||
|
||||
# For iterating over children
|
||||
def asList(self):
|
||||
"""Converts a NodePathCollection into a list"""
|
||||
if self.isEmpty():
|
||||
return []
|
||||
else:
|
||||
npList = []
|
||||
for nodePathIndex in range(self.getNumPaths()):
|
||||
npList.append(self.getPath(nodePathIndex))
|
||||
return npList
|
||||
|
||||
def getTightBounds(self):
|
||||
from pandac import Point3
|
||||
|
||||
if self.getNumPaths() == 0:
|
||||
return (Point3.Point3(0), Point3.Point3(0))
|
||||
|
||||
v1, v2 = self.getPath(0).getTightBounds()
|
||||
for i in range(1, self.getNumPaths()):
|
||||
v1x, v2x = self.getPath(i).getTightBounds()
|
||||
v1 = Point3.Point3(min(v1[0], v1x[0]),
|
||||
min(v1[1], v1x[1]),
|
||||
min(v1[2], v1x[2]))
|
||||
v2 = Point3.Point3(max(v2[0], v2x[0]),
|
||||
max(v2[1], v2x[1]),
|
||||
max(v2[2], v2x[2]))
|
||||
|
||||
return v1, v2
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
def getConvertedJoint(self, index):
|
||||
"""
|
||||
Return a downcast joint on this body.
|
||||
"""
|
||||
return self.getJoint(index).convert()
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
|
||||
def convert(self):
|
||||
"""
|
||||
Do a sort of pseudo-downcast on this geom in
|
||||
order to expose its specialized functions.
|
||||
"""
|
||||
if self.getGeomClass() == OdeGeom.GCSphere:
|
||||
return self.convertToSphere()
|
||||
elif self.getGeomClass() == OdeGeom.GCBox:
|
||||
return self.convertToBox()
|
||||
elif self.getGeomClass() == OdeGeom.GCCappedCylinder:
|
||||
return self.convertToCappedCylinder()
|
||||
elif self.getGeomClass() == OdeGeom.GCPlane:
|
||||
return self.convertToPlane()
|
||||
elif self.getGeomClass() == OdeGeom.GCRay:
|
||||
return self.convertToRay()
|
||||
# elif self.getGeomClass() == OdeGeom.GCConvex:
|
||||
# return self.convertToConvex()
|
||||
# elif self.getGeomClass() == OdeGeom.GCGeomTransform:
|
||||
# return self.convertToGeomTransform()
|
||||
elif self.getGeomClass() == OdeGeom.GCTriMesh:
|
||||
return self.convertToTriMesh()
|
||||
# elif self.getGeomClass() == OdeGeom.GCHeightfield:
|
||||
# return self.convertToHeightfield()
|
||||
elif self.getGeomClass() == OdeGeom.GCSimpleSpace:
|
||||
return self.convertToSimpleSpace()
|
||||
elif self.getGeomClass() == OdeGeom.GCHashSpace:
|
||||
return self.convertToHashSpace()
|
||||
elif self.getGeomClass() == OdeGeom.GCQuadTreeSpace:
|
||||
return self.convertToQuadTreeSpace()
|
||||
|
||||
def getConvertedSpace(self):
|
||||
"""
|
||||
"""
|
||||
return self.getSpace().convert()
|
||||
|
||||
def getAABounds(self):
|
||||
"""
|
||||
A more Pythonic way of calling getAABB().
|
||||
"""
|
||||
min = Point3()
|
||||
max = Point3()
|
||||
self.getAABB(min,max)
|
||||
return min,max
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
def attach(self, body1, body2):
|
||||
"""
|
||||
Attach two bodies together.
|
||||
If either body is None, the other will be attached to the environment.
|
||||
"""
|
||||
if body1 and body2:
|
||||
self.attachBodies(body1, body2)
|
||||
elif body1 and not body2:
|
||||
self.attachBody(body1, 0)
|
||||
elif not body1 and body2:
|
||||
self.attachBody(body2, 1)
|
||||
|
||||
def convert(self):
|
||||
"""
|
||||
Do a sort of pseudo-downcast on this joint in
|
||||
order to expose its specialized functions.
|
||||
"""
|
||||
if self.getJointType() == OdeJoint.JTBall:
|
||||
return self.convertToBall()
|
||||
elif self.getJointType() == OdeJoint.JTHinge:
|
||||
return self.convertToHinge()
|
||||
elif self.getJointType() == OdeJoint.JTSlider:
|
||||
return self.convertToSlider()
|
||||
elif self.getJointType() == OdeJoint.JTContact:
|
||||
return self.convertToContact()
|
||||
elif self.getJointType() == OdeJoint.JTUniversal:
|
||||
return self.convertToUniversal()
|
||||
elif self.getJointType() == OdeJoint.JTHinge2:
|
||||
return self.convertToHinge2()
|
||||
elif self.getJointType() == OdeJoint.JTFixed:
|
||||
return self.convertToFixed()
|
||||
elif self.getJointType() == OdeJoint.JTNull:
|
||||
return self.convertToNull()
|
||||
elif self.getJointType() == OdeJoint.JTAMotor:
|
||||
return self.convertToAMotor()
|
||||
elif self.getJointType() == OdeJoint.JTLMotor:
|
||||
return self.convertToLMotor()
|
||||
elif self.getJointType() == OdeJoint.JTPlane2d:
|
||||
return self.convertToPlane2d()
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
|
||||
def convert(self):
|
||||
"""
|
||||
Do a sort of pseudo-downcast on this space in
|
||||
order to expose its specialized functions.
|
||||
"""
|
||||
if self.getClass() == OdeGeom.GCSimpleSpace:
|
||||
return self.convertToSimpleSpace()
|
||||
elif self.getClass() == OdeGeom.GCHashSpace:
|
||||
return self.convertToHashSpace()
|
||||
elif self.getClass() == OdeGeom.GCQuadTreeSpace:
|
||||
return self.convertToQuadTreeSpace()
|
||||
|
||||
def getConvertedGeom(self, index):
|
||||
"""
|
||||
Return a downcast geom on this body.
|
||||
"""
|
||||
return self.getGeom(index).convert()
|
||||
|
||||
def getConvertedSpace(self):
|
||||
"""
|
||||
"""
|
||||
return self.getSpace().convert()
|
||||
|
||||
def getAABounds(self):
|
||||
"""
|
||||
A more Pythonic way of calling getAABB()
|
||||
"""
|
||||
min = Point3()
|
||||
max = Point3()
|
||||
self.getAABB(min,max)
|
||||
return min,max
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
"""
|
||||
Ramfile-extensions module: contains methods to extend functionality
|
||||
of the Ramfile class
|
||||
"""
|
||||
|
||||
def readlines(self):
|
||||
"""Reads all the lines at once and returns a list."""
|
||||
lines = []
|
||||
line = self.readline()
|
||||
while line:
|
||||
lines.append(line)
|
||||
line = self.readline()
|
||||
return lines
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
"""
|
||||
StreamReader-extensions module: contains methods to extend functionality
|
||||
of the StreamReader class
|
||||
"""
|
||||
|
||||
def readlines(self):
|
||||
"""Reads all the lines at once and returns a list."""
|
||||
lines = []
|
||||
line = self.readline()
|
||||
while line:
|
||||
lines.append(line)
|
||||
line = self.readline()
|
||||
return lines
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
####################################################################
|
||||
#Dtool_funcToMethod(func, class)
|
||||
#del func
|
||||
#####################################################################
|
||||
# For iterating over children
|
||||
def getChildren(self):
|
||||
"""Returns a Python list of the egg node's children."""
|
||||
result = []
|
||||
child = self.getFirstChild()
|
||||
while (child != None):
|
||||
result.append(child)
|
||||
child = self.getNextChild()
|
||||
return result
|
||||
|
||||
Dtool_funcToMethod(getChildren, EggGroupNode)
|
||||
del getChildren
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
####################################################################
|
||||
#Dtool_funcToMethod(func, class)
|
||||
#del func
|
||||
#####################################################################
|
||||
# For iterating over vertices
|
||||
def getVertices(self):
|
||||
"""Returns a Python list of the egg primitive's vertices."""
|
||||
result = []
|
||||
for i in range(self.getNumVertices()):
|
||||
result.append(self.getVertex(i))
|
||||
return result
|
||||
Dtool_funcToMethod(getVertices, EggPrimitive)
|
||||
del getVertices
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#####################################################################
|
||||
|
||||
# For iterating over children
|
||||
def asList(self):
|
||||
"""Converts a NodePathCollection into a list"""
|
||||
print "Warning: NodePathCollection.asList() is no longer needed and deprecated. Iterate on the collection directly instead."
|
||||
return list(self)
|
||||
|
||||
Dtool_funcToMethod(asList, NodePathCollection)
|
||||
del asList
|
||||
#####################################################################3333
|
||||
|
||||
def getTightBounds(self):
|
||||
from pandac.PandaModules import Point3
|
||||
|
||||
if self.getNumPaths() == 0:
|
||||
return (Point3(0), Point3(0))
|
||||
v1, v2 = self.getPath(0).getTightBounds()
|
||||
for i in range(1, self.getNumPaths()):
|
||||
v1x, v2x = self.getPath(i).getTightBounds()
|
||||
v1 = Point3(min(v1[0], v1x[0]),
|
||||
min(v1[1], v1x[1]),
|
||||
min(v1[2], v1x[2]))
|
||||
v2 = Point3(max(v2[0], v2x[0]),
|
||||
max(v2[1], v2x[1]),
|
||||
max(v2[2], v2x[2]))
|
||||
return v1, v2
|
||||
|
||||
Dtool_funcToMethod(getTightBounds, NodePathCollection)
|
||||
del getTightBounds
|
||||
#####################################################################3333
|
||||
|
|
@ -154,15 +154,6 @@ def getAncestry(self):
|
|||
Dtool_funcToMethod(getAncestry, NodePath)
|
||||
del getAncestry
|
||||
#####################################################################
|
||||
def getTightBounds(self):
|
||||
from pandac.PandaModules import Point3
|
||||
v1 = Point3(0)
|
||||
v2 = Point3(0)
|
||||
self.calcTightBounds(v1, v2)
|
||||
return v1, v2
|
||||
Dtool_funcToMethod(getTightBounds, NodePath)
|
||||
del getTightBounds
|
||||
#####################################################################
|
||||
|
||||
def pPrintString(self, other = None):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
####################################################################
|
||||
#Dtool_funcToMethod(func, class)
|
||||
#del func
|
||||
#####################################################################
|
||||
|
||||
"""
|
||||
OdeBody-extensions module: contains methods to extend functionality
|
||||
of the OdeBody classe
|
||||
"""
|
||||
|
||||
def getConvertedJoint(self, index):
|
||||
"""
|
||||
Return a downcast joint on this body.
|
||||
"""
|
||||
return self.getJoint(index).convert()
|
||||
Dtool_funcToMethod(getConvertedJoint, OdeBody)
|
||||
del getConvertedJoint
|
||||
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
####################################################################
|
||||
#Dtool_funcToMethod(func, class)
|
||||
#del func
|
||||
#####################################################################
|
||||
|
||||
"""
|
||||
OdeGeom-extensions module: contains methods to extend functionality
|
||||
of the OdeGeom class
|
||||
"""
|
||||
|
||||
def convert(self):
|
||||
"""
|
||||
Do a sort of pseudo-downcast on this geom in
|
||||
order to expose its specialized functions.
|
||||
"""
|
||||
if self.getClass() == OdeGeom.GCSphere:
|
||||
return self.convertToSphere()
|
||||
elif self.getClass() == OdeGeom.GCBox:
|
||||
return self.convertToBox()
|
||||
elif self.getClass() == OdeGeom.GCCappedCylinder:
|
||||
return self.convertToCappedCylinder()
|
||||
elif self.getClass() == OdeGeom.GCPlane:
|
||||
return self.convertToPlane()
|
||||
elif self.getClass() == OdeGeom.GCRay:
|
||||
return self.convertToRay()
|
||||
# elif self.getClass() == OdeGeom.GCConvex:
|
||||
# return self.convertToConvex()
|
||||
# elif self.getClass() == OdeGeom.GCGeomTransform:
|
||||
# return self.convertToGeomTransform()
|
||||
elif self.getClass() == OdeGeom.GCTriMesh:
|
||||
return self.convertToTriMesh()
|
||||
# elif self.getClass() == OdeGeom.GCHeightfield:
|
||||
# return self.convertToHeightfield()
|
||||
elif self.getClass() == OdeGeom.GCSimpleSpace:
|
||||
return self.convertToSimpleSpace()
|
||||
elif self.getClass() == OdeGeom.GCHashSpace:
|
||||
return self.convertToHashSpace()
|
||||
elif self.getClass() == OdeGeom.GCQuadTreeSpace:
|
||||
return self.convertToQuadTreeSpace()
|
||||
Dtool_funcToMethod(convert, OdeGeom)
|
||||
del convert
|
||||
|
||||
def getConvertedSpace(self):
|
||||
"""
|
||||
"""
|
||||
return self.getSpace().convert()
|
||||
Dtool_funcToMethod(getConvertedSpace, OdeGeom)
|
||||
del getConvertedSpace
|
||||
|
||||
def getAABounds(self):
|
||||
"""
|
||||
A more Pythonic way of calling getAABB()
|
||||
"""
|
||||
min = Point3()
|
||||
max = Point3()
|
||||
self.getAABB(min,max)
|
||||
return min,max
|
||||
Dtool_funcToMethod(getAABounds, OdeGeom)
|
||||
del getAABounds
|
||||
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
####################################################################
|
||||
#Dtool_funcToMethod(func, class)
|
||||
#del func
|
||||
#####################################################################
|
||||
|
||||
"""
|
||||
OdeJoint-extensions module: contains methods to extend functionality
|
||||
of the OdeJoint class
|
||||
"""
|
||||
|
||||
def attach(self, body1, body2):
|
||||
"""
|
||||
Attach two bodies together.
|
||||
If either body is None, the other will be attached to the environment.
|
||||
"""
|
||||
if body1 and body2:
|
||||
self.attachBodies(body1, body2)
|
||||
elif body1 and not body2:
|
||||
self.attachBody(body1, 0)
|
||||
elif not body1 and body2:
|
||||
self.attachBody(body2, 1)
|
||||
Dtool_funcToMethod(attach, OdeJoint)
|
||||
del attach
|
||||
|
||||
def convert(self):
|
||||
"""
|
||||
Do a sort of pseudo-downcast on this joint in
|
||||
order to expose its specialized functions.
|
||||
"""
|
||||
if self.getJointType() == OdeJoint.JTBall:
|
||||
return self.convertToBall()
|
||||
elif self.getJointType() == OdeJoint.JTHinge:
|
||||
return self.convertToHinge()
|
||||
elif self.getJointType() == OdeJoint.JTSlider:
|
||||
return self.convertToSlider()
|
||||
elif self.getJointType() == OdeJoint.JTContact:
|
||||
return self.convertToContact()
|
||||
elif self.getJointType() == OdeJoint.JTUniversal:
|
||||
return self.convertToUniversal()
|
||||
elif self.getJointType() == OdeJoint.JTHinge2:
|
||||
return self.convertToHinge2()
|
||||
elif self.getJointType() == OdeJoint.JTFixed:
|
||||
return self.convertToFixed()
|
||||
elif self.getJointType() == OdeJoint.JTNull:
|
||||
return self.convertToNull()
|
||||
elif self.getJointType() == OdeJoint.JTAMotor:
|
||||
return self.convertToAMotor()
|
||||
elif self.getJointType() == OdeJoint.JTLMotor:
|
||||
return self.convertToLMotor()
|
||||
elif self.getJointType() == OdeJoint.JTPlane2d:
|
||||
return self.convertToPlane2d()
|
||||
Dtool_funcToMethod(convert, OdeJoint)
|
||||
del convert
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
####################################################################
|
||||
#Dtool_funcToMethod(func, class)
|
||||
#del func
|
||||
#####################################################################
|
||||
|
||||
"""
|
||||
OdeSpace-extensions module: contains methods to extend functionality
|
||||
of the OdeSpace classe
|
||||
"""
|
||||
|
||||
def convert(self):
|
||||
"""
|
||||
Do a sort of pseudo-downcast on this space in
|
||||
order to expose its specialized functions.
|
||||
"""
|
||||
if self.getClass() == OdeGeom.GCSimpleSpace:
|
||||
return self.convertToSimpleSpace()
|
||||
elif self.getClass() == OdeGeom.GCHashSpace:
|
||||
return self.convertToHashSpace()
|
||||
elif self.getClass() == OdeGeom.GCQuadTreeSpace:
|
||||
return self.convertToQuadTreeSpace()
|
||||
Dtool_funcToMethod(convert, OdeSpace)
|
||||
del convert
|
||||
|
||||
def getConvertedGeom(self, index):
|
||||
"""
|
||||
Return a downcast geom on this space.
|
||||
"""
|
||||
return self.getGeom(index).convert()
|
||||
Dtool_funcToMethod(getConvertedGeom, OdeSpace)
|
||||
del getConvertedGeom
|
||||
|
||||
def getConvertedSpace(self):
|
||||
"""
|
||||
"""
|
||||
return self.getSpace().convert()
|
||||
Dtool_funcToMethod(getConvertedSpace, OdeSpace)
|
||||
del getConvertedSpace
|
||||
|
||||
def getAABounds(self):
|
||||
"""
|
||||
A more Pythonic way of calling getAABB()
|
||||
"""
|
||||
min = Point3()
|
||||
max = Point3()
|
||||
self.getAABB(min,max)
|
||||
return min,max
|
||||
Dtool_funcToMethod(getAABounds, OdeSpace)
|
||||
del getAABounds
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
"""
|
||||
Ramfile_extensions module: contains methods to extend functionality
|
||||
of the Ramfile class
|
||||
"""
|
||||
|
||||
def readlines(self):
|
||||
"""Reads all the lines at once and returns a list."""
|
||||
lines = []
|
||||
line = self.readline()
|
||||
while line:
|
||||
lines.append(line)
|
||||
line = self.readline()
|
||||
return lines
|
||||
|
||||
Dtool_funcToMethod(readlines, Ramfile)
|
||||
del readlines
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
"""
|
||||
StreamReader_extensions module: contains methods to extend functionality
|
||||
of the StreamReader class
|
||||
"""
|
||||
|
||||
def readlines(self):
|
||||
"""Reads all the lines at once and returns a list."""
|
||||
lines = []
|
||||
line = self.readline()
|
||||
while line:
|
||||
lines.append(line)
|
||||
line = self.readline()
|
||||
return lines
|
||||
|
||||
Dtool_funcToMethod(readlines, StreamReader)
|
||||
del readlines
|
||||
|
|
@ -10,7 +10,6 @@ from direct.directnotify import DirectNotifyGlobal
|
|||
from direct.showbase import PythonUtil
|
||||
from direct.stdpy.threading import RLock
|
||||
import types
|
||||
import string
|
||||
|
||||
class FSMException(Exception):
|
||||
pass
|
||||
|
|
@ -364,7 +363,7 @@ class FSM(DirectObject):
|
|||
# If self.defaultTransitions is None, it means to accept
|
||||
# all requests whose name begins with a capital letter.
|
||||
# These are direct requests to a particular state.
|
||||
if request[0] in string.uppercase:
|
||||
if request[0].isupper():
|
||||
return (request,) + args
|
||||
else:
|
||||
# If self.defaultTransitions is not None, it is a map of
|
||||
|
|
@ -381,7 +380,7 @@ class FSM(DirectObject):
|
|||
# to request a direct state transition (capital letter
|
||||
# request) not listed in defaultTransitions and not
|
||||
# handled by an earlier filter.
|
||||
if request[0] in string.uppercase:
|
||||
if request[0].isupper():
|
||||
raise RequestDenied, "%s (from state: %s)" % (request, self.state)
|
||||
|
||||
# In either case, we quietly ignore unhandled command
|
||||
|
|
@ -392,7 +391,7 @@ class FSM(DirectObject):
|
|||
def filterOff(self, request, args):
|
||||
"""From the off state, we can always go directly to any other
|
||||
state."""
|
||||
if request[0] in string.uppercase:
|
||||
if request[0].isupper():
|
||||
return (request,) + args
|
||||
return self.defaultFilter(request, args)
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ class FourState:
|
|||
off (and so is state 2 which is oposite of 4 and therefore
|
||||
oposite of 'on').
|
||||
"""
|
||||
self.stateIndex = 0
|
||||
assert self.debugPrint("FourState(names=%s)"%(names))
|
||||
self.track = None
|
||||
self.stateTime = 0.0
|
||||
|
|
@ -121,7 +122,6 @@ class FourState:
|
|||
self.exitState4,
|
||||
[names[1]]),
|
||||
}
|
||||
self.stateIndex = 0
|
||||
self.fsm = ClassicFSM.ClassicFSM('FourState',
|
||||
self.states.values(),
|
||||
# Initial State
|
||||
|
|
|
|||
|
|
@ -93,11 +93,11 @@ class FourStateAI:
|
|||
off (and so is state 2 which is oposite of state 4 and therefore
|
||||
oposite of 'on').
|
||||
"""
|
||||
self.stateIndex = 0
|
||||
assert self.debugPrint(
|
||||
"FourStateAI(names=%s, durations=%s)"
|
||||
%(names, durations))
|
||||
self.doLaterTask = None
|
||||
self.stateIndex = 0
|
||||
assert len(names) == 5
|
||||
assert len(names) == len(durations)
|
||||
self.names = names
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from direct.task import Task
|
|||
from direct.showbase import ShowBase
|
||||
from direct.showbase.PythonUtil import recordCreationStackStr
|
||||
from pandac.PandaModules import PStatCollector
|
||||
import string, types
|
||||
import types
|
||||
|
||||
guiObjectCollector = PStatCollector("Client::GuiObjects")
|
||||
|
||||
|
|
@ -192,9 +192,9 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
|
||||
# optimisations:
|
||||
optionInfo = self._optionInfo
|
||||
optionInfo_has_key = optionInfo.has_key
|
||||
optionInfo_has_key = optionInfo.__contains__
|
||||
keywords = self._constructorKeywords
|
||||
keywords_has_key = keywords.has_key
|
||||
keywords_has_key = keywords.__contains__
|
||||
FUNCTION = DGG._OPT_FUNCTION
|
||||
|
||||
for name, default, function in optionDefs:
|
||||
|
|
@ -251,7 +251,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
# This keyword argument has not been used. If it
|
||||
# does not refer to a dynamic group, mark it as
|
||||
# unused.
|
||||
index = string.find(name, '_')
|
||||
index = name.find('_')
|
||||
if index < 0 or name[:index] not in self._dynamicGroups:
|
||||
unusedOptions.append(name)
|
||||
self._constructorKeywords = {}
|
||||
|
|
@ -260,7 +260,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
text = 'Unknown option "'
|
||||
else:
|
||||
text = 'Unknown options "'
|
||||
raise KeyError, text + string.join(unusedOptions, ', ') + \
|
||||
raise KeyError, text + ', '.join(unusedOptions) + \
|
||||
'" for ' + myClass.__name__
|
||||
# Can now call post init func
|
||||
self.postInitialiseFunc()
|
||||
|
|
@ -326,11 +326,11 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
|
||||
# optimizations:
|
||||
optionInfo = self._optionInfo
|
||||
optionInfo_has_key = optionInfo.has_key
|
||||
optionInfo_has_key = optionInfo.__contains__
|
||||
componentInfo = self.__componentInfo
|
||||
componentInfo_has_key = componentInfo.has_key
|
||||
componentInfo_has_key = componentInfo.__contains__
|
||||
componentAliases = self.__componentAliases
|
||||
componentAliases_has_key = componentAliases.has_key
|
||||
componentAliases_has_key = componentAliases.__contains__
|
||||
VALUE = DGG._OPT_VALUE
|
||||
FUNCTION = DGG._OPT_FUNCTION
|
||||
|
||||
|
|
@ -345,7 +345,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
# component and whose values are a dictionary of options and
|
||||
# values for the component.
|
||||
indirectOptions = {}
|
||||
indirectOptions_has_key = indirectOptions.has_key
|
||||
indirectOptions_has_key = indirectOptions.__contains__
|
||||
|
||||
for option, value in kw.items():
|
||||
if optionInfo_has_key(option):
|
||||
|
|
@ -361,7 +361,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
optionInfo[option][VALUE] = value
|
||||
directOptions.append(option)
|
||||
else:
|
||||
index = string.find(option, '_')
|
||||
index = option.find('_')
|
||||
if index >= 0:
|
||||
# This option may be of the form <component>_<option>.
|
||||
# e.g. if alias ('efEntry', 'entryField_entry')
|
||||
|
|
@ -420,8 +420,8 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
|
||||
# Call the configure methods for any components.
|
||||
# Pass in the dictionary of keyword/values created above
|
||||
map(apply, indirectOptions.keys(),
|
||||
((),) * len(indirectOptions), indirectOptions.values())
|
||||
for func, options in indirectOptions.items():
|
||||
func(**options)
|
||||
|
||||
# Call the configuration callback function for each option.
|
||||
for option in directOptions:
|
||||
|
|
@ -432,7 +432,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
|
||||
# Allow index style references
|
||||
def __setitem__(self, key, value):
|
||||
apply(self.configure, (), {key: value})
|
||||
self.configure(**{key: value})
|
||||
|
||||
def cget(self, option):
|
||||
"""
|
||||
|
|
@ -442,7 +442,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
if option in self._optionInfo:
|
||||
return self._optionInfo[option][DGG._OPT_VALUE]
|
||||
else:
|
||||
index = string.find(option, '_')
|
||||
index = option.find('_')
|
||||
if index >= 0:
|
||||
component = option[:index]
|
||||
componentOption = option[(index + 1):]
|
||||
|
|
@ -494,7 +494,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
|
||||
for alias, component in componentAliases:
|
||||
# Create aliases to the component and its sub-components.
|
||||
index = string.find(component, '_')
|
||||
index = component.find('_')
|
||||
if index < 0:
|
||||
# Just a shorter name for one of this widget's components
|
||||
self.__componentAliases[alias] = (component, None)
|
||||
|
|
@ -529,7 +529,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
# keyword argument as being used, but do not remove it
|
||||
# since it may be required when creating another
|
||||
# component.
|
||||
index = string.find(option, '_')
|
||||
index = option.find('_')
|
||||
if index >= 0 and componentGroup == option[:index]:
|
||||
rest = option[(index + 1):]
|
||||
kw[rest] = keywords[option][0]
|
||||
|
|
@ -559,7 +559,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
# single tuple argument.
|
||||
widgetArgs = widgetArgs[0]
|
||||
# Create the widget
|
||||
widget = apply(widgetClass, widgetArgs, kw)
|
||||
widget = widgetClass(*widgetArgs, **kw)
|
||||
componentClass = widget.__class__.__name__
|
||||
self.__componentInfo[componentName] = (widget, widget.configure,
|
||||
componentClass, widget.cget, componentGroup)
|
||||
|
|
@ -572,7 +572,7 @@ class DirectGuiBase(DirectObject.DirectObject):
|
|||
# widget components directly.
|
||||
|
||||
# Find the main component and any subcomponents
|
||||
index = string.find(name, '_')
|
||||
index = name.find('_')
|
||||
if index < 0:
|
||||
component = name
|
||||
remainingComponents = None
|
||||
|
|
@ -748,35 +748,13 @@ class DirectGuiWidget(DirectGuiBase, NodePath):
|
|||
self.assign(parent.attachNewNode(self.guiItem, self['sortOrder']))
|
||||
# Update pose to initial values
|
||||
if self['pos']:
|
||||
pos = self['pos']
|
||||
# Can either be a VBase3 or a tuple of 3 values
|
||||
if isinstance(pos, VBase3):
|
||||
self.setPos(pos)
|
||||
else:
|
||||
apply(self.setPos, pos)
|
||||
self.setPos(self['pos'])
|
||||
if self['hpr']:
|
||||
hpr = self['hpr']
|
||||
# Can either be a VBase3 or a tuple of 3 values
|
||||
if isinstance(hpr, VBase3):
|
||||
self.setHpr(hpr)
|
||||
else:
|
||||
apply(self.setHpr, hpr)
|
||||
self.setHpr(self['hpr'])
|
||||
if self['scale']:
|
||||
scale = self['scale']
|
||||
# Can either be a VBase3 or a tuple of 3 values
|
||||
if (isinstance(scale, VBase3) or
|
||||
(type(scale) == types.IntType) or
|
||||
(type(scale) == types.FloatType)):
|
||||
self.setScale(scale)
|
||||
else:
|
||||
apply(self.setScale, scale)
|
||||
self.setScale(self['scale'])
|
||||
if self['color']:
|
||||
color = self['color']
|
||||
# Can either be a VBase4 or a tuple of 4 values
|
||||
if (isinstance(color, VBase4)):
|
||||
self.setColor(color)
|
||||
else:
|
||||
apply(self.setColor, color)
|
||||
self.setColor(self['color'])
|
||||
# Initialize names
|
||||
# Putting the class name in helps with debugging.
|
||||
self.setName("%s-%s" % (self.__class__.__name__, self.guiId))
|
||||
|
|
|
|||
|
|
@ -113,8 +113,7 @@ class OnscreenGeom(DirectObject, NodePath):
|
|||
for option, value in kw.items():
|
||||
# Use option string to access setter function
|
||||
try:
|
||||
setter = eval('self.set' +
|
||||
string.upper(option[0]) + option[1:])
|
||||
setter = getattr(self, 'set' + option[0].upper() + option[1:])
|
||||
if (((setter == self.setPos) or
|
||||
(setter == self.setHpr) or
|
||||
(setter == self.setScale)) and
|
||||
|
|
@ -133,7 +132,7 @@ class OnscreenGeom(DirectObject, NodePath):
|
|||
def cget(self, option):
|
||||
# Get current configuration setting.
|
||||
# This is for compatibility with DirectGui functions
|
||||
getter = eval('self.get' + string.upper(option[0]) + option[1:])
|
||||
getter = getattr(self, 'get' + option[0].upper() + option[1:])
|
||||
return getter()
|
||||
|
||||
# Allow index style refererences
|
||||
|
|
|
|||
|
|
@ -130,8 +130,7 @@ class OnscreenImage(DirectObject, NodePath):
|
|||
for option, value in kw.items():
|
||||
# Use option string to access setter function
|
||||
try:
|
||||
setter = eval('self.set' +
|
||||
string.upper(option[0]) + option[1:])
|
||||
setter = getattr(self, 'set' + option[0].upper() + option[1:])
|
||||
if (((setter == self.setPos) or
|
||||
(setter == self.setHpr) or
|
||||
(setter == self.setScale)) and
|
||||
|
|
@ -150,7 +149,7 @@ class OnscreenImage(DirectObject, NodePath):
|
|||
def cget(self, option):
|
||||
# Get current configuration setting.
|
||||
# This is for compatibility with DirectGui functions
|
||||
getter = eval('self.get' + string.upper(option[0]) + option[1:])
|
||||
getter = getattr(self, 'get' + option[0].upper() + option[1:])
|
||||
return getter()
|
||||
|
||||
# Allow index style refererences
|
||||
|
|
|
|||
|
|
@ -381,8 +381,7 @@ class OnscreenText(DirectObject, NodePath):
|
|||
for option, value in kw.items():
|
||||
# Use option string to access setter function
|
||||
try:
|
||||
setter = eval('self.set' +
|
||||
string.upper(option[0]) + option[1:])
|
||||
setter = getattr(self, 'set' + option[0].upper() + option[1:])
|
||||
if setter == self.setPos:
|
||||
setter(value[0], value[1])
|
||||
else:
|
||||
|
|
@ -397,7 +396,7 @@ class OnscreenText(DirectObject, NodePath):
|
|||
def cget(self, option):
|
||||
# Get current configuration setting.
|
||||
# This is for compatibility with DirectGui functions
|
||||
getter = eval('self.get' + string.upper(option[0]) + option[1:])
|
||||
getter = getattr(self, 'get' + option[0].upper() + option[1:])
|
||||
return getter()
|
||||
|
||||
def setAlign(self, align):
|
||||
|
|
|
|||
|
|
@ -57,9 +57,10 @@ class FunctionInterval(Interval.Interval):
|
|||
self.function = function
|
||||
|
||||
# Create a unique name for the interval if necessary
|
||||
if (name == None):
|
||||
if name is None:
|
||||
name = self.makeUniqueName(function)
|
||||
assert isinstance(name, types.StringType)
|
||||
assert isinstance(name, str)
|
||||
|
||||
# Record any arguments
|
||||
self.extraArgs = extraArgs
|
||||
self.kw = kw
|
||||
|
|
|
|||
|
|
@ -189,9 +189,9 @@ class ObjectMgrBase:
|
|||
if funcName.startswith('.'):
|
||||
# when it's using default objectHandler
|
||||
if self.editor:
|
||||
func = Functor(eval("self.editor.objectHandler%s"%funcName))
|
||||
func = Functor(getattr(self.editor, "objectHandler%s"%funcName))
|
||||
else: # when loaded outside of LE
|
||||
func = Functor(eval("base.objectHandler%s"%funcName))
|
||||
func = Functor(getattr(base, "objectHandler%s"%funcName))
|
||||
else:
|
||||
# when it's not using default objectHandler, whole name of the handling obj
|
||||
# should be included in function name
|
||||
|
|
@ -686,11 +686,11 @@ class ObjectMgrBase:
|
|||
if type(funcName) == types.StringType:
|
||||
if funcName.startswith('.'):
|
||||
if self.editor:
|
||||
func = Functor(eval("self.editor.objectHandler%s"%funcName), **kwargs)
|
||||
undoFunc = Functor(eval("self.editor.objectHandler%s"%funcName), **undoKwargs)
|
||||
func = Functor(getattr(self.editor, "objectHandler%s"%funcName), **kwargs)
|
||||
undoFunc = Functor(getattr(self.editor, "objectHandler%s"%funcName), **undoKwargs)
|
||||
else: # when loaded outside of LE
|
||||
func = Functor(eval("base.objectHandler%s"%funcName), **kwargs)
|
||||
undoFunc = Functor(eval("base.objectHandler%s"%funcName), **undoKwargs)
|
||||
func = Functor(getattr(base, "objectHandler%s"%funcName), **kwargs)
|
||||
undoFunc = Functor(getattr(base, ".objectHandler%s"%funcName), **undoKwargs)
|
||||
else:
|
||||
func = Functor(eval(funcName), **kwargs)
|
||||
undoFunc = Functor(eval(funcName), **undoKwargs)
|
||||
|
|
|
|||
|
|
@ -147,3 +147,9 @@ class box2d(package):
|
|||
require('panda3d')
|
||||
|
||||
module('Box2D', required = True)
|
||||
|
||||
class pyglet(package):
|
||||
config(display_name = "pyglet")
|
||||
require('panda3d')
|
||||
|
||||
module('pyglet', required = True)
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ class Particles(ParticleSystem):
|
|||
else:
|
||||
file.write(targ+'.renderer.setColorBlendMode(ColorBlendAttrib.%s)\n' % cbmLut[cbMode])
|
||||
cim = self.renderer.getColorInterpolationManager()
|
||||
segIdList = eval('['+cim.getSegmentIdList().replace(' ',', ')+']')
|
||||
segIdList = [int(seg) for seg in cim.getSegmentIdList().split()]
|
||||
for sid in segIdList:
|
||||
seg = cim.getSegment(sid)
|
||||
if seg.isEnabled():
|
||||
|
|
@ -457,7 +457,7 @@ class Particles(ParticleSystem):
|
|||
else:
|
||||
file.write(targ+'.renderer.setColorBlendMode(ColorBlendAttrib.%s)\n' % cbmLut[cbMode])
|
||||
cim = self.renderer.getColorInterpolationManager()
|
||||
segIdList = eval('['+cim.getSegmentIdList().replace(' ',', ')+']')
|
||||
segIdList = [int(seg) for seg in cim.getSegmentIdList().split()]
|
||||
for sid in segIdList:
|
||||
seg = cim.getSegment(sid)
|
||||
if seg.isEnabled():
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__FreeBSD__)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,9 @@
|
|||
#include <sys/stat.h> // for mkdir()
|
||||
#include <errno.h>
|
||||
#include <string.h> // strerror()
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: get_dirname
|
||||
// Description: Returns the directory component of the indicated
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <sys/select.h>
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -22,6 +22,10 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: P3DHost::Constructor
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -749,10 +749,7 @@ def _encode(s, encoding):
|
|||
except AttributeError:
|
||||
return s # 1.5.2: assume the string uses the right encoding
|
||||
|
||||
if sys.version[:3] == "1.5":
|
||||
_escape = re.compile(r"[&<>\"\x80-\xff]+") # 1.5.2
|
||||
else:
|
||||
_escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"'))
|
||||
_escape = re.compile(u"[&<>\"\u0080-\uffff]+")
|
||||
|
||||
_escape_map = {
|
||||
"&": "&",
|
||||
|
|
|
|||
|
|
@ -814,7 +814,7 @@ class Loader(DirectObject):
|
|||
result = []
|
||||
for soundPath in soundList:
|
||||
# should return a valid sound obj even if musicMgr is invalid
|
||||
sound = manager.getSound(soundPath)
|
||||
sound = manager.getSound(soundPath, positional)
|
||||
result.append(sound)
|
||||
|
||||
if gotList:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from PythonUtil import *
|
|||
from direct.directnotify import DirectNotifyGlobal
|
||||
import types
|
||||
|
||||
from libpandaexpress import ConfigVariableBool
|
||||
from panda3d.core import ConfigVariableBool
|
||||
|
||||
# If using the Toontown ActiveX launcher, this must be set true.
|
||||
# Also, Panda must be compiled with SIMPLE_THREADS or no HAVE_THREADS
|
||||
|
|
@ -634,7 +634,10 @@ class Messenger:
|
|||
functionName = method.im_class.__name__ + '.' + \
|
||||
method.im_func.__name__
|
||||
else:
|
||||
functionName = method.__name__
|
||||
if hasattr(method, "__name__"):
|
||||
functionName = method.__name__
|
||||
else:
|
||||
return ""
|
||||
return functionName
|
||||
|
||||
def __eventRepr(self, event):
|
||||
|
|
|
|||
|
|
@ -60,10 +60,7 @@ import bisect
|
|||
__report_indent = 3
|
||||
|
||||
from direct.directutil import Verify
|
||||
# Don't import libpandaexpressModules, which doesn't get built until
|
||||
# genPyCode.
|
||||
import direct.extensions_native.extension_native_helpers
|
||||
from libpandaexpress import ConfigVariableBool
|
||||
from panda3d.core import ConfigVariableBool
|
||||
|
||||
ScalarTypes = (types.FloatType, types.IntType, types.LongType)
|
||||
|
||||
|
|
@ -2462,7 +2459,8 @@ def _getDtoolSuperBase():
|
|||
from pandac.PandaModules import PandaNode
|
||||
dtoolSuperBase = PandaNode('').__class__.__bases__[0].__bases__[0].__bases__[0]
|
||||
assert repr(dtoolSuperBase) == "<type 'libdtoolconfig.DTOOL_SUPER_BASE111'>" \
|
||||
or repr(dtoolSuperBase) == "<type 'libdtoolconfig.DTOOL_SUPPER_BASE111'>"
|
||||
or repr(dtoolSuperBase) == "<type 'libdtoolconfig.DTOOL_SUPPER_BASE111'>" \
|
||||
or repr(dtoolSuperBase) == "<type 'dtoolconfig.DTOOL_SUPER_BASE111'>"
|
||||
|
||||
safeReprNotify = None
|
||||
|
||||
|
|
@ -4190,7 +4188,7 @@ def unescapeHtmlString(s):
|
|||
char = ' '
|
||||
elif char == '%':
|
||||
if i < (len(s)-2):
|
||||
num = eval('0x' + s[i+1:i+3])
|
||||
num = int(s[i+1:i+3], 16)
|
||||
char = chr(num)
|
||||
i += 2
|
||||
i += 1
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "functionRemap.h"
|
||||
#include "typeManager.h"
|
||||
#include "interrogate.h"
|
||||
#include "interrogate.h"
|
||||
#include "parameterRemap.h"
|
||||
#include "parameterRemapThis.h"
|
||||
#include "interfaceMaker.h"
|
||||
|
|
@ -324,7 +324,6 @@ make_wrapper_entry(FunctionIndex function_index) {
|
|||
_flags |= F_explicit_self;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!_void_return) {
|
||||
iwrapper._flags |= InterrogateFunctionWrapper::F_has_return;
|
||||
|
|
@ -340,15 +339,15 @@ make_wrapper_entry(FunctionIndex function_index) {
|
|||
if (_return_value_needs_management) {
|
||||
iwrapper._flags |= InterrogateFunctionWrapper::F_caller_manages;
|
||||
FunctionIndex destructor = _return_value_destructor;
|
||||
|
||||
|
||||
if (destructor != 0) {
|
||||
iwrapper._return_value_destructor = destructor;
|
||||
|
||||
|
||||
} else {
|
||||
// We don't need to report this warning, since the FFI code
|
||||
// understands that if the destructor function is zero, it
|
||||
// should use the regular class destructor.
|
||||
|
||||
|
||||
// nout << "Warning! Destructor for "
|
||||
// << *_return_type->get_orig_type()
|
||||
// << " is unavailable.\n"
|
||||
|
|
@ -397,8 +396,12 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
|||
|
||||
// If this function is marked as having an extension function,
|
||||
// call that instead.
|
||||
if (_extension && !container.empty()) {
|
||||
call << "invoke_extension(" << container << ").";
|
||||
if (_extension) {
|
||||
if (!container.empty()) {
|
||||
call << "invoke_extension(" << container << ").";
|
||||
} else {
|
||||
call << "Extension<" << _cpptype->get_local_name(&parser) << ">::";
|
||||
}
|
||||
|
||||
call << _cppfunc->get_local_name();
|
||||
call << "(";
|
||||
|
|
@ -413,7 +416,7 @@ get_call_str(const string &container, const vector_string &pexprs) const {
|
|||
// If we have a "this" parameter, the calling convention is also
|
||||
// a bit different.
|
||||
call << "(" << container << ")->" << _cppfunc->get_local_name();
|
||||
|
||||
|
||||
} else {
|
||||
call << _cppfunc->get_local_name(&parser);
|
||||
}
|
||||
|
|
@ -465,7 +468,7 @@ get_parameter_expr(int n, const vector_string &pexprs) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool FunctionRemap::
|
||||
setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_maker) {
|
||||
_function_signature =
|
||||
_function_signature =
|
||||
TypeManager::get_function_signature(_cppfunc, _num_default_parameters);
|
||||
_expression = ifunc._expression;
|
||||
|
||||
|
|
@ -519,7 +522,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
_parameters.push_back(param);
|
||||
_first_true_parameter = 1;
|
||||
}
|
||||
|
||||
|
||||
// Also check the name of the function. If it's one of the
|
||||
// assignment-style operators, flag it as such.
|
||||
if (fname == "operator =" ||
|
||||
|
|
@ -611,7 +614,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
}
|
||||
}
|
||||
|
||||
if (_return_type == (ParameterRemap *)NULL ||
|
||||
if (_return_type == (ParameterRemap *)NULL ||
|
||||
!_return_type->is_valid()) {
|
||||
// If our return type isn't something we can deal with, treat the
|
||||
// function as if it returns NULL.
|
||||
|
|
@ -621,25 +624,25 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
_return_type = interface_maker->remap_parameter(_cpptype, void_type);
|
||||
assert(_return_type != (ParameterRemap *)NULL);
|
||||
}
|
||||
|
||||
|
||||
// Do we need to manage the return value?
|
||||
_return_value_needs_management =
|
||||
_return_value_needs_management =
|
||||
_return_type->return_value_needs_management();
|
||||
_return_value_destructor =
|
||||
_return_value_destructor =
|
||||
_return_type->get_return_value_destructor();
|
||||
|
||||
|
||||
// Should we manage a reference count?
|
||||
CPPType *return_type = _return_type->get_new_type();
|
||||
return_type = TypeManager::resolve_type(return_type, _cppscope);
|
||||
CPPType *return_meat_type = TypeManager::unwrap_pointer(return_type);
|
||||
|
||||
|
||||
if (manage_reference_counts &&
|
||||
TypeManager::is_reference_count_pointer(return_type) &&
|
||||
!TypeManager::has_protected_destructor(return_meat_type)) {
|
||||
// Yes!
|
||||
_manage_reference_count = true;
|
||||
_return_value_needs_management = true;
|
||||
|
||||
|
||||
// This is problematic, because we might not have the class in
|
||||
// question fully defined here, particularly if the class is
|
||||
// defined in some other library.
|
||||
|
|
@ -709,11 +712,18 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
|
|||
|
||||
_flags |= F_releasebuffer;
|
||||
}
|
||||
|
||||
} else if (fname == "compare_to" ) {
|
||||
if (_has_this && _parameters.size() == 2 &&
|
||||
TypeManager::is_integer(_return_type->get_new_type())) {
|
||||
// It receives one parameter, and returns an integer.
|
||||
_flags |= F_compare_to;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (_type == T_constructor) {
|
||||
if (!_has_this && _parameters.size() == 1) {
|
||||
if (TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
|
||||
if (TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
|
||||
TypeManager::unwrap(_return_type->get_orig_type())) {
|
||||
// If this is the only parameter, and it's the same as the
|
||||
// "this" type, this is a copy constructor.
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ public:
|
|||
F_iter = 0x0100,
|
||||
F_getbuffer = 0x0200,
|
||||
F_releasebuffer = 0x0400,
|
||||
F_compare_to = 0x0800,
|
||||
};
|
||||
|
||||
typedef vector<Parameter> Parameters;
|
||||
|
|
@ -113,7 +114,7 @@ public:
|
|||
string _reported_name;
|
||||
string _wrapper_name;
|
||||
FunctionWrapperIndex _wrapper_index;
|
||||
|
||||
|
||||
bool _return_value_needs_management;
|
||||
FunctionIndex _return_value_destructor;
|
||||
bool _manage_reference_count;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -76,6 +76,7 @@ private:
|
|||
WT_inquiry,
|
||||
WT_getbuffer,
|
||||
WT_releasebuffer,
|
||||
WT_iter_next,
|
||||
};
|
||||
|
||||
class SlottedFunctionDef {
|
||||
|
|
|
|||
|
|
@ -1679,6 +1679,10 @@ get_function(CPPInstance *function, string description,
|
|||
InterrogateFunction &ifunction =
|
||||
InterrogateDatabase::get_ptr()->update_function(index);
|
||||
|
||||
// Not 100% sure why, but there's a case where this happens,
|
||||
// in a case where a typedef shadowed an actual type. ~rdb
|
||||
nassertr(&ifunction != NULL, 0);
|
||||
|
||||
ifunction._flags |= flags;
|
||||
|
||||
// Also, make sure this particular signature is defined.
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ int write_python_table_native(ostream &out) {
|
|||
pset<std::string >::iterator ii;
|
||||
for(ii = libraries.begin(); ii != libraries.end(); ii++) {
|
||||
printf("Referencing Library %s\n", (*ii).c_str());
|
||||
out << "extern LibraryDef " << *ii << "_moddef;\n";
|
||||
out << "IMPORT_THIS LibraryDef " << *ii << "_moddef;\n";
|
||||
}
|
||||
|
||||
out << "\n"
|
||||
|
|
|
|||
|
|
@ -17,10 +17,7 @@
|
|||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
struct _object;
|
||||
typedef struct _object PyObject;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : ExtensionBase
|
||||
// Description : This is where all extensions should derive from.
|
||||
// It defines the _self and _this members that can
|
||||
|
|
@ -30,7 +27,6 @@ template<class T>
|
|||
class EXPCL_DTOOLCONFIG ExtensionBase {
|
||||
public:
|
||||
T * _this;
|
||||
PyObject * _self;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -52,10 +48,9 @@ class EXPCL_DTOOLCONFIG Extension : public ExtensionBase<T> {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
inline Extension<T>
|
||||
invoke_extension(T *ptr, PyObject *self = NULL) {
|
||||
invoke_extension(T *ptr) {
|
||||
Extension<T> ext;
|
||||
ext._this = ptr;
|
||||
ext._self = self;
|
||||
return ext;
|
||||
}
|
||||
|
||||
|
|
@ -65,10 +60,9 @@ invoke_extension(T *ptr, PyObject *self = NULL) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
inline const Extension<T>
|
||||
invoke_extension(const T *ptr, PyObject *self = NULL) {
|
||||
invoke_extension(const T *ptr) {
|
||||
Extension<T> ext;
|
||||
ext._this = (T *) ptr;
|
||||
ext._self = self;
|
||||
return ext;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ bool DtoolCanThisBeAPandaInstance(PyObject *self) {
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
void DTOOL_Call_ExtractThisPointerForType(PyObject *self, Dtool_PyTypedObject *classdef, void **answer) {
|
||||
if (DtoolCanThisBeAPandaInstance(self)) {
|
||||
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self,classdef);
|
||||
*answer = ((Dtool_PyInstDef *)self)->_My_Type->_Dtool_UpcastInterface(self, classdef);
|
||||
} else {
|
||||
*answer = NULL;
|
||||
}
|
||||
|
|
@ -298,7 +298,7 @@ void *DTOOL_Call_GetPointerThis(PyObject *self) {
|
|||
// this function relies on the behavior of typed objects in the panda system.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, bool is_const, int RunTimeType) {
|
||||
PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject & known_class_type, bool memory_rules, bool is_const, int RunTimeType) {
|
||||
if (local_this_in == NULL) {
|
||||
// Let's not be stupid..
|
||||
PyErr_SetString(PyExc_TypeError, "C Function Return Null 'this'");
|
||||
|
|
@ -339,7 +339,7 @@ PyObject *DTool_CreatePyInstanceTyped(void *local_this_in, Dtool_PyTypedObject &
|
|||
// if we get this far .. just wrap the thing in the known type ??
|
||||
// better than aborting...I guess....
|
||||
/////////////////////////////////////////////////////
|
||||
Dtool_PyInstDef * self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL, NULL);
|
||||
Dtool_PyInstDef *self = (Dtool_PyInstDef *) known_class_type.As_PyTypeObject().tp_new(&known_class_type.As_PyTypeObject(), NULL, NULL);
|
||||
if (self != NULL) {
|
||||
self->_ptr_to_object = local_this_in;
|
||||
self->_memory_rules = memory_rules;
|
||||
|
|
|
|||
|
|
@ -25,4 +25,7 @@ class PyThreadState;
|
|||
typedef int Py_ssize_t;
|
||||
struct Py_buffer;
|
||||
|
||||
// This file defines PY_VERSION_HEX, which is used in some places.
|
||||
#include "patchlevel.h"
|
||||
|
||||
#endif // PYTHON_H
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ PUBLISHED:
|
|||
BLOCKING size_t extract_bytes(unsigned char *into, size_t size);
|
||||
|
||||
BLOCKING string readline();
|
||||
EXTENSION(BLOCKING PyObject *readlines());
|
||||
|
||||
private:
|
||||
istream *_in;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -125,7 +125,6 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
|
|||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/bin")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/include")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/panda3d")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/panda3d/direct")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/mime-info")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/mime/packages")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/application-registry")
|
||||
|
|
@ -137,7 +136,6 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
|
|||
oscmd("mkdir -m 0755 -p "+destdir+"/usr/local/libdata/ldconfig")
|
||||
else:
|
||||
oscmd("mkdir -m 0755 -p "+destdir+"/etc/ld.so.conf.d")
|
||||
WriteFile(destdir+prefix+"/share/panda3d/direct/__init__.py", "")
|
||||
Configrc = ReadFile(outputdir+"/etc/Config.prc")
|
||||
Configrc = Configrc.replace("model-path $THIS_PRC_DIR/..", "model-path "+prefix+"/share/panda3d")
|
||||
if (sys.platform.startswith("freebsd")):
|
||||
|
|
@ -147,13 +145,13 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
|
|||
WriteFile(destdir+"/etc/Config.prc", Configrc)
|
||||
oscmd("cp "+outputdir+"/etc/Confauto.prc "+destdir+"/etc/Confauto.prc")
|
||||
oscmd("cp -R "+outputdir+"/include "+destdir+prefix+"/include/panda3d")
|
||||
oscmd("cp -R direct/src/* "+destdir+prefix+"/share/panda3d/direct")
|
||||
oscmd("cp -R "+outputdir+"/pandac "+destdir+prefix+"/share/panda3d/pandac")
|
||||
oscmd("cp -R "+outputdir+"/models "+destdir+prefix+"/share/panda3d/models")
|
||||
oscmd("cp direct/src/ffi/panda3d.py "+destdir+prefix+"/share/panda3d/panda3d.py")
|
||||
if os.path.isdir("samples"): oscmd("cp -R samples "+destdir+prefix+"/share/panda3d/samples")
|
||||
if os.path.isdir(outputdir+"/Pmw"): oscmd("cp -R "+outputdir+"/Pmw "+destdir+prefix+"/share/panda3d/Pmw")
|
||||
if os.path.isdir(outputdir+"/plugins"): oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/plugins")
|
||||
oscmd("cp -R "+outputdir+"/direct "+destdir+prefix+"/share/panda3d/")
|
||||
oscmd("cp -R "+outputdir+"/pandac "+destdir+prefix+"/share/panda3d/")
|
||||
oscmd("cp -R "+outputdir+"/panda3d "+destdir+PPATH+"/")
|
||||
oscmd("cp -R "+outputdir+"/models "+destdir+prefix+"/share/panda3d/")
|
||||
if os.path.isdir("samples"): oscmd("cp -R samples "+destdir+prefix+"/share/panda3d/")
|
||||
if os.path.isdir(outputdir+"/Pmw"): oscmd("cp -R "+outputdir+"/Pmw "+destdir+prefix+"/share/panda3d/")
|
||||
if os.path.isdir(outputdir+"/plugins"): oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/")
|
||||
WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO)
|
||||
WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO)
|
||||
WriteMimeXMLFile(destdir+prefix+"/share/mime/packages/panda3d.xml", MIME_INFO)
|
||||
|
|
@ -169,7 +167,7 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
|
|||
else:
|
||||
oscmd("echo '"+libdir+"/panda3d'> "+destdir+"/etc/ld.so.conf.d/panda3d.conf")
|
||||
oscmd("chmod +x "+destdir+"/etc/ld.so.conf.d/panda3d.conf")
|
||||
oscmd("ln -s "+PEXEC+" "+destdir+prefix+"/bin/ppython")
|
||||
oscmd("ln -f -s "+PEXEC+" "+destdir+prefix+"/bin/ppython")
|
||||
oscmd("cp "+outputdir+"/bin/* "+destdir+prefix+"/bin/")
|
||||
for base in os.listdir(outputdir+"/lib"):
|
||||
if (not base.endswith(".a")) or base == "libp3pystub.a":
|
||||
|
|
@ -206,15 +204,15 @@ def InstallRuntime(destdir="", prefix="/usr", outputdir="built"):
|
|||
if sys.platform.startswith("freebsd"):
|
||||
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/browser_plugins/symlinks/gecko19")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/libxul/plugins")
|
||||
oscmd("ln -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/browser_plugins/symlinks/gecko19/nppanda3d.so")
|
||||
oscmd("ln -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/libxul/plugins/nppanda3d.so")
|
||||
oscmd("ln -f -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/browser_plugins/symlinks/gecko19/nppanda3d.so")
|
||||
oscmd("ln -f -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/libxul/plugins/nppanda3d.so")
|
||||
else:
|
||||
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/mozilla/plugins")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/mozilla-firefox/plugins")
|
||||
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/xulrunner-addons/plugins")
|
||||
oscmd("ln -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/mozilla/plugins/nppanda3d.so")
|
||||
oscmd("ln -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/mozilla-firefox/plugins/nppanda3d.so")
|
||||
oscmd("ln -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/xulrunner-addons/plugins/nppanda3d.so")
|
||||
oscmd("ln -f -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/mozilla/plugins/nppanda3d.so")
|
||||
oscmd("ln -f -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/mozilla-firefox/plugins/nppanda3d.so")
|
||||
oscmd("ln -f -s "+libdir+"/nppanda3d.so "+destdir+libdir+"/xulrunner-addons/plugins/nppanda3d.so")
|
||||
WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d-runtime.mime", MIME_INFO_PLUGIN)
|
||||
WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d-runtime.keys", MIME_INFO_PLUGIN)
|
||||
WriteMimeXMLFile(destdir+prefix+"/share/mime/packages/panda3d-runtime.xml", MIME_INFO_PLUGIN)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -9,13 +9,15 @@
|
|||
##
|
||||
########################################################################
|
||||
|
||||
import sys,os,time,stat,string,re,getopt,fnmatch,threading,signal,shutil,platform,glob,getpass,signal,thread
|
||||
import sys,os,time,stat,string,re,getopt,fnmatch,threading,signal,shutil,platform,glob,getpass,signal
|
||||
from distutils import sysconfig
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
import pickle
|
||||
import _thread as thread
|
||||
else:
|
||||
import cPickle as pickle
|
||||
import thread
|
||||
|
||||
SUFFIX_INC = [".cxx",".c",".h",".I",".yxx",".lxx",".mm",".rc",".r"]
|
||||
SUFFIX_DLL = [".dll",".dlo",".dle",".dli",".dlm",".mll",".exe",".pyd",".ocx"]
|
||||
|
|
@ -71,6 +73,7 @@ MAYAVERSIONINFO = [("MAYA6", "6.0"),
|
|||
("MAYA2013","2013"),
|
||||
("MAYA20135","2013.5"),
|
||||
("MAYA2014","2014"),
|
||||
("MAYA2015","2015"),
|
||||
]
|
||||
|
||||
MAXVERSIONINFO = [("MAX6", "SOFTWARE\\Autodesk\\3DSMAX\\6.0", "installdir", "maxsdk\\cssdk\\include"),
|
||||
|
|
@ -694,11 +697,16 @@ def CxxGetIncludes(path):
|
|||
except:
|
||||
exit("Cannot open source file \""+path+"\" for reading.")
|
||||
include = []
|
||||
for line in sfile:
|
||||
match = CxxIncludeRegex.match(line,0)
|
||||
if (match):
|
||||
incname = match.group(1)
|
||||
include.append(incname)
|
||||
try:
|
||||
for line in sfile:
|
||||
match = CxxIncludeRegex.match(line,0)
|
||||
if (match):
|
||||
incname = match.group(1)
|
||||
include.append(incname)
|
||||
except:
|
||||
print("Failed to determine dependencies of \""+path+"\".")
|
||||
raise
|
||||
|
||||
sfile.close()
|
||||
CXXINCLUDECACHE[path] = [date, include]
|
||||
return include
|
||||
|
|
@ -1062,6 +1070,8 @@ def MakeBuildTree():
|
|||
MakeDirectory(OUTPUTDIR + "/models/gui")
|
||||
MakeDirectory(OUTPUTDIR + "/pandac")
|
||||
MakeDirectory(OUTPUTDIR + "/pandac/input")
|
||||
MakeDirectory(OUTPUTDIR + "/panda3d")
|
||||
CreateFile(OUTPUTDIR + "/panda3d/__init__.py")
|
||||
|
||||
if GetTarget() == 'android':
|
||||
MakeDirectory(OUTPUTDIR + "/libs")
|
||||
|
|
@ -1549,9 +1559,14 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
|
|||
if SystemLibraryExists(libname):
|
||||
LibName(target_pkg, "-l" + libname)
|
||||
else:
|
||||
have_pkg = False
|
||||
if VERBOSE:
|
||||
print(GetColor("cyan") + "Couldn't find library lib" + libname + GetColor())
|
||||
# Try searching in the package's LibDirectories.
|
||||
lpath = [dir for ppkg, dir in LIBDIRECTORIES if pkg == ppkg]
|
||||
if LibraryExists(libname, lpath):
|
||||
LibName(target_pkg, "-l" + libname)
|
||||
else:
|
||||
have_pkg = False
|
||||
if VERBOSE:
|
||||
print(GetColor("cyan") + "Couldn't find library lib" + libname + GetColor())
|
||||
|
||||
for i in incs:
|
||||
incdir = None
|
||||
|
|
@ -1563,17 +1578,18 @@ def SmartPkgEnable(pkg, pkgconfig = None, libs = None, incs = None, defs = None,
|
|||
elif (os.path.isdir(sysroot_usr + "/PCBSD") and len(glob.glob(sysroot_usr + "/PCBSD/local/include/" + i)) > 0):
|
||||
incdir = sorted(glob.glob(sysroot_usr + "/PCBSD/local/include/" + i))[-1]
|
||||
else:
|
||||
have_pkg = False
|
||||
# Try searching in the package's IncDirectories.
|
||||
for ppkg, pdir in INCDIRECTORIES:
|
||||
if (pkg == ppkg and len(glob.glob(os.path.join(pdir, i))) > 0):
|
||||
if pkg == ppkg and len(glob.glob(os.path.join(pdir, i))) > 0:
|
||||
incdir = sorted(glob.glob(os.path.join(pdir, i)))[-1]
|
||||
have_pkg = True
|
||||
if (incdir == None and VERBOSE and i.endswith(".h")):
|
||||
print(GetColor("cyan") + "Couldn't find header file " + i + GetColor())
|
||||
|
||||
if incdir is None and i.endswith(".h"):
|
||||
have_pkg = False
|
||||
if VERBOSE:
|
||||
print(GetColor("cyan") + "Couldn't find header file " + i + GetColor())
|
||||
|
||||
# Note: It's possible to specify a file instead of a dir, for the sake of checking if it exists.
|
||||
if (incdir != None and os.path.isdir(incdir)):
|
||||
if incdir is not None and os.path.isdir(incdir):
|
||||
IncDirectory(target_pkg, incdir)
|
||||
|
||||
if (not have_pkg):
|
||||
|
|
@ -2318,8 +2334,12 @@ def CopyFile(dstfile, srcfile):
|
|||
if (fnl < 0): fn = srcfile
|
||||
else: fn = srcfile[fnl+1:]
|
||||
dstfile = dstdir + fn
|
||||
if (NeedsBuild([dstfile], [srcfile])):
|
||||
WriteBinaryFile(dstfile, ReadBinaryFile(srcfile))
|
||||
if NeedsBuild([dstfile], [srcfile]):
|
||||
if os.path.islink(srcfile):
|
||||
# Preserve symlinks
|
||||
os.symlink(os.readlink(srcfile), dstfile)
|
||||
else:
|
||||
WriteBinaryFile(dstfile, ReadBinaryFile(srcfile))
|
||||
JustBuilt([dstfile], [srcfile])
|
||||
|
||||
def CopyAllFiles(dstdir, srcdir, suffix=""):
|
||||
|
|
@ -2380,7 +2400,7 @@ def CopyPythonTree(dstdir, srcdir, lib2to3_fixers=[]):
|
|||
dstpth = os.path.join(dstdir, entry)
|
||||
if (os.path.isfile(srcpth)):
|
||||
base, ext = os.path.splitext(entry)
|
||||
if (entry != ".cvsignore" and ext not in SUFFIX_INC):
|
||||
if (entry != ".cvsignore" and ext not in SUFFIX_INC + ['.pyc', '.pyo']):
|
||||
if (NeedsBuild([dstpth], [srcpth])):
|
||||
WriteBinaryFile(dstpth, ReadBinaryFile(srcpth))
|
||||
|
||||
|
|
@ -2412,10 +2432,10 @@ def ParsePandaVersion(fn):
|
|||
f = open(fn, "r")
|
||||
pattern = re.compile('^[ \t]*[#][ \t]*define[ \t]+PANDA_VERSION[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)')
|
||||
for line in f:
|
||||
match = pattern.match(line,0)
|
||||
match = pattern.match(line, 0)
|
||||
if (match):
|
||||
f.close()
|
||||
return match.group(1)+"."+match.group(2)+"."+match.group(3)
|
||||
return match.group(1) + "." + match.group(2) + "." + match.group(3)
|
||||
f.close()
|
||||
except: pass
|
||||
return "0.0.0"
|
||||
|
|
@ -2428,7 +2448,7 @@ def ParsePluginVersion(fn):
|
|||
match = pattern.match(line,0)
|
||||
if (match):
|
||||
f.close()
|
||||
return match.group(1)+"."+match.group(2)+"."+match.group(3)
|
||||
return match.group(1) + "." + match.group(2) + "." + match.group(3)
|
||||
f.close()
|
||||
except: pass
|
||||
return "0.0.0"
|
||||
|
|
@ -2522,7 +2542,7 @@ def WriteResourceFile(basename, **kwargs):
|
|||
##
|
||||
########################################################################
|
||||
|
||||
ORIG_EXT={}
|
||||
ORIG_EXT = {}
|
||||
|
||||
def GetOrigExt(x):
|
||||
return ORIG_EXT[x]
|
||||
|
|
@ -2556,7 +2576,7 @@ def CalcLocation(fn, ipath):
|
|||
if (fn.endswith(".res")): return OUTPUTDIR+"/tmp/"+fn
|
||||
if (fn.endswith(".tlb")): return OUTPUTDIR+"/tmp/"+fn
|
||||
if (fn.endswith(".dll")): return OUTPUTDIR+"/bin/"+fn[:-4]+dllext+".dll"
|
||||
if (fn.endswith(".pyd")): return OUTPUTDIR+"/bin/"+fn[:-4]+dllext+".pyd"
|
||||
if (fn.endswith(".pyd")): return OUTPUTDIR+"/panda3d/"+fn[:-4]+dllext+".pyd"
|
||||
if (fn.endswith(".ocx")): return OUTPUTDIR+"/plugins/"+fn[:-4]+dllext+".ocx"
|
||||
if (fn.endswith(".mll")): return OUTPUTDIR+"/plugins/"+fn[:-4]+dllext+".mll"
|
||||
if (fn.endswith(".dlo")): return OUTPUTDIR+"/plugins/"+fn[:-4]+dllext+".dlo"
|
||||
|
|
@ -2572,7 +2592,7 @@ def CalcLocation(fn, ipath):
|
|||
if (fn.endswith(".plist")): return CxxFindSource(fn, ipath)
|
||||
if (fn.endswith(".obj")): return OUTPUTDIR+"/tmp/"+fn[:-4]+".o"
|
||||
if (fn.endswith(".dll")): return OUTPUTDIR+"/lib/"+fn[:-4]+".dylib"
|
||||
if (fn.endswith(".pyd")): return OUTPUTDIR+"/lib/"+fn[:-4]+".so"
|
||||
if (fn.endswith(".pyd")): return OUTPUTDIR+"/panda3d/"+fn[:-4]+".so"
|
||||
if (fn.endswith(".mll")): return OUTPUTDIR+"/plugins/"+fn
|
||||
if (fn.endswith(".exe")): return OUTPUTDIR+"/bin/"+fn[:-4]
|
||||
if (fn.endswith(".lib")): return OUTPUTDIR+"/lib/"+fn[:-4]+".a"
|
||||
|
|
@ -2593,7 +2613,7 @@ def CalcLocation(fn, ipath):
|
|||
else:
|
||||
if (fn.endswith(".obj")): return OUTPUTDIR+"/tmp/"+fn[:-4]+".o"
|
||||
if (fn.endswith(".dll")): return OUTPUTDIR+"/lib/"+fn[:-4]+".so"
|
||||
if (fn.endswith(".pyd")): return OUTPUTDIR+"/lib/"+fn[:-4]+".so"
|
||||
if (fn.endswith(".pyd")): return OUTPUTDIR+"/panda3d/"+fn[:-4]+".so"
|
||||
if (fn.endswith(".mll")): return OUTPUTDIR+"/plugins/"+fn
|
||||
if (fn.endswith(".plugin")):return OUTPUTDIR+"/plugins/"+fn[:-7]+dllext+".so"
|
||||
if (fn.endswith(".exe")): return OUTPUTDIR+"/bin/"+fn[:-4]
|
||||
|
|
@ -2669,6 +2689,11 @@ def TargetAdd(target, dummy=0, opts=0, input=0, dep=0, ipath=0, winrc=0):
|
|||
if (ipath == 0): ipath = []
|
||||
if (type(input) == str): input = [input]
|
||||
if (type(dep) == str): dep = [dep]
|
||||
|
||||
if os.path.splitext(target)[1] == '.pyd' and PkgSkip("PYTHON"):
|
||||
# It makes no sense to build Python modules with python disabled.
|
||||
return
|
||||
|
||||
full = FindLocation(target, [OUTPUTDIR + "/include"])
|
||||
|
||||
if (full not in TARGET_TABLE):
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ OpenALAudioSound(OpenALAudioManager* manager,
|
|||
_start_time(0.0),
|
||||
_current_time(0.0),
|
||||
_basename(movie->get_filename().get_basename()),
|
||||
_active(true),
|
||||
_active(manager->get_active()),
|
||||
_paused(false)
|
||||
{
|
||||
_location[0] = 0.0f;
|
||||
|
|
|
|||
|
|
@ -14,41 +14,40 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::get_node0
|
||||
// Function: BulletContact::get_node0
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *BulletContact::
|
||||
get_node0() const {
|
||||
|
||||
return _obj0 ? (PandaNode *)_obj0->getUserPointer() : NULL;
|
||||
return _node0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::get_node1
|
||||
// Function: BulletContact::get_node1
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PandaNode *BulletContact::
|
||||
get_node1() const {
|
||||
|
||||
return _obj1 ? (PandaNode *)_obj1->getUserPointer() : NULL;
|
||||
return _node1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::get_manifold_point
|
||||
// Function: BulletContact::get_manifold_point
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const BulletManifoldPoint *BulletContact::
|
||||
get_manifold_point() const {
|
||||
INLINE BulletManifoldPoint &BulletContact::
|
||||
get_manifold_point() {
|
||||
|
||||
btManifoldPoint &mp = const_cast<btManifoldPoint &>(_mp);
|
||||
return new BulletManifoldPoint(mp);
|
||||
return _mp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::get_idx0
|
||||
// Function: BulletContact::get_idx0
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -59,7 +58,7 @@ get_idx0() const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::get_idx1
|
||||
// Function: BulletContact::get_idx1
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -70,7 +69,7 @@ get_idx1() const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::get_part_id0
|
||||
// Function: BulletContact::get_part_id0
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -81,7 +80,7 @@ get_part_id0() const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::get_part_id1
|
||||
// Function: BulletContact::get_part_id1
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -107,8 +106,8 @@ get_num_contacts() const {
|
|||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const BulletContact &BulletContactResult::
|
||||
get_contact(int idx) const {
|
||||
INLINE BulletContact &BulletContactResult::
|
||||
get_contact(int idx) {
|
||||
|
||||
nassertr(idx >= 0 && idx < (int)_contacts.size(), _empty);
|
||||
return _contacts[idx];
|
||||
|
|
|
|||
|
|
@ -14,8 +14,37 @@
|
|||
|
||||
#include "bulletContactResult.h"
|
||||
|
||||
btManifoldPoint BulletContact::_empty;
|
||||
BulletContact BulletContactResult::_empty;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContact::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletContact::
|
||||
BulletContact() : _mp(_empty) {
|
||||
|
||||
_node0 = NULL;
|
||||
_node1 = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContact::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletContact::
|
||||
BulletContact(const BulletContact &other) : _mp(other._mp) {
|
||||
|
||||
_node0 = other._node0;
|
||||
_node1 = other._node1;
|
||||
_part_id0 = other._part_id0;
|
||||
_part_id1 = other._part_id1;
|
||||
_idx0 = other._idx0;
|
||||
_idx1 = other._idx1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::Constructor
|
||||
// Access: Protected
|
||||
|
|
@ -24,9 +53,46 @@ BulletContact BulletContactResult::_empty;
|
|||
BulletContactResult::
|
||||
BulletContactResult() : btCollisionWorld::ContactResultCallback() {
|
||||
|
||||
#if BT_BULLET_VERSION >= 281
|
||||
_filter_cb = NULL;
|
||||
_filter_proxy = NULL;
|
||||
_filter_set = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BT_BULLET_VERSION >= 281
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::use_filter
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletContactResult::
|
||||
use_filter(btOverlapFilterCallback *cb, btBroadphaseProxy *proxy) {
|
||||
|
||||
nassertv(cb);
|
||||
nassertv(proxy);
|
||||
|
||||
_filter_cb = cb;
|
||||
_filter_proxy = proxy;
|
||||
_filter_set = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::needsCollision
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BulletContactResult::
|
||||
needsCollision(btBroadphaseProxy *proxy0) const {
|
||||
|
||||
if (_filter_set) {
|
||||
return _filter_cb->needBroadphaseCollision(proxy0, _filter_proxy);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletContactResult::addSingleResult
|
||||
// Access: Published
|
||||
|
|
@ -37,11 +103,14 @@ addSingleResult(btManifoldPoint &mp,
|
|||
const btCollisionObjectWrapper *wrap0, int part_id0, int idx0,
|
||||
const btCollisionObjectWrapper *wrap1, int part_id1, int idx1) {
|
||||
|
||||
const btCollisionObject *obj0 = wrap0->getCollisionObject();
|
||||
const btCollisionObject *obj1 = wrap1->getCollisionObject();
|
||||
|
||||
BulletContact contact;
|
||||
|
||||
contact._mp = mp;
|
||||
contact._obj0 = wrap0->getCollisionObject();
|
||||
contact._obj1 = wrap1->getCollisionObject();
|
||||
contact._mp = BulletManifoldPoint(mp);
|
||||
contact._node0 = obj0 ? (PandaNode *)obj0->getUserPointer() : NULL;
|
||||
contact._node1 = obj1 ? (PandaNode *)obj1->getUserPointer() : NULL;
|
||||
contact._part_id0 = part_id0;
|
||||
contact._part_id1 = part_id1;
|
||||
contact._idx0 = idx0;
|
||||
|
|
@ -64,9 +133,9 @@ addSingleResult(btManifoldPoint &mp,
|
|||
|
||||
BulletContact contact;
|
||||
|
||||
contact._mp = mp;
|
||||
contact._obj0 = obj0;
|
||||
contact._obj1 = obj1;
|
||||
contact._mp = BulletManifoldPoint(mp);
|
||||
contact._node0 = obj0 ? (PandaNode *)obj0->getUserPointer() : NULL;
|
||||
contact._node1 = obj1 ? (PandaNode *)obj1->getUserPointer() : NULL;
|
||||
contact._part_id0 = part_id0;
|
||||
contact._part_id1 = part_id1;
|
||||
contact._idx0 = idx0;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,12 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
struct EXPCL_PANDABULLET BulletContact {
|
||||
|
||||
public:
|
||||
BulletContact();
|
||||
BulletContact(const BulletContact &other);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE const BulletManifoldPoint *get_manifold_point() const;
|
||||
INLINE BulletManifoldPoint &get_manifold_point();
|
||||
INLINE PandaNode *get_node0() const;
|
||||
INLINE PandaNode *get_node1() const;
|
||||
INLINE const int get_idx0() const;
|
||||
|
|
@ -38,9 +42,13 @@ PUBLISHED:
|
|||
INLINE const int get_part_id1() const;
|
||||
|
||||
private:
|
||||
btManifoldPoint _mp;
|
||||
const btCollisionObject *_obj0;
|
||||
const btCollisionObject *_obj1;
|
||||
static btManifoldPoint _empty;
|
||||
|
||||
BulletManifoldPoint _mp;
|
||||
|
||||
PT(PandaNode) _node0;
|
||||
PT(PandaNode) _node1;
|
||||
|
||||
int _part_id0;
|
||||
int _part_id1;
|
||||
int _idx0;
|
||||
|
|
@ -57,11 +65,13 @@ struct EXPCL_PANDABULLET BulletContactResult : public btCollisionWorld::ContactR
|
|||
|
||||
PUBLISHED:
|
||||
INLINE int get_num_contacts() const;
|
||||
INLINE const BulletContact &get_contact(int idx) const;
|
||||
INLINE BulletContact &get_contact(int idx);
|
||||
MAKE_SEQ(get_contacts, get_num_contacts, get_contact);
|
||||
|
||||
public:
|
||||
#if BT_BULLET_VERSION >= 281
|
||||
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
|
||||
|
||||
virtual btScalar addSingleResult(btManifoldPoint &mp,
|
||||
const btCollisionObjectWrapper *wrap0, int part_id0, int idx0,
|
||||
const btCollisionObjectWrapper *wrap1, int part_id1, int idx1);
|
||||
|
|
@ -74,11 +84,21 @@ public:
|
|||
protected:
|
||||
BulletContactResult();
|
||||
|
||||
#if BT_BULLET_VERSION >= 281
|
||||
void use_filter(btOverlapFilterCallback *cb, btBroadphaseProxy *proxy);
|
||||
#endif
|
||||
|
||||
private:
|
||||
static BulletContact _empty;
|
||||
|
||||
btAlignedObjectArray<BulletContact> _contacts;
|
||||
|
||||
#if BT_BULLET_VERSION >= 281
|
||||
bool _filter_set;
|
||||
btOverlapFilterCallback *_filter_cb;
|
||||
btBroadphaseProxy *_filter_proxy;
|
||||
#endif
|
||||
|
||||
friend class BulletWorld;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -220,9 +220,11 @@ make_geom(BulletSoftBodyNode *node, const GeomVertexFormat *format, bool two_sid
|
|||
|
||||
if (two_sided) {
|
||||
for (int j=0; j<nodes.size(); ++j) {
|
||||
btVector3 &v = nodes[j].m_x;
|
||||
btVector3 v = nodes[j].m_x;
|
||||
btVector3 &n = nodes[j].m_n;
|
||||
|
||||
v = trans.invXform(v);
|
||||
|
||||
vwriter.add_data3((PN_stdfloat)v.getX(), (PN_stdfloat)v.getY(), (PN_stdfloat)v.getZ());
|
||||
nwriter.add_data3((PN_stdfloat)n.getX(), (PN_stdfloat)n.getY(), (PN_stdfloat)n.getZ());
|
||||
fwriter.add_data1i(1);
|
||||
|
|
@ -231,23 +233,29 @@ make_geom(BulletSoftBodyNode *node, const GeomVertexFormat *format, bool two_sid
|
|||
|
||||
// Indices
|
||||
btSoftBody::Node *node0 = &nodes[0];
|
||||
int i0, i1, i2;
|
||||
|
||||
if (use_faces) {
|
||||
|
||||
btSoftBody::tFaceArray &faces(body->m_faces);
|
||||
|
||||
prim = new GeomTriangles(Geom::UH_stream);
|
||||
prim->set_shade_model(Geom::SM_uniform);
|
||||
|
||||
for (int j=0; j<faces.size(); ++j) {
|
||||
prim->add_vertices(int(faces[j].m_n[0] - node0),
|
||||
int(faces[j].m_n[1] - node0),
|
||||
int(faces[j].m_n[2] - node0));
|
||||
i0 = int(faces[j].m_n[0] - node0);
|
||||
i1 = int(faces[j].m_n[1] - node0);
|
||||
i2 = int(faces[j].m_n[2] - node0);
|
||||
|
||||
prim->add_vertices(i0, i1, i2);
|
||||
prim->close_primitive();
|
||||
|
||||
if (two_sided) {
|
||||
prim->add_vertices(nodes.size() + int(faces[j].m_n[0] - node0),
|
||||
nodes.size() + int(faces[j].m_n[2] - node0),
|
||||
nodes.size() + int(faces[j].m_n[1] - node0));
|
||||
i0 = nodes.size() + int(faces[j].m_n[0] - node0);
|
||||
i1 = nodes.size() + int(faces[j].m_n[2] - node0);
|
||||
i2 = nodes.size() + int(faces[j].m_n[1] - node0);
|
||||
|
||||
prim->add_vertices(i0, i1, i2);
|
||||
prim->close_primitive();
|
||||
}
|
||||
}
|
||||
|
|
@ -259,8 +267,10 @@ make_geom(BulletSoftBodyNode *node, const GeomVertexFormat *format, bool two_sid
|
|||
prim->set_shade_model(Geom::SM_uniform);
|
||||
|
||||
for (int j=0; j<links.size(); ++j) {
|
||||
prim->add_vertices(int(links[j].m_n[0] - node0),
|
||||
int(links[j].m_n[1] - node0));
|
||||
i0 = int(links[j].m_n[0] - node0);
|
||||
i1 = int(links[j].m_n[1] - node0);
|
||||
|
||||
prim->add_vertices(i0, i1);
|
||||
prim->close_primitive();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,29 @@ BulletManifoldPoint(btManifoldPoint &pt)
|
|||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletManifoldPoint::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletManifoldPoint::
|
||||
BulletManifoldPoint(const BulletManifoldPoint &other)
|
||||
: _pt(other._pt) {
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletManifoldPoint::Copy Assignment
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletManifoldPoint& BulletManifoldPoint::
|
||||
operator=(const BulletManifoldPoint& other) {
|
||||
|
||||
this->_pt = other._pt;
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletManifoldPoint::get_lift_time
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ PUBLISHED:
|
|||
public:
|
||||
BulletManifoldPoint(btManifoldPoint &pt);
|
||||
|
||||
BulletManifoldPoint(const BulletManifoldPoint &other);
|
||||
BulletManifoldPoint& operator=(const BulletManifoldPoint& other);
|
||||
|
||||
private:
|
||||
btManifoldPoint &_pt;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ PUBLISHED:
|
|||
INLINE ~BulletSoftBodyConfig();
|
||||
|
||||
enum CollisionFlag {
|
||||
CF_rigid__vs_soft_mask = 0x000f, // RVSmask: Rigid versus soft mask
|
||||
CF_rigid_vs_soft_mask = 0x000f, // RVSmask: Rigid versus soft mask
|
||||
CF_sdf_rigid_soft = 0x0001, // SDF_RS: SDF based rigid vs soft
|
||||
CF_cluster_rigid_soft = 0x0002, // CL_RS: Cluster vs convex rigid vs soft
|
||||
CF_soft_vs_soft_mask = 0x0030, // SVSmask: Soft versus soft mask
|
||||
|
|
|
|||
|
|
@ -194,22 +194,35 @@ transform_changed() {
|
|||
LMatrix4 m_ts = ts->get_mat();
|
||||
|
||||
if (!m_sync.almost_equal(m_ts)) {
|
||||
_sync = ts;
|
||||
|
||||
// New transform for the center
|
||||
btTransform trans = TransformState_to_btTrans(ts);
|
||||
|
||||
trans *= _soft->m_initialWorldTransform.inverse();
|
||||
// Offset between current approx center and current initial transform
|
||||
btVector3 pos = LVecBase3_to_btVector3(this->get_aabb().get_approx_center());
|
||||
btVector3 origin = _soft->m_initialWorldTransform.getOrigin();
|
||||
btVector3 offset = pos - origin;
|
||||
|
||||
// Subtract offset to get new transform for the body
|
||||
trans.setOrigin(trans.getOrigin() - offset);
|
||||
|
||||
// Now apply the new transform
|
||||
_soft->transform(_soft->m_initialWorldTransform.inverse());
|
||||
_soft->transform(trans);
|
||||
|
||||
if (ts->has_scale()) {
|
||||
LVecBase3 scale = ts->get_scale();
|
||||
if (!scale.almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
|
||||
for (int i=0; i<get_num_shapes(); i++) {
|
||||
PT(BulletShape) shape = _shapes[i];
|
||||
shape->set_local_scale(scale);
|
||||
}
|
||||
}
|
||||
btVector3 current_scale = LVecBase3_to_btVector3(_sync->get_scale());
|
||||
btVector3 new_scale = LVecBase3_to_btVector3(ts->get_scale());
|
||||
|
||||
current_scale.setX(1.0 / current_scale.getX());
|
||||
current_scale.setY(1.0 / current_scale.getY());
|
||||
current_scale.setZ(1.0 / current_scale.getZ());
|
||||
|
||||
_soft->scale(current_scale);
|
||||
_soft->scale(new_scale);
|
||||
}
|
||||
|
||||
_sync = ts;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,7 +234,7 @@ transform_changed() {
|
|||
void BulletSoftBodyNode::
|
||||
sync_p2b() {
|
||||
|
||||
transform_changed();
|
||||
//transform_changed(); Disabled for now...
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -280,22 +293,21 @@ sync_b2p() {
|
|||
}
|
||||
}
|
||||
|
||||
// It is ok to pass the address of a temporary object here, because
|
||||
// set_bounds does not store the pointer - it makes a copy using
|
||||
// volume->make_copy().
|
||||
BoundingBox bb = this->get_aabb();
|
||||
LVecBase3 pos = bb.get_approx_center();
|
||||
// Update the synchronized transform with the current
|
||||
// approximate center of the soft body
|
||||
LVecBase3 pos = this->get_aabb().get_approx_center();
|
||||
CPT(TransformState) ts = TransformState::make_pos(pos);
|
||||
|
||||
NodePath np = NodePath::any_path((PandaNode *)this);
|
||||
LVecBase3 scale = np.get_net_transform()->get_scale();
|
||||
|
||||
CPT(TransformState) ts = TransformState::make_pos(pos);
|
||||
ts = ts->set_scale(scale);
|
||||
|
||||
_sync = ts;
|
||||
_sync_disable = true;
|
||||
np.set_transform(NodePath(), ts);
|
||||
_sync_disable = false;
|
||||
/*
|
||||
*/
|
||||
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
this->r_mark_geom_bounds_stale(current_thread);
|
||||
|
|
@ -1135,3 +1147,26 @@ append_angular_joint(BulletBodyNode *body, const LVector3 &axis, PN_stdfloat erp
|
|||
_soft->appendAngularJoint(as, ptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletSoftBodyNode::set_wind_velocity
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletSoftBodyNode::
|
||||
set_wind_velocity(const LVector3 &velocity) {
|
||||
|
||||
nassertv(!velocity.is_nan());
|
||||
_soft->setWindVelocity(LVecBase3_to_btVector3(velocity));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletSoftBodyNode::get_wind_velocity
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LVector3 BulletSoftBodyNode::
|
||||
get_wind_velocity() const {
|
||||
|
||||
return btVector3_to_LVector3(_soft->getWindVelocity());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,9 @@ PUBLISHED:
|
|||
void add_velocity(const LVector3 &velocity);
|
||||
void add_velocity(const LVector3 &velocity, int node);
|
||||
|
||||
void set_wind_velocity(const LVector3 &velocity);
|
||||
LVector3 get_wind_velocity() const;
|
||||
|
||||
void set_pose(bool bvolume, bool bframe);
|
||||
|
||||
BoundingBox get_aabb() const;
|
||||
|
|
|
|||
|
|
@ -87,18 +87,21 @@ BulletWorld() {
|
|||
// Filter callback
|
||||
switch (bullet_filter_algorithm) {
|
||||
case FA_mask:
|
||||
_world->getPairCache()->setOverlapFilterCallback(&_filter_cb1);
|
||||
_filter_cb = &_filter_cb1;
|
||||
break;
|
||||
case FA_groups_mask:
|
||||
_world->getPairCache()->setOverlapFilterCallback(&_filter_cb2);
|
||||
_filter_cb = &_filter_cb2;
|
||||
break;
|
||||
case FA_callback:
|
||||
_world->getPairCache()->setOverlapFilterCallback(&_filter_cb3);
|
||||
_filter_cb = &_filter_cb3;
|
||||
break;
|
||||
default:
|
||||
bullet_cat.error() << "no proper filter algorithm!" << endl;
|
||||
_filter_cb = NULL;
|
||||
}
|
||||
|
||||
_world->getPairCache()->setOverlapFilterCallback(_filter_cb);
|
||||
|
||||
// Tick callback
|
||||
_tick_callback_obj = NULL;
|
||||
|
||||
|
|
@ -712,19 +715,61 @@ sweep_test_closest(BulletShape *shape, const TransformState &from_ts, const Tran
|
|||
return cb;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletWorld::filter_test
|
||||
// Access: Published
|
||||
// Description: Performs a test if two bodies should collide or
|
||||
// not, based on the collision filter setting.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BulletWorld::
|
||||
filter_test(PandaNode *node0, PandaNode *node1) const {
|
||||
|
||||
nassertr(node0, false);
|
||||
nassertr(node1, false);
|
||||
nassertr(_filter_cb, false);
|
||||
|
||||
btCollisionObject *obj0 = get_collision_object(node0);
|
||||
btCollisionObject *obj1 = get_collision_object(node1);
|
||||
|
||||
nassertr(obj0, false);
|
||||
nassertr(obj1, false);
|
||||
|
||||
btBroadphaseProxy *proxy0 = obj0->getBroadphaseHandle();
|
||||
btBroadphaseProxy *proxy1 = obj1->getBroadphaseHandle();
|
||||
|
||||
nassertr(proxy0, false);
|
||||
nassertr(proxy1, false);
|
||||
|
||||
return _filter_cb->needBroadphaseCollision(proxy0, proxy1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletWorld::contact_test
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description: Performas a test for all bodies which are
|
||||
// currently in contact with the given body.
|
||||
// The test returns a BulletContactResult object
|
||||
// which may contain zero, one or more contacts.
|
||||
//
|
||||
// If the optional parameter use_filter is set to
|
||||
// TRUE this test will consider filter settings.
|
||||
// Otherwise all objects in contact are reported,
|
||||
// no matter if they would collide or not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletContactResult BulletWorld::
|
||||
contact_test(PandaNode *node) const {
|
||||
contact_test(PandaNode *node, bool use_filter) const {
|
||||
|
||||
btCollisionObject *obj = get_collision_object(node);
|
||||
|
||||
BulletContactResult cb;
|
||||
|
||||
if (obj) {
|
||||
#if BT_BULLET_VERSION >= 281
|
||||
if (use_filter) {
|
||||
cb.use_filter(_filter_cb, obj->getBroadphaseHandle());
|
||||
}
|
||||
#endif
|
||||
|
||||
_world->contactTest(obj, cb);
|
||||
}
|
||||
|
||||
|
|
@ -734,7 +779,10 @@ contact_test(PandaNode *node) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletWorld::contact_pair_test
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description: Performas a test if the two bodies given as
|
||||
// parameters are in contact or not.
|
||||
// The test returns a BulletContactResult object
|
||||
// which may contain zero or one contacts.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BulletContactResult BulletWorld::
|
||||
contact_test_pair(PandaNode *node0, PandaNode *node1) const {
|
||||
|
|
@ -745,6 +793,7 @@ contact_test_pair(PandaNode *node0, PandaNode *node1) const {
|
|||
BulletContactResult cb;
|
||||
|
||||
if (obj0 && obj1) {
|
||||
|
||||
_world->contactPairTest(obj0, obj1, cb);
|
||||
}
|
||||
|
||||
|
|
@ -806,7 +855,7 @@ set_group_collision_flag(unsigned int group1, unsigned int group2, bool enable)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletWorld::get_collision_object
|
||||
// Function: BulletWorld::get_group_collision_flag
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -123,9 +123,11 @@ PUBLISHED:
|
|||
const CollideMask &mask=CollideMask::all_on(),
|
||||
PN_stdfloat penetration=0.0f) const;
|
||||
|
||||
BulletContactResult contact_test(PandaNode *node) const;
|
||||
BulletContactResult contact_test(PandaNode *node, bool use_filter=false) const;
|
||||
BulletContactResult contact_test_pair(PandaNode *node0, PandaNode *node1) const;
|
||||
|
||||
bool filter_test(PandaNode *node0, PandaNode *node1) const;
|
||||
|
||||
// Manifolds
|
||||
INLINE int get_num_manifolds() const;
|
||||
BulletPersistentManifold *get_manifold(int idx) const;
|
||||
|
|
@ -232,6 +234,7 @@ private:
|
|||
btFilterCallback1 _filter_cb1;
|
||||
btFilterCallback2 _filter_cb2;
|
||||
btFilterCallback3 _filter_cb3;
|
||||
btOverlapFilterCallback *_filter_cb;
|
||||
|
||||
PT(CallbackObject) _tick_callback_obj;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class AnimChannelBase;
|
|||
// MovingPart. It defines a hierarchy of MovingParts.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_CHAN PartGroup : public TypedWritableReferenceCount, public Namable {
|
||||
public:
|
||||
PUBLISHED:
|
||||
// This enum defines bits which may be passed into check_hierarchy()
|
||||
// and PartBundle::bind_anim() to allow an inexact match of channel
|
||||
// hierarchies. This specifies conditions that we don't care about
|
||||
|
|
|
|||
|
|
@ -17,13 +17,14 @@
|
|||
cocoaGraphicsPipe.h cocoaGraphicsPipe.I \
|
||||
cocoaGraphicsWindow.h cocoaGraphicsWindow.I \
|
||||
cocoaGraphicsStateGuardian.h cocoaGraphicsStateGuardian.I \
|
||||
cocoaPandaView.h cocoaPandaWindowDelegate.h
|
||||
cocoaPandaApp.h cocoaPandaView.h cocoaPandaWindowDelegate.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_cocoadisplay.mm \
|
||||
cocoaGraphicsPipe.mm \
|
||||
cocoaGraphicsStateGuardian.mm \
|
||||
cocoaGraphicsWindow.mm \
|
||||
cocoaPandaApp.mm \
|
||||
cocoaPandaView.mm \
|
||||
cocoaPandaWindow.mm \
|
||||
cocoaPandaWindowDelegate.mm
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
//#include "cocoaGraphicsBuffer.h"
|
||||
#include "cocoaGraphicsWindow.h"
|
||||
#include "cocoaGraphicsStateGuardian.h"
|
||||
#include "cocoaPandaApp.h"
|
||||
#include "config_cocoadisplay.h"
|
||||
#include "frameBufferProperties.h"
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ TypeHandle CocoaGraphicsPipe::_type_handle;
|
|||
static void init_app() {
|
||||
if (NSApp == nil) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
[NSApplication sharedApplication];
|
||||
[CocoaPandaApp sharedApplication];
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ public:
|
|||
void handle_mouse_button_event(int button, bool down);
|
||||
void handle_mouse_moved_event(bool in_window, double x, double y, bool absolute);
|
||||
void handle_wheel_event(double x, double y);
|
||||
virtual ButtonMap *get_keyboard_map() const;
|
||||
|
||||
INLINE NSWindow *get_nswindow() const;
|
||||
INLINE NSView *get_nsview() const;
|
||||
|
|
@ -80,7 +81,9 @@ protected:
|
|||
private:
|
||||
NSImage *load_image(const Filename &filename);
|
||||
|
||||
ButtonHandle map_key(unsigned short keycode);
|
||||
void handle_modifier(NSUInteger modifierFlags, NSUInteger mask, ButtonHandle button);
|
||||
ButtonHandle map_key(unsigned short c) const;
|
||||
ButtonHandle map_raw_key(unsigned short keycode) const;
|
||||
|
||||
private:
|
||||
NSWindow *_window;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#import <AppKit/NSImage.h>
|
||||
#import <AppKit/NSScreen.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
//#import <Carbon/Carbon.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
TypeHandle CocoaGraphicsWindow::_type_handle;
|
||||
|
||||
|
|
@ -1495,54 +1495,73 @@ void CocoaGraphicsWindow::
|
|||
handle_key_event(NSEvent *event) {
|
||||
NSUInteger modifierFlags = [event modifierFlags];
|
||||
|
||||
if ((modifierFlags ^ _modifier_keys) & NSAlphaShiftKeyMask) {
|
||||
if (modifierFlags & NSAlphaShiftKeyMask) {
|
||||
_input_devices[0].button_down(KeyboardButton::caps_lock());
|
||||
} else {
|
||||
_input_devices[0].button_up(KeyboardButton::caps_lock());
|
||||
}
|
||||
}
|
||||
//NB. This is actually a on-off toggle, not up-down.
|
||||
// Should we instead rapidly fire two successive up-down events?
|
||||
handle_modifier(modifierFlags, NSAlphaShiftKeyMask, KeyboardButton::caps_lock());
|
||||
|
||||
if ((modifierFlags ^ _modifier_keys) & NSShiftKeyMask) {
|
||||
if (modifierFlags & NSShiftKeyMask) {
|
||||
_input_devices[0].button_down(KeyboardButton::shift());
|
||||
} else {
|
||||
_input_devices[0].button_up(KeyboardButton::shift());
|
||||
}
|
||||
}
|
||||
// Check if any of the modifier keys have changed.
|
||||
handle_modifier(modifierFlags, NSShiftKeyMask, KeyboardButton::shift());
|
||||
handle_modifier(modifierFlags, NSControlKeyMask, KeyboardButton::control());
|
||||
handle_modifier(modifierFlags, NSAlternateKeyMask, KeyboardButton::alt());
|
||||
handle_modifier(modifierFlags, NSCommandKeyMask, KeyboardButton::meta());
|
||||
|
||||
if ((modifierFlags ^ _modifier_keys) & NSControlKeyMask) {
|
||||
if (modifierFlags & NSControlKeyMask) {
|
||||
_input_devices[0].button_down(KeyboardButton::control());
|
||||
} else {
|
||||
_input_devices[0].button_up(KeyboardButton::control());
|
||||
}
|
||||
}
|
||||
|
||||
if ((modifierFlags ^ _modifier_keys) & NSAlternateKeyMask) {
|
||||
if (modifierFlags & NSAlternateKeyMask) {
|
||||
_input_devices[0].button_down(KeyboardButton::alt());
|
||||
} else {
|
||||
_input_devices[0].button_up(KeyboardButton::alt());
|
||||
}
|
||||
}
|
||||
|
||||
if ((modifierFlags ^ _modifier_keys) & NSCommandKeyMask) {
|
||||
if (modifierFlags & NSCommandKeyMask) {
|
||||
_input_devices[0].button_down(KeyboardButton::meta());
|
||||
} else {
|
||||
_input_devices[0].button_up(KeyboardButton::meta());
|
||||
}
|
||||
}
|
||||
|
||||
// I'd add the help key too, but something else in Cocoa messes
|
||||
// around with it. The up event is registered fine below, but
|
||||
// the down event isn't, and the modifier flag gets stuck after 1 press.
|
||||
// More testing is needed, but I don't think it's worth it until
|
||||
// we encounter someone who requires support for the help key.
|
||||
// These are not documented, but they seem to be a reliable indicator
|
||||
// of the status of the left/right modifier keys.
|
||||
handle_modifier(modifierFlags, 0x0002, KeyboardButton::lshift());
|
||||
handle_modifier(modifierFlags, 0x0004, KeyboardButton::rshift());
|
||||
handle_modifier(modifierFlags, 0x0001, KeyboardButton::lcontrol());
|
||||
handle_modifier(modifierFlags, 0x2000, KeyboardButton::rcontrol());
|
||||
handle_modifier(modifierFlags, 0x0020, KeyboardButton::lalt());
|
||||
handle_modifier(modifierFlags, 0x0040, KeyboardButton::ralt());
|
||||
handle_modifier(modifierFlags, 0x0008, KeyboardButton::lmeta());
|
||||
handle_modifier(modifierFlags, 0x0010, KeyboardButton::rmeta());
|
||||
|
||||
_modifier_keys = modifierFlags;
|
||||
|
||||
// Get the raw button and send it.
|
||||
ButtonHandle raw_button = map_raw_key([event keyCode]);
|
||||
if (raw_button != ButtonHandle::none()) {
|
||||
// This is not perfect. Eventually, this whole thing should
|
||||
// probably be replaced with something that uses IOKit or so.
|
||||
// In particular, the flaws are:
|
||||
// - OS eats unmodified F11, F12, scroll lock, pause
|
||||
// - no up events for caps lock
|
||||
// - no robust way to distinguish up/down for modkeys
|
||||
if ([event type] == NSKeyUp) {
|
||||
_input_devices[0].raw_button_up(raw_button);
|
||||
|
||||
} else if ([event type] == NSFlagsChanged) {
|
||||
bool down = false;
|
||||
if (raw_button == KeyboardButton::lshift()) {
|
||||
down = (modifierFlags & 0x0002);
|
||||
} else if (raw_button == KeyboardButton::rshift()) {
|
||||
down = (modifierFlags & 0x0004);
|
||||
} else if (raw_button == KeyboardButton::lcontrol()) {
|
||||
down = (modifierFlags & 0x0001);
|
||||
} else if (raw_button == KeyboardButton::rcontrol()) {
|
||||
down = (modifierFlags & 0x2000);
|
||||
} else if (raw_button == KeyboardButton::lalt()) {
|
||||
down = (modifierFlags & 0x0020);
|
||||
} else if (raw_button == KeyboardButton::ralt()) {
|
||||
down = (modifierFlags & 0x0040);
|
||||
} else if (raw_button == KeyboardButton::lmeta()) {
|
||||
down = (modifierFlags & 0x0008);
|
||||
} else if (raw_button == KeyboardButton::rmeta()) {
|
||||
down = (modifierFlags & 0x0010);
|
||||
} else if (raw_button == KeyboardButton::caps_lock()) {
|
||||
// Emulate down-up, annoying hack!
|
||||
_input_devices[0].raw_button_down(raw_button);
|
||||
}
|
||||
if (down) {
|
||||
_input_devices[0].raw_button_down(raw_button);
|
||||
} else {
|
||||
_input_devices[0].raw_button_up(raw_button);
|
||||
}
|
||||
} else if (![event isARepeat]) {
|
||||
_input_devices[0].raw_button_down(raw_button);
|
||||
}
|
||||
}
|
||||
|
||||
// FlagsChanged events only carry modifier key information.
|
||||
if ([event type] == NSFlagsChanged) {
|
||||
return;
|
||||
|
|
@ -1597,6 +1616,23 @@ handle_key_event(NSEvent *event) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::handle_modifier
|
||||
// Access: Private
|
||||
// Description: Called by handle_key_event to read the state of
|
||||
// a modifier key.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CocoaGraphicsWindow::
|
||||
handle_modifier(NSUInteger modifierFlags, NSUInteger mask, ButtonHandle button) {
|
||||
if ((modifierFlags ^ _modifier_keys) & mask) {
|
||||
if (modifierFlags & mask) {
|
||||
_input_devices[0].button_down(button);
|
||||
} else {
|
||||
_input_devices[0].button_up(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::handle_mouse_button_event
|
||||
// Access: Public
|
||||
|
|
@ -1694,14 +1730,71 @@ handle_wheel_event(double x, double y) {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::get_keyboard_map
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a ButtonMap containing the association
|
||||
// between raw buttons and virtual buttons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonMap *CocoaGraphicsWindow::
|
||||
get_keyboard_map() const {
|
||||
TISInputSourceRef input_source;
|
||||
CFDataRef layout_data;
|
||||
const UCKeyboardLayout *layout;
|
||||
|
||||
// Get the current keyboard layout data.
|
||||
input_source = TISCopyCurrentKeyboardInputSource();
|
||||
layout_data = (CFDataRef) TISGetInputSourceProperty(input_source, kTISPropertyUnicodeKeyLayoutData);
|
||||
layout = (const UCKeyboardLayout *)CFDataGetBytePtr(layout_data);
|
||||
|
||||
ButtonMap *map = new ButtonMap;
|
||||
|
||||
UniChar chars[4];
|
||||
UniCharCount num_chars;
|
||||
|
||||
// Iterate through the known scancode range and see what
|
||||
// every scan code is mapped to.
|
||||
for (int k = 0; k <= 0x7E; ++k) {
|
||||
ButtonHandle raw_button = map_raw_key(k);
|
||||
if (raw_button == ButtonHandle::none()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UInt32 dead_keys = 0;
|
||||
if (UCKeyTranslate(layout, k, kUCKeyActionDisplay, 0, LMGetKbdType(),
|
||||
kUCKeyTranslateNoDeadKeysMask, &dead_keys, 4,
|
||||
&num_chars, chars) == noErr) {
|
||||
if (num_chars > 0 && chars[0] != 0x10) {
|
||||
ButtonHandle button = ButtonHandle::none();
|
||||
|
||||
if (chars[0] > 0 && chars[0] <= 0x7f) {
|
||||
button = KeyboardButton::ascii_key(chars[0]);
|
||||
}
|
||||
if (button == ButtonHandle::none()) {
|
||||
button = map_key(chars[0]);
|
||||
}
|
||||
if (button != ButtonHandle::none()) {
|
||||
map->map_button(raw_button, button);
|
||||
}
|
||||
} else {
|
||||
// A special function key or modifier key, which isn't remapped by the OS.
|
||||
map->map_button(raw_button, raw_button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(input_source);
|
||||
return map;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::map_key
|
||||
// Access: Private
|
||||
// Description:
|
||||
// Description: Maps a unicode key character to a ButtonHandle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle CocoaGraphicsWindow::
|
||||
map_key(unsigned short keycode) {
|
||||
switch (keycode) {
|
||||
map_key(unsigned short c) const {
|
||||
switch (c) {
|
||||
case NSEnterCharacter:
|
||||
return KeyboardButton::enter();
|
||||
case NSBackspaceCharacter:
|
||||
|
|
@ -1713,12 +1806,21 @@ map_key(unsigned short keycode) {
|
|||
// BackTabCharacter is sent when shift-tab is used.
|
||||
return KeyboardButton::tab();
|
||||
|
||||
case 0x10:
|
||||
// No idea where this constant comes from, but it
|
||||
// is sent whenever the menu key is pressed.
|
||||
return KeyboardButton::menu();
|
||||
|
||||
case 0x1e:
|
||||
case NSUpArrowFunctionKey:
|
||||
return KeyboardButton::up();
|
||||
case 0x1f:
|
||||
case NSDownArrowFunctionKey:
|
||||
return KeyboardButton::down();
|
||||
case 0x1c:
|
||||
case NSLeftArrowFunctionKey:
|
||||
return KeyboardButton::left();
|
||||
case 0x1d:
|
||||
case NSRightArrowFunctionKey:
|
||||
return KeyboardButton::right();
|
||||
case NSF1FunctionKey:
|
||||
|
|
@ -1777,14 +1879,18 @@ map_key(unsigned short keycode) {
|
|||
return KeyboardButton::insert();
|
||||
case NSDeleteFunctionKey:
|
||||
return KeyboardButton::del();
|
||||
case 0x01:
|
||||
case NSHomeFunctionKey:
|
||||
return KeyboardButton::home();
|
||||
case NSBeginFunctionKey:
|
||||
break;
|
||||
case 0x04:
|
||||
case NSEndFunctionKey:
|
||||
return KeyboardButton::end();
|
||||
case 0x0b:
|
||||
case NSPageUpFunctionKey:
|
||||
return KeyboardButton::page_up();
|
||||
case 0x0c:
|
||||
case NSPageDownFunctionKey:
|
||||
return KeyboardButton::page_down();
|
||||
case NSPrintScreenFunctionKey:
|
||||
|
|
@ -1817,6 +1923,7 @@ map_key(unsigned short keycode) {
|
|||
case NSRedoFunctionKey:
|
||||
case NSFindFunctionKey:
|
||||
break;
|
||||
case 0x05:
|
||||
case NSHelpFunctionKey:
|
||||
return KeyboardButton::help();
|
||||
case NSModeSwitchFunctionKey:
|
||||
|
|
@ -1824,3 +1931,124 @@ map_key(unsigned short keycode) {
|
|||
}
|
||||
return ButtonHandle::none();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CocoaGraphicsWindow::map_raw_key
|
||||
// Access: Private
|
||||
// Description: Maps a keycode to a ButtonHandle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonHandle CocoaGraphicsWindow::
|
||||
map_raw_key(unsigned short keycode) const {
|
||||
if (keycode > 0x7f) {
|
||||
return ButtonHandle::none();
|
||||
}
|
||||
switch ((unsigned char) keycode) {
|
||||
/* See HIToolBox/Events.h */
|
||||
case 0x00: return KeyboardButton::ascii_key('a');
|
||||
case 0x01: return KeyboardButton::ascii_key('s');
|
||||
case 0x02: return KeyboardButton::ascii_key('d');
|
||||
case 0x03: return KeyboardButton::ascii_key('f');
|
||||
case 0x04: return KeyboardButton::ascii_key('h');
|
||||
case 0x05: return KeyboardButton::ascii_key('g');
|
||||
case 0x06: return KeyboardButton::ascii_key('z');
|
||||
case 0x07: return KeyboardButton::ascii_key('x');
|
||||
case 0x08: return KeyboardButton::ascii_key('c');
|
||||
case 0x09: return KeyboardButton::ascii_key('v');
|
||||
case 0x0B: return KeyboardButton::ascii_key('b');
|
||||
case 0x0C: return KeyboardButton::ascii_key('q');
|
||||
case 0x0D: return KeyboardButton::ascii_key('w');
|
||||
case 0x0E: return KeyboardButton::ascii_key('e');
|
||||
case 0x0F: return KeyboardButton::ascii_key('r');
|
||||
case 0x10: return KeyboardButton::ascii_key('y');
|
||||
case 0x11: return KeyboardButton::ascii_key('t');
|
||||
case 0x12: return KeyboardButton::ascii_key('1');
|
||||
case 0x13: return KeyboardButton::ascii_key('2');
|
||||
case 0x14: return KeyboardButton::ascii_key('3');
|
||||
case 0x15: return KeyboardButton::ascii_key('4');
|
||||
case 0x16: return KeyboardButton::ascii_key('6');
|
||||
case 0x17: return KeyboardButton::ascii_key('5');
|
||||
case 0x18: return KeyboardButton::ascii_key('=');
|
||||
case 0x19: return KeyboardButton::ascii_key('9');
|
||||
case 0x1A: return KeyboardButton::ascii_key('7');
|
||||
case 0x1B: return KeyboardButton::ascii_key('-');
|
||||
case 0x1C: return KeyboardButton::ascii_key('8');
|
||||
case 0x1D: return KeyboardButton::ascii_key('0');
|
||||
case 0x1E: return KeyboardButton::ascii_key(']');
|
||||
case 0x1F: return KeyboardButton::ascii_key('o');
|
||||
case 0x20: return KeyboardButton::ascii_key('u');
|
||||
case 0x21: return KeyboardButton::ascii_key('[');
|
||||
case 0x22: return KeyboardButton::ascii_key('i');
|
||||
case 0x23: return KeyboardButton::ascii_key('p');
|
||||
case 0x24: return KeyboardButton::enter();
|
||||
case 0x25: return KeyboardButton::ascii_key('l');
|
||||
case 0x26: return KeyboardButton::ascii_key('j');
|
||||
case 0x27: return KeyboardButton::ascii_key('\'');
|
||||
case 0x28: return KeyboardButton::ascii_key('k');
|
||||
case 0x29: return KeyboardButton::ascii_key(';');
|
||||
case 0x2A: return KeyboardButton::ascii_key('\\');
|
||||
case 0x2B: return KeyboardButton::ascii_key(',');
|
||||
case 0x2C: return KeyboardButton::ascii_key('/');
|
||||
case 0x2D: return KeyboardButton::ascii_key('n');
|
||||
case 0x2E: return KeyboardButton::ascii_key('m');
|
||||
case 0x2F: return KeyboardButton::ascii_key('.');
|
||||
case 0x30: return KeyboardButton::tab();
|
||||
case 0x31: return KeyboardButton::ascii_key(' ');
|
||||
case 0x32: return KeyboardButton::ascii_key('`');
|
||||
case 0x33: return KeyboardButton::backspace();
|
||||
case 0x35: return KeyboardButton::escape();
|
||||
case 0x36: return KeyboardButton::rmeta();
|
||||
case 0x37: return KeyboardButton::lmeta();
|
||||
case 0x38: return KeyboardButton::lshift();
|
||||
case 0x39: return KeyboardButton::caps_lock();
|
||||
case 0x3A: return KeyboardButton::lalt();
|
||||
case 0x3B: return KeyboardButton::lcontrol();
|
||||
case 0x3C: return KeyboardButton::rshift();
|
||||
case 0x3D: return KeyboardButton::ralt();
|
||||
case 0x3E: return KeyboardButton::rcontrol();
|
||||
case 0x41: return KeyboardButton::ascii_key('.');
|
||||
case 0x43: return KeyboardButton::ascii_key('*');
|
||||
case 0x45: return KeyboardButton::ascii_key('+');
|
||||
case 0x47: return KeyboardButton::num_lock();
|
||||
case 0x4B: return KeyboardButton::ascii_key('/');
|
||||
case 0x4C: return KeyboardButton::enter();
|
||||
case 0x4E: return KeyboardButton::ascii_key('-');
|
||||
case 0x51: return KeyboardButton::ascii_key('=');
|
||||
case 0x52: return KeyboardButton::ascii_key('0');
|
||||
case 0x53: return KeyboardButton::ascii_key('1');
|
||||
case 0x54: return KeyboardButton::ascii_key('2');
|
||||
case 0x55: return KeyboardButton::ascii_key('3');
|
||||
case 0x56: return KeyboardButton::ascii_key('4');
|
||||
case 0x57: return KeyboardButton::ascii_key('5');
|
||||
case 0x58: return KeyboardButton::ascii_key('6');
|
||||
case 0x59: return KeyboardButton::ascii_key('7');
|
||||
case 0x5B: return KeyboardButton::ascii_key('8');
|
||||
case 0x5C: return KeyboardButton::ascii_key('9');
|
||||
case 0x60: return KeyboardButton::f5();
|
||||
case 0x61: return KeyboardButton::f6();
|
||||
case 0x62: return KeyboardButton::f7();
|
||||
case 0x63: return KeyboardButton::f3();
|
||||
case 0x64: return KeyboardButton::f8();
|
||||
case 0x65: return KeyboardButton::f9();
|
||||
case 0x67: return KeyboardButton::f11();
|
||||
case 0x69: return KeyboardButton::print_screen();
|
||||
case 0x6B: return KeyboardButton::scroll_lock();
|
||||
case 0x6D: return KeyboardButton::f10();
|
||||
case 0x6E: return KeyboardButton::menu();
|
||||
case 0x6F: return KeyboardButton::f12();
|
||||
case 0x71: return KeyboardButton::pause();
|
||||
case 0x72: return KeyboardButton::insert();
|
||||
case 0x73: return KeyboardButton::home();
|
||||
case 0x74: return KeyboardButton::page_up();
|
||||
case 0x75: return KeyboardButton::del();
|
||||
case 0x76: return KeyboardButton::f4();
|
||||
case 0x77: return KeyboardButton::end();
|
||||
case 0x78: return KeyboardButton::f2();
|
||||
case 0x79: return KeyboardButton::page_down();
|
||||
case 0x7A: return KeyboardButton::f1();
|
||||
case 0x7B: return KeyboardButton::left();
|
||||
case 0x7C: return KeyboardButton::right();
|
||||
case 0x7D: return KeyboardButton::down();
|
||||
case 0x7E: return KeyboardButton::up();
|
||||
default: return ButtonHandle::none();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
// Filename: cocoaPandaApp.h
|
||||
// Created by: rdb (08Mar14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import <AppKit/NSApplication.h>
|
||||
|
||||
// This class solely exists so that we can override sendEvent in order
|
||||
// to prevent NSApplication from eating certain keyboard events.
|
||||
@interface CocoaPandaApp : NSApplication
|
||||
- (void) sendEvent: (NSEvent *) event;
|
||||
@end
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Filename: cocoaPandaApp.mm
|
||||
// Created by: rdb (08Mar14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#import "cocoaPandaApp.h"
|
||||
|
||||
@implementation CocoaPandaApp
|
||||
- (void) sendEvent: (NSEvent *) event {
|
||||
// This is a hack that allows us to receive cmd-key-up events correctly.
|
||||
// Also prevent it from eating the insert/help key.
|
||||
if (([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask))
|
||||
||([event type] == NSKeyDown && [event keyCode] == 0x72)) {
|
||||
|
||||
[[self keyWindow] sendEvent: event];
|
||||
} else {
|
||||
[super sendEvent: event];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#include "cocoaGraphicsPipe.mm"
|
||||
#include "cocoaGraphicsStateGuardian.mm"
|
||||
#include "cocoaGraphicsWindow.mm"
|
||||
#include "cocoaPandaApp.mm"
|
||||
#include "cocoaPandaView.mm"
|
||||
#include "cocoaPandaWindow.mm"
|
||||
#include "cocoaPandaWindowDelegate.mm"
|
||||
#include "cocoaPandaWindowDelegate.mm"
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
graphicsDevice.h graphicsDevice.I \
|
||||
graphicsPipe.I graphicsPipe.h \
|
||||
graphicsPipeSelection.I graphicsPipeSelection.h \
|
||||
graphicsStateGuardian.I \
|
||||
graphicsStateGuardian.h \
|
||||
graphicsStateGuardian.I graphicsStateGuardian.h \
|
||||
graphicsStateGuardian_ext.cxx graphicsStateGuardian_ext.h \
|
||||
graphicsThreadingModel.I graphicsThreadingModel.h \
|
||||
graphicsWindow.I graphicsWindow.h \
|
||||
graphicsWindowInputDevice.I \
|
||||
|
|
|
|||
|
|
@ -124,6 +124,11 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||
void CallbackGraphicsWindow::
|
||||
end_frame(FrameMode mode, Thread *current_thread) {
|
||||
if (_render_callback != NULL) {
|
||||
// In case the callback or the application hosting the OpenGL
|
||||
// context wants to do more rendering, let's give it a blank slate.
|
||||
_gsg->set_state_and_transform(RenderState::make_empty(), _gsg->get_internal_transform());
|
||||
_gsg->clear_before_callback();
|
||||
|
||||
RenderCallbackData data(this, RCT_end_frame, mode);
|
||||
_render_callback->do_callback(&data);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -172,6 +172,17 @@ ConfigVariableInt max_texture_stages
|
|||
"this number of texture stages simultaneously, regardless of "
|
||||
"what the GSG says it can do."));
|
||||
|
||||
ConfigVariableInt max_color_targets
|
||||
("max-color-targets", -1,
|
||||
PRC_DESC("Set this to a positive integer to limit the number of "
|
||||
"color targets reported by the GSG. This can be used to limit "
|
||||
"the amount of render targets Panda will attempt to use. "
|
||||
"If this is zero or less, the GSG will report its honest number "
|
||||
"of color targets, allowing Panda the full use of the graphics "
|
||||
"card; if it is 1 or more, then Panda will never allow more than "
|
||||
"this number of color targets simultaneously, regardless of "
|
||||
"what the GSG says it can do."));
|
||||
|
||||
ConfigVariableBool support_render_texture
|
||||
("support-render-texture", true,
|
||||
PRC_DESC("Set this true allow use of the render-to-a-texture feature, if it "
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool force_parasite_buffer;
|
|||
extern EXPCL_PANDA_DISPLAY ConfigVariableBool prefer_single_buffer;
|
||||
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableInt max_texture_stages;
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableInt max_color_targets;
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_render_texture;
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_rescale_normal;
|
||||
extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_stencil;
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ get_texture_reload_priority() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DisplayRegion::
|
||||
set_cube_map_index(int cube_map_index) {
|
||||
set_target_tex_page(cube_map_index, 0);
|
||||
set_target_tex_page(cube_map_index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -262,20 +262,6 @@ get_target_tex_page() const {
|
|||
return cdata->_target_tex_page;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::get_target_tex_view
|
||||
// Access: Published
|
||||
// Description: Returns the target view number associated with this
|
||||
// particular DisplayRegion, or -1 if it is not
|
||||
// associated with a view. See
|
||||
// set_target_tex_page().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DisplayRegion::
|
||||
get_target_tex_view() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_target_tex_view;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegion::set_cull_callback
|
||||
// Access: Published
|
||||
|
|
@ -812,19 +798,6 @@ get_target_tex_page() const {
|
|||
return _cdata->_target_tex_page;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegionPipelineReader::get_target_tex_view
|
||||
// Access: Published
|
||||
// Description: Returns the target view number associated with this
|
||||
// particular DisplayRegion, or -1 if it is not
|
||||
// associated with a view. See
|
||||
// set_target_tex_page().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DisplayRegionPipelineReader::
|
||||
get_target_tex_view() const {
|
||||
return _cdata->_target_tex_view;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DisplayRegionPipelineReader::get_draw_callback
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -404,12 +404,11 @@ get_cull_traverser() {
|
|||
// and/or stereo textures.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DisplayRegion::
|
||||
set_target_tex_page(int page, int view) {
|
||||
set_target_tex_page(int page) {
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
nassertv(pipeline_stage == 0);
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_target_tex_page = page;
|
||||
cdata->_target_tex_view = view;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -587,7 +586,7 @@ get_screenshot() {
|
|||
|
||||
RenderBuffer buffer = gsg->get_render_buffer(get_screenshot_buffer_type(),
|
||||
_window->get_fb_properties());
|
||||
if (!gsg->framebuffer_copy_to_ram(tex, -1, this, buffer)) {
|
||||
if (!gsg->framebuffer_copy_to_ram(tex, 0, -1, this, buffer)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -823,8 +822,7 @@ CData() :
|
|||
_sort(0),
|
||||
_stereo_channel(Lens::SC_mono),
|
||||
_tex_view_offset(0),
|
||||
_target_tex_page(-1),
|
||||
_target_tex_view(-1)
|
||||
_target_tex_page(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -849,8 +847,7 @@ CData(const DisplayRegion::CData ©) :
|
|||
_sort(copy._sort),
|
||||
_stereo_channel(copy._stereo_channel),
|
||||
_tex_view_offset(copy._tex_view_offset),
|
||||
_target_tex_page(copy._target_tex_page),
|
||||
_target_tex_view(copy._target_tex_view)
|
||||
_target_tex_page(copy._target_tex_page)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,9 +112,8 @@ PUBLISHED:
|
|||
CullTraverser *get_cull_traverser();
|
||||
|
||||
INLINE void set_cube_map_index(int cube_map_index);
|
||||
virtual void set_target_tex_page(int page, int view);
|
||||
virtual void set_target_tex_page(int page);
|
||||
INLINE int get_target_tex_page() const;
|
||||
INLINE int get_target_tex_view() const;
|
||||
|
||||
INLINE void set_cull_callback(CallbackObject *object);
|
||||
INLINE void clear_cull_callback();
|
||||
|
|
@ -213,7 +212,6 @@ private:
|
|||
Lens::StereoChannel _stereo_channel;
|
||||
int _tex_view_offset;
|
||||
int _target_tex_page;
|
||||
int _target_tex_view;
|
||||
|
||||
PT(CallbackObject) _cull_callback;
|
||||
PT(CallbackObject) _draw_callback;
|
||||
|
|
@ -312,7 +310,6 @@ public:
|
|||
INLINE int get_tex_view_offset();
|
||||
INLINE bool get_clear_depth_between_eyes() const;
|
||||
INLINE int get_target_tex_page() const;
|
||||
INLINE int get_target_tex_view() const;
|
||||
INLINE CallbackObject *get_draw_callback() const;
|
||||
|
||||
INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const;
|
||||
|
|
|
|||
|
|
@ -863,12 +863,11 @@ end_frame_spam(FrameMode mode) {
|
|||
// Function: GraphicsOutput::clear_cube_map_selection
|
||||
// Access: Public
|
||||
// Description: Clear the variables that select a cube-map face (or
|
||||
// other multipage or multiview texture face).
|
||||
// other multipage texture face).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GraphicsOutput::
|
||||
clear_cube_map_selection() {
|
||||
_target_tex_page = -1;
|
||||
_target_tex_view = -1;
|
||||
_prev_page_dr = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,6 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe,
|
|||
_is_valid = false;
|
||||
_flip_ready = false;
|
||||
_target_tex_page = -1;
|
||||
_target_tex_view = -1;
|
||||
_prev_page_dr = NULL;
|
||||
_sort = 0;
|
||||
_child_sort = 0;
|
||||
|
|
@ -373,6 +372,12 @@ add_render_texture(Texture *tex, RenderTextureMode mode,
|
|||
// which has system-imposed restrictions on size).
|
||||
tex->set_size_padded(get_x_size(), get_y_size(), tex->get_z_size());
|
||||
|
||||
if (_fb_properties.is_stereo() && plane == RTP_color) {
|
||||
if (tex->get_num_views() < 2) {
|
||||
tex->set_num_views(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (!support_render_texture || !get_supports_render_texture()) {
|
||||
// Binding is not supported or it is disabled, so just fall back
|
||||
// to copy instead.
|
||||
|
|
@ -1069,7 +1074,7 @@ make_cube_map(const string &name, int size, NodePath &camera_rig,
|
|||
DisplayRegion *dr;
|
||||
dr = buffer->make_display_region();
|
||||
|
||||
dr->set_target_tex_page(i, 0);
|
||||
dr->set_target_tex_page(i);
|
||||
dr->copy_clear_settings(*this);
|
||||
dr->set_camera(camera_np);
|
||||
}
|
||||
|
|
@ -1342,38 +1347,34 @@ end_frame(FrameMode mode, Thread *current_thread) {
|
|||
void GraphicsOutput::
|
||||
change_scenes(DisplayRegionPipelineReader *new_dr) {
|
||||
int new_target_tex_page = new_dr->get_target_tex_page();
|
||||
int new_target_tex_view = new_dr->get_target_tex_view();
|
||||
if ((new_target_tex_page != -1 && new_target_tex_page != _target_tex_page) ||
|
||||
new_target_tex_view != _target_tex_view) {
|
||||
|
||||
if (new_target_tex_page != -1 && new_target_tex_page != _target_tex_page) {
|
||||
|
||||
if (new_target_tex_page == -1) {
|
||||
new_target_tex_page = 0;
|
||||
}
|
||||
int old_target_tex_page = _target_tex_page;
|
||||
int old_target_tex_view = _target_tex_view;
|
||||
DisplayRegion *old_page_dr = _prev_page_dr;
|
||||
_target_tex_page = new_target_tex_page;
|
||||
_target_tex_view = new_target_tex_view;
|
||||
_prev_page_dr = new_dr->get_object();
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
RenderTextures::const_iterator ri;
|
||||
for (ri = cdata->_textures.begin(); ri != cdata->_textures.end(); ++ri) {
|
||||
RenderTextureMode rtm_mode = (*ri)._rtm_mode;
|
||||
RenderTexturePlane plane = (*ri)._plane;
|
||||
Texture *texture = (*ri)._texture;
|
||||
if (rtm_mode != RTM_none) {
|
||||
if (rtm_mode == RTM_bind_or_copy || rtm_mode == RTM_bind_layered) {
|
||||
// In render-to-texture mode, switch the rendering backend
|
||||
// to the new page, so that the subsequent frame will be
|
||||
// rendered to the correct page.
|
||||
select_target_tex_page(_target_tex_page, _target_tex_view);
|
||||
select_target_tex_page(_target_tex_page);
|
||||
|
||||
} else if (old_target_tex_page != -1) {
|
||||
// In copy-to-texture mode, copy the just-rendered framebuffer
|
||||
// to the old texture page.
|
||||
|
||||
// TODO: we should probably pass the view parameter into
|
||||
// framebuffer_copy_to_xxx(), as we do the page parameter.
|
||||
// Instead these methods draw the view parameter from
|
||||
// dr->get_target_tex_view(), which is not altogether wrong
|
||||
// but is a strange approach.
|
||||
|
||||
nassertv(old_page_dr != (DisplayRegion *)NULL);
|
||||
if (display_cat.is_debug()) {
|
||||
display_cat.debug()
|
||||
|
|
@ -1383,12 +1384,31 @@ change_scenes(DisplayRegionPipelineReader *new_dr) {
|
|||
}
|
||||
RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type(),
|
||||
get_fb_properties());
|
||||
if (rtm_mode == RTM_copy_ram) {
|
||||
_gsg->framebuffer_copy_to_ram(texture, old_target_tex_page,
|
||||
old_page_dr, buffer);
|
||||
|
||||
if (plane == RTP_color && _fb_properties.is_stereo()) {
|
||||
// We've got two texture views to copy.
|
||||
RenderBuffer left(_gsg, buffer._buffer_type & ~RenderBuffer::T_right);
|
||||
RenderBuffer right(_gsg, buffer._buffer_type & ~RenderBuffer::T_left);
|
||||
|
||||
if (rtm_mode == RTM_copy_ram) {
|
||||
_gsg->framebuffer_copy_to_ram(texture, 0, old_target_tex_page,
|
||||
old_page_dr, left);
|
||||
_gsg->framebuffer_copy_to_ram(texture, 1, old_target_tex_page,
|
||||
old_page_dr, right);
|
||||
} else {
|
||||
_gsg->framebuffer_copy_to_texture(texture, 0, old_target_tex_page,
|
||||
old_page_dr, left);
|
||||
_gsg->framebuffer_copy_to_texture(texture, 1, old_target_tex_page,
|
||||
old_page_dr, right);
|
||||
}
|
||||
} else {
|
||||
_gsg->framebuffer_copy_to_texture(texture, old_target_tex_page,
|
||||
old_page_dr, buffer);
|
||||
if (rtm_mode == RTM_copy_ram) {
|
||||
_gsg->framebuffer_copy_to_ram(texture, 0, old_target_tex_page,
|
||||
old_page_dr, buffer);
|
||||
} else {
|
||||
_gsg->framebuffer_copy_to_texture(texture, 0, old_target_tex_page,
|
||||
old_page_dr, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1402,12 +1422,11 @@ change_scenes(DisplayRegionPipelineReader *new_dr) {
|
|||
// Description: Called internally when the window is in
|
||||
// render-to-a-texture mode and we are in the process of
|
||||
// rendering the six faces of a cube map, or any other
|
||||
// multi-page and/or multi-view texture. This should do
|
||||
// whatever needs to be done to switch the buffer to the
|
||||
// indicated page and view.
|
||||
// multi-page texture. This should do whatever needs
|
||||
// to be done to switch the buffer to the indicated page.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsOutput::
|
||||
select_target_tex_page(int, int) {
|
||||
select_target_tex_page(int) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1588,25 +1607,34 @@ copy_to_textures() {
|
|||
}
|
||||
|
||||
bool copied = false;
|
||||
DisplayRegion *dr = _overlay_display_region;
|
||||
if (_prev_page_dr != (DisplayRegion *)NULL) {
|
||||
dr = _prev_page_dr;
|
||||
}
|
||||
|
||||
if (plane == RTP_color && _fb_properties.is_stereo()) {
|
||||
// We've got two texture views to copy.
|
||||
RenderBuffer left(_gsg, buffer._buffer_type & ~RenderBuffer::T_right);
|
||||
RenderBuffer right(_gsg, buffer._buffer_type & ~RenderBuffer::T_left);
|
||||
|
||||
if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
|
||||
copied =
|
||||
_gsg->framebuffer_copy_to_ram(texture, _target_tex_page,
|
||||
_prev_page_dr, buffer);
|
||||
copied = _gsg->framebuffer_copy_to_ram(texture, 0, _target_tex_page,
|
||||
dr, left);
|
||||
copied = _gsg->framebuffer_copy_to_ram(texture, 1, _target_tex_page,
|
||||
dr, right) && copied;
|
||||
} else {
|
||||
copied =
|
||||
_gsg->framebuffer_copy_to_texture(texture, _target_tex_page,
|
||||
_prev_page_dr, buffer);
|
||||
copied = _gsg->framebuffer_copy_to_texture(texture, 0, _target_tex_page,
|
||||
dr, left);
|
||||
copied = _gsg->framebuffer_copy_to_texture(texture, 1, _target_tex_page,
|
||||
dr, right) && copied;
|
||||
}
|
||||
} else {
|
||||
if ((rtm_mode == RTM_copy_ram)||(rtm_mode == RTM_triggered_copy_ram)) {
|
||||
copied =
|
||||
_gsg->framebuffer_copy_to_ram(texture, _target_tex_page,
|
||||
_overlay_display_region, buffer);
|
||||
copied = _gsg->framebuffer_copy_to_ram(texture, 0, _target_tex_page,
|
||||
dr, buffer);
|
||||
} else {
|
||||
copied =
|
||||
_gsg->framebuffer_copy_to_texture(texture, _target_tex_page,
|
||||
_overlay_display_region, buffer);
|
||||
copied = _gsg->framebuffer_copy_to_texture(texture, 0, _target_tex_page,
|
||||
dr, buffer);
|
||||
}
|
||||
}
|
||||
if (!copied) {
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ public:
|
|||
virtual void end_frame(FrameMode mode, Thread *current_thread);
|
||||
|
||||
void change_scenes(DisplayRegionPipelineReader *new_dr);
|
||||
virtual void select_target_tex_page(int page, int view);
|
||||
virtual void select_target_tex_page(int page);
|
||||
|
||||
// These methods will be called within the app (main) thread.
|
||||
virtual void begin_flip();
|
||||
|
|
|
|||
|
|
@ -702,15 +702,38 @@ get_supports_geometry_instancing() const {
|
|||
return _supports_geometry_instancing;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_max_color_targets
|
||||
// Access: Published
|
||||
// Description: Returns the maximum number of simultaneous color
|
||||
// textures that may be attached for render-to-texture,
|
||||
// as supported by this particular GSG. If you exceed
|
||||
// this number, the lowest-priority render targets will
|
||||
// not be applied. Use RenderTarget::set_priority() to
|
||||
// adjust the relative importance of the different
|
||||
// render targets.
|
||||
//
|
||||
// The value returned may not be meaningful until after
|
||||
// the graphics context has been fully created (e.g. the
|
||||
// window has been opened).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GraphicsStateGuardian::
|
||||
get_max_color_targets() const {
|
||||
if (max_color_targets > 0) {
|
||||
return min(_max_color_targets, (int)max_color_targets);
|
||||
}
|
||||
return _max_color_targets;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_maximum_simultaneous_render_targets
|
||||
// Access: Published
|
||||
// Description: Returns the maximum simultaneous render targets
|
||||
// supported.
|
||||
// Description: Deprecated. Use get_max_color_targets() instead,
|
||||
// which returns the exact same value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GraphicsStateGuardian::
|
||||
get_maximum_simultaneous_render_targets() const {
|
||||
return _maximum_simultaneous_render_targets;
|
||||
return get_max_color_targets();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -59,13 +59,6 @@
|
|||
#include <algorithm>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
#include "py_panda.h"
|
||||
#ifndef CPPPARSER
|
||||
IMPORT_THIS struct Dtool_PyTypedObject Dtool_Texture;
|
||||
#endif
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
PStatCollector GraphicsStateGuardian::_vertex_buffer_switch_pcollector("Vertex buffer switch:Vertex");
|
||||
PStatCollector GraphicsStateGuardian::_index_buffer_switch_pcollector("Vertex buffer switch:Index");
|
||||
PStatCollector GraphicsStateGuardian::_load_vertex_buffer_pcollector("Draw:Transfer data:Vertex buffer");
|
||||
|
|
@ -225,7 +218,8 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||
_supports_two_sided_stencil = false;
|
||||
_supports_geometry_instancing = false;
|
||||
|
||||
_maximum_simultaneous_render_targets = 1;
|
||||
// Assume a maximum of 1 render target in absence of MRT.
|
||||
_max_color_targets = 1;
|
||||
|
||||
_supported_geom_rendering = 0;
|
||||
|
||||
|
|
@ -247,10 +241,10 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||
// The default is no shader support.
|
||||
_auto_detect_shader_model = SM_00;
|
||||
_shader_model = SM_00;
|
||||
|
||||
|
||||
_gamma = 1.0f;
|
||||
_texture_quality_override = Texture::QL_default;
|
||||
|
||||
|
||||
_shader_generator = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -435,41 +429,6 @@ void GraphicsStateGuardian::
|
|||
restore_gamma() {
|
||||
}
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_prepared_textures
|
||||
// Access: Published
|
||||
// Description: Returns a Python list of all of the
|
||||
// currently-prepared textures within the GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *GraphicsStateGuardian::
|
||||
get_prepared_textures() const {
|
||||
ReMutexHolder holder(_prepared_objects->_lock);
|
||||
size_t num_textures = _prepared_objects->_prepared_textures.size();
|
||||
PyObject *list = PyList_New(num_textures);
|
||||
|
||||
size_t i = 0;
|
||||
PreparedGraphicsObjects::Textures::const_iterator ti;
|
||||
for (ti = _prepared_objects->_prepared_textures.begin();
|
||||
ti != _prepared_objects->_prepared_textures.end();
|
||||
++ti) {
|
||||
PT(Texture) tex = (*ti)->get_texture();
|
||||
|
||||
PyObject *element =
|
||||
DTool_CreatePyInstanceTyped(tex, Dtool_Texture,
|
||||
true, false, tex->get_type_index());
|
||||
tex->ref();
|
||||
|
||||
nassertr(i < num_textures, NULL);
|
||||
PyList_SetItem(list, i, element);
|
||||
++i;
|
||||
}
|
||||
nassertr(i == num_textures, NULL);
|
||||
|
||||
return list;
|
||||
}
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::traverse_prepared_textures
|
||||
// Access: Public
|
||||
|
|
@ -485,7 +444,7 @@ traverse_prepared_textures(GraphicsStateGuardian::TextureCallback *func,
|
|||
for (ti = _prepared_objects->_prepared_textures.begin();
|
||||
ti != _prepared_objects->_prepared_textures.end();
|
||||
++ti) {
|
||||
bool result = (*func)(*ti,callback_arg);
|
||||
bool result = (*func)(*ti, callback_arg);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -996,6 +955,16 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
|
|||
0.0);
|
||||
return &t;
|
||||
}
|
||||
case Shader::SMO_frame_time: {
|
||||
PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time();
|
||||
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
|
||||
return &t;
|
||||
}
|
||||
case Shader::SMO_frame_delta: {
|
||||
PN_stdfloat dt = ClockObject::get_global_clock()->get_dt();
|
||||
t = LMatrix4(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
|
||||
return &t;
|
||||
}
|
||||
case Shader::SMO_texpad_x: {
|
||||
Texture *tex = _target_shader->get_shader_input_texture(name);
|
||||
nassertr(tex != 0, &LMatrix4::zeros_mat());
|
||||
|
|
@ -1349,14 +1318,14 @@ prepare_display_region(DisplayRegionPipelineReader *dr) {
|
|||
case Lens::SC_left:
|
||||
_color_write_mask = dr->get_window()->get_left_eye_color_mask();
|
||||
if (_current_properties->is_stereo()) {
|
||||
_stereo_buffer_mask = ~(RenderBuffer::T_front_right | RenderBuffer::T_back_right);
|
||||
_stereo_buffer_mask = ~RenderBuffer::T_right;
|
||||
}
|
||||
break;
|
||||
|
||||
case Lens::SC_right:
|
||||
_color_write_mask = dr->get_window()->get_right_eye_color_mask();
|
||||
if (_current_properties->is_stereo()) {
|
||||
_stereo_buffer_mask = ~(RenderBuffer::T_front_left | RenderBuffer::T_back_left);
|
||||
_stereo_buffer_mask = ~RenderBuffer::T_left;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -2182,7 +2151,7 @@ do_issue_light() {
|
|||
// copy.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
framebuffer_copy_to_texture(Texture *, int, const DisplayRegion *,
|
||||
framebuffer_copy_to_texture(Texture *, int, int, const DisplayRegion *,
|
||||
const RenderBuffer &) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2199,7 +2168,7 @@ framebuffer_copy_to_texture(Texture *, int, const DisplayRegion *,
|
|||
// indicated texture.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
framebuffer_copy_to_ram(Texture *, int, const DisplayRegion *,
|
||||
framebuffer_copy_to_ram(Texture *, int, int, const DisplayRegion *,
|
||||
const RenderBuffer &) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2463,11 +2432,11 @@ determine_target_texture() {
|
|||
target_tex_gen != (TexGenAttrib *)NULL);
|
||||
_target_texture = target_texture;
|
||||
_target_tex_gen = target_tex_gen;
|
||||
|
||||
|
||||
if (_has_texture_alpha_scale) {
|
||||
PT(TextureStage) stage = get_alpha_scale_texture_stage();
|
||||
PT(Texture) texture = TexturePool::get_alpha_scale_map();
|
||||
|
||||
|
||||
_target_texture = DCAST(TextureAttrib, _target_texture->add_on_stage(stage, texture));
|
||||
_target_tex_gen = DCAST(TexGenAttrib, _target_tex_gen->add_stage
|
||||
(stage, TexGenAttrib::M_constant, LTexCoord3(_current_color_scale[3], 0.0f, 0.0f)));
|
||||
|
|
@ -2754,7 +2723,7 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
|
|||
for (int i = 0; i < 6; ++i) {
|
||||
PT(DisplayRegion) dr = sbuffer->make_mono_display_region(0, 1, 0, 1);
|
||||
dr->set_lens_index(i);
|
||||
dr->set_target_tex_page(i, 0);
|
||||
dr->set_target_tex_page(i);
|
||||
dr->set_camera(light_np);
|
||||
dr->set_clear_depth_active(true);
|
||||
}
|
||||
|
|
@ -2791,6 +2760,9 @@ string GraphicsStateGuardian::get_driver_renderer() {
|
|||
// Function: GraphicsStateGuardian::get_driver_version
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns driver version
|
||||
// This has an implementation-defined meaning, and may
|
||||
// be "0" if the particular graphics implementation
|
||||
// does not provide a way to query this information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string GraphicsStateGuardian::
|
||||
get_driver_version() {
|
||||
|
|
@ -2800,7 +2772,10 @@ get_driver_version() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_driver_version_major
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns major version of the video driver
|
||||
// Description: Returns major version of the video driver.
|
||||
// This has an implementation-defined meaning, and may
|
||||
// be -1 if the particular graphics implementation
|
||||
// does not provide a way to query this information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GraphicsStateGuardian::
|
||||
get_driver_version_major() {
|
||||
|
|
@ -2810,7 +2785,10 @@ get_driver_version_major() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_driver_version_minor
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the minor version of the video driver
|
||||
// Description: Returns the minor version of the video driver.
|
||||
// This has an implementation-defined meaning, and may
|
||||
// be -1 if the particular graphics implementation
|
||||
// does not provide a way to query this information.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GraphicsStateGuardian::
|
||||
get_driver_version_minor() {
|
||||
|
|
@ -2820,7 +2798,7 @@ get_driver_version_minor() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_driver_shader_version_major
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the major version of the shader model
|
||||
// Description: Returns the major version of the shader model.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GraphicsStateGuardian::
|
||||
get_driver_shader_version_major() {
|
||||
|
|
@ -2830,7 +2808,7 @@ get_driver_shader_version_major() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_driver_shader_version_minor
|
||||
// Access: Public, Virtual
|
||||
// Description: Returns the minor version of the shader model
|
||||
// Description: Returns the minor version of the shader model.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GraphicsStateGuardian::
|
||||
get_driver_shader_version_minor() {
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@
|
|||
#include "occlusionQueryContext.h"
|
||||
#include "stencilRenderStates.h"
|
||||
#include "loader.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "texGenAttrib.h"
|
||||
#include "shaderAttrib.h"
|
||||
#include "texGenAttrib.h"
|
||||
#include "textureAttrib.h"
|
||||
|
||||
class DrawableRegion;
|
||||
class GraphicsEngine;
|
||||
|
|
@ -150,6 +150,7 @@ PUBLISHED:
|
|||
INLINE bool get_supports_two_sided_stencil() const;
|
||||
INLINE bool get_supports_geometry_instancing() const;
|
||||
|
||||
INLINE int get_max_color_targets() const;
|
||||
INLINE int get_maximum_simultaneous_render_targets() const;
|
||||
|
||||
INLINE int get_shader_model() const;
|
||||
|
|
@ -179,9 +180,7 @@ PUBLISHED:
|
|||
INLINE void set_texture_quality_override(Texture::QualityLevel quality_level);
|
||||
INLINE Texture::QualityLevel get_texture_quality_override() const;
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject *get_prepared_textures() const;
|
||||
#endif
|
||||
EXTENSION(PyObject *get_prepared_textures() const);
|
||||
typedef bool TextureCallback(TextureContext *tc, void *callback_arg);
|
||||
void traverse_prepared_textures(TextureCallback *func, void *callback_arg);
|
||||
|
||||
|
|
@ -310,9 +309,9 @@ public:
|
|||
virtual void do_issue_light();
|
||||
|
||||
virtual bool framebuffer_copy_to_texture
|
||||
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
|
||||
(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb);
|
||||
virtual bool framebuffer_copy_to_ram
|
||||
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb);
|
||||
(Texture *tex, int view, int z, const DisplayRegion *dr, const RenderBuffer &rb);
|
||||
|
||||
virtual void bind_light(PointLight *light_obj, const NodePath &light,
|
||||
int light_id);
|
||||
|
|
@ -497,7 +496,7 @@ protected:
|
|||
bool _supports_two_sided_stencil;
|
||||
bool _supports_geometry_instancing;
|
||||
|
||||
int _maximum_simultaneous_render_targets;
|
||||
int _max_color_targets;
|
||||
|
||||
int _supported_geom_rendering;
|
||||
bool _color_scale_via_lighting;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
// Filename: graphicsStateGuardian_ext.cxx
|
||||
// Created by: rdb (10Dec13)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "graphicsStateGuardian_ext.h"
|
||||
#include "textureContext.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#ifndef CPPPARSER
|
||||
IMPORT_THIS struct Dtool_PyTypedObject Dtool_Texture;
|
||||
#endif
|
||||
|
||||
static bool traverse_callback(TextureContext *tc, void *data) {
|
||||
PT(Texture) tex = tc->get_texture();
|
||||
PyObject *element =
|
||||
DTool_CreatePyInstanceTyped(tex, Dtool_Texture,
|
||||
true, false, tex->get_type_index());
|
||||
tex->ref();
|
||||
|
||||
PyObject *list = (PyObject *) data;
|
||||
PyList_Append(list, element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_prepared_textures
|
||||
// Access: Published
|
||||
// Description: Returns a Python list of all of the
|
||||
// currently-prepared textures within the GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PyObject *Extension<GraphicsStateGuardian>::
|
||||
get_prepared_textures() const {
|
||||
PyObject *list = PyList_New(0);
|
||||
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_this->traverse_prepared_textures(&traverse_callback, (void *)list);
|
||||
return list;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
// Filename: graphicsStateGuardian_ext.h
|
||||
// Created by: rdb (10Dec13)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef GRAPHICSSTATEGUARDIAN_EXT_H
|
||||
#define GRAPHICSSTATEGUARDIAN_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "graphicsStateGuardian.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<GraphicsStateGuardian>
|
||||
// Description : This class defines the extension methods for
|
||||
// Ramfile, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<GraphicsStateGuardian> : public ExtensionBase<GraphicsStateGuardian> {
|
||||
public:
|
||||
PyObject *get_prepared_textures() const;
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // GRAPHICSSTATEGUARDIAN_EXT_H
|
||||
|
|
@ -77,8 +77,8 @@ GraphicsWindow::
|
|||
// Clean up python event handlers.
|
||||
#ifdef HAVE_PYTHON
|
||||
PythonWinProcClasses::iterator iter;
|
||||
for (iter = _python_window_proc_classes.begin();
|
||||
iter != _python_window_proc_classes.end();
|
||||
for (iter = _python_window_proc_classes.begin();
|
||||
iter != _python_window_proc_classes.end();
|
||||
++iter) {
|
||||
delete *iter;
|
||||
}
|
||||
|
|
@ -340,6 +340,17 @@ has_keyboard(int device) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: x11GraphicsWindow::get_keyboard_map
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns a ButtonMap containing the association
|
||||
// between raw buttons and virtual buttons.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ButtonMap *GraphicsWindow::
|
||||
get_keyboard_map() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::enable_pointer_events
|
||||
// Access: Published
|
||||
|
|
@ -391,8 +402,10 @@ disable_pointer_mode(int device) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindow::get_pointer
|
||||
// Access: Published
|
||||
// Description: Returns the MouseData associated with the nth input
|
||||
// device's pointer.
|
||||
// Description: Returns the MouseData associated with the nth
|
||||
// input device's pointer. This is deprecated; use
|
||||
// get_pointer_device().get_pointer() instead, or for
|
||||
// raw mice, use the InputDeviceManager interface.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
MouseData GraphicsWindow::
|
||||
get_pointer(int device) const {
|
||||
|
|
@ -409,7 +422,7 @@ get_pointer(int device) const {
|
|||
// Function: GraphicsWindow::move_pointer
|
||||
// Access: Published, Virtual
|
||||
// Description: Forces the pointer to the indicated position within
|
||||
// the window, if possible.
|
||||
// the window, if possible.
|
||||
//
|
||||
// Returns true if successful, false on failure. This
|
||||
// may fail if the mouse is not currently within the
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "modifierButtons.h"
|
||||
#include "buttonEvent.h"
|
||||
#include "keyboardButton.h"
|
||||
#include "buttonMap.h"
|
||||
#include "pnotify.h"
|
||||
#include "lightMutex.h"
|
||||
#include "lightReMutex.h"
|
||||
|
|
@ -82,7 +83,7 @@ PUBLISHED:
|
|||
MAKE_SEQ(get_input_device_names, get_num_input_devices, get_input_device_name);
|
||||
bool has_pointer(int device) const;
|
||||
bool has_keyboard(int device) const;
|
||||
|
||||
virtual ButtonMap *get_keyboard_map() const;
|
||||
|
||||
void enable_pointer_events(int device);
|
||||
void disable_pointer_events(int device);
|
||||
|
|
|
|||
|
|
@ -365,3 +365,25 @@ focus_lost(double time) {
|
|||
}
|
||||
_buttons_held.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::raw_button_down
|
||||
// Access: Public
|
||||
// Description: Records that the indicated button has been depressed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
raw_button_down(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_raw_down, time));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsWindowInputDevice::raw_button_up
|
||||
// Access: Public
|
||||
// Description: Records that the indicated button has been released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsWindowInputDevice::
|
||||
raw_button_up(ButtonHandle button, double time) {
|
||||
LightMutexHolder holder(_lock);
|
||||
_button_events.push_back(ButtonEvent(button, ButtonEvent::T_raw_up, time));
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue