Merge branch 'master' into cmake
This commit is contained in:
commit
25e2e0221d
|
|
@ -7,6 +7,8 @@
|
|||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#include <Python.h>
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#include <wchar.h>
|
||||
|
|
@ -71,7 +73,7 @@ int main(int argc, char *argv[]) {
|
|||
char *path = getenv("PATH");
|
||||
char *result = strtok(path, ";");
|
||||
while (result != NULL) {
|
||||
struct stat st;
|
||||
struct stat st;
|
||||
char *ppython = (char*) malloc(strlen(result) + 13);
|
||||
strcpy(ppython, result);
|
||||
strcat(ppython, "\\ppython.exe");
|
||||
|
|
@ -79,13 +81,13 @@ int main(int argc, char *argv[]) {
|
|||
Py_SetPythonHome(result);
|
||||
free(ppython);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = strtok(NULL, ";");
|
||||
free(ppython);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
if (Py_VerboseFlag) {
|
||||
|
|
|
|||
|
|
@ -9,15 +9,15 @@
|
|||
##############################################################################
|
||||
|
||||
import os,sys,gc
|
||||
from pandac.PandaModules import *
|
||||
from panda3d.core import *
|
||||
|
||||
class EggCacher:
|
||||
def __init__(self, args):
|
||||
maindir = Filename.fromOsSpecific(os.getcwd()).getFullpath()
|
||||
ExecutionEnvironment.setEnvironmentVariable("MAIN_DIR", maindir)
|
||||
self.bamcache = BamCache.getGlobalPtr()
|
||||
self.pandaloader = PandaLoader()
|
||||
self.loaderopts = LoaderOptions()
|
||||
self.pandaloader = Loader()
|
||||
self.loaderopts = LoaderOptions(LoaderOptions.LF_no_ram_cache)
|
||||
if (self.bamcache.getActive() == 0):
|
||||
print "The model cache is not currently active."
|
||||
print "You must set a model-cache-dir in your config file."
|
||||
|
|
@ -69,12 +69,12 @@ class EggCacher:
|
|||
|
||||
def processFiles(self, files):
|
||||
total = 0
|
||||
for (path,size) in files:
|
||||
for (path, size) in files:
|
||||
total += size
|
||||
progress = 0
|
||||
for (path,size) in files:
|
||||
fn = Filename.fromOsSpecific(path)
|
||||
cached = self.bamcache.lookup(fn,"bam")
|
||||
cached = self.bamcache.lookup(fn, "bam")
|
||||
percent = (progress * 100) / total
|
||||
report = path
|
||||
if (self.concise): report = os.path.basename(report)
|
||||
|
|
@ -87,6 +87,4 @@ class EggCacher:
|
|||
TexturePool.releaseAllTextures()
|
||||
progress += size
|
||||
|
||||
|
||||
cacher = EggCacher(sys.argv[1:])
|
||||
|
||||
|
|
|
|||
|
|
@ -94,8 +94,9 @@ class DirectDialog(DirectFrame):
|
|||
('text', '', None),
|
||||
('text_align', TextNode.ALeft, None),
|
||||
('text_scale', 0.06, None),
|
||||
('image', DGG.getDefaultDialogGeom(), None),
|
||||
('relief', None, None),
|
||||
('image', None, None),
|
||||
('relief', DGG.RAISED, None),
|
||||
('borderWidth', (0.01, 0.01), None),
|
||||
('buttonTextList', [], DGG.INITOPT),
|
||||
('buttonGeomList', [], DGG.INITOPT),
|
||||
('buttonImageList', [], DGG.INITOPT),
|
||||
|
|
@ -210,10 +211,16 @@ class DirectDialog(DirectFrame):
|
|||
bounds = self.stateNodePath[0].getTightBounds()
|
||||
if image:
|
||||
image.reparentTo(self.stateNodePath[0])
|
||||
l = bounds[0][0]
|
||||
r = bounds[1][0]
|
||||
b = bounds[0][2]
|
||||
t = bounds[1][2]
|
||||
if bounds is None:
|
||||
l = 0
|
||||
r = 0
|
||||
b = 0
|
||||
t = 0
|
||||
else:
|
||||
l = bounds[0][0]
|
||||
r = bounds[1][0]
|
||||
b = bounds[0][2]
|
||||
t = bounds[1][2]
|
||||
# Center text and geom around origin
|
||||
# How far is center of text from origin?
|
||||
xOffset = -(l+r)*0.5
|
||||
|
|
@ -246,10 +253,16 @@ class DirectDialog(DirectFrame):
|
|||
bl = br = bb = bt = 0
|
||||
for button in self.buttonList:
|
||||
bounds = button.stateNodePath[0].getTightBounds()
|
||||
bl = min(bl, bounds[0][0])
|
||||
br = max(br, bounds[1][0])
|
||||
bb = min(bb, bounds[0][2])
|
||||
bt = max(bt, bounds[1][2])
|
||||
if bounds is None:
|
||||
bl = 0
|
||||
br = 0
|
||||
bb = 0
|
||||
bt = 0
|
||||
else:
|
||||
bl = min(bl, bounds[0][0])
|
||||
br = max(br, bounds[1][0])
|
||||
bb = min(bb, bounds[0][2])
|
||||
bt = max(bt, bounds[1][2])
|
||||
bl -= bpad[0]
|
||||
br += bpad[0]
|
||||
bb -= bpad[1]
|
||||
|
|
@ -303,6 +316,7 @@ class DirectDialog(DirectFrame):
|
|||
# reduce bottom by pad, button height and 2*button pad
|
||||
b = min(b - self['midPad'] - bpad[1] - bHeight - bpad[1], b) - pad[1]
|
||||
t = t + self['topPad'] + pad[1]
|
||||
self['frameSize'] = (l, r, b, t)
|
||||
self['image_scale'] = (r - l, 1, t - b)
|
||||
# Center frame about text and buttons
|
||||
self['image_pos'] = ((l+r)*0.5, 0.0, (b+t)*0.5)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class DirectRadioButton(DirectButton):
|
|||
('boxGeom', None, None),
|
||||
('boxGeomColor', None, None),
|
||||
('boxGeomScale', 1.0, None),
|
||||
('boxImage', loader.loadModel('models/gui/radio_button_gui'), None),
|
||||
('boxImage', None, None),
|
||||
('boxImageScale', 1.0, None),
|
||||
('boxImageColor', VBase4(1, 1, 1, 1), None),
|
||||
('boxRelief', None, None),
|
||||
|
|
@ -69,9 +69,11 @@ class DirectRadioButton(DirectButton):
|
|||
# Call option initialization functions
|
||||
self.initialiseoptions(DirectRadioButton)
|
||||
# After initialization with X giving it the correct size, put back space
|
||||
if self['boxGeom'] == None:
|
||||
if self['boxGeom'] is None:
|
||||
if not 'boxRelief' in kw and self['boxImage'] is None:
|
||||
self.indicator['relief'] = DGG.SUNKEN
|
||||
self.indicator['text'] = (' ', '*')
|
||||
self.indicator['text_pos'] = (0, -.5)
|
||||
self.indicator['text_pos'] = (0, -.25)
|
||||
else:
|
||||
self.indicator['text'] = (' ', ' ')
|
||||
|
||||
|
|
|
|||
|
|
@ -59,15 +59,12 @@ class Transitions:
|
|||
|
||||
# Reload fade if its already been created
|
||||
if self.fade:
|
||||
del self.fade
|
||||
self.fade.destroy()
|
||||
self.fade = None
|
||||
self.loadFade()
|
||||
|
||||
def loadFade(self):
|
||||
if not self.fadeModel:
|
||||
self.fadeModel = loader.loadModel(self.FadeModelName)
|
||||
|
||||
if self.fade == None:
|
||||
if self.fade is None:
|
||||
# We create a DirectFrame for the fade polygon, instead of
|
||||
# simply loading the polygon model and using it directly,
|
||||
# so that it will also obscure mouse events for objects
|
||||
|
|
@ -80,10 +77,15 @@ class Transitions:
|
|||
image_scale = (4, 2, 2),
|
||||
state = DGG.NORMAL,
|
||||
)
|
||||
if not self.fadeModel:
|
||||
# No fade model was given, so we make this the fade model.
|
||||
self.fade["relief"] = DGG.FLAT
|
||||
self.fade["frameSize"] = (-2, 2, -1, 1)
|
||||
self.fade["frameColor"] = (0, 0, 0, 1)
|
||||
self.fade.setTransparency(TransparencyAttrib.MAlpha)
|
||||
self.fade.setBin('unsorted', 0)
|
||||
self.fade.setColor(0,0,0,0)
|
||||
|
||||
|
||||
def getFadeInIval(self, t=0.5, finishIval=None):
|
||||
"""
|
||||
Returns an interval without starting it. This is particularly useful in
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ extern char **environ;
|
|||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(IS_LINUX) || defined(IS_OSX)
|
||||
#if defined(IS_LINUX) || defined(IS_OSX) || defined(IS_FREEBSD)
|
||||
// For link_map and dlinfo.
|
||||
#include <link.h>
|
||||
#include <dlfcn.h>
|
||||
|
|
|
|||
|
|
@ -64,6 +64,39 @@ Filename(const Filename ©) :
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::Move Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Filename::
|
||||
Filename(string &&filename) NOEXCEPT {
|
||||
_flags = 0;
|
||||
(*this) = move(filename);
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::Move Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Filename::
|
||||
Filename(Filename &&from) NOEXCEPT :
|
||||
_filename(move(from._filename)),
|
||||
_dirname_end(from._dirname_end),
|
||||
_basename_start(from._basename_start),
|
||||
_basename_end(from._basename_end),
|
||||
_extension_start(from._extension_start),
|
||||
_hash_start(from._hash_start),
|
||||
_hash_end(from._hash_end),
|
||||
_flags(from._flags)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::text_filename named constructor
|
||||
// Access: Published
|
||||
|
|
@ -216,6 +249,42 @@ operator = (const Filename ©) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::Move assignment operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Filename &Filename::
|
||||
operator = (string &&filename) NOEXCEPT {
|
||||
_filename = move(filename);
|
||||
|
||||
locate_basename();
|
||||
locate_extension();
|
||||
locate_hash();
|
||||
return *this;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::Move assignment operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Filename &Filename::
|
||||
operator = (Filename &&from) NOEXCEPT {
|
||||
_filename = MOVE(from._filename);
|
||||
_dirname_end = from._dirname_end;
|
||||
_basename_start = from._basename_start;
|
||||
_basename_end = from._basename_end;
|
||||
_extension_start = from._extension_start;
|
||||
_hash_start = from._hash_start;
|
||||
_hash_end = from._hash_end;
|
||||
_flags = from._flags;
|
||||
return *this;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Filename::string typecast operator
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ PUBLISHED:
|
|||
Filename(const Filename &dirname, const Filename &basename);
|
||||
INLINE ~Filename();
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Filename(string &&filename) NOEXCEPT;
|
||||
INLINE Filename(Filename &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
PyObject *__reduce__(PyObject *self) const;
|
||||
#endif
|
||||
|
|
@ -88,7 +93,7 @@ PUBLISHED:
|
|||
Type type = T_general);
|
||||
static Filename from_os_specific_w(const wstring &os_specific,
|
||||
Type type = T_general);
|
||||
static Filename expand_from(const string &user_string,
|
||||
static Filename expand_from(const string &user_string,
|
||||
Type type = T_general);
|
||||
static Filename temporary(const string &dirname, const string &prefix,
|
||||
const string &suffix = string(),
|
||||
|
|
@ -105,6 +110,11 @@ PUBLISHED:
|
|||
INLINE Filename &operator = (const char *filename);
|
||||
INLINE Filename &operator = (const Filename ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Filename &operator = (string &&filename) NOEXCEPT;
|
||||
INLINE Filename &operator = (Filename &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
// And retrieval is by any of the classic string operations.
|
||||
INLINE operator const string & () const;
|
||||
INLINE const char *c_str() const;
|
||||
|
|
|
|||
|
|
@ -3204,7 +3204,8 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj,
|
|||
}
|
||||
extra_convert += "PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
|
||||
extra_param_check += " && " + param_name + "_long != NULL";
|
||||
pexpr_string = "PyLong_AsUnsignedLongLong(" + param_name + "_long)";
|
||||
pexpr_string = "(" + type->get_local_name(&parser) + ")" +
|
||||
"PyLong_AsUnsignedLongLong(" + param_name + "_long)";
|
||||
extra_cleanup += "Py_XDECREF(" + param_name + "_long);";
|
||||
expected_params += "unsigned long long";
|
||||
++num_params;
|
||||
|
|
@ -3219,7 +3220,8 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj,
|
|||
}
|
||||
extra_convert += "PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
|
||||
extra_param_check += " && " + param_name + "_long != NULL";
|
||||
pexpr_string = "PyLong_AsLongLong(" + param_name + "_long)";
|
||||
pexpr_string = "(" + type->get_local_name(&parser) + ")" +
|
||||
"PyLong_AsLongLong(" + param_name + "_long)";
|
||||
extra_cleanup += "Py_XDECREF(" + param_name + "_long);";
|
||||
expected_params += "long long";
|
||||
++num_params;
|
||||
|
|
@ -3234,7 +3236,8 @@ write_function_instance(ostream &out, InterfaceMaker::Object *obj,
|
|||
}
|
||||
extra_convert += "PyObject *" + param_name + "_long = PyNumber_Long(" + param_name + ");";
|
||||
extra_param_check += " && " + param_name + "_long != NULL";
|
||||
pexpr_string = "PyLong_AsUnsignedLong(" + param_name + "_long)";
|
||||
pexpr_string = "(" + type->get_local_name(&parser) + ")" +
|
||||
"PyLong_AsUnsignedLong(" + param_name + "_long)";
|
||||
extra_cleanup += "Py_XDECREF(" + param_name + "_long);";
|
||||
expected_params += "unsigned int";
|
||||
++num_params;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -949,7 +949,7 @@ def CompileCxx(obj,src,opts):
|
|||
if PkgSkip("TOUCHINPUT") == 0:
|
||||
cmd += "/DWINVER=0x601 "
|
||||
cmd += "/Fo" + obj + " /nologo /c"
|
||||
if (GetTargetArch() != 'x64' and PkgSkip("SSE2") == 0):
|
||||
if GetTargetArch() != 'x64' and (not PkgSkip("SSE2") or 'SSE2' in opts):
|
||||
cmd += " /arch:SSE2"
|
||||
for x in ipath: cmd += " /I" + x
|
||||
for (opt,dir) in INCDIRECTORIES:
|
||||
|
|
@ -1160,7 +1160,7 @@ def CompileCxx(obj,src,opts):
|
|||
if optlevel >= 4 or GetTarget() == "android":
|
||||
cmd += " -fno-rtti"
|
||||
|
||||
if PkgSkip("SSE2") == 0 and not arch.startswith("arm"):
|
||||
if ('SSE2' in opts or not PkgSkip("SSE2")) and not arch.startswith("arm"):
|
||||
cmd += " -msse2"
|
||||
|
||||
if optlevel >= 3:
|
||||
|
|
@ -1705,7 +1705,7 @@ def RunGenPyCode(target, inputs, opts):
|
|||
if (PkgSkip("PYTHON") != 0):
|
||||
return
|
||||
|
||||
cmdstr = sys.executable + " "
|
||||
cmdstr = BracketNameWithQuotes(SDK["PYTHONEXEC"]) + " "
|
||||
if sys.version_info >= (2, 6):
|
||||
cmdstr += "-B "
|
||||
|
||||
|
|
@ -1729,7 +1729,7 @@ def RunGenPyCode(target, inputs, opts):
|
|||
def FreezePy(target, inputs, opts):
|
||||
assert len(inputs) > 0
|
||||
# Make sure this function isn't called before genpycode is run.
|
||||
cmdstr = sys.executable + " "
|
||||
cmdstr = BracketNameWithQuotes(SDK["PYTHONEXEC"]) + " "
|
||||
if sys.version_info >= (2, 6):
|
||||
cmdstr += "-B "
|
||||
|
||||
|
|
@ -1757,7 +1757,7 @@ def FreezePy(target, inputs, opts):
|
|||
def Package(target, inputs, opts):
|
||||
assert len(inputs) == 1
|
||||
# Invoke the ppackage script.
|
||||
command = sys.executable + " "
|
||||
command = BracketNameWithQuotes(SDK["PYTHONEXEC"]) + " "
|
||||
if GetOptimizeOption(opts) >= 4:
|
||||
command += "-OO "
|
||||
|
||||
|
|
@ -3192,6 +3192,7 @@ if (not RUNTIME):
|
|||
OPTS=['DIR:panda/src/pnmimage', 'BUILDING:PANDA', 'ZLIB']
|
||||
TargetAdd('p3pnmimage_composite1.obj', opts=OPTS, input='p3pnmimage_composite1.cxx')
|
||||
TargetAdd('p3pnmimage_composite2.obj', opts=OPTS, input='p3pnmimage_composite2.cxx')
|
||||
TargetAdd('p3pnmimage_convert_srgb_sse2.obj', opts=OPTS+['SSE2'], input='convert_srgb_sse2.cxx')
|
||||
|
||||
OPTS=['DIR:panda/src/pnmimage', 'ZLIB']
|
||||
IGATEFILES=GetDirectoryContents('panda/src/pnmimage', ["*.h", "*_composite*.cxx"])
|
||||
|
|
@ -3621,6 +3622,7 @@ if (not RUNTIME):
|
|||
TargetAdd('libpanda.dll', input='p3pnmimagetypes_composite2.obj')
|
||||
TargetAdd('libpanda.dll', input='p3pnmimage_composite1.obj')
|
||||
TargetAdd('libpanda.dll', input='p3pnmimage_composite2.obj')
|
||||
TargetAdd('libpanda.dll', input='p3pnmimage_convert_srgb_sse2.obj')
|
||||
TargetAdd('libpanda.dll', input='p3text_composite1.obj')
|
||||
TargetAdd('libpanda.dll', input='p3text_composite2.obj')
|
||||
TargetAdd('libpanda.dll', input='p3tform_composite1.obj')
|
||||
|
|
@ -4609,7 +4611,7 @@ if (PkgSkip("DIRECT")==0):
|
|||
OPTS=['DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT', 'BISONPREFIX_dcyy']
|
||||
CreateFile(GetOutputDir()+"/include/dcParser.h")
|
||||
TargetAdd('p3dcparser_dcParser.obj', opts=OPTS, input='dcParser.yxx')
|
||||
TargetAdd('dcParser.h', input='p3egg_parser.obj', opts=['DEPENDENCYONLY'])
|
||||
TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY'])
|
||||
TargetAdd('p3dcparser_dcLexer.obj', opts=OPTS, input='dcLexer.lxx')
|
||||
TargetAdd('p3dcparser_composite1.obj', opts=OPTS, input='p3dcparser_composite1.cxx')
|
||||
TargetAdd('p3dcparser_composite2.obj', opts=OPTS, input='p3dcparser_composite2.cxx')
|
||||
|
|
@ -6171,7 +6173,7 @@ except:
|
|||
#
|
||||
##########################################################################################
|
||||
|
||||
def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
|
||||
def MakeInstallerNSIS(file, title, installdir):
|
||||
if (os.path.isfile(file)):
|
||||
os.remove(file)
|
||||
elif (os.path.isdir(file)):
|
||||
|
|
@ -6199,7 +6201,7 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
|
|||
shutil.move("direct\\src\\plugin_installer\\p3d-setup.exe", file)
|
||||
return
|
||||
|
||||
print("Building "+fullname+" installer. This can take up to an hour.")
|
||||
print("Building "+title+" installer. This can take up to an hour.")
|
||||
if (COMPRESSOR != "lzma"):
|
||||
print("Note: you are using zlib, which is faster, but lzma gives better compression.")
|
||||
if (os.path.exists("nsis-output.exe")):
|
||||
|
|
@ -6210,19 +6212,13 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
|
|||
|
||||
nsis_defs = {
|
||||
'COMPRESSOR' : COMPRESSOR,
|
||||
'NAME' : fullname,
|
||||
'SMDIRECTORY' : smdirectory,
|
||||
'TITLE' : title,
|
||||
'INSTALLDIR' : installdir,
|
||||
'OUTFILE' : os.path.join(psource, 'nsis-output.exe'),
|
||||
'LICENSE' : os.path.join(panda, 'LICENSE'),
|
||||
'LANGUAGE' : "English",
|
||||
'RUNTEXT' : "Visit the Panda Manual",
|
||||
'IBITMAP' : "panda-install.bmp",
|
||||
'UBITMAP' : "panda-install.bmp",
|
||||
'PANDA' : panda,
|
||||
'BUILT' : panda,
|
||||
'SOURCE' : psource,
|
||||
'PYVER' : SDK["PYTHONVERSION"][6:9],
|
||||
'PANDACONF' : os.path.join(panda, 'etc'),
|
||||
'PSOURCE' : psource,
|
||||
'PYEXTRAS' : os.path.join(os.path.abspath(GetThirdpartyBase()), 'win-extras'),
|
||||
'REGVIEW' : regview,
|
||||
}
|
||||
|
|
@ -6236,7 +6232,7 @@ def MakeInstallerNSIS(file, fullname, smdirectory, installdir):
|
|||
for item in nsis_defs.items():
|
||||
cmd += ' -D%s="%s"' % item
|
||||
|
||||
cmd += ' "%s"' % (os.path.join(psource, 'direct', 'src', 'directscripts', 'packpanda.nsi'))
|
||||
cmd += ' "%s"' % (os.path.join(psource, 'makepanda', 'installer.nsi'))
|
||||
oscmd(cmd)
|
||||
os.rename("nsis-output.exe", file)
|
||||
|
||||
|
|
@ -6761,14 +6757,14 @@ try:
|
|||
if (GetOptimize() <= 2): dbg = "-dbg"
|
||||
if GetTargetArch() == 'x64':
|
||||
if (RUNTIME):
|
||||
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
|
||||
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+"-x64.exe", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
|
||||
else:
|
||||
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
|
||||
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+"-x64.exe", "Panda3D SDK "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
|
||||
else:
|
||||
if (RUNTIME):
|
||||
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
|
||||
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+".exe", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
|
||||
else:
|
||||
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
|
||||
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+".exe", "Panda3D SDK "+VERSION, "C:\\Panda3D-"+VERSION)
|
||||
elif (target == 'linux'):
|
||||
MakeInstallerLinux()
|
||||
elif (target == 'darwin'):
|
||||
|
|
|
|||
|
|
@ -210,6 +210,8 @@ def PrettyTime(t):
|
|||
return "%d sec" % (seconds)
|
||||
|
||||
def ProgressOutput(progress, msg, target = None):
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
prefix = ""
|
||||
thisthread = threading.currentThread()
|
||||
if thisthread is MAINTHREAD:
|
||||
|
|
@ -235,6 +237,8 @@ def ProgressOutput(progress, msg, target = None):
|
|||
suffix = GetColor()
|
||||
|
||||
print(''.join((prefix, msg, suffix)))
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
def exit(msg = ""):
|
||||
sys.stdout.flush()
|
||||
|
|
@ -498,7 +502,7 @@ def oscmd(cmd, ignoreError = False):
|
|||
print(GetColor("blue") + cmd.split(" ", 1)[0] + " " + GetColor("magenta") + cmd.split(" ", 1)[1] + GetColor())
|
||||
sys.stdout.flush()
|
||||
|
||||
if sys.platform == "win32":
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
exe = cmd.split()[0]
|
||||
exe_path = LocateBinary(exe)
|
||||
if exe_path is None:
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
|
|
@ -156,7 +156,7 @@ get_hit_fraction() const {
|
|||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PandaNode *BulletRayHit::
|
||||
const PandaNode *BulletRayHit::
|
||||
get_node() const {
|
||||
|
||||
return (_object) ? (PandaNode *)_object->getUserPointer() : NULL;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ struct EXPCL_PANDABULLET BulletRayHit {
|
|||
PUBLISHED:
|
||||
INLINE static BulletRayHit empty();
|
||||
|
||||
PandaNode *get_node() const;
|
||||
const PandaNode *get_node() const;
|
||||
LPoint3 get_hit_pos() const;
|
||||
LVector3 get_hit_normal() const;
|
||||
PN_stdfloat get_hit_fraction() const;
|
||||
|
|
|
|||
|
|
@ -608,11 +608,12 @@ remove_vehicle(BulletVehicle *vehicle) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BulletWorld::attach_constraint
|
||||
// Access: Published
|
||||
// Description: Deprecated!
|
||||
// Please use BulletWorld::attach
|
||||
// Description: Attaches a single constraint to a world. Collision
|
||||
// checks between the linked objects will be disabled
|
||||
// if the second parameter is set to TRUE.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BulletWorld::
|
||||
attach_constraint(BulletConstraint *constraint) {
|
||||
attach_constraint(BulletConstraint *constraint, bool linked_collision) {
|
||||
|
||||
nassertv(constraint);
|
||||
|
||||
|
|
@ -622,7 +623,7 @@ attach_constraint(BulletConstraint *constraint) {
|
|||
|
||||
if (found == _constraints.end()) {
|
||||
_constraints.push_back(constraint);
|
||||
_world->addConstraint(constraint->ptr());
|
||||
_world->addConstraint(constraint->ptr(), linked_collision);
|
||||
}
|
||||
else {
|
||||
bullet_cat.warning() << "constraint already attached" << endl;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ PUBLISHED:
|
|||
|
||||
// Attach/Remove
|
||||
void attach(TypedObject *object);
|
||||
void attach_constraint(BulletConstraint *constraint, bool linked_collision=false);
|
||||
|
||||
void remove(TypedObject *object);
|
||||
|
||||
// Ghost object
|
||||
|
|
@ -172,7 +174,6 @@ PUBLISHED: // Deprecated methods, will become private soon
|
|||
void attach_character(BulletBaseCharacterControllerNode *node);
|
||||
void remove_character(BulletBaseCharacterControllerNode *node);
|
||||
|
||||
void attach_constraint(BulletConstraint *constraint);
|
||||
void remove_constraint(BulletConstraint *constraint);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -144,15 +144,19 @@ test_intersection(const CollisionEntry &entry) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CollisionBox::
|
||||
xform(const LMatrix4 &mat) {
|
||||
_min = _min * mat;
|
||||
_max = _max * mat;
|
||||
_center = _center * mat;
|
||||
for(int v = 0; v < 8; v++)
|
||||
for(int v = 0; v < 8; v++) {
|
||||
_vertex[v] = _vertex[v] * mat;
|
||||
for(int p = 0; p < 6 ; p++)
|
||||
}
|
||||
for(int p = 0; p < 6 ; p++) {
|
||||
_planes[p] = set_plane(p);
|
||||
_x = _vertex[0].get_x()-_center.get_x();
|
||||
_y = _vertex[0].get_y()-_center.get_y();
|
||||
_z = _vertex[0].get_z()-_center.get_z();
|
||||
_radius = sqrt( _x*_x + _y*_y + _z*_z );
|
||||
}
|
||||
_x = _vertex[0].get_x() - _center.get_x();
|
||||
_y = _vertex[0].get_y() - _center.get_y();
|
||||
_z = _vertex[0].get_z() - _center.get_z();
|
||||
_radius = sqrt(_x * _x + _y * _y + _z * _z);
|
||||
setup_box();
|
||||
mark_viz_stale();
|
||||
mark_internal_bounds_stale();
|
||||
|
|
|
|||
|
|
@ -1407,22 +1407,29 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
|
||||
|
||||
if (attrib == IN_ambient) {
|
||||
#ifndef NDEBUG
|
||||
Light *light = np.node()->as_light();
|
||||
nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
|
||||
#endif
|
||||
// Lights don't currently have an ambient color in Panda3D.
|
||||
// We still have to support the attribute.
|
||||
t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
if (np.node()->is_of_type(AmbientLight::get_class_type())) {
|
||||
LColor c = light->get_color();
|
||||
c.componentwise_mult(_light_color_scale);
|
||||
t.set_row(3, c);
|
||||
} else {
|
||||
// Non-ambient lights don't currently have an ambient color in Panda3D.
|
||||
t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
return &t;
|
||||
|
||||
} else if (attrib == IN_diffuse) {
|
||||
Light *light = np.node()->as_light();
|
||||
nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
|
||||
|
||||
LColor c = light->get_color();
|
||||
c.componentwise_mult(_light_color_scale);
|
||||
t.set_row(3, c);
|
||||
if (np.node()->is_of_type(AmbientLight::get_class_type())) {
|
||||
// Ambient light has no diffuse color.
|
||||
t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
} else {
|
||||
LColor c = light->get_color();
|
||||
c.componentwise_mult(_light_color_scale);
|
||||
t.set_row(3, c);
|
||||
}
|
||||
return &t;
|
||||
|
||||
} else if (attrib == IN_specular) {
|
||||
|
|
@ -1432,7 +1439,11 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
return &t;
|
||||
|
||||
} else if (attrib == IN_position) {
|
||||
if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
|
||||
if (np.node()->is_of_type(AmbientLight::get_class_type())) {
|
||||
// Ambient light has no position.
|
||||
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
||||
return &t;
|
||||
} else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
|
||||
DirectionalLight *light;
|
||||
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
|
||||
|
||||
|
|
@ -1458,7 +1469,11 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
}
|
||||
|
||||
} else if (attrib == IN_halfVector) {
|
||||
if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
|
||||
if (np.node()->is_of_type(AmbientLight::get_class_type())) {
|
||||
// Ambient light has no half-vector.
|
||||
t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
||||
return &t;
|
||||
} else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
|
||||
DirectionalLight *light;
|
||||
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
|
||||
|
||||
|
|
@ -1490,19 +1505,25 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|||
}
|
||||
|
||||
} else if (attrib == IN_spotDirection) {
|
||||
LightLensNode *light;
|
||||
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
|
||||
Lens *lens = light->get_lens();
|
||||
nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
|
||||
if (np.node()->is_of_type(AmbientLight::get_class_type())) {
|
||||
// Ambient light has no spot direction.
|
||||
t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
|
||||
return &t;
|
||||
} else {
|
||||
LightLensNode *light;
|
||||
DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
|
||||
Lens *lens = light->get_lens();
|
||||
nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
|
||||
|
||||
CPT(TransformState) transform =
|
||||
get_scene()->get_cs_world_transform()->compose(
|
||||
np.get_transform(_scene_setup->get_scene_root().get_parent()));
|
||||
CPT(TransformState) transform =
|
||||
get_scene()->get_cs_world_transform()->compose(
|
||||
np.get_transform(_scene_setup->get_scene_root().get_parent()));
|
||||
|
||||
const LMatrix4 &light_mat = transform->get_mat();
|
||||
LVector3 dir = lens->get_view_vector() * light_mat;
|
||||
t.set_row(3, dir);
|
||||
return &t;
|
||||
const LMatrix4 &light_mat = transform->get_mat();
|
||||
LVector3 dir = lens->get_view_vector() * light_mat;
|
||||
t.set_row(3, dir);
|
||||
return &t;
|
||||
}
|
||||
|
||||
} else if (attrib == IN_spotCutoff) {
|
||||
if (np.node()->is_of_type(Spotlight::get_class_type())) {
|
||||
|
|
|
|||
|
|
@ -1476,6 +1476,10 @@ GROUPING ENTRIES
|
|||
its geometry is used to define the extent of the collision
|
||||
surface (unless the "descend" flag is given; see below).
|
||||
|
||||
It is now deprecated to use <Collide> without "descend"; it will
|
||||
become the default soon. You should always specify it for best
|
||||
compatibility.
|
||||
|
||||
Valid types so far are:
|
||||
|
||||
Plane
|
||||
|
|
@ -1538,11 +1542,12 @@ GROUPING ENTRIES
|
|||
|
||||
descend
|
||||
|
||||
Instead of creating only one collision object of the given type,
|
||||
each group descended from this node that contains geometry will
|
||||
Each group descended from this node that contains geometry will
|
||||
define a new collision object of the given type. The event
|
||||
name, if any, will also be inherited from the top node and
|
||||
shared among all the collision objects.
|
||||
shared among all the collision objects. This option will soon
|
||||
be the default; it is suggested that it is always specified for
|
||||
most compatibility.
|
||||
|
||||
keep
|
||||
|
||||
|
|
|
|||
|
|
@ -223,8 +223,14 @@ HTTPDate(const string &format) {
|
|||
if (_time != (time_t)-1) {
|
||||
// Unfortunately, mktime() assumes local time; convert this back
|
||||
// to GMT.
|
||||
#ifdef IS_FREEBSD
|
||||
time_t now = time(NULL);
|
||||
struct tm *tp = localtime(&now);
|
||||
_time -= tp->tm_gmtoff;
|
||||
#else /* IS_FREEBSD */
|
||||
extern long int timezone;
|
||||
_time -= timezone;
|
||||
#endif /* IS_FREEBSD */
|
||||
}
|
||||
#endif // __GNUC__
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1865,6 +1865,10 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
|
|||
node = new CollisionNode(egg_group->get_name());
|
||||
|
||||
make_collision_solids(egg_group, egg_group, (CollisionNode *)node.p());
|
||||
|
||||
// Transform all of the collision solids into local space.
|
||||
node->xform(LCAST(PN_stdfloat, egg_group->get_vertex_to_node()));
|
||||
|
||||
if ((egg_group->get_collide_flags() & EggGroup::CF_keep) != 0) {
|
||||
// If we also specified to keep the geometry, continue the
|
||||
// traversal. In this case, we create a new PandaNode to be the
|
||||
|
|
@ -1925,8 +1929,11 @@ make_node(EggGroup *egg_group, PandaNode *parent) {
|
|||
pnode->set_pos(center);
|
||||
pnode->set_color(color);
|
||||
pnode->set_radius(radius);
|
||||
|
||||
pnode->xform(LCAST(PN_stdfloat, egg_group->get_vertex_to_node()));
|
||||
|
||||
node = pnode;
|
||||
|
||||
|
||||
} else if (egg_group->get_switch_flag()) {
|
||||
if (egg_group->get_switch_fps() != 0.0) {
|
||||
// Create a sequence node.
|
||||
|
|
@ -2790,7 +2797,6 @@ find_first_polygon(EggGroup *egg_group) {
|
|||
bool EggLoader::
|
||||
make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
||||
LPoint3 ¢er, PN_stdfloat &radius, LColor &color) {
|
||||
bool success=false;
|
||||
EggGroup *geom_group = find_collision_geometry(egg_group, flags);
|
||||
if (geom_group != (EggGroup *)NULL) {
|
||||
// Collect all of the vertices.
|
||||
|
|
@ -2822,15 +2828,12 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
|||
d_center /= (double)num_vertices;
|
||||
//egg2pg_cat.debug() << "make_sphere d_center: " << d_center << "\n";
|
||||
|
||||
LMatrix4d mat = egg_group->get_vertex_to_node();
|
||||
d_center = d_center * mat;
|
||||
|
||||
// And the furthest vertex determines the radius.
|
||||
double radius2 = 0.0;
|
||||
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
|
||||
EggVertex *vtx = (*vi);
|
||||
LPoint3d p3 = vtx->get_pos3();
|
||||
LVector3d v = p3 * mat - d_center;
|
||||
LVector3d v = p3 - d_center;
|
||||
radius2 = max(radius2, v.length_squared());
|
||||
}
|
||||
|
||||
|
|
@ -2841,10 +2844,10 @@ make_sphere(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
|||
vi = vertices.begin();
|
||||
EggVertex *clr_vtx = (*vi);
|
||||
color = clr_vtx->get_color();
|
||||
success = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2900,9 +2903,8 @@ make_box(EggGroup *egg_group, EggGroup::CollideFlags flags,
|
|||
max(max_pd[2], pos[2]));
|
||||
}
|
||||
|
||||
LMatrix4d mat = egg_group->get_vertex_to_node();
|
||||
min_p = LCAST(PN_stdfloat, min_pd * mat);
|
||||
max_p = LCAST(PN_stdfloat, max_pd * mat);
|
||||
min_p = LCAST(PN_stdfloat, min_pd);
|
||||
max_p = LCAST(PN_stdfloat, max_pd);
|
||||
return (min_pd != max_pd);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -2968,6 +2970,10 @@ make_collision_solids(EggGroup *start_group, EggGroup *egg_group,
|
|||
make_collision_solids(start_group, DCAST(EggGroup, *ci), cnode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
egg2pg_cat.warning()
|
||||
<< "Using <Collide> without 'descend' is deprecated. 'descend' "
|
||||
<< "will become the default in a future version of Panda3D.\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3170,7 +3176,6 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
|||
// also determine the centroid). We compute this in node space.
|
||||
size_t num_vertices = vertices.size();
|
||||
if (num_vertices != 0) {
|
||||
LMatrix4d mat = egg_group->get_vertex_to_node();
|
||||
pvector<LPoint3d> vpos;
|
||||
vpos.reserve(num_vertices);
|
||||
|
||||
|
|
@ -3178,7 +3183,7 @@ make_collision_tube(EggGroup *egg_group, CollisionNode *cnode,
|
|||
pset<EggVertex *>::const_iterator vi;
|
||||
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
|
||||
EggVertex *vtx = (*vi);
|
||||
LPoint3d pos = vtx->get_pos3() * mat;
|
||||
const LPoint3d &pos = vtx->get_pos3();
|
||||
vpos.push_back(pos);
|
||||
center += pos;
|
||||
}
|
||||
|
|
@ -3420,20 +3425,18 @@ create_collision_plane(EggPolygon *egg_poly, EggGroup *parent_group) {
|
|||
<< "\n";
|
||||
}
|
||||
|
||||
LMatrix4d mat = egg_poly->get_vertex_to_node();
|
||||
|
||||
pvector<LVertex> vertices;
|
||||
if (!egg_poly->empty()) {
|
||||
EggPolygon::const_iterator vi;
|
||||
vi = egg_poly->begin();
|
||||
|
||||
LVertexd vert = (*vi)->get_pos3() * mat;
|
||||
LVertexd vert = (*vi)->get_pos3();
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
|
||||
LVertexd last_vert = vert;
|
||||
++vi;
|
||||
while (vi != egg_poly->end()) {
|
||||
vert = (*vi)->get_pos3() * mat;
|
||||
vert = (*vi)->get_pos3();
|
||||
if (!vert.almost_equal(last_vert)) {
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
}
|
||||
|
|
@ -3461,7 +3464,6 @@ void EggLoader::
|
|||
create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
||||
EggGroup *parent_group,
|
||||
EggGroup::CollideFlags flags) {
|
||||
LMatrix4d mat = egg_poly->get_vertex_to_node();
|
||||
|
||||
PT(EggGroup) group = new EggGroup;
|
||||
|
||||
|
|
@ -3489,13 +3491,13 @@ create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
|||
EggPolygon::const_iterator vi;
|
||||
vi = poly->begin();
|
||||
|
||||
LVertexd vert = (*vi)->get_pos3() * mat;
|
||||
LVertexd vert = (*vi)->get_pos3();
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
|
||||
LVertexd last_vert = vert;
|
||||
++vi;
|
||||
while (vi != poly->end()) {
|
||||
vert = (*vi)->get_pos3() * mat;
|
||||
vert = (*vi)->get_pos3();
|
||||
if (!vert.almost_equal(last_vert)) {
|
||||
vertices.push_back(LCAST(PN_stdfloat, vert));
|
||||
}
|
||||
|
|
@ -3513,12 +3515,11 @@ create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
|||
if (cspoly->is_valid()) {
|
||||
apply_collision_flags(cspoly, flags);
|
||||
cnode->add_solid(cspoly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::create_collision_floor_mesh
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "transformState.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "materialAttrib.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "cullFaceAttrib.h"
|
||||
#include "transparencyAttrib.h"
|
||||
|
|
@ -347,7 +348,7 @@ convert_character_bundle(PartGroup *bundleNode, EggGroupNode *egg_parent, Charac
|
|||
CharacterJoint *character_joint = DCAST(CharacterJoint, bundleNode);
|
||||
|
||||
LMatrix4 transformf;
|
||||
character_joint->get_net_transform(transformf);
|
||||
character_joint->get_transform(transformf);
|
||||
LMatrix4d transformd(LCAST(double, transformf));
|
||||
EggGroup *joint = new EggGroup(bundleNode->get_name());
|
||||
joint->add_matrix4(transformd);
|
||||
|
|
@ -577,6 +578,13 @@ convert_primitive(const GeomVertexData *vertex_data,
|
|||
}
|
||||
}
|
||||
|
||||
// Check for a material.
|
||||
EggMaterial *egg_mat = (EggMaterial *)NULL;
|
||||
const MaterialAttrib *ma = DCAST(MaterialAttrib, net_state->get_attrib(MaterialAttrib::get_class_type()));
|
||||
if (ma != (const MaterialAttrib *)NULL) {
|
||||
egg_mat = get_egg_material(ma->get_material());
|
||||
}
|
||||
|
||||
// Check for a texture.
|
||||
EggTexture *egg_tex = (EggTexture *)NULL;
|
||||
const TextureAttrib *ta = DCAST(TextureAttrib, net_state->get_attrib(TextureAttrib::get_class_type()));
|
||||
|
|
@ -703,11 +711,15 @@ convert_primitive(const GeomVertexData *vertex_data,
|
|||
// Huh, an unknown geometry type.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < num_primitives; ++i) {
|
||||
PT(EggPrimitive) egg_prim = (*make_func)();
|
||||
|
||||
egg_parent->add_child(egg_prim);
|
||||
|
||||
if (egg_mat != (EggMaterial *)NULL) {
|
||||
egg_prim->set_material(egg_mat);
|
||||
}
|
||||
if (egg_tex != (EggTexture *)NULL) {
|
||||
egg_prim->set_texture(egg_tex);
|
||||
}
|
||||
|
|
@ -947,6 +959,41 @@ apply_tag(EggGroup *egg_group, PandaNode *node, const string &tag) {
|
|||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggSaver::get_egg_material
|
||||
// Access: Private
|
||||
// Description: Returns an EggMaterial pointer that corresponds to
|
||||
// the indicated Material.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMaterial *EggSaver::
|
||||
get_egg_material(Material *mat) {
|
||||
if (mat != (Material *)NULL) {
|
||||
EggMaterial temp(mat->get_name());
|
||||
if (mat->has_ambient()) {
|
||||
temp.set_amb(mat->get_ambient());
|
||||
}
|
||||
|
||||
if (mat->has_diffuse()) {
|
||||
temp.set_diff(mat->get_diffuse());
|
||||
}
|
||||
|
||||
if (mat->has_specular()) {
|
||||
temp.set_spec(mat->get_specular());
|
||||
}
|
||||
|
||||
if (mat->has_emission()) {
|
||||
temp.set_emit(mat->get_emission());
|
||||
}
|
||||
|
||||
temp.set_shininess(mat->get_shininess());
|
||||
temp.set_local(mat->get_local());
|
||||
|
||||
return _materials.create_unique_material(temp, ~EggMaterial::E_mref_name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggSaver::get_egg_texture
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ private:
|
|||
bool apply_tags(EggGroup *egg_group, PandaNode *node);
|
||||
bool apply_tag(EggGroup *egg_group, PandaNode *node, const string &tag);
|
||||
|
||||
EggMaterial *get_egg_material(Material *tex);
|
||||
EggTexture *get_egg_texture(Texture *tex);
|
||||
|
||||
static EggPrimitive *make_egg_polygon();
|
||||
|
|
@ -102,8 +103,8 @@ private:
|
|||
PT(EggData) _data;
|
||||
|
||||
PT(EggVertexPool) _vpool;
|
||||
EggTextureCollection _textures;
|
||||
EggMaterialCollection _materials;
|
||||
EggTextureCollection _textures;
|
||||
};
|
||||
|
||||
#include "eggSaver.I"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: eglGraphicsBuffer.cxx
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
// Created by: rdb (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -28,7 +28,7 @@ TypeHandle eglGraphicsBuffer::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
eglGraphicsBuffer::
|
||||
eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
eglGraphicsBuffer(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
|
|
@ -187,7 +187,7 @@ open_buffer() {
|
|||
_gsg = eglgsg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (eglgsg->_fbconfig == None) {
|
||||
// If we didn't use an fbconfig to create the GSG, we can't create
|
||||
// a PBuffer.
|
||||
|
|
@ -195,11 +195,11 @@ open_buffer() {
|
|||
}
|
||||
|
||||
int attrib_list[] = {
|
||||
EGL_WIDTH, _x_size,
|
||||
EGL_HEIGHT, _y_size,
|
||||
EGL_WIDTH, _size.get_x(),
|
||||
EGL_HEIGHT, _size.get_y(),
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
|
||||
_pbuffer = eglCreatePbufferSurface(eglgsg->_egl_display, eglgsg->_fbconfig, attrib_list);
|
||||
|
||||
if (_pbuffer == EGL_NO_SURFACE) {
|
||||
|
|
@ -224,7 +224,7 @@ open_buffer() {
|
|||
return false;
|
||||
}
|
||||
_fb_properties = eglgsg->get_fb_properties();
|
||||
|
||||
|
||||
_is_valid = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: eglGraphicsBuffer.h
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
// Created by: rdb (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: eglGraphicsPixmap.cxx
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
// Created by: rdb (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -29,7 +29,7 @@ TypeHandle eglGraphicsPixmap::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
eglGraphicsPixmap::
|
||||
eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
|
|
@ -105,7 +105,7 @@ begin_frame(FrameMode mode, Thread *current_thread) {
|
|||
}
|
||||
clear_cube_map_selection();
|
||||
}
|
||||
|
||||
|
||||
_gsg->set_current_properties(&get_fb_properties());
|
||||
return _gsg->begin_frame(current_thread);
|
||||
}
|
||||
|
|
@ -195,7 +195,7 @@ open_buffer() {
|
|||
_gsg = eglgsg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (eglgsg->_fbconfig == None) {
|
||||
// If we didn't use an fbconfig to create the GSG, we can't create
|
||||
// a PBuffer.
|
||||
|
|
@ -221,8 +221,8 @@ open_buffer() {
|
|||
}
|
||||
}
|
||||
|
||||
_x_pixmap = XCreatePixmap(_display, _drawable,
|
||||
_x_size, _y_size, visual_info->depth);
|
||||
_x_pixmap = XCreatePixmap(_display, _drawable,
|
||||
_size.get_x(), _size.get_y(), visual_info->depth);
|
||||
if (_x_pixmap == None) {
|
||||
egldisplay_cat.error()
|
||||
<< "Failed to create X pixmap.\n";
|
||||
|
|
@ -253,7 +253,7 @@ open_buffer() {
|
|||
return false;
|
||||
}
|
||||
_fb_properties = eglgsg->get_fb_properties();
|
||||
|
||||
|
||||
_is_valid = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// Filename: eglGraphicsPixmap.h
|
||||
// Created by: pro-rsoft (13Jun09)
|
||||
// Created by: rdb (13Jun09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class eglGraphicsPixmap : public GraphicsBuffer {
|
||||
public:
|
||||
eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
eglGraphicsPixmap(GraphicsEngine *engine, GraphicsPipe *pipe,
|
||||
const string &name,
|
||||
const FrameBufferProperties &fb_prop,
|
||||
const WindowProperties &win_prop,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,33 @@ operator = (const Datagram ©) {
|
|||
_stdfloat_double = copy._stdfloat_double;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Datagram::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Datagram::
|
||||
Datagram(Datagram &&from) NOEXCEPT :
|
||||
_data(move(from._data)),
|
||||
_stdfloat_double(from._stdfloat_double)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Datagram::Move Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void Datagram::
|
||||
operator = (Datagram &&from) NOEXCEPT {
|
||||
_data = move(from._data);
|
||||
_stdfloat_double = from._stdfloat_double;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Datagram::add_bool
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ PUBLISHED:
|
|||
INLINE Datagram(const Datagram ©);
|
||||
INLINE void operator = (const Datagram ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE Datagram(Datagram &&from) NOEXCEPT;
|
||||
INLINE void operator = (Datagram &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
virtual ~Datagram();
|
||||
|
||||
virtual void clear();
|
||||
|
|
|
|||
|
|
@ -77,6 +77,21 @@ PointerToArray(const PointerToArray<Element> ©) :
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArray::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE PointerToArray<Element>::
|
||||
PointerToArray(PointerToArray<Element> &&from) NOEXCEPT :
|
||||
PointerToArrayBase<Element>(move(from)),
|
||||
_type_handle(from._type_handle)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArray::begin
|
||||
// Access: Public
|
||||
|
|
@ -682,6 +697,21 @@ operator = (const PointerToArray<Element> ©) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArray::Assignment operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE PointerToArray<Element> &PointerToArray<Element>::
|
||||
operator = (PointerToArray<Element> &&from) NOEXCEPT {
|
||||
_type_handle = from._type_handle;
|
||||
((PointerToArray<Element> *)this)->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArray::clear
|
||||
// Access: Public
|
||||
|
|
@ -736,6 +766,36 @@ ConstPointerToArray(const ConstPointerToArray<Element> ©) :
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerToArray::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE ConstPointerToArray<Element>::
|
||||
ConstPointerToArray(PointerToArray<Element> &&from) NOEXCEPT :
|
||||
PointerToArrayBase<Element>(move(from)),
|
||||
_type_handle(from._type_handle)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerToArray::Move Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE ConstPointerToArray<Element>::
|
||||
ConstPointerToArray(ConstPointerToArray<Element> &&from) NOEXCEPT :
|
||||
PointerToArrayBase<Element>(move(from)),
|
||||
_type_handle(from._type_handle)
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerToArray::begin
|
||||
// Access: Public
|
||||
|
|
@ -1141,6 +1201,36 @@ operator = (const ConstPointerToArray<Element> ©) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerToArray::Assignment operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
|
||||
operator = (PointerToArray<Element> &&from) NOEXCEPT {
|
||||
_type_handle = from._type_handle;
|
||||
((ConstPointerToArray<Element> *)this)->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerToArray::Assignment operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE ConstPointerToArray<Element> &ConstPointerToArray<Element>::
|
||||
operator = (ConstPointerToArray<Element> &&from) NOEXCEPT {
|
||||
_type_handle = from._type_handle;
|
||||
((ConstPointerToArray<Element> *)this)->reassign(move(from));
|
||||
return *this;
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ConstPointerToArray::clear
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -151,6 +151,10 @@ public:
|
|||
INLINE PointerToArray(size_type n, const Element &value, TypeHandle type_handle = get_type_handle(Element));
|
||||
INLINE PointerToArray(const PointerToArray<Element> ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE PointerToArray(PointerToArray<Element> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
public:
|
||||
// Duplicating the interface of vector. The following member
|
||||
// functions are all const, because they do not reassign the
|
||||
|
|
@ -231,6 +235,12 @@ public:
|
|||
operator = (ReferenceCountedVector<Element> *ptr);
|
||||
INLINE PointerToArray<Element> &
|
||||
operator = (const PointerToArray<Element> ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE PointerToArray<Element> &
|
||||
operator = (PointerToArray<Element> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE void clear();
|
||||
|
||||
private:
|
||||
|
|
@ -305,6 +315,11 @@ PUBLISHED:
|
|||
INLINE ConstPointerToArray(const PointerToArray<Element> ©);
|
||||
INLINE ConstPointerToArray(const ConstPointerToArray<Element> ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE ConstPointerToArray(PointerToArray<Element> &&from) NOEXCEPT;
|
||||
INLINE ConstPointerToArray(ConstPointerToArray<Element> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
// Duplicating the interface of vector.
|
||||
|
||||
INLINE iterator begin() const;
|
||||
|
|
@ -355,6 +370,14 @@ PUBLISHED:
|
|||
operator = (const PointerToArray<Element> ©);
|
||||
INLINE ConstPointerToArray<Element> &
|
||||
operator = (const ConstPointerToArray<Element> ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE ConstPointerToArray<Element> &
|
||||
operator = (PointerToArray<Element> &&from) NOEXCEPT;
|
||||
INLINE ConstPointerToArray<Element> &
|
||||
operator = (ConstPointerToArray<Element> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE void clear();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -57,11 +57,11 @@ template<class Element>
|
|||
INLINE ReferenceCountedVector<Element>::
|
||||
~ReferenceCountedVector() {
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCountedVector::size
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE TYPENAME ReferenceCountedVector<Element>::size_type ReferenceCountedVector<Element>::
|
||||
|
|
@ -72,7 +72,7 @@ size() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCountedVector::insert
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE TYPENAME ReferenceCountedVector<Element>::iterator ReferenceCountedVector<Element>::
|
||||
|
|
@ -83,7 +83,7 @@ insert(iterator position, const Element &x) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCountedVector::insert
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void ReferenceCountedVector<Element>::
|
||||
|
|
@ -94,7 +94,7 @@ insert(iterator position, size_type n, const Element &x) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCountedVector::erase
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void ReferenceCountedVector<Element>::
|
||||
|
|
@ -105,7 +105,7 @@ erase(iterator position) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCountedVector::erase
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void ReferenceCountedVector<Element>::
|
||||
|
|
@ -116,7 +116,7 @@ erase(iterator first, iterator last) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCountedVector::pop_back
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void ReferenceCountedVector<Element>::
|
||||
|
|
@ -127,7 +127,7 @@ pop_back() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCountedVector::clear
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void ReferenceCountedVector<Element>::
|
||||
|
|
@ -138,7 +138,7 @@ clear() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArrayBase::Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE PointerToArrayBase<Element>::
|
||||
|
|
@ -150,7 +150,7 @@ PointerToArrayBase(ReferenceCountedVector<Element> *ptr) :
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArrayBase::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE PointerToArrayBase<Element>::
|
||||
|
|
@ -159,10 +159,24 @@ PointerToArrayBase(const PointerToArrayBase<Element> ©) :
|
|||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArrayBase::Move Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE PointerToArrayBase<Element>::
|
||||
PointerToArrayBase(PointerToArrayBase<Element> &&from) NOEXCEPT :
|
||||
PointerToBase<ReferenceCountedVector<Element> >(move(from))
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PointerToArrayBase::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE PointerToArrayBase<Element>::
|
||||
|
|
|
|||
|
|
@ -82,6 +82,10 @@ protected:
|
|||
INLINE PointerToArrayBase(ReferenceCountedVector<Element> *ptr);
|
||||
INLINE PointerToArrayBase(const PointerToArrayBase<Element> ©);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE PointerToArrayBase(PointerToArrayBase<Element> &&from) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
PUBLISHED:
|
||||
INLINE ~PointerToArrayBase();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,26 +22,33 @@
|
|||
// Python buffer protocol.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
void Extension<PointerToArray<Element> >::
|
||||
INLINE void Extension<PointerToArray<Element> >::
|
||||
__init__(PyObject *self, PyObject *source) {
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
if (PyObject_CheckBuffer(source)) {
|
||||
// User passed a buffer object.
|
||||
Py_buffer view;
|
||||
if (PyObject_GetBuffer(source, &view, PyBUF_CONTIG_RO) == -1) {
|
||||
PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a contiguous buffer");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"PointerToArray constructor requires a contiguous buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (view.itemsize != 1 && view.itemsize != sizeof(Element)) {
|
||||
PyErr_SetString(PyExc_TypeError, "buffer.itemsize does not match PointerToArray element size");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"buffer.itemsize does not match PointerToArray element size");
|
||||
return;
|
||||
}
|
||||
|
||||
int num_elements = view.len / sizeof(Element);
|
||||
this->_this->insert(this->_this->begin(), num_elements, Element());
|
||||
if (view.len % sizeof(Element) != 0) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"byte buffer is not a multiple of %zu bytes",
|
||||
sizeof(Element));
|
||||
return;
|
||||
}
|
||||
|
||||
if (view.len > 0) {
|
||||
this->_this->resize(view.len / sizeof(Element));
|
||||
memcpy(this->_this->p(), view.buf, view.len);
|
||||
}
|
||||
|
||||
|
|
@ -52,21 +59,22 @@ __init__(PyObject *self, PyObject *source) {
|
|||
|
||||
if (!PySequence_Check(source)) {
|
||||
// If passed with a non-sequence, this isn't the right constructor.
|
||||
PyErr_SetString(PyExc_TypeError, "PointerToArray constructor requires a sequence or buffer object");
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"PointerToArray constructor requires a sequence or buffer object");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we were passed a Python string, then instead of storing it
|
||||
// character-at-a-time, just load the whole string as a data
|
||||
// buffer.
|
||||
// buffer. Not sure if this case is still necessary - don't Python
|
||||
// str/bytes objects export the buffer protocol, as above?
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
if (PyBytes_Check(source)) {
|
||||
int size = PyBytes_Size(source);
|
||||
if (size % sizeof(Element) != 0) {
|
||||
ostringstream stream;
|
||||
stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
|
||||
string str = stream.str();
|
||||
PyErr_SetString(PyExc_ValueError, str.c_str());
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"bytes object is not a multiple of %zu bytes",
|
||||
sizeof(Element));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -85,10 +93,9 @@ __init__(PyObject *self, PyObject *source) {
|
|||
if (PyString_CheckExact(source)) {
|
||||
int size = PyString_Size(source);
|
||||
if (size % sizeof(Element) != 0) {
|
||||
ostringstream stream;
|
||||
stream << "Buffer not a multiple of " << sizeof(Element) << " bytes";
|
||||
string str = stream.str();
|
||||
PyErr_SetString(PyExc_ValueError, str.c_str());
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"str object is not a multiple of %zu bytes",
|
||||
sizeof(Element));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -107,20 +114,29 @@ __init__(PyObject *self, PyObject *source) {
|
|||
|
||||
// Now construct the internal list by copying the elements
|
||||
// one-at-a-time from Python.
|
||||
PyObject *push_back = PyObject_GetAttrString(self, "push_back");
|
||||
if (push_back == NULL) {
|
||||
PyErr_BadArgument();
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to initialize the this pointer before we can call push_back.
|
||||
((Dtool_PyInstDef *)self)->_ptr_to_object = (void *)this->_this;
|
||||
|
||||
int size = PySequence_Size(source);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
PyObject *item = PySequence_GetItem(source, i);
|
||||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod(self, (char *)"push_back", (char *)"O", item);
|
||||
PyObject *result = PyObject_CallFunctionObjArgs(push_back, item, NULL);
|
||||
Py_DECREF(item);
|
||||
if (result == NULL) {
|
||||
// Unable to add item--probably it wasn't of the appropriate type.
|
||||
ostringstream stream;
|
||||
stream << "Element " << i << " in sequence passed to PointerToArray constructor could not be added";
|
||||
string str = stream.str();
|
||||
PyErr_SetString(PyExc_TypeError, str.c_str());
|
||||
PyErr_Print();
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Element %d in sequence passed to PointerToArray "
|
||||
"constructor could not be added", i);
|
||||
return;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
|
|
@ -161,7 +177,9 @@ __setitem__(size_t n, const Element &value) {
|
|||
template<class Element>
|
||||
INLINE void Extension<ConstPointerToArray<Element> >::
|
||||
__init__(PyObject *self, PyObject *source) {
|
||||
new (this->_this) ConstPointerToArray<Element>(get_type_handle(Element));
|
||||
PointerToArray<Element> array;
|
||||
invoke_extension(&array).__init__(self, source);
|
||||
*(this->_this) = MOVE(array);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -240,7 +258,7 @@ __releasebuffer__(PyObject *self, Py_buffer *view) const {
|
|||
|
||||
if (view->internal != NULL) {
|
||||
// Oh, right, let's not forget to unref this.
|
||||
((const PointerToArray<Element> *) view->internal)->unref();
|
||||
unref_delete((const PointerToArray<Element> *)view->internal);
|
||||
view->internal = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -314,7 +332,7 @@ __releasebuffer__(PyObject *self, Py_buffer *view) const {
|
|||
|
||||
if (view->internal != NULL) {
|
||||
// Oh, right, let's not forget to unref this.
|
||||
((const PointerToArray<Element> *) view->internal)->unref();
|
||||
unref_delete((const PointerToArray<Element> *)view->internal);
|
||||
view->internal = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,26 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Ugh... MSVC needs this because they still don't have a decent linker.
|
||||
#include "PTA_uchar.h"
|
||||
#include "PTA_ushort.h"
|
||||
#include "PTA_float.h"
|
||||
#include "PTA_double.h"
|
||||
#include "PTA_int.h"
|
||||
|
||||
template class EXPORT_THIS Extension<PTA_uchar>;
|
||||
template class EXPORT_THIS Extension<PTA_ushort>;
|
||||
template class EXPORT_THIS Extension<PTA_float>;
|
||||
template class EXPORT_THIS Extension<PTA_double>;
|
||||
template class EXPORT_THIS Extension<PTA_int>;
|
||||
template class EXPORT_THIS Extension<CPTA_uchar>;
|
||||
template class EXPORT_THIS Extension<CPTA_ushort>;
|
||||
template class EXPORT_THIS Extension<CPTA_float>;
|
||||
template class EXPORT_THIS Extension<CPTA_double>;
|
||||
template class EXPORT_THIS Extension<CPTA_int>;
|
||||
#endif
|
||||
|
||||
// This macro is used to map a data type to a format code
|
||||
// as used in the Python 'struct' and 'array' modules.
|
||||
#define get_format_code(type) _get_format_code((const type *)0)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,11 @@ FfmpegAudioCursor(FfmpegAudio *src) :
|
|||
_can_seek = true;
|
||||
_can_seek_fast = true;
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100)
|
||||
_frame = av_frame_alloc();
|
||||
#else
|
||||
_frame = avcodec_alloc_frame();
|
||||
#endif
|
||||
|
||||
_packet = new AVPacket;
|
||||
_buffer_size = AVCODEC_MAX_AUDIO_FRAME_SIZE / 2;
|
||||
|
|
@ -194,7 +198,9 @@ FfmpegAudioCursor::
|
|||
void FfmpegAudioCursor::
|
||||
cleanup() {
|
||||
if (_frame) {
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100)
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 45, 101)
|
||||
av_frame_free(&_frame);
|
||||
#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100)
|
||||
avcodec_free_frame(&_frame);
|
||||
#else
|
||||
av_free(&_frame);
|
||||
|
|
@ -313,8 +319,7 @@ reload_buffer() {
|
|||
#ifdef HAVE_SWRESAMPLE
|
||||
if (_resample_ctx) {
|
||||
// Resample the data to signed 16-bit sample format.
|
||||
uint8_t* out[SWR_CH_MAX] = {(uint8_t*) _buffer, NULL};
|
||||
bufsize = swr_convert(_resample_ctx, out, _buffer_size / 2, (const uint8_t**)_frame->extended_data, _frame->nb_samples);
|
||||
bufsize = swr_convert(_resample_ctx, (uint8_t **)&_buffer, _buffer_size / 2, (const uint8_t**)_frame->extended_data, _frame->nb_samples);
|
||||
bufsize *= _audio_channels * 2;
|
||||
} else
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -94,8 +94,13 @@ init_from(FfmpegVideo *source) {
|
|||
PIX_FMT_BGR24, SWS_BILINEAR | SWS_PRINT_INFO, NULL, NULL, NULL);
|
||||
#endif // HAVE_SWSCALE
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 59, 100)
|
||||
_frame = av_frame_alloc();
|
||||
_frame_out = av_frame_alloc();
|
||||
#else
|
||||
_frame = avcodec_alloc_frame();
|
||||
_frame_out = avcodec_alloc_frame();
|
||||
#endif
|
||||
|
||||
if ((_frame == 0)||(_frame_out == 0)) {
|
||||
cleanup();
|
||||
|
|
|
|||
|
|
@ -798,15 +798,28 @@ next_anim_control() {
|
|||
if (_anim_controls_enabled) {
|
||||
destroy_anim_controls();
|
||||
|
||||
if (_anim_controls.get_num_anims() == 0) {
|
||||
set_anim_controls(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop the active animation.
|
||||
pause_button();
|
||||
++_anim_index;
|
||||
|
||||
if (_anim_index >= _anim_controls.get_num_anims()) {
|
||||
set_anim_controls(false);
|
||||
_anim_controls.loop_all(true);
|
||||
} else {
|
||||
create_anim_controls();
|
||||
play_button();
|
||||
}
|
||||
} else {
|
||||
_anim_index = 0;
|
||||
set_anim_controls(true);
|
||||
if (_anim_controls.get_num_anims() > 0) {
|
||||
play_button();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1451,6 +1464,23 @@ create_anim_controls() {
|
|||
AnimControl *control = _anim_controls.get_anim(_anim_index);
|
||||
nassertv(control != (AnimControl *)NULL);
|
||||
|
||||
if (control->get_num_frames() <= 1) {
|
||||
// Don't show the controls when the animation has only 0 or 1 frames.
|
||||
ostringstream text;
|
||||
text << _anim_controls.get_anim_name(_anim_index);
|
||||
text << " (" << control->get_num_frames() << " frame"
|
||||
<< ((control->get_num_frames() == 1) ? "" : "s") << ")";
|
||||
|
||||
PT(TextNode) label = new TextNode("label");
|
||||
label->set_align(TextNode::A_center);
|
||||
label->set_text(text.str());
|
||||
NodePath tnp = _anim_controls_group.attach_new_node(label);
|
||||
tnp.set_pos(0.0f, 0.0f, 0.07f);
|
||||
tnp.set_scale(0.1f);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PT(TextNode) label = new TextNode("anim_name");
|
||||
label->set_align(TextNode::A_left);
|
||||
label->set_text(_anim_controls.get_anim_name(_anim_index));
|
||||
|
|
@ -1525,13 +1555,17 @@ update_anim_controls() {
|
|||
AnimControl *control = _anim_controls.get_anim(_anim_index);
|
||||
nassertv(control != (AnimControl *)NULL);
|
||||
|
||||
if (_anim_slider->is_button_down()) {
|
||||
control->pose((int)(_anim_slider->get_value() + 0.5));
|
||||
} else {
|
||||
_anim_slider->set_value((PN_stdfloat)control->get_frame());
|
||||
if (_anim_slider != NULL) {
|
||||
if (_anim_slider->is_button_down()) {
|
||||
control->pose((int)(_anim_slider->get_value() + 0.5));
|
||||
} else {
|
||||
_anim_slider->set_value((PN_stdfloat)control->get_frame());
|
||||
}
|
||||
}
|
||||
|
||||
_frame_number->set_text(format_string(control->get_frame()));
|
||||
if (_frame_number != NULL) {
|
||||
_frame_number->set_text(format_string(control->get_frame()));
|
||||
}
|
||||
|
||||
control->set_play_rate(_play_rate_slider->get_value());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
// #include <GLES2/gl2ext.h>
|
||||
#endif
|
||||
|
||||
#include "panda_esgl2ext.h"
|
||||
#include "panda_esgl2ext.h"
|
||||
|
||||
// This helps to keep the source clean of hundreds of #ifdefs.
|
||||
typedef char GLchar;
|
||||
|
|
@ -100,20 +100,19 @@ typedef char GLchar;
|
|||
#define GL_RGBA16F GL_RGBA16F_EXT
|
||||
#define GL_RGB32F GL_RGB32F_EXT
|
||||
#define GL_RGBA32F GL_RGBA32F_EXT
|
||||
#define GL_DEBUG_SEVERITY_HIGH GL_DEBUG_SEVERITY_HIGH_KHR
|
||||
#define GL_DEBUG_SEVERITY_MEDIUM GL_DEBUG_SEVERITY_MEDIUM_KHR
|
||||
#define GL_DEBUG_SEVERITY_LOW GL_DEBUG_SEVERITY_LOW_KHR
|
||||
#define GL_DEBUG_SEVERITY_NOTIFICATION GL_DEBUG_SEVERITY_NOTIFICATION_KHR
|
||||
#define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
|
||||
#define GL_FRAMEBUFFER_SRGB GL_FRAMEBUFFER_SRGB_EXT
|
||||
#define GL_SRGB GL_SRGB_EXT
|
||||
#define GL_SRGB_ALPHA GL_SRGB_ALPHA_EXT
|
||||
#define GL_SRGB8 GL_SRGB8_EXT
|
||||
#define GL_SRGB8_ALPHA GL_SRGB8_ALPHA_EXT
|
||||
#define GL_SLUMINANCE GL_SLUMINANCE_NV
|
||||
#define GL_SLUMINANCE_ALPHA GL_SLUMINANCE_ALPHA_NV
|
||||
#define GL_SLUMINANCE8 GL_SLUMINANCE8_NV
|
||||
#define GL_SLUMINANCE8_ALPHA GL_SLUMINANCE8_ALPHA_NV
|
||||
#define GL_SRGB8_ALPHA8 GL_SRGB8_ALPHA8_EXT
|
||||
#define GL_RGBA8 GL_RGBA8_OES
|
||||
#define GL_R8 GL_R8_EXT
|
||||
#define GL_RG8 GL_RG8_EXT
|
||||
#define GL_ALPHA8 GL_ALPHA8_OES
|
||||
#define GL_LUMINANCE8 GL_LUMINANCE8_OES
|
||||
#define GL_LUMINANCE8_ALPHA8 GL_LUMINANCE8_ALPHA8_EXT
|
||||
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
|
||||
#define GL_R32F GL_R32F_EXT
|
||||
#define GL_RG32F GL_RG32F_EXT
|
||||
#define GL_RGB8 GL_RGB8_OES
|
||||
|
||||
#undef SUPPORT_IMMEDIATE_MODE
|
||||
#define APIENTRY
|
||||
|
|
|
|||
|
|
@ -115,6 +115,9 @@
|
|||
#define GL_RGBA16F GL_RGBA16F_EXT
|
||||
#define GL_RGB32F GL_RGB32F_EXT
|
||||
#define GL_RGBA32F GL_RGBA32F_EXT
|
||||
#define GL_ALPHA8 GL_ALPHA8_EXT
|
||||
#define GL_LUMINANCE8 GL_LUMINANCE8_EXT
|
||||
#define GL_LUMINANCE8_ALPHA8 GL_LUMINANCE8_ALPHA8_EXT
|
||||
|
||||
#undef SUPPORT_IMMEDIATE_MODE
|
||||
#define APIENTRY
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ CLP(CgShaderContext)::
|
|||
CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext(s) {
|
||||
_glgsg = glgsg;
|
||||
_cg_program = 0;
|
||||
_glsl_profile = false;
|
||||
|
||||
nassertv(s->get_language() == Shader::SL_Cg);
|
||||
|
||||
|
|
@ -63,10 +62,6 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
|
|||
release_resources();
|
||||
|
||||
} else {
|
||||
if (cgGetProgramProfile(_cg_program) == CG_PROFILE_GLSLC) {
|
||||
_glsl_profile = true;
|
||||
}
|
||||
|
||||
cgGLLoadProgram(_cg_program);
|
||||
CGerror error = cgGetError();
|
||||
if (error != CG_NO_ERROR) {
|
||||
|
|
@ -412,7 +407,7 @@ disable_shader_vertex_arrays() {
|
|||
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
|
||||
if (p == 0) continue;
|
||||
|
||||
if (_glsl_profile && cgGetParameterBaseResource(p) == CG_ATTR0) {
|
||||
if (cgGetParameterBaseResource(p) == CG_ATTR0) {
|
||||
int index = cgGetParameterResourceIndex(p);
|
||||
if (index >= 8) {
|
||||
_glgsg->_glClientActiveTexture(GL_TEXTURE0 + (index - 8));
|
||||
|
|
@ -501,11 +496,9 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
|
|||
num_values = GL_BGRA;
|
||||
}
|
||||
|
||||
// This is truly the most preposterous hack. When using the GLSL
|
||||
// profiles, cgGLSetParameterPointer relies on the the driver mapping
|
||||
// standard attributes to fixed indices (and breaking the spec doing
|
||||
// so), which only the NVIDIA drivers do. Unbelievable.
|
||||
if (_glsl_profile && cgGetParameterBaseResource(p) == CG_ATTR0) {
|
||||
// cgGLSetParameterPointer is just stupidly bugged on every level.
|
||||
// Sigh. This seems to work on both NVIDIA and AMD cards now.
|
||||
if (cgGetParameterBaseResource(p) == CG_ATTR0) {
|
||||
int index = cgGetParameterResourceIndex(p);
|
||||
switch (index) {
|
||||
case 0: // gl_Vertex
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ public:
|
|||
|
||||
private:
|
||||
CGprogram _cg_program;
|
||||
bool _glsl_profile;
|
||||
|
||||
pvector<CGparameter> _cg_parameter_map;
|
||||
|
||||
|
|
|
|||
|
|
@ -1674,7 +1674,7 @@ resolve_multisamples() {
|
|||
GL_NEAREST);
|
||||
}
|
||||
// Now handle the other color buffers.
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
int next = GL_COLOR_ATTACHMENT1_EXT;
|
||||
if (_fb_properties.is_stereo()) {
|
||||
glReadBuffer(next);
|
||||
|
|
|
|||
|
|
@ -745,9 +745,12 @@ call_glTexParameterfv(GLenum target, GLenum pname, const LVecBase4 &value) {
|
|||
// Access: Public
|
||||
// Description: Convert index to gl light id
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GLenum CLP(GraphicsStateGuardian)::get_light_id(int index) const {
|
||||
INLINE GLenum CLP(GraphicsStateGuardian)::
|
||||
get_light_id(int index) const {
|
||||
#ifndef OPENGLES_2
|
||||
return GL_LIGHT0 + index;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -760,6 +763,8 @@ INLINE GLenum CLP(GraphicsStateGuardian)::
|
|||
get_clip_plane_id(int index) const {
|
||||
#ifndef OPENGLES_2
|
||||
return GL_CLIP_PLANE0 + index;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,16 +127,16 @@ null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
|
|||
// a fixed-function pipeline.
|
||||
// This default shader just outputs a red color, telling
|
||||
// the user that something went wrong.
|
||||
CPT(Shader::ShaderFile) default_shader_name = new Shader::ShaderFile("default-shader");
|
||||
CPT(Shader::ShaderFile) default_shader_body = new Shader::ShaderFile("\
|
||||
uniform mediump mat4 p3d_ModelViewProjectionMatrix;\
|
||||
attribute highp vec4 p3d_Vertex;\
|
||||
void main(void) {\
|
||||
gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\
|
||||
}\n",
|
||||
"void main(void) {\
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\
|
||||
}\n", "", "", "");
|
||||
static const string default_vshader =
|
||||
"uniform mediump mat4 p3d_ModelViewProjectionMatrix;\n"
|
||||
"attribute highp vec4 p3d_Vertex;\n"
|
||||
"void main(void) {\n"
|
||||
" gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
|
||||
"}\n";
|
||||
static const string default_fshader =
|
||||
"void main(void) {\n"
|
||||
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -558,10 +558,13 @@ reset() {
|
|||
_glPrimitiveRestartIndex = NULL;
|
||||
|
||||
if (gl_support_primitive_restart_index) {
|
||||
if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_ES3_compatibility")) {
|
||||
if ((is_at_least_gl_version(4, 3) || has_extension("GL_ARB_ES3_compatibility")) &&
|
||||
_gl_renderer.substr(0, 7) != "Gallium") {
|
||||
// As long as we enable this, OpenGL will always use the highest possible index
|
||||
// for a numeric type as strip cut index, which coincides with our convention.
|
||||
// This saves us a call to glPrimitiveRestartIndex.
|
||||
// This saves us a call to glPrimitiveRestartIndex
|
||||
// ... of course, though, the Gallium driver bugs out here. See also:
|
||||
// https://www.panda3d.org/forums/viewtopic.php?f=5&t=17512
|
||||
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
|
||||
_supported_geom_rendering |= Geom::GR_strip_cut_index;
|
||||
|
||||
|
|
@ -1370,7 +1373,7 @@ reset() {
|
|||
// if it failed to compile. This default shader just outputs
|
||||
// a red color, indicating that something went wrong.
|
||||
if (_default_shader == NULL) {
|
||||
_default_shader = new Shader(default_shader_name, default_shader_body, Shader::SL_GLSL);
|
||||
_default_shader = Shader::load(Shader::SL_GLSL, default_vshader, default_fshader);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1915,6 +1918,8 @@ reset() {
|
|||
}
|
||||
|
||||
_supports_sampler_objects = false;
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (gl_support_sampler_objects &&
|
||||
((is_at_least_gl_version(3, 3) || has_extension("GL_ARB_sampler_objects")))) {
|
||||
_glGenSamplers = (PFNGLGENSAMPLERSPROC) get_extension_func("glGenSamplers");
|
||||
|
|
@ -1935,6 +1940,7 @@ reset() {
|
|||
_supports_sampler_objects = true;
|
||||
}
|
||||
}
|
||||
#endif // OPENGLES
|
||||
|
||||
// Check availability of multi-bind functions.
|
||||
_supports_multi_bind = false;
|
||||
|
|
@ -1944,10 +1950,12 @@ reset() {
|
|||
_glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
|
||||
get_extension_func("glBindImageTextures");
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (_supports_sampler_objects) {
|
||||
_glBindSamplers = (PFNGLBINDSAMPLERSPROC)
|
||||
get_extension_func("glBindSamplers");
|
||||
}
|
||||
#endif // OPENGLES
|
||||
|
||||
if (_glBindTextures != NULL && _glBindImageTextures != NULL) {
|
||||
_supports_multi_bind = true;
|
||||
|
|
@ -2011,14 +2019,18 @@ reset() {
|
|||
|
||||
_supports_stencil_wrap =
|
||||
has_extension("GL_EXT_stencil_wrap") || has_extension("GL_OES_stencil_wrap");
|
||||
_supports_two_sided_stencil = has_extension("GL_EXT_stencil_two_side");
|
||||
if (_supports_two_sided_stencil) {
|
||||
|
||||
|
||||
_supports_two_sided_stencil = false;
|
||||
#ifndef OPENGLES
|
||||
if (has_extension("GL_EXT_stencil_two_side")) {
|
||||
_glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
|
||||
get_extension_func("glActiveStencilFaceEXT");
|
||||
}
|
||||
else {
|
||||
_supports_two_sided_stencil = true;
|
||||
} else {
|
||||
_glActiveStencilFaceEXT = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES
|
||||
// Some drivers expose one, some expose the other. ARB seems to be the newer one.
|
||||
|
|
@ -2618,9 +2630,11 @@ clear_before_callback() {
|
|||
|
||||
// Clear the bound sampler object, so that we do not inadvertently
|
||||
// override the callback's desired sampler settings.
|
||||
#ifndef OPENGLES
|
||||
if (_supports_sampler_objects) {
|
||||
_glBindSampler(0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2761,7 +2775,7 @@ begin_frame(Thread *current_thread) {
|
|||
}*/
|
||||
#endif
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (_current_properties->get_srgb_color()) {
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
|
|
@ -2819,7 +2833,7 @@ void CLP(GraphicsStateGuardian)::
|
|||
end_frame(Thread *current_thread) {
|
||||
report_my_gl_errors();
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (_current_properties->get_srgb_color()) {
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
|
|
@ -4521,8 +4535,10 @@ prepare_sampler(const SamplerState &sampler) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
release_sampler(SamplerContext *sc) {
|
||||
#ifndef OPENGLES
|
||||
CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
|
||||
delete gsc;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -5205,7 +5221,7 @@ make_geom_munger(const RenderState *state, Thread *current_thread) {
|
|||
// from the camera plane. The point is assumed to be
|
||||
// in the GSG's internal coordinate system.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PN_stdfloat GLGraphicsStateGuardian::
|
||||
PN_stdfloat CLP(GraphicsStateGuardian)::
|
||||
compute_distance_to(const LPoint3 &point) const {
|
||||
return -point[2];
|
||||
}
|
||||
|
|
@ -7447,7 +7463,7 @@ get_external_image_format(Texture *tex) const {
|
|||
break;
|
||||
|
||||
case Texture::CM_dxt1:
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (format == Texture::F_srgb_alpha) {
|
||||
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||
} else if (format == Texture::F_srgb) {
|
||||
|
|
@ -7484,13 +7500,13 @@ get_external_image_format(Texture *tex) const {
|
|||
|
||||
#else
|
||||
case Texture::CM_pvr1_2bpp:
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (format == Texture::F_srgb_alpha) {
|
||||
return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
|
||||
} else if (format == Texture::F_srgb) {
|
||||
return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
|
||||
} else
|
||||
#endif // OPENGLES_1
|
||||
#endif // OPENGLES
|
||||
if (Texture::has_alpha(format)) {
|
||||
return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
} else {
|
||||
|
|
@ -7498,13 +7514,13 @@ get_external_image_format(Texture *tex) const {
|
|||
}
|
||||
|
||||
case Texture::CM_pvr1_4bpp:
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (format == Texture::F_srgb_alpha) {
|
||||
return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
|
||||
} else if (format == Texture::F_srgb) {
|
||||
return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
|
||||
} else
|
||||
#endif // OPENGLES_1
|
||||
#endif // OPENGLES
|
||||
if (Texture::has_alpha(format)) {
|
||||
return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
} else {
|
||||
|
|
@ -7762,7 +7778,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
#endif
|
||||
|
||||
case Texture::CM_dxt1:
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (format == Texture::F_srgb_alpha) {
|
||||
return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||
} else if (format == Texture::F_srgb) {
|
||||
|
|
@ -7798,13 +7814,6 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
}
|
||||
#else
|
||||
case Texture::CM_pvr1_2bpp:
|
||||
#ifndef OPENGLES_1
|
||||
if (format == Texture::F_srgb_alpha) {
|
||||
return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
|
||||
} else if (format == Texture::F_srgb) {
|
||||
return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
|
||||
} else
|
||||
#endif // OPENGLES_1
|
||||
if (Texture::has_alpha(format)) {
|
||||
return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
} else {
|
||||
|
|
@ -7812,13 +7821,6 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
}
|
||||
|
||||
case Texture::CM_pvr1_4bpp:
|
||||
#ifndef OPENGLES_1
|
||||
if (format == Texture::F_srgb_alpha) {
|
||||
return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
|
||||
} else if (format == Texture::F_srgb) {
|
||||
return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
|
||||
} else
|
||||
#endif // OPENGLES_1
|
||||
if (Texture::has_alpha(format)) {
|
||||
return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
} else {
|
||||
|
|
@ -7843,7 +7845,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
|
||||
case Texture::F_depth_stencil:
|
||||
if (_supports_depth_stencil) {
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
if (tex->get_component_type() == Texture::T_float) {
|
||||
return GL_DEPTH32F_STENCIL8;
|
||||
} else
|
||||
|
|
@ -7903,7 +7905,10 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
#ifndef OPENGLES_1
|
||||
if (tex->get_component_type() == Texture::T_float) {
|
||||
return GL_RGBA16F;
|
||||
} else if (tex->get_component_type() == Texture::T_unsigned_short) {
|
||||
} else
|
||||
#endif
|
||||
#ifndef OPENGLES
|
||||
if (tex->get_component_type() == Texture::T_unsigned_short) {
|
||||
return GL_RGBA16;
|
||||
} else
|
||||
#endif
|
||||
|
|
@ -7949,7 +7954,7 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
case Texture::F_rgba12:
|
||||
return GL_RGBA12;
|
||||
#endif // OPENGLES
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
case Texture::F_rgba16:
|
||||
if (tex->get_component_type() == Texture::T_float) {
|
||||
return GL_RGBA16F;
|
||||
|
|
@ -8040,26 +8045,36 @@ get_internal_image_format(Texture *tex, bool force_sized) const {
|
|||
return force_sized ? GL_ALPHA8 : GL_ALPHA;
|
||||
|
||||
case Texture::F_luminance:
|
||||
#ifndef OPENGLES
|
||||
if (tex->get_component_type() == Texture::T_float) {
|
||||
return GL_LUMINANCE16F_ARB;
|
||||
} else if (tex->get_component_type() == Texture::T_unsigned_short) {
|
||||
return GL_LUMINANCE16;
|
||||
} else {
|
||||
} else
|
||||
#endif // OPENGLES
|
||||
{
|
||||
return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
|
||||
}
|
||||
case Texture::F_luminance_alpha:
|
||||
case Texture::F_luminance_alphamask:
|
||||
#ifndef OPENGLES
|
||||
if (tex->get_component_type() == Texture::T_float || tex->get_component_type() == Texture::T_unsigned_short) {
|
||||
return GL_LUMINANCE_ALPHA16F_ARB;
|
||||
} else {
|
||||
} else
|
||||
#endif // OPENGLES
|
||||
{
|
||||
return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
|
||||
}
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
case Texture::F_srgb:
|
||||
#ifndef OPENGLES
|
||||
return GL_SRGB8;
|
||||
#endif
|
||||
case Texture::F_srgb_alpha:
|
||||
return GL_SRGB8_ALPHA8;
|
||||
#endif
|
||||
#ifndef OPENGLES
|
||||
case Texture::F_sluminance:
|
||||
return GL_SLUMINANCE8;
|
||||
case Texture::F_sluminance_alpha:
|
||||
|
|
@ -9043,7 +9058,7 @@ set_state_and_transform(const RenderState *target,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
free_pointers() {
|
||||
#ifdef HAVE_CG
|
||||
#if defined(HAVE_CG) && !defined(OPENGLES)
|
||||
if (_cg_context != 0) {
|
||||
cgDestroyContext(_cg_context);
|
||||
_cg_context = 0;
|
||||
|
|
@ -10081,6 +10096,7 @@ bool CLP(GraphicsStateGuardian)::
|
|||
apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
|
||||
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (_supports_sampler_objects) {
|
||||
// We support sampler objects. Prepare the sampler object and
|
||||
// bind it to the indicated texture unit.
|
||||
|
|
@ -10097,7 +10113,9 @@ apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
|
|||
<< "bind " << unit << " " << sampler << "\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
} else
|
||||
#endif // OPENGLES
|
||||
{
|
||||
// We don't support sampler objects. We'll have to bind the
|
||||
// texture and change the texture parameters if they don't match.
|
||||
if (gtc->_active_sampler != sampler) {
|
||||
|
|
@ -10678,6 +10696,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|||
if (tex->has_clear_color()) {
|
||||
// The texture has a clear color, so we should fill this mipmap
|
||||
// level to a solid color.
|
||||
#ifndef OPENGLES
|
||||
if (_supports_clear_texture) {
|
||||
// We can do that with the convenient glClearTexImage function.
|
||||
string clear_data = tex->get_clear_data();
|
||||
|
|
@ -10685,12 +10704,13 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|||
_glClearTexImage(gtc->_index, n - mipmap_bias, external_format,
|
||||
component_type, (void *)clear_data.data());
|
||||
continue;
|
||||
} else {
|
||||
// Ask the Texture class to create the mipmap level in RAM.
|
||||
// It'll fill it in with the correct clear color, which we
|
||||
// can then upload.
|
||||
ptimage = tex->make_ram_mipmap_image(n);
|
||||
}
|
||||
#endif // OPENGLES
|
||||
// Ask the Texture class to create the mipmap level in RAM.
|
||||
// It'll fill it in with the correct clear color, which we
|
||||
// can then upload.
|
||||
ptimage = tex->make_ram_mipmap_image(n);
|
||||
|
||||
} else {
|
||||
// No clear color and no more images.
|
||||
break;
|
||||
|
|
@ -10726,13 +10746,8 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|||
_data_transferred_pcollector.add_level(view_size);
|
||||
#endif
|
||||
switch (texture_target) {
|
||||
#ifdef OPENGLES_2
|
||||
case GL_TEXTURE_3D_OES:
|
||||
#endif
|
||||
#ifndef OPENGLES
|
||||
case GL_TEXTURE_3D:
|
||||
#endif
|
||||
#ifndef OPENGLES_1
|
||||
case GL_TEXTURE_3D:
|
||||
if (_supports_3d_texture) {
|
||||
if (image_compression == Texture::CM_off) {
|
||||
_glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
|
||||
|
|
@ -10746,7 +10761,9 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
#endif // OPENGLES_1
|
||||
|
||||
#ifndef OPENGLES
|
||||
case GL_TEXTURE_1D:
|
||||
if (image_compression == Texture::CM_off) {
|
||||
glTexSubImage1D(page_target, n - mipmap_bias, 0, width,
|
||||
|
|
@ -10756,7 +10773,8 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|||
external_format, view_size, image_ptr);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif // OPENGLES
|
||||
|
||||
#ifndef OPENGLES
|
||||
case GL_TEXTURE_2D_ARRAY_EXT:
|
||||
if (_supports_2d_texture_array) {
|
||||
|
|
@ -10772,7 +10790,8 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif // OPENGLES
|
||||
|
||||
default:
|
||||
if (image_compression == Texture::CM_off) {
|
||||
if (n==0) {
|
||||
|
|
@ -11319,7 +11338,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
|
|||
type = Texture::T_unsigned_int_24_8;
|
||||
format = Texture::F_depth_stencil;
|
||||
break;
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
case GL_DEPTH32F_STENCIL8:
|
||||
type = Texture::T_float;
|
||||
format = Texture::F_depth_stencil;
|
||||
|
|
@ -11483,26 +11502,34 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
|
|||
format = Texture::F_alpha;
|
||||
break;
|
||||
case GL_LUMINANCE:
|
||||
#ifndef OPENGLES
|
||||
case GL_LUMINANCE16:
|
||||
case GL_LUMINANCE16F_ARB:
|
||||
#endif
|
||||
case 1:
|
||||
format = Texture::F_luminance;
|
||||
break;
|
||||
case GL_LUMINANCE_ALPHA:
|
||||
#ifndef OPENGLES
|
||||
case GL_LUMINANCE_ALPHA16F_ARB:
|
||||
#endif
|
||||
case 2:
|
||||
format = Texture::F_luminance_alpha;
|
||||
break;
|
||||
|
||||
#ifndef OPENGLES_1
|
||||
case GL_SRGB:
|
||||
#ifndef OPENGLES
|
||||
case GL_SRGB8:
|
||||
#endif
|
||||
format = Texture::F_srgb;
|
||||
break;
|
||||
case GL_SRGB_ALPHA:
|
||||
case GL_SRGB8_ALPHA8:
|
||||
format = Texture::F_srgb_alpha;
|
||||
break;
|
||||
#endif // OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
case GL_SLUMINANCE:
|
||||
case GL_SLUMINANCE8:
|
||||
format = Texture::F_sluminance;
|
||||
|
|
@ -11511,7 +11538,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
|
|||
case GL_SLUMINANCE8_ALPHA8:
|
||||
format = Texture::F_sluminance_alpha;
|
||||
break;
|
||||
#endif
|
||||
#endif // OPENGLES
|
||||
|
||||
#ifndef OPENGLES
|
||||
case GL_COMPRESSED_RGB:
|
||||
|
|
@ -11561,7 +11588,7 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
|
|||
format = Texture::F_rgbm;
|
||||
compression = Texture::CM_dxt1;
|
||||
break;
|
||||
#ifndef OPENGLES_1
|
||||
#ifndef OPENGLES
|
||||
case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
|
||||
format = Texture::F_srgb;
|
||||
compression = Texture::CM_dxt1;
|
||||
|
|
@ -11572,25 +11599,6 @@ do_extract_texture_data(CLP(TextureContext) *gtc) {
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef OPENGLES_2
|
||||
case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
|
||||
format = Texture::F_srgb;
|
||||
compression = Texture::CM_pvr1_2bpp;
|
||||
break;
|
||||
case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
|
||||
format = Texture::F_srgb_alpha;
|
||||
compression = Texture::CM_pvr1_2bpp;
|
||||
break;
|
||||
case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
|
||||
format = Texture::F_srgb;
|
||||
compression = Texture::CM_pvr1_4bpp;
|
||||
break;
|
||||
case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
|
||||
format = Texture::F_srgb_alpha;
|
||||
compression = Texture::CM_pvr1_4bpp;
|
||||
break;
|
||||
#endif // OPENGLES_2
|
||||
|
||||
#ifdef OPENGLES
|
||||
case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
|
||||
format = Texture::F_rgb;
|
||||
|
|
@ -11963,6 +11971,7 @@ do_issue_stencil() {
|
|||
<< "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
|
||||
}
|
||||
|
||||
#ifndef OPENGLES
|
||||
if (_supports_two_sided_stencil) {
|
||||
//TODO: add support for OpenGL 2.0-style glStencilFuncSeparate.
|
||||
unsigned int back_compare;
|
||||
|
|
@ -11989,6 +11998,7 @@ do_issue_stencil() {
|
|||
|
||||
_glActiveStencilFaceEXT(GL_FRONT);
|
||||
}
|
||||
#endif // OPENGLES
|
||||
|
||||
unsigned int front_compare;
|
||||
front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function);
|
||||
|
|
@ -12018,9 +12028,11 @@ do_issue_stencil() {
|
|||
}
|
||||
} else {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
#ifndef OPENGLES
|
||||
if (_supports_two_sided_stencil) {
|
||||
glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
}
|
||||
#endif // OPENGLES
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -12067,9 +12079,12 @@ do_issue_scissor() {
|
|||
if (_scissor_array.size() > 0) {
|
||||
// Scissoring is enabled on the display region.
|
||||
// Revert to the scissor state specified in the DisplayRegion.
|
||||
#ifndef OPENGLES
|
||||
if (_supports_viewport_arrays) {
|
||||
_glScissorArrayv(0, _scissor_array.size(), _scissor_array[0].get_data());
|
||||
} else {
|
||||
} else
|
||||
#endif // OPENGLES
|
||||
{
|
||||
const LVecBase4i sr = _scissor_array[0];
|
||||
glScissor(sr[0], sr[1], sr[2], sr[3]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "pnotify.h"
|
||||
|
||||
#ifndef OPENGLES
|
||||
|
||||
TypeHandle CLP(SamplerContext)::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -81,3 +83,5 @@ reset_data() {
|
|||
// re-load the sampler later.
|
||||
//glGenSamplers(1, &_index);
|
||||
}
|
||||
|
||||
#endif // OPENGLES
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef OPENGLES
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "samplerContext.h"
|
||||
#include "deletedChain.h"
|
||||
|
|
@ -56,3 +58,5 @@ public:
|
|||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#endif // OPENGLES
|
||||
|
|
|
|||
|
|
@ -412,6 +412,20 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||
s->_mat_spec.push_back(bind);
|
||||
continue;
|
||||
}
|
||||
if (noprefix == "Color") {
|
||||
Shader::ShaderMatSpec bind;
|
||||
bind._id = arg_id;
|
||||
bind._piece = Shader::SMP_row3;
|
||||
bind._func = Shader::SMF_first;
|
||||
bind._part[0] = Shader::SMO_attr_color;
|
||||
bind._arg[0] = NULL;
|
||||
bind._dep[0] = Shader::SSD_general | Shader::SSD_color;
|
||||
bind._part[1] = Shader::SMO_identity;
|
||||
bind._arg[1] = NULL;
|
||||
bind._dep[1] = Shader::SSD_NONE;
|
||||
s->_mat_spec.push_back(bind);
|
||||
continue;
|
||||
}
|
||||
if (noprefix == "ClipPlane") {
|
||||
for (int i = 0; i < param_size; ++i) {
|
||||
Shader::ShaderMatSpec bind;
|
||||
|
|
@ -821,10 +835,12 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||
param_type == GL_INT_VEC2 ||
|
||||
param_type == GL_INT_VEC3 ||
|
||||
param_type == GL_INT_VEC4 ||
|
||||
param_type == GL_UNSIGNED_INT ||
|
||||
#ifndef OPENGLES
|
||||
param_type == GL_UNSIGNED_INT_VEC2 ||
|
||||
param_type == GL_UNSIGNED_INT_VEC3 ||
|
||||
param_type == GL_UNSIGNED_INT_VEC4);
|
||||
param_type == GL_UNSIGNED_INT_VEC4 ||
|
||||
#endif
|
||||
param_type == GL_UNSIGNED_INT );
|
||||
|
||||
if (noprefix.empty()) {
|
||||
// Arbitrarily named attribute.
|
||||
|
|
@ -863,12 +879,16 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
|
|||
// Get the number of bind points.
|
||||
switch (param_type) {
|
||||
case GL_FLOAT_MAT3:
|
||||
#ifndef OPENGLES
|
||||
case GL_DOUBLE_MAT3:
|
||||
#endif
|
||||
bind._elements = 3 * param_size;
|
||||
break;
|
||||
|
||||
case GL_FLOAT_MAT4:
|
||||
#ifndef OPENGLES
|
||||
case GL_DOUBLE_MAT4:
|
||||
#endif
|
||||
bind._elements = 4 * param_size;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -283,7 +283,9 @@ void CLP(init_classes)() {
|
|||
CLP(ShaderContext)::init_type();
|
||||
#endif
|
||||
CLP(TextureContext)::init_type();
|
||||
#ifndef OPENGLES
|
||||
CLP(SamplerContext)::init_type();
|
||||
#endif
|
||||
CLP(VertexBufferContext)::init_type();
|
||||
CLP(GraphicsBuffer)::init_type();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ make(PyUnicodeObject *str) {
|
|||
}
|
||||
|
||||
string name(c_str, len);
|
||||
return InternalName::make(c_str, len);
|
||||
return InternalName::make(name);
|
||||
}
|
||||
|
||||
InternalName::PyInternTable::const_iterator it;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "pandabase.h"
|
||||
|
||||
#include "adaptiveLru.h"
|
||||
#include "simpleLru.h"
|
||||
#include "samplerState.h"
|
||||
#include "savedContext.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "namable.h"
|
||||
#include "luse.h"
|
||||
#include "numeric_types.h"
|
||||
#include "bamReader.h"
|
||||
#include "config_gobj.h"
|
||||
|
||||
class FactoryParams;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "pbitops.h"
|
||||
#include "streamReader.h"
|
||||
#include "texturePeeker.h"
|
||||
#include "convert_srgb.h"
|
||||
|
||||
#ifdef HAVE_SQUISH
|
||||
#include <squish.h>
|
||||
|
|
@ -131,46 +132,6 @@ struct DDSHeader {
|
|||
DDSCaps2 caps;
|
||||
};
|
||||
|
||||
// This table is used for converting unsigned char texture values in an sRGB
|
||||
// texture to linear RGB values, for use in mipmap generation.
|
||||
static float srgb_to_lrgbf[256] = {0.000000f, 0.000304f, 0.000607f, 0.000911f,
|
||||
0.001214f, 0.001518f, 0.001821f, 0.002125f, 0.002428f, 0.002732f, 0.003035f,
|
||||
0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, 0.005182f, 0.005605f,
|
||||
0.006049f, 0.006512f, 0.006995f, 0.007499f, 0.008023f, 0.008568f, 0.009134f,
|
||||
0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f,
|
||||
0.014444f, 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f,
|
||||
0.020289f, 0.021219f, 0.022174f, 0.023153f, 0.024158f, 0.025187f, 0.026241f,
|
||||
0.027321f, 0.028426f, 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f,
|
||||
0.035601f, 0.036889f, 0.038204f, 0.039546f, 0.040915f, 0.042311f, 0.043735f,
|
||||
0.045186f, 0.046665f, 0.048172f, 0.049707f, 0.051269f, 0.052861f, 0.054480f,
|
||||
0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, 0.064803f, 0.066626f,
|
||||
0.068478f, 0.070360f, 0.072272f, 0.074214f, 0.076185f, 0.078187f, 0.080220f,
|
||||
0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f,
|
||||
0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f,
|
||||
0.114435f, 0.116971f, 0.119538f, 0.122139f, 0.124772f, 0.127438f, 0.130136f,
|
||||
0.132868f, 0.135633f, 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f,
|
||||
0.152926f, 0.155926f, 0.158961f, 0.162029f, 0.165132f, 0.168269f, 0.171441f,
|
||||
0.174647f, 0.177888f, 0.181164f, 0.184475f, 0.187821f, 0.191202f, 0.194618f,
|
||||
0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, 0.215861f, 0.219526f,
|
||||
0.223228f, 0.226966f, 0.230740f, 0.234551f, 0.238398f, 0.242281f, 0.246201f,
|
||||
0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f, 0.274677f,
|
||||
0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f,
|
||||
0.309469f, 0.313989f, 0.318547f, 0.323143f, 0.327778f, 0.332452f, 0.337164f,
|
||||
0.341914f, 0.346704f, 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f,
|
||||
0.376262f, 0.381326f, 0.386429f, 0.391572f, 0.396755f, 0.401978f, 0.407240f,
|
||||
0.412543f, 0.417885f, 0.423268f, 0.428690f, 0.434154f, 0.439657f, 0.445201f,
|
||||
0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473531f, 0.479320f, 0.485150f,
|
||||
0.491021f, 0.496933f, 0.502886f, 0.508881f, 0.514918f, 0.520996f, 0.527115f,
|
||||
0.533276f, 0.539479f, 0.545724f, 0.552011f, 0.558340f, 0.564712f, 0.571125f,
|
||||
0.577580f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f,
|
||||
0.623960f, 0.630757f, 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f,
|
||||
0.672443f, 0.679542f, 0.686685f, 0.693872f, 0.701102f, 0.708376f, 0.715694f,
|
||||
0.723055f, 0.730461f, 0.737910f, 0.745404f, 0.752942f, 0.760525f, 0.768151f,
|
||||
0.775822f, 0.783538f, 0.791298f, 0.799103f, 0.806952f, 0.814847f, 0.822786f,
|
||||
0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, 0.871367f, 0.879622f,
|
||||
0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, 0.938686f,
|
||||
0.947307f, 0.955973f, 0.964686f, 0.973445f, 0.982251f, 0.991102f, 1.000000f};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::Constructor
|
||||
// Access: Published
|
||||
|
|
@ -6990,7 +6951,13 @@ do_filter_2d_mipmap_pages(const CData *cdata,
|
|||
// We currently only support sRGB mipmap generation for
|
||||
// unsigned byte textures, due to our use of a lookup table.
|
||||
nassertv(cdata->_component_type == T_unsigned_byte);
|
||||
filter_component = &filter_2d_unsigned_byte_srgb;
|
||||
|
||||
if (has_sse2_sRGB_encode()) {
|
||||
filter_component = &filter_2d_unsigned_byte_srgb_sse2;
|
||||
} else {
|
||||
filter_component = &filter_2d_unsigned_byte_srgb;
|
||||
}
|
||||
|
||||
// Alpha is always linear.
|
||||
filter_alpha = &filter_2d_unsigned_byte;
|
||||
|
||||
|
|
@ -7140,7 +7107,13 @@ do_filter_3d_mipmap_level(const CData *cdata,
|
|||
// We currently only support sRGB mipmap generation for
|
||||
// unsigned byte textures, due to our use of a lookup table.
|
||||
nassertv(cdata->_component_type == T_unsigned_byte);
|
||||
filter_component = &filter_3d_unsigned_byte_srgb;
|
||||
|
||||
if (has_sse2_sRGB_encode()) {
|
||||
filter_component = &filter_3d_unsigned_byte_srgb_sse2;
|
||||
} else {
|
||||
filter_component = &filter_3d_unsigned_byte_srgb;
|
||||
}
|
||||
|
||||
// Alpha is always linear.
|
||||
filter_alpha = &filter_3d_unsigned_byte;
|
||||
|
||||
|
|
@ -7385,18 +7358,32 @@ filter_2d_unsigned_byte(unsigned char *&p, const unsigned char *&q,
|
|||
void Texture::
|
||||
filter_2d_unsigned_byte_srgb(unsigned char *&p, const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size) {
|
||||
float result = (srgb_to_lrgbf[q[0]] +
|
||||
srgb_to_lrgbf[q[pixel_size]] +
|
||||
srgb_to_lrgbf[q[row_size]] +
|
||||
srgb_to_lrgbf[q[pixel_size + row_size]]) / 4.0f;
|
||||
float result = (decode_sRGB_float(q[0]) +
|
||||
decode_sRGB_float(q[pixel_size]) +
|
||||
decode_sRGB_float(q[row_size]) +
|
||||
decode_sRGB_float(q[pixel_size + row_size]));
|
||||
|
||||
// This is based on the formula out of the EXT_texture_sRGB
|
||||
// specification, except the factors are multiplied with 255.0f.
|
||||
if (result < 0.0031308f) {
|
||||
*p = (unsigned char)(result * 3294.6f);
|
||||
} else {
|
||||
*p = (unsigned char)(269.025f * powf(result, 0.41666f) - 14.025f);
|
||||
}
|
||||
*p = encode_sRGB_uchar(result * 0.25f);
|
||||
++p;
|
||||
++q;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::filter_2d_unsigned_byte_srgb_sse2
|
||||
// Access: Public, Static
|
||||
// Description: Averages a 2x2 block of pixel components into a
|
||||
// single pixel component, for producing the next mipmap
|
||||
// level. Increments p and q to the next component.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
filter_2d_unsigned_byte_srgb_sse2(unsigned char *&p, const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size) {
|
||||
float result = (decode_sRGB_float(q[0]) +
|
||||
decode_sRGB_float(q[pixel_size]) +
|
||||
decode_sRGB_float(q[row_size]) +
|
||||
decode_sRGB_float(q[pixel_size + row_size]));
|
||||
|
||||
*p = encode_sRGB_uchar_sse2(result * 0.25f);
|
||||
++p;
|
||||
++q;
|
||||
}
|
||||
|
|
@ -7470,22 +7457,40 @@ filter_3d_unsigned_byte(unsigned char *&p, const unsigned char *&q,
|
|||
void Texture::
|
||||
filter_3d_unsigned_byte_srgb(unsigned char *&p, const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size, size_t page_size) {
|
||||
float result = (srgb_to_lrgbf[q[0]] +
|
||||
srgb_to_lrgbf[q[pixel_size]] +
|
||||
srgb_to_lrgbf[q[row_size]] +
|
||||
srgb_to_lrgbf[q[pixel_size + row_size]] +
|
||||
srgb_to_lrgbf[q[page_size]] +
|
||||
srgb_to_lrgbf[q[pixel_size + page_size]] +
|
||||
srgb_to_lrgbf[q[row_size + page_size]] +
|
||||
srgb_to_lrgbf[q[pixel_size + row_size + page_size]]) / 8.0f;
|
||||
float result = (decode_sRGB_float(q[0]) +
|
||||
decode_sRGB_float(q[pixel_size]) +
|
||||
decode_sRGB_float(q[row_size]) +
|
||||
decode_sRGB_float(q[pixel_size + row_size]) +
|
||||
decode_sRGB_float(q[page_size]) +
|
||||
decode_sRGB_float(q[pixel_size + page_size]) +
|
||||
decode_sRGB_float(q[row_size + page_size]) +
|
||||
decode_sRGB_float(q[pixel_size + row_size + page_size]));
|
||||
|
||||
// This is based on the formula out of the EXT_texture_sRGB
|
||||
// specification, except the factors are multiplied with 255.0f.
|
||||
if (result < 0.0031308f) {
|
||||
*p = (unsigned char)(result * 3294.6f);
|
||||
} else {
|
||||
*p = (unsigned char)(269.025f * powf(result, 0.41666f) - 14.025f);
|
||||
}
|
||||
*p = encode_sRGB_uchar(result * 0.125f);
|
||||
++p;
|
||||
++q;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::filter_3d_unsigned_byte_srgb_sse2
|
||||
// Access: Public, Static
|
||||
// Description: Averages a 2x2x2 block of pixel components into a
|
||||
// single pixel component, for producing the next mipmap
|
||||
// level. Increments p and q to the next component.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
filter_3d_unsigned_byte_srgb_sse2(unsigned char *&p, const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size, size_t page_size) {
|
||||
float result = (decode_sRGB_float(q[0]) +
|
||||
decode_sRGB_float(q[pixel_size]) +
|
||||
decode_sRGB_float(q[row_size]) +
|
||||
decode_sRGB_float(q[pixel_size + row_size]) +
|
||||
decode_sRGB_float(q[page_size]) +
|
||||
decode_sRGB_float(q[pixel_size + page_size]) +
|
||||
decode_sRGB_float(q[row_size + page_size]) +
|
||||
decode_sRGB_float(q[pixel_size + row_size + page_size]));
|
||||
|
||||
*p = encode_sRGB_uchar_sse2(result * 0.125f);
|
||||
++p;
|
||||
++q;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -749,6 +749,9 @@ private:
|
|||
static void filter_2d_unsigned_byte_srgb(unsigned char *&p,
|
||||
const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size);
|
||||
static void filter_2d_unsigned_byte_srgb_sse2(unsigned char *&p,
|
||||
const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size);
|
||||
static void filter_2d_unsigned_short(unsigned char *&p,
|
||||
const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size);
|
||||
|
|
@ -763,6 +766,10 @@ private:
|
|||
const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size,
|
||||
size_t page_size);
|
||||
static void filter_3d_unsigned_byte_srgb_sse2(unsigned char *&p,
|
||||
const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size,
|
||||
size_t page_size);
|
||||
static void filter_3d_unsigned_short(unsigned char *&p,
|
||||
const unsigned char *&q,
|
||||
size_t pixel_size, size_t row_size,
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ bool FLOATNAME(LMatrix3)::
|
|||
almost_equal(const FLOATNAME(LMatrix3) &other, FLOATTYPE threshold) const {
|
||||
TAU_PROFILE("bool LMatrix3::almost_equal(const LMatrix3 &, FLOATTYPE)", " ", TAU_USER);
|
||||
#ifdef HAVE_EIGEN
|
||||
return ((_m - other._m).cwiseAbs().maxCoeff() < NEARLY_ZERO(FLOATTYPE));
|
||||
return ((_m - other._m).cwiseAbs().maxCoeff() < threshold);
|
||||
#else
|
||||
return (IS_THRESHOLD_EQUAL((*this)(0, 0), other(0, 0), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(0, 1), other(0, 1), threshold) &&
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ bool FLOATNAME(LMatrix4)::
|
|||
almost_equal(const FLOATNAME(LMatrix4) &other, FLOATTYPE threshold) const {
|
||||
TAU_PROFILE("bool LMatrix4::almost_equal(const LMatrix4 &, FLOATTYPE)", " ", TAU_USER);
|
||||
#ifdef HAVE_EIGEN
|
||||
return ((_m - other._m).cwiseAbs().maxCoeff() < NEARLY_ZERO(FLOATTYPE));
|
||||
return ((_m - other._m).cwiseAbs().maxCoeff() < threshold);
|
||||
#else
|
||||
return (IS_THRESHOLD_EQUAL((*this)(0, 0), other(0, 0), threshold) &&
|
||||
IS_THRESHOLD_EQUAL((*this)(0, 1), other(0, 1), threshold) &&
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
// Filename: pta_LMatrix3_ext.h
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PTA_LMATRIX3_EXT_H
|
||||
#define PTA_LMATRIX3_EXT_H
|
||||
|
||||
#include "pointerToArray_ext.h"
|
||||
#include "pta_LMatrix3.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(CPPPARSER)
|
||||
template class EXPORT_THIS Extension<PTA_LMatrix3f>;
|
||||
template class EXPORT_THIS Extension<PTA_LMatrix3d>;
|
||||
template class EXPORT_THIS Extension<CPTA_LMatrix3f>;
|
||||
template class EXPORT_THIS Extension<CPTA_LMatrix3d>;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Filename: pta_LMatrix4_ext.h
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PTA_LMATRIX4_EXT_H
|
||||
#define PTA_LMATRIX4_EXT_H
|
||||
|
||||
#include "pointerToArray_ext.h"
|
||||
#include "pta_LMatrix4.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(CPPPARSER)
|
||||
template class EXPORT_THIS Extension<PTA_LMatrix4f>;
|
||||
template class EXPORT_THIS Extension<PTA_LMatrix4d>;
|
||||
template class EXPORT_THIS Extension<CPTA_LMatrix4f>;
|
||||
template class EXPORT_THIS Extension<CPTA_LMatrix4d>;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Filename: pta_LVecBase2_ext.h
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PTA_LVECBASE2_EXT_H
|
||||
#define PTA_LVECBASE2_EXT_H
|
||||
|
||||
#include "pointerToArray_ext.h"
|
||||
#include "pta_LVecBase2.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(CPPPARSER)
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase2f>;
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase2d>;
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase2i>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase2f>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase2d>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase2i>;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Filename: pta_LVecBase3_ext.h
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PTA_LVECBASE3_EXT_H
|
||||
#define PTA_LVECBASE3_EXT_H
|
||||
|
||||
#include "pointerToArray_ext.h"
|
||||
#include "pta_LVecBase3.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(CPPPARSER)
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase3f>;
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase3d>;
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase3i>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase3f>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase3d>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase3i>;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Filename: pta_LVecBase4_ext.h
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PTA_LVECBASE4_EXT_H
|
||||
#define PTA_LVECBASE4_EXT_H
|
||||
|
||||
#include "pointerToArray_ext.h"
|
||||
#include "pta_LVecBase4.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(CPPPARSER)
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase4f>;
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase4d>;
|
||||
template class EXPORT_THIS Extension<PTA_LVecBase4i>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase4f>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase4d>;
|
||||
template class EXPORT_THIS Extension<CPTA_LVecBase4i>;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -79,6 +79,7 @@
|
|||
occluderNode.I occluderNode.h \
|
||||
pandaNode.I pandaNode.h \
|
||||
pandaNodeChain.I pandaNodeChain.h \
|
||||
paramNodePath.I paramNodePath.h \
|
||||
planeNode.I planeNode.h \
|
||||
polylightEffect.I polylightEffect.h \
|
||||
polylightNode.I polylightNode.h \
|
||||
|
|
@ -184,6 +185,7 @@
|
|||
occluderNode.cxx \
|
||||
pandaNode.cxx \
|
||||
pandaNodeChain.cxx \
|
||||
paramNodePath.cxx \
|
||||
planeNode.cxx \
|
||||
polylightEffect.cxx \
|
||||
polylightNode.cxx \
|
||||
|
|
@ -286,6 +288,7 @@
|
|||
pandaNode.I pandaNode.h \
|
||||
pandaNode_ext.h pandaNode_ext.cxx \
|
||||
pandaNodeChain.I pandaNodeChain.h \
|
||||
paramNodePath.I paramNodePath.h \
|
||||
planeNode.I planeNode.h \
|
||||
polylightEffect.I polylightEffect.h \
|
||||
polylightNode.I polylightNode.h \
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
#include "nodePath.h"
|
||||
#include "nodePathComponent.h"
|
||||
#include "pandaNode.h"
|
||||
#include "paramNodePath.h"
|
||||
#include "planeNode.h"
|
||||
#include "polylightEffect.h"
|
||||
#include "polylightNode.h"
|
||||
|
|
@ -436,6 +437,7 @@ init_libpgraph() {
|
|||
NodePathComponent::init_type();
|
||||
PandaNode::init_type();
|
||||
PandaNodePipelineReader::init_type();
|
||||
ParamNodePath::init_type();
|
||||
PlaneNode::init_type();
|
||||
PolylightNode::init_type();
|
||||
PolylightEffect::init_type();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "cullBinEnums.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pvector.h"
|
||||
#include "epvector.h"
|
||||
#include "pmap.h"
|
||||
#include "vector_int.h"
|
||||
#include "pStatCollector.h"
|
||||
|
|
|
|||
|
|
@ -343,11 +343,11 @@ try_load_file(const Filename &pathname, const LoaderOptions &options,
|
|||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (loader_cat.is_debug()) {
|
||||
loader_cat.debug()
|
||||
<< "Model " << pathname << " not found in cache.\n";
|
||||
if (loader_cat.is_debug()) {
|
||||
loader_cat.debug()
|
||||
<< "Model " << pathname << " not found in cache.\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool cache_only = (options.get_flags() & LoaderOptions::LF_cache_only) != 0;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@
|
|||
#include "pta_LVecBase3.h"
|
||||
#include "pta_LVecBase2.h"
|
||||
#include "stl_compares.h"
|
||||
#include "shaderInput.h"
|
||||
#include "textureCollection.h"
|
||||
#include "textureStageCollection.h"
|
||||
|
||||
class NodePathCollection;
|
||||
class FindApproxPath;
|
||||
|
|
@ -1008,9 +1011,6 @@ private:
|
|||
|
||||
INLINE ostream &operator << (ostream &out, const NodePath &node_path);
|
||||
|
||||
// We have to put this down here, to work around a circular include.
|
||||
#include "shaderInput.h"
|
||||
|
||||
#include "nodePath.I"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "occluderNode.cxx"
|
||||
#include "pandaNode.cxx"
|
||||
#include "pandaNodeChain.cxx"
|
||||
#include "paramNodePath.cxx"
|
||||
#include "planeNode.cxx"
|
||||
#include "polylightEffect.cxx"
|
||||
#include "polylightNode.cxx"
|
||||
|
|
|
|||
|
|
@ -721,13 +721,15 @@ get_user_bounds(int pipeline_stage, Thread *current_thread) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PandaNode::
|
||||
mark_bounds_stale(int pipeline_stage, Thread *current_thread) const {
|
||||
// It's important that we don't hold the lock during the call to
|
||||
// force_bounds_stale().
|
||||
// We check whether it is already marked stale. If so, we don't have
|
||||
// to make the call to force_bounds_stale().
|
||||
bool is_stale_bounds;
|
||||
{
|
||||
CDStageReader cdata(_cycler, pipeline_stage, current_thread);
|
||||
is_stale_bounds = (cdata->_last_bounds_update != cdata->_next_update);
|
||||
is_stale_bounds = (cdata->_last_update != cdata->_next_update);
|
||||
}
|
||||
// It's important that we don't hold the lock during the call to
|
||||
// force_bounds_stale().
|
||||
if (!is_stale_bounds) {
|
||||
((PandaNode *)this)->force_bounds_stale(pipeline_stage, current_thread);
|
||||
}
|
||||
|
|
@ -1833,7 +1835,7 @@ get_off_clip_planes() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(BoundingVolume) PandaNodePipelineReader::
|
||||
get_bounds() const {
|
||||
nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_external_bounds);
|
||||
nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_external_bounds);
|
||||
return _cdata->_external_bounds;
|
||||
}
|
||||
|
||||
|
|
@ -1852,7 +1854,7 @@ get_bounds() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int PandaNodePipelineReader::
|
||||
get_nested_vertices() const {
|
||||
nassertr(_cdata->_last_update == _cdata->_next_update, _cdata->_nested_vertices);
|
||||
nassertr(_cdata->_last_bounds_update == _cdata->_next_update, _cdata->_nested_vertices);
|
||||
return _cdata->_nested_vertices;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
// Filename: paramNodePath.I
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::Constructor
|
||||
// Access: Published
|
||||
// Description: Creates a new ParamNodePath storing the given
|
||||
// node path object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ParamNodePath::
|
||||
ParamNodePath(const NodePath &node_path) :
|
||||
_node_path(node_path)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::Move Constructor
|
||||
// Access: Published
|
||||
// Description: Creates a new ParamNodePath storing the given
|
||||
// node path object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ParamNodePath::
|
||||
ParamNodePath(NodePath &&node_path) NOEXCEPT :
|
||||
_node_path(move(node_path))
|
||||
{
|
||||
}
|
||||
#endif // USE_MOVE_SEMANTICS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::get_value_type
|
||||
// Access: Published, Virtual
|
||||
// Description: Returns NodePath::get_class_type().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE TypeHandle ParamNodePath::
|
||||
get_value_type() const {
|
||||
return NodePath::get_class_type();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::get_value
|
||||
// Access: Published
|
||||
// Description: Retrieves the NodePath stored in the parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const NodePath &ParamNodePath::
|
||||
get_value() const {
|
||||
return _node_path;
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
// Filename: paramNodePath.cxx
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "paramNodePath.h"
|
||||
#include "dcast.h"
|
||||
#include "pandaNode.h"
|
||||
|
||||
TypeHandle ParamNodePath::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::output
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParamNodePath::
|
||||
output(ostream &out) const {
|
||||
out << "node path " << _node_path;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// ParamValue.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParamNodePath::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParamNodePath::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
ParamValueBase::write_datagram(manager, dg);
|
||||
|
||||
// We can't store a NodePath, so we store a pointer to the
|
||||
// underlying node, and pray that there is an unambiguous path
|
||||
// from the root to it.
|
||||
if (_node_path.is_empty()) {
|
||||
manager->write_pointer(dg, NULL);
|
||||
} else {
|
||||
manager->write_pointer(dg, _node_path.node());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ParamNodePath::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = ParamValueBase::complete_pointers(p_list, manager);
|
||||
_node_path = NodePath(DCAST(PandaNode, p_list[pi++]));
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type ParamValue is encountered
|
||||
// in the Bam file. It should create the ParamValue
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *ParamNodePath::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
ParamNodePath *param = new ParamNodePath;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
param->fillin(scan, manager);
|
||||
|
||||
return param;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ParamNodePath::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new ParamValue.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ParamNodePath::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
ParamValueBase::fillin(scan, manager);
|
||||
manager->read_pointer(scan);
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
// Filename: paramNodePath.h
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 PARAMNODEPATH_H
|
||||
#define PARAMNODEPATH_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "paramValue.h"
|
||||
#include "nodePath.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ParamNodePath
|
||||
// Description : A class object for storing a NodePath as a parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA_GOBJ ParamNodePath : public ParamValueBase {
|
||||
protected:
|
||||
INLINE ParamNodePath() {};
|
||||
|
||||
PUBLISHED:
|
||||
INLINE ParamNodePath(const NodePath &node_path);
|
||||
|
||||
#ifdef USE_MOVE_SEMANTICS
|
||||
INLINE ParamNodePath(NodePath &&node_path) NOEXCEPT;
|
||||
#endif
|
||||
|
||||
INLINE virtual TypeHandle get_value_type() const;
|
||||
INLINE const NodePath &get_value() const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
private:
|
||||
NodePath _node_path;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist,
|
||||
BamReader *manager);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
ParamValueBase::init_type();
|
||||
register_type(_type_handle, "ParamNodePath",
|
||||
ParamValueBase::get_class_type());
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "paramNodePath.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -85,11 +85,10 @@ disable(){
|
|||
// Description: Set this light's position
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void PolylightNode::
|
||||
set_pos(const LVecBase3 &position){
|
||||
set_pos(const LPoint3 &position) {
|
||||
_position = position;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PolylightNode::set_pos
|
||||
// Access: Published
|
||||
|
|
@ -107,7 +106,7 @@ set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z){
|
|||
// Access: Published
|
||||
// Description: Returns position as a LPoint3
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LVecBase3 PolylightNode::
|
||||
INLINE LPoint3 PolylightNode::
|
||||
get_pos() const {
|
||||
return _position;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,30 @@ make_copy() const {
|
|||
return new PolylightNode(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PolylightNode::xform
|
||||
// Access: Public, Virtual
|
||||
// Description: Transforms the contents of this node by the indicated
|
||||
// matrix, if it means anything to do so. For most
|
||||
// kinds of nodes, this does nothing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PolylightNode::
|
||||
xform(const LMatrix4 &mat) {
|
||||
nassertv(!mat.is_nan());
|
||||
|
||||
if (mat.almost_equal(LMatrix4::ident_mat())) {
|
||||
return;
|
||||
}
|
||||
|
||||
_position = _position * mat;
|
||||
|
||||
// This is a little cheesy and fails miserably in the presence of a
|
||||
// non-uniform scale.
|
||||
LVector3 radius_v = LVector3(_radius, 0.0f, 0.0f) * mat;
|
||||
_radius = length(radius_v);
|
||||
mark_internal_bounds_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PolylightNode::Constructor
|
||||
// Access: Public
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ PUBLISHED:
|
|||
PolylightNode(const string &name);
|
||||
INLINE void enable();
|
||||
INLINE void disable();
|
||||
INLINE void set_pos(const LVecBase3 &position);
|
||||
INLINE void set_pos(const LPoint3 &position);
|
||||
INLINE void set_pos(PN_stdfloat x,PN_stdfloat y, PN_stdfloat z);
|
||||
INLINE LVecBase3 get_pos() const;
|
||||
INLINE LPoint3 get_pos() const;
|
||||
INLINE void set_color(const LColor &color);
|
||||
INLINE void set_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b);
|
||||
INLINE LColor get_color() const;
|
||||
|
|
@ -100,11 +100,11 @@ PUBLISHED:
|
|||
public:
|
||||
LColor flicker() const;
|
||||
virtual PandaNode *make_copy() const;
|
||||
virtual void xform(const LMatrix4 &mat);
|
||||
|
||||
|
||||
private:
|
||||
bool _enabled;
|
||||
LVecBase3 _position;
|
||||
LPoint3 _position;
|
||||
LColor _color;
|
||||
PN_stdfloat _radius;
|
||||
Attenuation_Type _attenuation_type;
|
||||
|
|
|
|||
|
|
@ -119,23 +119,6 @@ ShaderInput(CPT_InternalName name, ParamValueBase *param, int priority) :
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderInput::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ShaderInput::
|
||||
ShaderInput(CPT_InternalName name, const NodePath &np, int priority) :
|
||||
_name(MOVE(name)),
|
||||
_type(M_nodepath),
|
||||
_priority(priority),
|
||||
_stored_nodepath(np),
|
||||
_bind_layer(0),
|
||||
_bind_level(0),
|
||||
_access(A_read)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderInput::Constructor
|
||||
// Access: Published
|
||||
|
|
@ -678,16 +661,6 @@ get_texture() const {
|
|||
return DCAST(Texture, _value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderInput::get_nodepath
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const NodePath &ShaderInput::
|
||||
get_nodepath() const {
|
||||
return _stored_nodepath;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderInput::get_vector
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "shaderInput.h"
|
||||
#include "paramNodePath.h"
|
||||
|
||||
TypeHandle ShaderInput::_type_handle;
|
||||
|
||||
|
|
@ -32,13 +33,40 @@ get_blank() {
|
|||
return blank;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderInput::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ShaderInput::
|
||||
ShaderInput(CPT_InternalName name, const NodePath &np, int priority) :
|
||||
_name(MOVE(name)),
|
||||
_type(M_nodepath),
|
||||
_priority(priority),
|
||||
_value(new ParamNodePath(np)),
|
||||
_bind_layer(0),
|
||||
_bind_level(0),
|
||||
_access(A_read)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderInput::get_nodepath
|
||||
// Access: Published
|
||||
// Description: Warning: no error checking is done. This *will*
|
||||
// crash if get_value_type() is not M_nodepath.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const NodePath &ShaderInput::
|
||||
get_nodepath() const {
|
||||
return DCAST(ParamNodePath, _value)->get_value();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderInput::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ShaderInput::
|
||||
register_with_read_factory() {
|
||||
// IMPLEMENT ME
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "nodePath.h"
|
||||
#include "internalName.h"
|
||||
#include "paramValue.h"
|
||||
#include "pta_float.h"
|
||||
|
|
@ -53,7 +52,6 @@ PUBLISHED:
|
|||
|
||||
static const ShaderInput *get_blank();
|
||||
INLINE ShaderInput(CPT_InternalName name, int priority=0);
|
||||
INLINE ShaderInput(CPT_InternalName name, const NodePath &np, int priority=0);
|
||||
INLINE ShaderInput(CPT_InternalName name, Texture *tex, int priority=0);
|
||||
INLINE ShaderInput(CPT_InternalName name, Texture *tex, const SamplerState &sampler, int priority=0);
|
||||
INLINE ShaderInput(CPT_InternalName name, Texture *tex, bool read, bool write, int z=-1, int n=0, int priority=0);
|
||||
|
|
@ -90,6 +88,8 @@ PUBLISHED:
|
|||
INLINE ShaderInput(CPT_InternalName name, const LVecBase3i &vec, int priority=0);
|
||||
INLINE ShaderInput(CPT_InternalName name, const LVecBase2i &vec, int priority=0);
|
||||
|
||||
ShaderInput(CPT_InternalName name, const NodePath &np, int priority=0);
|
||||
|
||||
enum ShaderInputType {
|
||||
M_invalid = 0,
|
||||
M_texture,
|
||||
|
|
@ -105,11 +105,12 @@ PUBLISHED:
|
|||
INLINE int get_value_type() const;
|
||||
INLINE int get_priority() const;
|
||||
INLINE Texture *get_texture() const;
|
||||
INLINE const NodePath &get_nodepath() const;
|
||||
INLINE const LVecBase4 &get_vector() const;
|
||||
INLINE const Shader::ShaderPtrData &get_ptr() const;
|
||||
INLINE const SamplerState &get_sampler() const;
|
||||
|
||||
const NodePath &get_nodepath() const;
|
||||
|
||||
public:
|
||||
INLINE ParamValueBase *get_param() const;
|
||||
|
||||
|
|
@ -118,7 +119,6 @@ public:
|
|||
private:
|
||||
SamplerState _sampler;
|
||||
LVecBase4 _stored_vector;
|
||||
NodePath _stored_nodepath;
|
||||
Shader::ShaderPtrData _stored_ptr;
|
||||
CPT_InternalName _name;
|
||||
PT(TypedWritableReferenceCount) _value;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "virtualFileSystem.h"
|
||||
#include "loader.h"
|
||||
#include "shader.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
ShaderPool *ShaderPool::_global_ptr = (ShaderPool *)NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,175 @@
|
|||
// Filename: convert_srgb.I
|
||||
// Created by: rdb (29Oct14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: decode_sRGB_float
|
||||
// Description: Decodes the sRGB-encoded unsigned char value to
|
||||
// a linearized float in the range 0-1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CONSTEXPR float decode_sRGB_float(unsigned char val) {
|
||||
return to_linear_float_table[val];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encode_sRGB_float
|
||||
// Description: Decodes the sRGB-encoded floating-point value in
|
||||
// the range 0-1 to a linearized float in the range
|
||||
// 0-1. Inputs outside this range produce invalid
|
||||
// results.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float decode_sRGB_float(float val) {
|
||||
return (val <= 0.04045f)
|
||||
? (val * (1.f / 12.92f))
|
||||
: cpow((val + 0.055f) * (1.f / 1.055f), 2.4f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: decode_sRGB_uchar
|
||||
// Description: Decodes the sRGB-encoded unsigned char value to
|
||||
// a linearized unsigned char value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CONSTEXPR unsigned char decode_sRGB_uchar(unsigned char val) {
|
||||
return to_linear_uchar_table[val];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: decode_sRGB_uchar
|
||||
// Description: Decodes the sRGB-encoded floating-point value in
|
||||
// the range 0-1 to a linearized unsigned char value.
|
||||
// Inputs outside this range are clamped.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned char decode_sRGB_uchar(float val) {
|
||||
return (val <= 0.04045f)
|
||||
? (unsigned char)(max(0.f, val) * (255.f / 12.92f) + 0.5f)
|
||||
: (unsigned char)(cpow((min(val, 1.f) + 0.055f) * (1.f / 1.055f), 2.4f) * 255.f + 0.5f);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encode_sRGB_float
|
||||
// Description: Encodes the linearized unsigned char value to an
|
||||
// sRGB-encoded floating-point value in ther range 0-1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float
|
||||
encode_sRGB_float(unsigned char val) {
|
||||
// This seems like a very unlikely use case, so I didn't bother
|
||||
// making a look-up table for this.
|
||||
return (val == 0) ? 0
|
||||
: (1.055f * cpow((float)val * (1.f / 255.f), 0.41666f) - 0.055);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encode_sRGB_float
|
||||
// Description: Encodes the linearized floating-point value in the
|
||||
// range 0-1 to an sRGB-encoded float in the range
|
||||
// 0-1. Inputs outside this range produce invalid
|
||||
// results.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float
|
||||
encode_sRGB_float(float val) {
|
||||
return (val < 0.0031308f)
|
||||
? (val * 12.92f)
|
||||
: (1.055f * cpow(val, 0.41666f) - 0.055);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encode_sRGB_uchar
|
||||
// Description: Encodes the linearized unsigned char value to an
|
||||
// sRGB-encoded unsigned char value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CONSTEXPR unsigned char
|
||||
encode_sRGB_uchar(unsigned char val) {
|
||||
return to_srgb8_table[val];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encode_sRGB_uchar
|
||||
// Description: Encodes the linearized floating-point value in the
|
||||
// range 0-1 to an sRGB-encoded unsigned char value.
|
||||
// Inputs outside this range are clamped.
|
||||
//
|
||||
// When SSE2 support is known at compile time, this
|
||||
// automatically uses an optimized version. Otherwise,
|
||||
// it does not attempt runtime CPU detection. If you
|
||||
// know that SSE2 is supported (ie. if the function
|
||||
// has_sse2_sRGB_encode() returns true) you should
|
||||
// call encode_sRGB_uchar_sse2 instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned char
|
||||
encode_sRGB_uchar(float val) {
|
||||
#if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
|
||||
// Use a highly optimized approximation that has more than enough
|
||||
// accuracy for an unsigned char.
|
||||
return encode_sRGB_uchar_sse2(val);
|
||||
#else
|
||||
return (val < 0.0031308f)
|
||||
? (unsigned char) (max(0.f, val) * 3294.6f + 0.5f)
|
||||
: (unsigned char) (269.025f * cpow(min(val, 1.f), 0.41666f) - 13.525f);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encode_sRGB_uchar
|
||||
// Description: Encodes the linearized floating-point color value
|
||||
// an sRGB-encoded xel in the range 0-255.
|
||||
//
|
||||
// When SSE2 support is known at compile time, this
|
||||
// automatically uses an optimized version. Otherwise,
|
||||
// it does not attempt runtime CPU detection. If you
|
||||
// know that SSE2 is supported (ie. if the function
|
||||
// has_sse2_sRGB_encode() returns true) you should
|
||||
// call encode_sRGB_uchar_sse2 instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void
|
||||
encode_sRGB_uchar(const LColorf &color, xel &into) {
|
||||
#if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
|
||||
// SSE2 support compiled-in; we're guaranteed to have it.
|
||||
encode_sRGB_uchar_sse2(color, into);
|
||||
#else
|
||||
// Boring, slow, non-SSE2 version.
|
||||
PPM_ASSIGN(into,
|
||||
encode_sRGB_uchar(color[0]),
|
||||
encode_sRGB_uchar(color[1]),
|
||||
encode_sRGB_uchar(color[2]));
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: encode_sRGB_uchar
|
||||
// Description: Encodes the linearized floating-point color value
|
||||
// an sRGB-encoded xel and alpha in the range 0-255.
|
||||
// The alpha value is not sRGB-encoded.
|
||||
//
|
||||
// When SSE2 support is known at compile time, this
|
||||
// automatically uses an optimized version. Otherwise,
|
||||
// it does not attempt runtime CPU detection. If you
|
||||
// know that SSE2 is supported (ie. if the function
|
||||
// has_sse2_sRGB_encode() returns true) you should
|
||||
// call encode_sRGB_uchar_sse2 instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void
|
||||
encode_sRGB_uchar(const LColorf &color, xel &into, xelval &into_alpha) {
|
||||
#if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
|
||||
// SSE2 support compiled-in; we're guaranteed to have it.
|
||||
encode_sRGB_uchar_sse2(color, into, into_alpha);
|
||||
#else
|
||||
// Boring, slow, non-SSE2 version.
|
||||
PPM_ASSIGN(into,
|
||||
encode_sRGB_uchar(color[0]),
|
||||
encode_sRGB_uchar(color[1]),
|
||||
encode_sRGB_uchar(color[2]));
|
||||
|
||||
into_alpha = (xelval) (color[3] * 255.f + 0.5f);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
// Filename: convert_srgb.cxx
|
||||
// Created by: rdb (13Nov14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "convert_srgb.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// Lookup tables for converting from unsigned char formats.
|
||||
ALIGN_64BYTE const
|
||||
unsigned char to_srgb8_table[256] = { 0x00, 0x0d, 0x16, 0x1c, 0x22, 0x26, 0x2a,
|
||||
0x2e, 0x32, 0x35, 0x38, 0x3b, 0x3d, 0x40, 0x42, 0x45, 0x47, 0x49, 0x4b, 0x4d,
|
||||
0x4f, 0x51, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5d, 0x5f, 0x60, 0x62, 0x63,
|
||||
0x65, 0x66, 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x70, 0x71, 0x72, 0x73, 0x75,
|
||||
0x76, 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
|
||||
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
|
||||
0x91, 0x92, 0x93, 0x94, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b,
|
||||
0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6,
|
||||
0xa7, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xaf, 0xaf,
|
||||
0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb7, 0xb8, 0xb9,
|
||||
0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbd, 0xbd, 0xbe, 0xbe, 0xbf, 0xc0, 0xc0, 0xc1,
|
||||
0xc2, 0xc2, 0xc3, 0xc4, 0xc4, 0xc5, 0xc5, 0xc6, 0xc7, 0xc7, 0xc8, 0xc8, 0xc9,
|
||||
0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf, 0xd0, 0xd0, 0xd1,
|
||||
0xd1, 0xd2, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd5, 0xd6, 0xd6, 0xd7, 0xd7, 0xd8,
|
||||
0xd8, 0xd9, 0xda, 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xde, 0xde, 0xdf,
|
||||
0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe4, 0xe4, 0xe5, 0xe5, 0xe6,
|
||||
0xe6, 0xe7, 0xe7, 0xe8, 0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xeb, 0xec, 0xec,
|
||||
0xed, 0xed, 0xee, 0xee, 0xee, 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2, 0xf2,
|
||||
0xf3, 0xf3, 0xf4, 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8, 0xf8,
|
||||
0xf9, 0xf9, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe,
|
||||
0xff, 0xff};
|
||||
|
||||
ALIGN_64BYTE const
|
||||
unsigned char to_linear_uchar_table[256] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x07,
|
||||
0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0b,
|
||||
0x0b, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10,
|
||||
0x11, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x16, 0x16, 0x17,
|
||||
0x17, 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e,
|
||||
0x1f, 0x20, 0x20, 0x21, 0x22, 0x23, 0x23, 0x24, 0x25, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
|
||||
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4c, 0x4d,
|
||||
0x4e, 0x4f, 0x50, 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5a, 0x5b, 0x5c,
|
||||
0x5d, 0x5f, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6b, 0x6c, 0x6d,
|
||||
0x6f, 0x70, 0x72, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7a, 0x7c, 0x7d, 0x7f, 0x80,
|
||||
0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x92, 0x93, 0x95,
|
||||
0x97, 0x98, 0x9a, 0x9c, 0x9d, 0x9f, 0xa1, 0xa3, 0xa4, 0xa6, 0xa8, 0xaa, 0xab,
|
||||
0xad, 0xaf, 0xb1, 0xb3, 0xb5, 0xb7, 0xb8, 0xba, 0xbc, 0xbe, 0xc0, 0xc2, 0xc4,
|
||||
0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
|
||||
0xe0, 0xe2, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, 0xef, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa,
|
||||
0xfd, 0xff};
|
||||
|
||||
ALIGN_64BYTE
|
||||
const float to_linear_float_table[256] = { 0, 0.000304f, 0.000607f, 0.000911f,
|
||||
0.001214f, 0.001518f, 0.001821f, 0.002125f, 0.002428f, 0.002732f, 0.003035f,
|
||||
0.003347f, 0.003677f, 0.004025f, 0.004391f, 0.004777f, 0.005182f, 0.005605f,
|
||||
0.006049f, 0.006512f, 0.006995f, 0.007499f, 0.008023f, 0.008568f, 0.009134f,
|
||||
0.009721f, 0.010330f, 0.010960f, 0.011612f, 0.012286f, 0.012983f, 0.013702f,
|
||||
0.014444f, 0.015209f, 0.015996f, 0.016807f, 0.017642f, 0.018500f, 0.019382f,
|
||||
0.020289f, 0.021219f, 0.022174f, 0.023153f, 0.024158f, 0.025187f, 0.026241f,
|
||||
0.027321f, 0.028426f, 0.029557f, 0.030713f, 0.031896f, 0.033105f, 0.034340f,
|
||||
0.035601f, 0.036889f, 0.038204f, 0.039546f, 0.040915f, 0.042311f, 0.043735f,
|
||||
0.045186f, 0.046665f, 0.048172f, 0.049707f, 0.051269f, 0.052861f, 0.054480f,
|
||||
0.056128f, 0.057805f, 0.059511f, 0.061246f, 0.063010f, 0.064803f, 0.066626f,
|
||||
0.068478f, 0.070360f, 0.072272f, 0.074214f, 0.076185f, 0.078187f, 0.080220f,
|
||||
0.082283f, 0.084376f, 0.086500f, 0.088656f, 0.090842f, 0.093059f, 0.095307f,
|
||||
0.097587f, 0.099899f, 0.102242f, 0.104616f, 0.107023f, 0.109462f, 0.111932f,
|
||||
0.114435f, 0.116971f, 0.119538f, 0.122139f, 0.124772f, 0.127438f, 0.130136f,
|
||||
0.132868f, 0.135633f, 0.138432f, 0.141263f, 0.144128f, 0.147027f, 0.149960f,
|
||||
0.152926f, 0.155926f, 0.158961f, 0.162029f, 0.165132f, 0.168269f, 0.171441f,
|
||||
0.174647f, 0.177888f, 0.181164f, 0.184475f, 0.187821f, 0.191202f, 0.194618f,
|
||||
0.198069f, 0.201556f, 0.205079f, 0.208637f, 0.212231f, 0.215861f, 0.219526f,
|
||||
0.223228f, 0.226966f, 0.230740f, 0.234551f, 0.238398f, 0.242281f, 0.246201f,
|
||||
0.250158f, 0.254152f, 0.258183f, 0.262251f, 0.266356f, 0.270498f, 0.274677f,
|
||||
0.278894f, 0.283149f, 0.287441f, 0.291771f, 0.296138f, 0.300544f, 0.304987f,
|
||||
0.309469f, 0.313989f, 0.318547f, 0.323143f, 0.327778f, 0.332452f, 0.337164f,
|
||||
0.341914f, 0.346704f, 0.351533f, 0.356400f, 0.361307f, 0.366253f, 0.371238f,
|
||||
0.376262f, 0.381326f, 0.386429f, 0.391572f, 0.396755f, 0.401978f, 0.407240f,
|
||||
0.412543f, 0.417885f, 0.423268f, 0.428690f, 0.434154f, 0.439657f, 0.445201f,
|
||||
0.450786f, 0.456411f, 0.462077f, 0.467784f, 0.473531f, 0.479320f, 0.485150f,
|
||||
0.491021f, 0.496933f, 0.502886f, 0.508881f, 0.514918f, 0.520996f, 0.527115f,
|
||||
0.533276f, 0.539479f, 0.545724f, 0.552011f, 0.558340f, 0.564712f, 0.571125f,
|
||||
0.577580f, 0.584078f, 0.590619f, 0.597202f, 0.603827f, 0.610496f, 0.617207f,
|
||||
0.623960f, 0.630757f, 0.637597f, 0.644480f, 0.651406f, 0.658375f, 0.665387f,
|
||||
0.672443f, 0.679542f, 0.686685f, 0.693872f, 0.701102f, 0.708376f, 0.715694f,
|
||||
0.723055f, 0.730461f, 0.737910f, 0.745404f, 0.752942f, 0.760525f, 0.768151f,
|
||||
0.775822f, 0.783538f, 0.791298f, 0.799103f, 0.806952f, 0.814847f, 0.822786f,
|
||||
0.830770f, 0.838799f, 0.846873f, 0.854993f, 0.863157f, 0.871367f, 0.879622f,
|
||||
0.887923f, 0.896269f, 0.904661f, 0.913099f, 0.921582f, 0.930111f, 0.938686f,
|
||||
0.947307f, 0.955973f, 0.964686f, 0.973445f, 0.982251f, 0.991102f, 1.000000f};
|
||||
|
||||
|
||||
#if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
|
||||
// SSE2 support enabled at compile time. No runtime detection mechanism needed.
|
||||
bool
|
||||
has_sse2_sRGB_encode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
// SSE2 support not guaranteed. Use a runtime detection mechanism.
|
||||
|
||||
bool
|
||||
has_sse2_sRGB_encode() {
|
||||
#if defined(__GNUC__)
|
||||
unsigned int a, b, c, d;
|
||||
static const bool has_support =
|
||||
(__get_cpuid(1, &a, &b, &c, &d) == 1 && (d & 0x04000000) != 0);
|
||||
|
||||
#elif defined(_WIN32)
|
||||
static const bool has_support =
|
||||
(IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE) != FALSE);
|
||||
|
||||
#else
|
||||
static const bool has_support = false;
|
||||
#endif
|
||||
|
||||
if (pnmimage_cat.is_debug()) {
|
||||
static bool checked = false;
|
||||
if (!checked) {
|
||||
#if defined(__GNUC__) || defined(_WIN32)
|
||||
if (has_support) {
|
||||
pnmimage_cat.debug()
|
||||
<< "Runtime detection reports SSE2 instructions available: "
|
||||
<< "SSE2-optimized sRGB encoding routines enabled.\n";
|
||||
} else {
|
||||
pnmimage_cat.debug()
|
||||
<< "Runtime detection reports SSE2 instructions unavailable: "
|
||||
<< "SSE2-optimized sRGB encoding routines disabled.\n";
|
||||
}
|
||||
#else
|
||||
pnmimage_cat.debug()
|
||||
<< "No runtime detection mechanism for SSE2 instructions available: "
|
||||
<< "SSE2-optimized sRGB encoding routines disabled.\n";
|
||||
#endif
|
||||
checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
return has_support;
|
||||
}
|
||||
|
||||
#endif // __SSE2__
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// Filename: convert_srgb.h
|
||||
// Created by: rdb (13Nov14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 CONVERT_SRGB_H
|
||||
#define CONVERT_SRGB_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "luse.h"
|
||||
#include "pnmimage_base.h"
|
||||
|
||||
// The below functions can encode and decode sRGB colors in various
|
||||
// representations. Some of them are implemented using look-up tables,
|
||||
// some others using SSE2 intrinsics.
|
||||
extern EXPCL_PANDA_PNMIMAGE const unsigned char to_srgb8_table[256];
|
||||
extern EXPCL_PANDA_PNMIMAGE const unsigned char to_linear_uchar_table[256];
|
||||
extern EXPCL_PANDA_PNMIMAGE const float to_linear_float_table[256];
|
||||
|
||||
EXPCL_PANDA_PNMIMAGE CONSTEXPR float decode_sRGB_float(unsigned char val);
|
||||
EXPCL_PANDA_PNMIMAGE INLINE float decode_sRGB_float(float val);
|
||||
EXPCL_PANDA_PNMIMAGE CONSTEXPR unsigned char decode_sRGB_uchar(unsigned char val);
|
||||
EXPCL_PANDA_PNMIMAGE INLINE unsigned char decode_sRGB_uchar(float val);
|
||||
|
||||
EXPCL_PANDA_PNMIMAGE INLINE float encode_sRGB_float(unsigned char val);
|
||||
EXPCL_PANDA_PNMIMAGE INLINE float encode_sRGB_float(float val);
|
||||
EXPCL_PANDA_PNMIMAGE CONSTEXPR unsigned char encode_sRGB_uchar(unsigned char val);
|
||||
EXPCL_PANDA_PNMIMAGE INLINE unsigned char encode_sRGB_uchar(float val);
|
||||
|
||||
// These functions convert more than one component in one go,
|
||||
// which can be faster due to vectorization.
|
||||
EXPCL_PANDA_PNMIMAGE INLINE void encode_sRGB_uchar(const LColorf &from,
|
||||
xel &into);
|
||||
EXPCL_PANDA_PNMIMAGE INLINE void encode_sRGB_uchar(const LColorf &from,
|
||||
xel &into, xelval &into_alpha);
|
||||
|
||||
// Use these functions if you know that SSE2 support is available.
|
||||
// Otherwise, they will crash!
|
||||
EXPCL_PANDA_PNMIMAGE unsigned char encode_sRGB_uchar_sse2(float val);
|
||||
EXPCL_PANDA_PNMIMAGE void encode_sRGB_uchar_sse2(const LColorf &from,
|
||||
xel &into);
|
||||
EXPCL_PANDA_PNMIMAGE void encode_sRGB_uchar_sse2(const LColorf &from,
|
||||
xel &into, xelval &into_alpha);
|
||||
|
||||
// Use the following to find out if you can call either of the above.
|
||||
EXPCL_PANDA_PNMIMAGE bool has_sse2_sRGB_encode();
|
||||
|
||||
#include "convert_srgb.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
// Filename: convert_srgb_sse2.cxx
|
||||
// Created by: rdb (13Nov14)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file should always be compiled with SSE2 support. These
|
||||
// functions will only be called when SSE2 support is detected at
|
||||
// run-time.
|
||||
|
||||
#include "convert_srgb.h"
|
||||
#include "luse.h"
|
||||
|
||||
#if defined(__SSE2__) || (_M_IX86_FP >= 2) || defined(_M_X64) || defined(_M_AMD64)
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
static INLINE __m128i _encode_sRGB_sse2_mul255(__m128 val) {
|
||||
// This an SSE2-based approximation of the sRGB encode function.
|
||||
// It has a maximum error of around 0.001, which is by far small
|
||||
// enough for a uchar. It is also at least 10x as fast as the
|
||||
// original; up to 40x when taking advantage of vectorization.
|
||||
// Note that the fourth float is only multiplied with 255.
|
||||
|
||||
// Part of the code in this function is derived from:
|
||||
// http://stackoverflow.com/a/6486630/2135754
|
||||
|
||||
// Clamp to 0-1 range.
|
||||
val = _mm_max_ps(val, _mm_set1_ps(0.0f));
|
||||
val = _mm_min_ps(val, _mm_set1_ps(1.0f));
|
||||
|
||||
// Pre-multiply with constant factor to adjust for exp bias.
|
||||
__m128 xf = _mm_mul_ps(val, _mm_set1_ps(6.3307e18f));
|
||||
|
||||
// Approximate logarithm by... casting!
|
||||
xf = _mm_cvtepi32_ps(_mm_castps_si128(xf));
|
||||
|
||||
// Multiply 'logarithm' by power.
|
||||
xf = _mm_mul_ps(xf, _mm_set1_ps(2.0f / 3.0f));
|
||||
|
||||
// Reverse operation of above: cast the other way.
|
||||
xf = _mm_castsi128_ps(_mm_cvtps_epi32(xf));
|
||||
|
||||
// Make an overestimate and an underestimate.
|
||||
__m128 xover = _mm_mul_ps(val, xf);
|
||||
__m128 xunder = _mm_mul_ps(_mm_mul_ps(val, val),
|
||||
_mm_rsqrt_ps(xf));
|
||||
|
||||
// Average the two factors, with a slight bias.
|
||||
__m128 xavg = _mm_mul_ps(_mm_add_ps(xover, xunder),
|
||||
_mm_set1_ps(0.5286098f));
|
||||
|
||||
// Take square root twice. Note that this is faster than
|
||||
// the more expensive _mm_sqrt_ps instruction.
|
||||
xavg = _mm_mul_ps(xavg, _mm_rsqrt_ps(xavg));
|
||||
xavg = _mm_mul_ps(xavg, _mm_rsqrt_ps(xavg));
|
||||
|
||||
// Bring it into the correct range. These factors are determined
|
||||
// not on the basis of accuracy, but are chosen such that the
|
||||
// decoder lookup table produces an equivalent result for any value.
|
||||
xavg = _mm_mul_ps(xavg, _mm_set1_ps(269.122f));
|
||||
xavg = _mm_sub_ps(xavg, _mm_set1_ps(13.55f));
|
||||
|
||||
// Compute the linear section. This is also the path that
|
||||
// the alpha channel takes, so we set the alpha multiplier
|
||||
// to 255 (since alpha is not sRGB-converted).
|
||||
__m128 lval = _mm_mul_ps(val,
|
||||
_mm_set_ps(255.0f, 3294.6f, 3294.6f, 3294.6f));
|
||||
|
||||
lval = _mm_add_ps(lval, _mm_set1_ps(0.5f));
|
||||
|
||||
// Decide which version to return. Rig the alpha
|
||||
// comparator to always fail so that the linear path
|
||||
// is always chosen for alpha.
|
||||
__m128 mask = _mm_cmpge_ps(val,
|
||||
_mm_set_ps(2.0f, 0.0031308f, 0.0031308f, 0.0031308f));
|
||||
|
||||
// This is a non-branching way to return one or the other value.
|
||||
return _mm_cvttps_epi32(_mm_or_ps(
|
||||
_mm_and_ps(mask, xavg),
|
||||
_mm_andnot_ps(mask, lval)));
|
||||
}
|
||||
|
||||
unsigned char
|
||||
encode_sRGB_uchar_sse2(float val) {
|
||||
// Running only a single component through this function is still
|
||||
// way faster than the equivalent non-SSE2 version.
|
||||
return (unsigned char)
|
||||
_mm_extract_epi16(_encode_sRGB_sse2_mul255(_mm_set1_ps(val)), 0);
|
||||
}
|
||||
|
||||
void
|
||||
encode_sRGB_uchar_sse2(const LColorf &color, xel &into) {
|
||||
#ifdef LINMATH_ALIGN
|
||||
__m128 vec = _mm_load_ps(color.get_data());
|
||||
#else
|
||||
__m128 vec = _mm_loadu_ps(color.get_data());
|
||||
#endif
|
||||
|
||||
__m128i vals = _encode_sRGB_sse2_mul255(vec);
|
||||
into.r = _mm_extract_epi16(vals, 0);
|
||||
into.g = _mm_extract_epi16(vals, 2);
|
||||
into.b = _mm_extract_epi16(vals, 4);
|
||||
}
|
||||
|
||||
void
|
||||
encode_sRGB_uchar_sse2(const LColorf &color, xel &into, xelval &into_alpha) {
|
||||
#ifdef LINMATH_ALIGN
|
||||
__m128 vec = _mm_load_ps(color.get_data());
|
||||
#else
|
||||
__m128 vec = _mm_loadu_ps(color.get_data());
|
||||
#endif
|
||||
|
||||
__m128i vals = _encode_sRGB_sse2_mul255(vec);
|
||||
into.r = _mm_extract_epi16(vals, 0);
|
||||
into.g = _mm_extract_epi16(vals, 2);
|
||||
into.b = _mm_extract_epi16(vals, 4);
|
||||
into_alpha = _mm_extract_epi16(vals, 6);
|
||||
}
|
||||
|
||||
#else
|
||||
// Somehow we're still compiling this without SSE2 support. We'll
|
||||
// still have to define these functions, but emit a warning that the
|
||||
// build system isn't configured properly.
|
||||
#warning convert_srgb_sse2.cxx is being compiled without SSE2 support!
|
||||
|
||||
unsigned char
|
||||
encode_sRGB_uchar_sse2(float val) {
|
||||
return encode_sRGB_uchar(val);
|
||||
}
|
||||
|
||||
void
|
||||
encode_sRGB_uchar_sse2(const LColorf &color, xel &into) {
|
||||
encode_sRGB_uchar(color, into);
|
||||
}
|
||||
|
||||
void
|
||||
encode_sRGB_uchar_sse2(const LColorf &color, xel &into, xelval &into_alpha) {
|
||||
encode_sRGB_uchar(color, into, into_alpha);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "config_pnmimage.cxx"
|
||||
#include "convert_srgb.cxx"
|
||||
#include "pfmFile.cxx"
|
||||
#include "pnm-image-filter.cxx"
|
||||
#include "pnmbitio.cxx"
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I \
|
||||
callbackData.h callbackData.I \
|
||||
callbackObject.h callbackObject.I \
|
||||
callbackObject_ext.h callbackObject_ext.I \
|
||||
clockObject.h clockObject.I \
|
||||
collideMask.h \
|
||||
copyOnWriteObject.h copyOnWriteObject.I \
|
||||
|
|
@ -139,6 +140,7 @@
|
|||
cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I \
|
||||
callbackData.h callbackData.I \
|
||||
callbackObject.h callbackObject.I \
|
||||
callbackObject_ext.h callbackObject_ext.I \
|
||||
clockObject.h clockObject.I \
|
||||
collideMask.h \
|
||||
copyOnWriteObject.h copyOnWriteObject.I \
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ BamCache() :
|
|||
_index_stale_since(0)
|
||||
{
|
||||
ConfigVariableFilename model_cache_dir
|
||||
("model-cache-dir", Filename(),
|
||||
("model-cache-dir", Filename(),
|
||||
PRC_DESC("The full path to a directory, local to this computer, in which "
|
||||
"model and texture files will be cached on load. If a directory "
|
||||
"name is specified here, files may be loaded from the cache "
|
||||
|
|
@ -51,7 +51,7 @@ BamCache() :
|
|||
"especially if you are loading egg files instead of bam files, "
|
||||
"or if you are loading models from a shared network drive. "
|
||||
"If this is the empty string, no cache will be used."));
|
||||
|
||||
|
||||
ConfigVariableInt model_cache_flush
|
||||
("model-cache-flush", 30,
|
||||
PRC_DESC("This is the amount of time, in seconds, between automatic "
|
||||
|
|
@ -138,7 +138,7 @@ set_root(const Filename &root) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamCache::lookup
|
||||
// Access: Published
|
||||
// Description: Looks up a file in the cache.
|
||||
// Description: Looks up a file in the cache.
|
||||
//
|
||||
// If the file is cacheable, then regardless of whether
|
||||
// the file is found in the cache or not, this returns a
|
||||
|
|
@ -163,7 +163,7 @@ lookup(const Filename &source_filename, const string &cache_extension) {
|
|||
consider_flush_index();
|
||||
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
|
||||
Filename source_pathname(source_filename);
|
||||
source_pathname.make_absolute(vfs->get_cwd());
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ store(BamCacheRecord *record) {
|
|||
if (_read_only) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
consider_flush_index();
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
@ -231,7 +231,7 @@ store(BamCacheRecord *record) {
|
|||
emergency_read_only();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!dout.write_header(_bam_header)) {
|
||||
util_cat.error()
|
||||
<< "Unable to write to " << temp_pathname << "\n";
|
||||
|
|
@ -247,7 +247,7 @@ store(BamCacheRecord *record) {
|
|||
vfs->delete_file(temp_pathname);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
TypeRegistry *type_registry = TypeRegistry::ptr();
|
||||
TypeHandle texture_type = type_registry->find_type("Texture");
|
||||
if (record->get_data()->is_of_type(texture_type)) {
|
||||
|
|
@ -257,14 +257,14 @@ store(BamCacheRecord *record) {
|
|||
// Any other kinds of objects write texture references.
|
||||
writer.set_file_texture_mode(BamWriter::BTM_fullpath);
|
||||
}
|
||||
|
||||
|
||||
if (!writer.write_object(record)) {
|
||||
util_cat.error()
|
||||
<< "Unable to write object to " << temp_pathname << "\n";
|
||||
vfs->delete_file(temp_pathname);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!writer.write_object(record->get_data())) {
|
||||
util_cat.error()
|
||||
<< "Unable to write object data to " << temp_pathname << "\n";
|
||||
|
|
@ -354,7 +354,7 @@ flush_index() {
|
|||
emergency_read_only();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Now atomically write the name of this index file to the index
|
||||
// reference file.
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
|
@ -385,6 +385,16 @@ flush_index() {
|
|||
check_cache_size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamCache::list_index
|
||||
// Access: Published
|
||||
// Description: Writes the contents of the index to standard output.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BamCache::
|
||||
list_index(ostream &out, int indent_level) const {
|
||||
_index->write(out, indent_level);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BamCache::read_index
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -73,13 +73,15 @@ PUBLISHED:
|
|||
INLINE void set_read_only(bool ro);
|
||||
INLINE bool get_read_only() const;
|
||||
|
||||
PT(BamCacheRecord) lookup(const Filename &source_filename,
|
||||
PT(BamCacheRecord) lookup(const Filename &source_filename,
|
||||
const string &cache_extension);
|
||||
bool store(BamCacheRecord *record);
|
||||
|
||||
void consider_flush_index();
|
||||
void flush_index();
|
||||
|
||||
|
||||
void list_index(ostream &out, int indent_level = 0) const;
|
||||
|
||||
INLINE static BamCache *get_global_ptr();
|
||||
|
||||
private:
|
||||
|
|
@ -96,7 +98,7 @@ private:
|
|||
void check_cache_size();
|
||||
|
||||
void emergency_read_only();
|
||||
|
||||
|
||||
static BamCacheIndex *do_read_index(const Filename &index_pathname);
|
||||
static bool do_write_index(const Filename &index_pathname, const BamCacheIndex *index);
|
||||
|
||||
|
|
@ -105,7 +107,7 @@ private:
|
|||
PT(BamCacheRecord) read_record(const Filename &source_pathname,
|
||||
const Filename &cache_filename,
|
||||
int pass);
|
||||
static PT(BamCacheRecord) do_read_record(const Filename &cache_pathname,
|
||||
static PT(BamCacheRecord) do_read_record(const Filename &cache_pathname,
|
||||
bool read_data);
|
||||
|
||||
static string hash_filename(const string &filename);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ public:
|
|||
PUBLISHED:
|
||||
virtual void output(ostream &out) const;
|
||||
|
||||
EXTENSION(static PT(CallbackObject) make(PyObject *function));
|
||||
|
||||
public:
|
||||
virtual void do_callback(CallbackData *cbdata);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// Filename: callbackObject_ext.I
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Extension<CallbackObject>::make
|
||||
// Access: Published
|
||||
// Description: This static constructor is merely provided so that
|
||||
// interrogate can automatically coerce Python
|
||||
// functions when passing them to a C++ function that
|
||||
// accepts a CallbackObject.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(CallbackObject) Extension<CallbackObject>::
|
||||
make(PyObject *function) {
|
||||
if (function != Py_None && !PyCallable_Check(function)) {
|
||||
PyErr_SetString(PyExc_TypeError, "expected callable or None");
|
||||
return NULL;
|
||||
} else {
|
||||
return new PythonCallbackObject(function);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Filename: callbackObject_ext.h
|
||||
// Created by: rdb (25Feb15)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 CALLBACKOBJECT_EXT_H
|
||||
#define CALLBACKOBJECT_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "pythonCallbackObject.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extension<CallbackObject>
|
||||
// Description : This class defines the extension methods for
|
||||
// CallbackObject, which are called instead of
|
||||
// any C++ methods with the same prototype.
|
||||
//
|
||||
// This just defines a static constructor, which makes
|
||||
// it possible for Interrogate to automatically accept
|
||||
// a Python function wherever a CallbackObject is
|
||||
// accepted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<>
|
||||
class Extension<CallbackObject> : public ExtensionBase<CallbackObject> {
|
||||
public:
|
||||
INLINE static PT(CallbackObject) make(PyObject *function);
|
||||
};
|
||||
|
||||
#include "callbackObject_ext.I"
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // CALLBACKOBJECT_EXT_H
|
||||
|
|
@ -75,7 +75,7 @@ typedef unsigned int ZPOINT;
|
|||
((((unsigned int)(a) << 24) & 0xff000000) | (((unsigned int)(r) << 16) & 0xff0000) | (((unsigned int)(g) << 8) & 0xff00) | (unsigned int)(b))
|
||||
|
||||
#define SRGB_TO_PIXEL(r,g,b) \
|
||||
((encode_sRGB[(unsigned int)(r) >> 4] << 16) | (encode_sRGB10[(unsigned int)(g) >> 4] << 8) | (encode_sRGB[(unsigned int)(b) >> 4]))
|
||||
((encode_sRGB[(unsigned int)(r) >> 4] << 16) | (encode_sRGB[(unsigned int)(g) >> 4] << 8) | (encode_sRGB[(unsigned int)(b) >> 4]))
|
||||
#define SRGBA_TO_PIXEL(r,g,b,a) \
|
||||
((((unsigned int)(a) << 16) & 0xff000000) | (encode_sRGB[(unsigned int)(r) >> 4] << 16) | (encode_sRGB[(unsigned int)(g) >> 4] << 8) | (encode_sRGB[(unsigned int)(b) >> 4]))
|
||||
|
||||
|
|
|
|||
|
|
@ -17,88 +17,316 @@
|
|||
#include "fcollada_utils.h"
|
||||
#include "pt_EggVertex.h"
|
||||
#include "eggXfmSAnim.h"
|
||||
#include "daeToEggConverter.h"
|
||||
#include "daeMaterials.h"
|
||||
|
||||
#include "eggExternalReference.h"
|
||||
|
||||
#include "FCDocument/FCDocument.h"
|
||||
#include "FCDocument/FCDController.h"
|
||||
#include "FCDocument/FCDGeometry.h"
|
||||
#include "FCDocument/FCDSceneNodeTools.h"
|
||||
|
||||
#include "FCDocument/FCDSceneNode.h"
|
||||
#include "FCDocument/FCDTransform.h"
|
||||
#include "FCDocument/FCDAnimated.h"
|
||||
#include "FCDocument/FCDAnimationCurve.h"
|
||||
#include "FCDocument/FCDAnimationKey.h"
|
||||
|
||||
TypeHandle DaeCharacter::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeCharacter::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DaeCharacter::
|
||||
DaeCharacter(const string name, const FCDControllerInstance* controller_instance) {
|
||||
_controller_instance = (FCDControllerInstance*) controller_instance;
|
||||
_name = name;
|
||||
_frame_rate = 0;
|
||||
_skin_controller = NULL;
|
||||
DaeCharacter(EggGroup *node_group, const FCDControllerInstance *instance) :
|
||||
_node_group(node_group),
|
||||
_name(node_group->get_name()),
|
||||
_instance(instance),
|
||||
_skin_controller(NULL),
|
||||
_skin_mesh(NULL) {
|
||||
|
||||
_bind_shape_mat = LMatrix4d::ident_mat();
|
||||
|
||||
// If it's a skin controller, add the controller joints.
|
||||
FCDController* controller = (FCDController*) controller_instance->GetEntity();
|
||||
if (controller == NULL) return;
|
||||
const FCDController *controller = (const FCDController *)instance->GetEntity();
|
||||
if (controller == NULL) {
|
||||
return;
|
||||
}
|
||||
_skin_mesh = controller->GetBaseGeometry()->GetMesh();
|
||||
|
||||
if (controller->IsSkin()) {
|
||||
_skin_controller = controller->GetSkinController();
|
||||
if (_skin_controller == NULL) return;
|
||||
for (size_t j = 0; j < _skin_controller->GetJointCount(); ++j) {
|
||||
_controller_joints[FROM_FSTRING(_skin_controller->GetJoint(j)->GetId())] = (FCDSkinControllerJoint*) _skin_controller->GetJoint(j);
|
||||
_bind_shape_mat = DAEToEggConverter::convert_matrix(_skin_controller->GetBindShapeTransform());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeCharacter::bind_joints
|
||||
// Access: Public
|
||||
// Description: Binds the joints to the character. This means
|
||||
// changing them to the bind pose. It is necessary
|
||||
// to call this before process_skin_geometry.
|
||||
//
|
||||
// Returns the root group.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DaeCharacter::
|
||||
bind_joints(JointMap &joint_map) {
|
||||
_joints.clear();
|
||||
|
||||
size_t num_joints = _skin_controller->GetJointCount();
|
||||
_joints.reserve(num_joints);
|
||||
|
||||
// Record the bind pose for each joint.
|
||||
for (size_t j = 0; j < num_joints; ++j) {
|
||||
const FCDSkinControllerJoint *skin_joint = _skin_controller->GetJoint(j);
|
||||
string sid = FROM_FSTRING(skin_joint->GetId());
|
||||
LMatrix4d bind_pose;
|
||||
bind_pose.invert_from(DAEToEggConverter::convert_matrix(
|
||||
skin_joint->GetBindPoseInverse()));
|
||||
|
||||
// Check that we already encountered this joint during traversal.
|
||||
JointMap::iterator ji = joint_map.find(sid);
|
||||
if (ji != joint_map.end()) {
|
||||
Joint &joint = ji->second;
|
||||
|
||||
if (joint._character != (DaeCharacter *)NULL) {
|
||||
// In some cases, though, multiple controllers share the same joints.
|
||||
// We can't support this without duplicating the joint structure,
|
||||
// so we check if the bind poses are the same.
|
||||
if (!joint._bind_pose.almost_equal(bind_pose, 0.0001)) {
|
||||
// Ugh. What else could we do?
|
||||
daeegg_cat.error()
|
||||
<< "Multiple controllers share joint with sid " << sid
|
||||
<< ", with different bind poses.\n";
|
||||
}
|
||||
} else {
|
||||
// Mark the joint as being controlled by this character.
|
||||
joint._bind_pose = bind_pose;
|
||||
joint._character = this;
|
||||
}
|
||||
|
||||
_joints.push_back(joint);
|
||||
} else {
|
||||
daeegg_cat.warning()
|
||||
<< "Unknown joint sid being referenced: '" << sid << "'\n";
|
||||
|
||||
// We still have to add a dummy joint or the index will be off.
|
||||
_joints.push_back(Joint(NULL, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeCharacter::as_egg_bundle
|
||||
// Function: DaeCharacter::adjust_joints
|
||||
// Access: Public
|
||||
// Description: Returns the character as a <Bundle> element,
|
||||
// suited for the animation table.
|
||||
// Description: Traverses through the character hierarchy in order
|
||||
// to bind the mesh to the character. This involves
|
||||
// reorienting the joints to match the bind pose.
|
||||
//
|
||||
// It is important that this is called only once.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(EggTable) DaeCharacter::
|
||||
as_egg_bundle() {
|
||||
PT(EggTable) bundle = new EggTable(_name);
|
||||
bundle->set_table_type(EggTable::TT_bundle);
|
||||
PT(EggTable) skeleton = new EggTable("<skeleton>");
|
||||
skeleton->set_table_type(EggTable::TT_table);
|
||||
bundle->add_child(skeleton);
|
||||
// Loop through the joint hierarchy
|
||||
#if FCOLLADA_VERSION < 0x00030005
|
||||
FCDSceneNodeList roots = _controller_instance->FindSkeletonNodes();
|
||||
#else
|
||||
FCDSceneNodeList roots;
|
||||
_controller_instance->FindSkeletonNodes(roots);
|
||||
#endif
|
||||
for (FCDSceneNodeList::iterator it = roots.begin(); it != roots.end(); ++it) {
|
||||
process_joint(skeleton, *it);
|
||||
void DaeCharacter::
|
||||
adjust_joints(FCDSceneNode *node, const JointMap &joint_map,
|
||||
const LMatrix4d &transform) {
|
||||
|
||||
LMatrix4d this_transform = transform;
|
||||
|
||||
if (node->IsJoint()) {
|
||||
string sid = FROM_FSTRING(node->GetSubId());
|
||||
|
||||
JointMap::const_iterator ji = joint_map.find(sid);
|
||||
if (ji != joint_map.end()) {
|
||||
const Joint &joint = ji->second;
|
||||
|
||||
// Panda needs the joints to be in bind pose. Not fun! We copy the joint
|
||||
// transform to the default pose, though, so that Panda will restore the
|
||||
// joint transformation after binding.
|
||||
|
||||
if (joint._character == this) {
|
||||
LMatrix4d bind_pose = joint._bind_pose * _bind_shape_mat *
|
||||
invert(transform);
|
||||
//LMatrix4d bind_pose = joint._bind_pose * _bind_shape_mat *
|
||||
// joint._group->get_parent()->get_node_frame_inv();
|
||||
|
||||
this_transform = bind_pose * this_transform;
|
||||
joint._group->set_default_pose(*joint._group);
|
||||
joint._group->set_transform3d(bind_pose);
|
||||
|
||||
/*
|
||||
PT(EggGroup) sphere = new EggGroup;
|
||||
sphere->add_uniform_scale(0.1);
|
||||
sphere->set_group_type(EggGroup::GT_instance);
|
||||
sphere->add_child(new EggExternalReference("", "jack.egg"));
|
||||
joint._group->add_child(sphere);
|
||||
*/
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//this_transform = DAEToEggConverter::convert_matrix(node->ToMatrix());
|
||||
}
|
||||
|
||||
// Loop through the children joints
|
||||
for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
|
||||
//if (node->GetChild(ch)->IsJoint()) {
|
||||
adjust_joints(node->GetChild(ch), joint_map, this_transform);
|
||||
//}
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeCharacter::process_joint
|
||||
// Function: DaeCharacter::influence_vertex
|
||||
// Access: Public
|
||||
// Description: Adds the influences for the given vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DaeCharacter::
|
||||
influence_vertex(int index, EggVertex *vertex) {
|
||||
const FCDSkinControllerVertex *influence = _skin_controller->GetVertexInfluence(index);
|
||||
|
||||
for (size_t pa = 0; pa < influence->GetPairCount(); ++pa) {
|
||||
const FCDJointWeightPair* jwpair = influence->GetPair(pa);
|
||||
|
||||
if (jwpair->jointIndex >= 0 && jwpair->jointIndex < _joints.size()) {
|
||||
EggGroup *joint = _joints[jwpair->jointIndex]._group.p();
|
||||
if (joint != NULL) {
|
||||
joint->ref_vertex(vertex, jwpair->weight);
|
||||
}
|
||||
} else {
|
||||
daeegg_cat.error()
|
||||
<< "Invalid joint index: " << jwpair->jointIndex << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeCharacter::collect_keys
|
||||
// Access: Public
|
||||
// Description: Collects all animation keys of animations applied
|
||||
// to this character.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DaeCharacter::
|
||||
collect_keys(pset<float> &keys) {
|
||||
#if FCOLLADA_VERSION < 0x00030005
|
||||
FCDSceneNodeList roots = _instance->FindSkeletonNodes();
|
||||
#else
|
||||
FCDSceneNodeList roots;
|
||||
_instance->FindSkeletonNodes(roots);
|
||||
#endif
|
||||
|
||||
for (FCDSceneNodeList::iterator it = roots.begin(); it != roots.end(); ++it) {
|
||||
r_collect_keys(*it, keys);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeCharacter::r_collect_keys
|
||||
// Access: Public
|
||||
// Description: Collects all animation keys found for the given
|
||||
// node tree.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DaeCharacter::
|
||||
r_collect_keys(FCDSceneNode* node, pset<float> &keys) {
|
||||
FCDAnimatedList animateds;
|
||||
|
||||
// Collect all the animation curves
|
||||
for (size_t t = 0; t < node->GetTransformCount(); ++t) {
|
||||
FCDTransform *transform = node->GetTransform(t);
|
||||
FCDAnimated *animated = transform->GetAnimated();
|
||||
|
||||
if (animated != NULL) {
|
||||
const FCDAnimationCurveListList &all_curves = animated->GetCurves();
|
||||
|
||||
for (size_t ci = 0; ci < all_curves.size(); ++ci) {
|
||||
const FCDAnimationCurveTrackList &curves = all_curves[ci];
|
||||
if (curves.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t num_keys = curves.front()->GetKeyCount();
|
||||
const FCDAnimationKey **curve_keys = curves.front()->GetKeys();
|
||||
|
||||
for (size_t c = 0; c < num_keys; ++c) {
|
||||
keys.insert(curve_keys[c]->input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeCharacter::build_table
|
||||
// Access: Public
|
||||
// Description: Processes a joint node and its transforms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DaeCharacter::
|
||||
process_joint(PT(EggTable) parent, FCDSceneNode* node) {
|
||||
build_table(EggTable *parent, FCDSceneNode* node, const pset<float> &keys) {
|
||||
nassertv(node != NULL);
|
||||
string node_id = FROM_FSTRING(node->GetDaeId());
|
||||
PT(EggTable) joint = new EggTable(node_id);
|
||||
joint->set_table_type(EggTable::TT_table);
|
||||
parent->add_child(joint);
|
||||
PT(EggXfmSAnim) xform = new EggXfmSAnim("xform");
|
||||
joint->add_child(xform);
|
||||
xform->set_fps(_frame_rate);
|
||||
// Generate the sampled animation and loop through the matrices
|
||||
FCDSceneNodeTools::GenerateSampledAnimation(node);
|
||||
FMMatrix44List matrices = FCDSceneNodeTools::GetSampledAnimationMatrices();
|
||||
for (FMMatrix44List::const_iterator it = matrices.begin(); it != matrices.end(); ++it) {
|
||||
LMatrix4d matr = DAEToEggConverter::convert_matrix(*it);
|
||||
assert(xform->add_data(matr));
|
||||
|
||||
if (!node->IsJoint()) {
|
||||
for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
|
||||
build_table(parent, node->GetChild(ch), keys);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Loop through the children joints
|
||||
for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
|
||||
if (node->GetChild(ch)->IsJoint()) {
|
||||
process_joint(joint, node->GetChild(ch));
|
||||
|
||||
string node_id = FROM_FSTRING(node->GetDaeId());
|
||||
PT(EggTable) table = new EggTable(node_id);
|
||||
table->set_table_type(EggTable::TT_table);
|
||||
parent->add_child(table);
|
||||
|
||||
PT(EggXfmSAnim) xform = new EggXfmSAnim("xform");
|
||||
table->add_child(xform);
|
||||
|
||||
// Generate the sampled animation and loop through the matrices
|
||||
FCDAnimatedList animateds;
|
||||
|
||||
// Collect all the animation curves
|
||||
for (size_t t = 0; t < node->GetTransformCount(); ++t) {
|
||||
FCDTransform *transform = node->GetTransform(t);
|
||||
FCDAnimated *animated = transform->GetAnimated();
|
||||
if (animated != (FCDAnimated *)NULL) {
|
||||
if (animated->HasCurve()) {
|
||||
animateds.push_back(animated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sample the scene node transform
|
||||
float last_key;
|
||||
float timing_total = 0;
|
||||
pset<float>::const_iterator ki;
|
||||
for (ki = keys.begin(); ki != keys.end(); ++ki) {
|
||||
for (FCDAnimatedList::iterator it = animateds.begin(); it != animateds.end(); ++it) {
|
||||
// Sample each animated, which changes the transform values directly
|
||||
(*it)->Evaluate(*ki);
|
||||
}
|
||||
|
||||
if (ki != keys.begin()) {
|
||||
timing_total += (*ki - last_key);
|
||||
}
|
||||
last_key = *ki;
|
||||
|
||||
// Retrieve the new transform matrix for the COLLADA scene node
|
||||
FMMatrix44 fmat = node->ToMatrix();
|
||||
|
||||
// Work around issue in buggy exporters (like ColladaMax)
|
||||
if (IS_NEARLY_ZERO(fmat[3][3])) {
|
||||
fmat[3][3] = 1;
|
||||
}
|
||||
|
||||
xform->add_data(DAEToEggConverter::convert_matrix(fmat));
|
||||
}
|
||||
|
||||
// Quantize the FPS, otherwise Panda complains about FPS mismatches.
|
||||
float fps = cfloor(((keys.size() - 1) / timing_total) * 100 + 0.5f) * 0.01f;
|
||||
xform->set_fps(fps);
|
||||
|
||||
// Loop through the children joints
|
||||
for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
|
||||
//if (node->GetChild(ch)->IsJoint()) {
|
||||
build_table(table, node->GetChild(ch), keys);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,20 +12,22 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DAECHARACTER_H
|
||||
#define DAECHARACTER_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "typeHandle.h"
|
||||
#include "eggTable.h"
|
||||
#include "daeToEggConverter.h"
|
||||
|
||||
#include "pre_fcollada_include.h"
|
||||
#include "FCollada.h"
|
||||
#include "FCDocument/FCDSceneNode.h"
|
||||
#include "FCDocument/FCDControllerInstance.h"
|
||||
#include "FCDocument/FCDSkinController.h"
|
||||
#include "FCDocument/FCDGeometryMesh.h"
|
||||
|
||||
#ifndef DAECHARACTER_H
|
||||
#define DAECHARACTER_H
|
||||
class DAEToEggConverter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DaeCharacter
|
||||
|
|
@ -33,17 +35,46 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class DaeCharacter : public TypedReferenceCount {
|
||||
public:
|
||||
DaeCharacter(const string name, const FCDControllerInstance* controller_instance);
|
||||
PT(EggTable) as_egg_bundle();
|
||||
void process_joint(PT(EggTable) parent, FCDSceneNode* node);
|
||||
|
||||
DaeCharacter(EggGroup *node_group, const FCDControllerInstance* controller_instance);
|
||||
|
||||
struct Joint {
|
||||
INLINE Joint(EggGroup *group, const FCDSceneNode *scene_node) :
|
||||
_group(group),
|
||||
_scene_node(scene_node),
|
||||
_character(NULL),
|
||||
_bind_pose(LMatrix4d::ident_mat()) {}
|
||||
|
||||
LMatrix4d _bind_pose;
|
||||
PT(EggGroup) _group;
|
||||
const FCDSceneNode *_scene_node;
|
||||
DaeCharacter *_character;
|
||||
};
|
||||
typedef pvector<Joint> Joints;
|
||||
typedef pmap<string, Joint> JointMap;
|
||||
|
||||
void bind_joints(JointMap &joint_map);
|
||||
void adjust_joints(FCDSceneNode *node, const JointMap &joint_map,
|
||||
const LMatrix4d &transform = LMatrix4d::ident_mat());
|
||||
|
||||
void influence_vertex(int index, EggVertex *vertex);
|
||||
|
||||
void collect_keys(pset<float> &keys);
|
||||
void r_collect_keys(FCDSceneNode *node, pset<float> &keys);
|
||||
|
||||
void build_table(EggTable *parent, FCDSceneNode* node, const pset<float> &keys);
|
||||
|
||||
public:
|
||||
PT(EggGroup) _node_group;
|
||||
const FCDGeometryMesh *_skin_mesh;
|
||||
const FCDControllerInstance *_instance;
|
||||
LMatrix4d _bind_shape_mat;
|
||||
|
||||
private:
|
||||
int _frame_rate;
|
||||
string _name;
|
||||
FCDControllerInstance* _controller_instance;
|
||||
FCDSkinController* _skin_controller;
|
||||
pmap<string, FCDSkinControllerJoint*> _controller_joints;
|
||||
|
||||
const FCDSkinController *_skin_controller;
|
||||
Joints _joints;
|
||||
JointMap _bound_joints;
|
||||
|
||||
public:
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ TypeHandle DaeMaterials::_type_handle;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DaeMaterials::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DaeMaterials::
|
||||
DaeMaterials(const FCDGeometryInstance* geometry_instance) {
|
||||
|
|
@ -58,7 +58,7 @@ void DaeMaterials::add_material_instance(const FCDMaterialInstance* instance) {
|
|||
return;
|
||||
}
|
||||
_materials[semantic] = new DaeMaterial();
|
||||
|
||||
|
||||
// Load in the uvsets
|
||||
for (size_t vib = 0; vib < instance->GetVertexInputBindingCount(); ++vib) {
|
||||
const FCDMaterialInstanceBindVertexInput* mivib = instance->GetVertexInputBinding(vib);
|
||||
|
|
@ -74,7 +74,7 @@ void DaeMaterials::add_material_instance(const FCDMaterialInstance* instance) {
|
|||
#endif
|
||||
_materials[semantic]->_uvsets.push_back(bvi);
|
||||
}
|
||||
|
||||
|
||||
// Handle the material stuff
|
||||
daeegg_cat.spam() << "Trying to process material with semantic " << semantic << endl;
|
||||
PT_EggMaterial egg_material = new EggMaterial(semantic);
|
||||
|
|
@ -204,12 +204,13 @@ process_extra(const string semantic, const FCDExtra* extra) {
|
|||
for (size_t et = 0; et < etype->GetTechniqueCount(); ++et) {
|
||||
const FCDENode* enode = ((const FCDENode*)(etype->GetTechnique(et)))->FindChildNode("double_sided");
|
||||
if (enode != NULL) {
|
||||
if (trim(enode->GetContent()) == "1") {
|
||||
string content = trim(enode->GetContent());
|
||||
if (content == "1" || content == "true") {
|
||||
_materials[semantic]->_double_sided = true;
|
||||
} else if (trim(enode->GetContent()) == "0") {
|
||||
} else if (content == "0" || content == "false") {
|
||||
_materials[semantic]->_double_sided = false;
|
||||
} else {
|
||||
daeegg_cat.warning() << "Expected <double_sided> tag to be either 1 or 0, found '" << enode->GetContent() << "' instead" << endl;
|
||||
daeegg_cat.warning() << "Expected <double_sided> tag to be either 1 or 0, found '" << content << "' instead" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -391,7 +392,7 @@ convert_blend(FCDEffectStandard::TransparencyMode mode, const LColor &transparen
|
|||
blend->_color = LColor::zero();
|
||||
blend->_operand_a = EggGroup::BO_unspecified;
|
||||
blend->_operand_b = EggGroup::BO_unspecified;
|
||||
|
||||
|
||||
// First fill in the color value.
|
||||
if (mode == FCDEffectStandard::A_ONE) {// || mode == FCDEffectStandard::A_ZERO) {
|
||||
double value = transparent[3] * transparency;
|
||||
|
|
@ -404,7 +405,7 @@ convert_blend(FCDEffectStandard::TransparencyMode mode, const LColor &transparen
|
|||
blend->_enabled = false;
|
||||
return blend;
|
||||
}
|
||||
|
||||
|
||||
// Now figure out the operands.
|
||||
if (mode == FCDEffectStandard::RGB_ZERO) {// || mode == FCDEffectStandard::A_ZERO) {
|
||||
blend->_operand_a = EggGroup::BO_one_minus_constant_color;
|
||||
|
|
@ -417,7 +418,7 @@ convert_blend(FCDEffectStandard::TransparencyMode mode, const LColor &transparen
|
|||
blend->_enabled = false;
|
||||
return blend;
|
||||
}
|
||||
|
||||
|
||||
// See if we can optimize out the color.
|
||||
if (blend->_operand_a == EggGroup::BO_constant_color) {
|
||||
if (blend->_color == LColor::zero()) {
|
||||
|
|
@ -447,7 +448,7 @@ convert_blend(FCDEffectStandard::TransparencyMode mode, const LColor &transparen
|
|||
blend->_operand_b = EggGroup::BO_zero;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// See if we can entirely disable the blend.
|
||||
if (blend->_operand_a == EggGroup::BO_one && blend->_operand_b == EggGroup::BO_zero) {
|
||||
blend->_enabled = false;
|
||||
|
|
|
|||
|
|
@ -56,9 +56,10 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
DAEToEggConverter::
|
||||
DAEToEggConverter() {
|
||||
_unit_name = "meter";
|
||||
_unit_meters = 1.0;
|
||||
_document = NULL;
|
||||
_table = NULL;
|
||||
_frame_rate = -1;
|
||||
_error_handler = NULL;
|
||||
_invert_transparency = false;
|
||||
}
|
||||
|
|
@ -131,18 +132,15 @@ convert_file(const Filename &filename) {
|
|||
// Reset stuff
|
||||
clear_error();
|
||||
_joints.clear();
|
||||
_vertex_pools.clear();
|
||||
_skeletons.clear();
|
||||
_frame_rate = -1;
|
||||
if (_error_handler == NULL) {
|
||||
_error_handler = new FUErrorSimpleHandler;
|
||||
}
|
||||
|
||||
|
||||
// The default coordinate system is Y-up
|
||||
if (_egg_data->get_coordinate_system() == CS_default) {
|
||||
_egg_data->set_coordinate_system(CS_yup_right);
|
||||
}
|
||||
|
||||
|
||||
// Read the file
|
||||
FCollada::Initialize();
|
||||
_document = FCollada::LoadDocument(filename.to_os_specific().c_str());
|
||||
|
|
@ -155,201 +153,375 @@ convert_file(const Filename &filename) {
|
|||
if (_document->GetAsset() != NULL) {
|
||||
FCDocumentTools::StandardizeUpAxisAndLength(_document);
|
||||
}
|
||||
|
||||
_table = new EggTable();
|
||||
_table->set_table_type(EggTable::TT_table);
|
||||
// Process the stuff
|
||||
|
||||
// Process the scene
|
||||
process_asset();
|
||||
preprocess();
|
||||
PT(EggGroup) scene_group;
|
||||
string model_name = _character_name;
|
||||
|
||||
FCDSceneNode* visual_scene = _document->GetVisualSceneInstance();
|
||||
if (visual_scene != NULL) {
|
||||
// First check for an <extra> tag
|
||||
const FCDExtra* extra = visual_scene->GetExtra();
|
||||
//FIXME: eek this looks horrid
|
||||
if (extra != NULL) {
|
||||
const FCDEType* etype = extra->GetDefaultType();
|
||||
if (etype != NULL) {
|
||||
const FCDENode* enode = (const FCDENode*) etype->FindTechnique("MAX3D");
|
||||
if (enode != NULL) {
|
||||
enode = enode->FindChildNode("frame_rate");
|
||||
if (enode != NULL && !string_to_int(enode->GetContent(), _frame_rate)) {
|
||||
daeegg_cat.warning() << "Invalid integer in <frame_rate> tag: '" << enode->GetContent() << "'" << endl;
|
||||
} } } }
|
||||
// Now loop through the children
|
||||
if (model_name.empty()) {
|
||||
// By lack of anything better...
|
||||
model_name = FROM_FSTRING(visual_scene->GetName());
|
||||
}
|
||||
scene_group = new EggGroup(model_name);
|
||||
_egg_data->add_child(scene_group);
|
||||
|
||||
for (size_t ch = 0; ch < visual_scene->GetChildrenCount(); ++ch) {
|
||||
process_node(DCAST(EggGroupNode, _egg_data), visual_scene->GetChild(ch));
|
||||
process_node(scene_group, visual_scene->GetChild(ch));
|
||||
}
|
||||
} else {
|
||||
daeegg_cat.warning()
|
||||
<< "No visual scene instance found in COLLADA document.\n";
|
||||
}
|
||||
|
||||
// Now process the characters. This depends on information from collected
|
||||
// joints, which is why it's done in a second step.
|
||||
if (get_animation_convert() != AC_none) {
|
||||
Characters::iterator it;
|
||||
DaeCharacter *character;
|
||||
for (it = _characters.begin(); it != _characters.end(); ++it) {
|
||||
character = *it;
|
||||
if (get_animation_convert() != AC_chan) {
|
||||
character->bind_joints(_joints);
|
||||
|
||||
const FCDGeometryMesh *mesh = character->_skin_mesh;
|
||||
|
||||
if (mesh != NULL) {
|
||||
PT(DaeMaterials) materials = new DaeMaterials(character->_instance);
|
||||
daeegg_cat.spam() << "Processing mesh for controller\n";
|
||||
process_mesh(character->_node_group, mesh, materials, character);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put the joints in bind pose.
|
||||
for (size_t ch = 0; ch < visual_scene->GetChildrenCount(); ++ch) {
|
||||
character->adjust_joints(visual_scene->GetChild(ch), _joints, LMatrix4d::ident_mat());
|
||||
}
|
||||
|
||||
if (scene_group != NULL) {
|
||||
// Mark the scene as character.
|
||||
if (get_animation_convert() == AC_chan) {
|
||||
_egg_data->remove_child(scene_group);
|
||||
} else {
|
||||
scene_group->set_dart_type(EggGroup::DT_default);
|
||||
}
|
||||
}
|
||||
|
||||
if (get_animation_convert() != AC_model) {
|
||||
_table = new EggTable();
|
||||
_table->set_table_type(EggTable::TT_table);
|
||||
_egg_data->add_child(_table);
|
||||
|
||||
PT(EggTable) bundle = new EggTable(model_name);
|
||||
bundle->set_table_type(EggTable::TT_bundle);
|
||||
_table->add_child(bundle);
|
||||
|
||||
PT(EggTable) skeleton = new EggTable("<skeleton>");
|
||||
skeleton->set_table_type(EggTable::TT_table);
|
||||
bundle->add_child(skeleton);
|
||||
|
||||
pset<float> keys;
|
||||
|
||||
Characters::iterator it;
|
||||
DaeCharacter *character;
|
||||
for (it = _characters.begin(); it != _characters.end(); ++it) {
|
||||
character = *it;
|
||||
|
||||
// Collect key frame timings.
|
||||
if (get_animation_convert() == AC_both ||
|
||||
get_animation_convert() == AC_chan) {
|
||||
character->collect_keys(keys);
|
||||
}
|
||||
}
|
||||
|
||||
if (_frame_inc != 0.0) {
|
||||
// A frame increment was given, this means that we have to sample the
|
||||
// animation.
|
||||
float start, end;
|
||||
if (_end_frame != _start_frame) {
|
||||
start = _start_frame;
|
||||
end = _end_frame;
|
||||
} else {
|
||||
// No range was given. Infer the frame range from the keys.
|
||||
start = *keys.begin();
|
||||
end = *keys.rbegin();
|
||||
}
|
||||
keys.clear();
|
||||
|
||||
for (float t = start; t <= end; t += _frame_inc) {
|
||||
keys.insert(t);
|
||||
}
|
||||
} else {
|
||||
// No sampling parameters given; not necessarily a failure, since the
|
||||
// animation may already be sampled. We use the key frames as animation
|
||||
// frames.
|
||||
if (_end_frame != 0.0) {
|
||||
// An end frame was given, chop off all keys after that.
|
||||
float end = _end_frame;
|
||||
pset<float>::iterator ki;
|
||||
for (ki = keys.begin(); ki != keys.end(); ++ki) {
|
||||
if (*ki > end && !IS_THRESHOLD_EQUAL(*ki, end, 0.001)) {
|
||||
keys.erase(ki, keys.end());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_start_frame != 0.0) {
|
||||
// A start frame was given, chop off all keys before that.
|
||||
float start = _start_frame;
|
||||
pset<float>::iterator ki;
|
||||
for (ki = keys.begin(); ki != keys.end(); ++ki) {
|
||||
if (*ki > start && !IS_THRESHOLD_EQUAL(*ki, start, 0.001)) {
|
||||
keys.erase(keys.begin(), ki);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that this does indeed look like a sampled animation; if not,
|
||||
// issue an appropriate warning.
|
||||
pset<float>::const_iterator ki = keys.begin();
|
||||
if (ki != keys.end()) {
|
||||
float last = *ki;
|
||||
float diff = 0;
|
||||
|
||||
for (++ki; ki != keys.end(); ++ki) {
|
||||
if (diff != 0 && !IS_THRESHOLD_EQUAL((*ki - last), diff, 0.001)) {
|
||||
daeegg_cat.error()
|
||||
<< "This does not appear to be a sampled animation.\n"
|
||||
<< "Specify the -sf, -ef and -if options to indicate how the "
|
||||
<< "animations should be sampled.\n";
|
||||
break;
|
||||
}
|
||||
diff = (*ki - last);
|
||||
last = *ki;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It doesn't really matter which character we grab for this as
|
||||
// it'll iterate over the whole graph right now anyway.
|
||||
for (size_t ch = 0; ch < visual_scene->GetChildrenCount(); ++ch) {
|
||||
character->build_table(skeleton, visual_scene->GetChild(ch), keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
SAFE_DELETE(visual_scene);
|
||||
|
||||
_egg_data->add_child(_table);
|
||||
|
||||
|
||||
// Clean up and return
|
||||
SAFE_DELETE(visual_scene);
|
||||
SAFE_DELETE(_document);
|
||||
FCollada::Release();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DAEToEggConverter::process_asset() {
|
||||
if (_document->GetAsset() == NULL) return;
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DAEToEggConverter::get_input_units
|
||||
// Access: Public, Virtual
|
||||
// Description: This may be called after convert_file() has been
|
||||
// called and returned true, indicating a successful
|
||||
// conversion. It will return the distance units
|
||||
// represented by the converted egg file, if known, or
|
||||
// DU_invalid if not known.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DistanceUnit DAEToEggConverter::
|
||||
get_input_units() {
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 0.001)) {
|
||||
return DU_millimeters;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 0.01)) {
|
||||
return DU_centimeters;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 1.0)) {
|
||||
return DU_meters;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 1000.0)) {
|
||||
return DU_kilometers;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 3.0 * 12.0 * 0.0254)) {
|
||||
return DU_yards;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 12.0 * 0.0254)) {
|
||||
return DU_feet;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 0.0254)) {
|
||||
return DU_inches;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 1852.0)) {
|
||||
return DU_nautical_miles;
|
||||
}
|
||||
if (IS_NEARLY_EQUAL(_unit_meters, 5280.0 * 12.0 * 0.0254)) {
|
||||
return DU_statute_miles;
|
||||
}
|
||||
|
||||
// Whatever.
|
||||
return DU_invalid;
|
||||
}
|
||||
|
||||
void DAEToEggConverter::
|
||||
process_asset() {
|
||||
const FCDAsset *asset = _document->GetAsset();
|
||||
if (_document->GetAsset() == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_unit_name = FROM_FSTRING(asset->GetUnitName());
|
||||
_unit_meters = asset->GetUnitConversionFactor();
|
||||
|
||||
// Read out the coordinate system
|
||||
FMVector3 up_axis (_document->GetAsset()->GetUpAxis());
|
||||
FMVector3 up_axis = asset->GetUpAxis();
|
||||
|
||||
if (up_axis == FMVector3(0, 1, 0)) {
|
||||
_egg_data->set_coordinate_system(CS_yup_right);
|
||||
|
||||
} else if (up_axis == FMVector3(0, 0, 1)) {
|
||||
_egg_data->set_coordinate_system(CS_zup_right);
|
||||
|
||||
} else {
|
||||
_egg_data->set_coordinate_system(CS_invalid);
|
||||
daeegg_cat.warning() << "Unrecognized coordinate system!\n";
|
||||
}
|
||||
}
|
||||
|
||||
// This function lists all the joints and referenced skeletons
|
||||
void DAEToEggConverter::preprocess(const FCDSceneNode* node) {
|
||||
// If the node is NULL, take the visual scene instance.
|
||||
if (node == NULL) {
|
||||
assert(_document != NULL);
|
||||
_skeletons.clear();
|
||||
_joints.clear();
|
||||
node = _document->GetVisualSceneInstance();
|
||||
}
|
||||
if (node == NULL) return;
|
||||
if (node->IsJoint()) {
|
||||
_joints[FROM_FSTRING(node->GetDaeId())] = NULL;
|
||||
}
|
||||
// Loop through the instances first.
|
||||
for (size_t in = 0; in < node->GetInstanceCount(); ++in) {
|
||||
if (node->GetInstance(in)->GetType() == FCDEntityInstance::CONTROLLER) {
|
||||
// Loop through the skeleton roots now.
|
||||
#if FCOLLADA_VERSION < 0x00030005
|
||||
FCDSceneNodeList roots = ((FCDControllerInstance*) node->GetInstance(in))->FindSkeletonNodes();
|
||||
#else
|
||||
FCDSceneNodeList roots;
|
||||
((FCDControllerInstance*) node->GetInstance(in))->FindSkeletonNodes(roots);
|
||||
#endif
|
||||
for (FCDSceneNodeList::iterator it = roots.begin(); it != roots.end(); ++it) {
|
||||
daeegg_cat.spam() << "Found referenced skeleton root " << FROM_FSTRING((*it)->GetDaeId()) << endl;
|
||||
_skeletons.push_back(FROM_FSTRING((*it)->GetDaeId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now loop through the children and recurse.
|
||||
for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
|
||||
preprocess(node->GetChild(ch));
|
||||
}
|
||||
}
|
||||
|
||||
// Process the node. If forced is true, it will even process it if its known to be a skeleton root.
|
||||
void DAEToEggConverter::process_node(PT(EggGroupNode) parent, const FCDSceneNode* node, bool forced) {
|
||||
void DAEToEggConverter::
|
||||
process_node(EggGroupNode *parent, const FCDSceneNode* node, bool forced) {
|
||||
nassertv(node != NULL);
|
||||
string node_id = FROM_FSTRING(node->GetDaeId());
|
||||
daeegg_cat.spam() << "Processing node with ID '" << node_id << "'" << endl;
|
||||
// Important! If it's known to be a skeleton root, ignore it for now, unless we're processing forced.
|
||||
if (!forced && count(_skeletons.begin(), _skeletons.end(), node_id) > 0) {
|
||||
daeegg_cat.spam() << "Ignoring skeleton root node with ID '" << node_id << "', we'll process it later" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create an egg group for this node
|
||||
PT(EggGroup) node_group = new EggGroup(FROM_FSTRING(node->GetName()));
|
||||
PT(EggGroup) node_group = new EggGroup(FROM_FSTRING(node->GetDaeId()));
|
||||
process_extra(node_group, node->GetExtra());
|
||||
parent->add_child(node_group);
|
||||
|
||||
// Check if its a joint
|
||||
if (node->IsJoint()) {
|
||||
string sid = FROM_FSTRING(node->GetSubId());
|
||||
node_group->set_group_type(EggGroup::GT_joint);
|
||||
_joints[node_id] = node_group;
|
||||
|
||||
if (!_joints.insert(DaeCharacter::JointMap::value_type(sid,
|
||||
DaeCharacter::Joint(node_group, node))).second) {
|
||||
daeegg_cat.error()
|
||||
<< "Joint with sid " << sid << " occurs more than once!\n";
|
||||
}
|
||||
}
|
||||
// Loop through the transforms and apply them
|
||||
for (size_t tr = 0; tr < node->GetTransformCount(); ++tr) {
|
||||
apply_transform(node_group, node->GetTransform(tr));
|
||||
|
||||
// Loop through the transforms and apply them (in reverse order)
|
||||
for (size_t tr = node->GetTransformCount(); tr > 0; --tr) {
|
||||
apply_transform(node_group, node->GetTransform(tr - 1));
|
||||
}
|
||||
//node_group->set_transform3d(convert_matrix(node->ToMatrix()));
|
||||
|
||||
// Loop through the instances and process them
|
||||
for (size_t in = 0; in < node->GetInstanceCount(); ++in) {
|
||||
process_instance(node_group, node->GetInstance(in));
|
||||
}
|
||||
|
||||
// Loop through the children and recursively process them
|
||||
for (size_t ch = 0; ch < node->GetChildrenCount(); ++ch) {
|
||||
process_node(DCAST(EggGroupNode, node_group), node->GetChild(ch));
|
||||
}
|
||||
|
||||
// Loop through any possible scene node instances and process those, too.
|
||||
for (size_t in = 0; in < node->GetInstanceCount(); ++in) {
|
||||
if (node->GetInstance(in)->GetEntity() && node->GetInstance(in)->GetEntity()->GetType() == FCDEntity::SCENE_NODE) {
|
||||
process_node(DCAST(EggGroupNode, node_group), (const FCDSceneNode*) node->GetInstance(in)->GetEntity());
|
||||
const FCDEntity *entity = node->GetInstance(in)->GetEntity();
|
||||
if (entity && entity->GetType() == FCDEntity::SCENE_NODE) {
|
||||
process_node(node_group, (const FCDSceneNode*) entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DAEToEggConverter::process_instance(PT(EggGroup) parent, const FCDEntityInstance* instance) {
|
||||
void DAEToEggConverter::
|
||||
process_instance(EggGroup *parent, const FCDEntityInstance* instance) {
|
||||
nassertv(instance != NULL);
|
||||
nassertv(instance->GetEntity() != NULL);
|
||||
// Check what kind of instance this is
|
||||
switch (instance->GetType()) {
|
||||
case FCDEntityInstance::GEOMETRY: {
|
||||
const FCDGeometry* geometry = (const FCDGeometry*) instance->GetEntity();
|
||||
assert(geometry != NULL);
|
||||
if (geometry->IsMesh()) {
|
||||
// Now, handle the mesh.
|
||||
process_mesh(parent, geometry->GetMesh(), new DaeMaterials((const FCDGeometryInstance*) instance));
|
||||
case FCDEntityInstance::GEOMETRY:
|
||||
{
|
||||
if (get_animation_convert() != AC_chan) {
|
||||
const FCDGeometry* geometry = (const FCDGeometry*) instance->GetEntity();
|
||||
assert(geometry != NULL);
|
||||
if (geometry->IsMesh()) {
|
||||
// Now, handle the mesh.
|
||||
process_mesh(parent, geometry->GetMesh(), new DaeMaterials((const FCDGeometryInstance*) instance));
|
||||
}
|
||||
if (geometry->IsSpline()) {
|
||||
process_spline(parent, FROM_FSTRING(geometry->GetName()), const_cast<FCDGeometrySpline*> (geometry->GetSpline()));
|
||||
}
|
||||
}
|
||||
if (geometry->IsSpline()) {
|
||||
process_spline(parent, FROM_FSTRING(geometry->GetName()), const_cast<FCDGeometrySpline*> (geometry->GetSpline()));
|
||||
}
|
||||
break; }
|
||||
case FCDEntityInstance::CONTROLLER: {
|
||||
// Add the dart tag and process the controller instance
|
||||
parent->set_dart_type(EggGroup::DT_default);
|
||||
process_controller(parent, (const FCDControllerInstance*) instance);
|
||||
break; }
|
||||
case FCDEntityInstance::MATERIAL:
|
||||
// We don't process this directly, handled per-geometry instead.
|
||||
break;
|
||||
case FCDEntityInstance::SIMPLE: {
|
||||
// Grab the entity and check it's type.
|
||||
}
|
||||
break;
|
||||
|
||||
case FCDEntityInstance::CONTROLLER:
|
||||
// Add the dart tag and process the controller instance
|
||||
//parent->set_dart_type(EggGroup::DT_default);
|
||||
process_controller(parent, (const FCDControllerInstance*) instance);
|
||||
break;
|
||||
|
||||
case FCDEntityInstance::MATERIAL:
|
||||
// We don't process this directly, handled per-geometry instead.
|
||||
break;
|
||||
|
||||
case FCDEntityInstance::SIMPLE:
|
||||
{
|
||||
// Grab the entity and check its type.
|
||||
const FCDEntity* entity = instance->GetEntity();
|
||||
if (entity->GetType() != FCDEntity::SCENE_NODE) {
|
||||
daeegg_cat.warning() << "Unsupported entity type found" << endl;
|
||||
}
|
||||
break; }
|
||||
default:
|
||||
daeegg_cat.warning() << "Unsupported instance type found" << endl;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
daeegg_cat.warning() << "Unsupported instance type found" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Processes the given mesh.
|
||||
void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh* mesh, PT(DaeMaterials) materials) {
|
||||
void DAEToEggConverter::
|
||||
process_mesh(EggGroup *parent, const FCDGeometryMesh* mesh,
|
||||
DaeMaterials *materials, DaeCharacter *character) {
|
||||
|
||||
nassertv(mesh != NULL);
|
||||
daeegg_cat.debug() << "Processing mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << endl;
|
||||
|
||||
|
||||
// Create the egg stuff to hold this mesh
|
||||
PT(EggGroup) mesh_group = new EggGroup(FROM_FSTRING(mesh->GetDaeId()));
|
||||
parent->add_child(mesh_group);
|
||||
PT(EggVertexPool) mesh_pool = new EggVertexPool(FROM_FSTRING(mesh->GetDaeId()));
|
||||
mesh_group->add_child(mesh_pool);
|
||||
_vertex_pools[FROM_FSTRING(mesh->GetDaeId())] = mesh_pool;
|
||||
|
||||
|
||||
// First retrieve the vertex source
|
||||
if (mesh->GetSourceCount() == 0) {
|
||||
daeegg_cat.debug() << "Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << " has no sources" << endl;
|
||||
return;
|
||||
}
|
||||
const FCDGeometrySource* vsource = mesh->FindSourceByType(FUDaeGeometryInput::POSITION);
|
||||
const FCDGeometrySource* vsource = mesh->FindSourceByType(FUDaeGeometryInput::POSITION);
|
||||
if (vsource == NULL) {
|
||||
daeegg_cat.debug() << "Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << " has no source for POSITION data" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Loop through the polygon groups and add them
|
||||
daeegg_cat.spam() << "Mesh with id " << FROM_FSTRING(mesh->GetDaeId()) << " has " << mesh->GetPolygonsCount() << " polygon groups" << endl;
|
||||
if (mesh->GetPolygonsCount() == 0) return;
|
||||
|
||||
|
||||
// This is an array of pointers, I know. But since they are refcounted, I don't have a better idea.
|
||||
PT(EggGroup) *primitive_holders = new PT(EggGroup) [mesh->GetPolygonsCount()];
|
||||
for (size_t gr = 0; gr < mesh->GetPolygonsCount(); ++gr) {
|
||||
const FCDGeometryPolygons* polygons = mesh->GetPolygons(gr);
|
||||
string material_semantic = FROM_FSTRING(polygons->GetMaterialSemantic());
|
||||
|
||||
// Stores which group holds the primitives.
|
||||
PT(EggGroup) primitiveholder;
|
||||
// If we have materials, make a group for each material. Then, apply the material's per-group stuff.
|
||||
if (materials != NULL && (!polygons->GetMaterialSemantic().empty()) && mesh->GetPolygonsCount() > 1) {
|
||||
primitiveholder = new EggGroup(FROM_FSTRING(mesh->GetDaeId()) + "." + FROM_FSTRING(polygons->GetMaterialSemantic()));
|
||||
//primitiveholder = new EggGroup(FROM_FSTRING(mesh->GetDaeId()) + "." + material_semantic);
|
||||
primitiveholder = new EggGroup;
|
||||
mesh_group->add_child(primitiveholder);
|
||||
} else {
|
||||
primitiveholder = mesh_group;
|
||||
|
|
@ -357,7 +529,7 @@ void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh*
|
|||
primitive_holders[gr] = primitiveholder;
|
||||
// Apply the per-group data of the materials, if we have it.
|
||||
if (materials != NULL) {
|
||||
materials->apply_to_group(FROM_FSTRING(polygons->GetMaterialSemantic()), primitiveholder, _invert_transparency);
|
||||
materials->apply_to_group(material_semantic, primitiveholder, _invert_transparency);
|
||||
}
|
||||
// Find the position sources
|
||||
const FCDGeometryPolygonsInput* pinput = polygons->FindInput(FUDaeGeometryInput::POSITION);
|
||||
|
|
@ -389,26 +561,47 @@ void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh*
|
|||
const uint32* tindices;
|
||||
if (tinput != NULL) tindices = tinput->GetIndices();
|
||||
// Get a name for potential coordinate sets
|
||||
string tcsetname ("");
|
||||
string tcsetname;
|
||||
if (materials != NULL && tcinput != NULL) {
|
||||
daeegg_cat.debug() << "Assigning texcoord set " << tcinput->GetSet() << " to semantic '" << FROM_FSTRING(polygons->GetMaterialSemantic()) << "'\n";
|
||||
tcsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXCOORD, tcinput->GetSet());
|
||||
if (daeegg_cat.is_debug()) {
|
||||
daeegg_cat.debug()
|
||||
<< "Assigning texcoord set " << tcinput->GetSet()
|
||||
<< " to semantic '" << material_semantic << "'\n";
|
||||
}
|
||||
tcsetname = materials->get_uvset_name(material_semantic,
|
||||
FUDaeGeometryInput::TEXCOORD, tcinput->GetSet());
|
||||
}
|
||||
string tbsetname ("");
|
||||
string tbsetname;
|
||||
if (materials != NULL && binput != NULL) {
|
||||
daeegg_cat.debug() << "Assigning texbinormal set " << binput->GetSet() << " to semantic '" << FROM_FSTRING(polygons->GetMaterialSemantic()) << "'\n";
|
||||
tbsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXBINORMAL, binput->GetSet());
|
||||
if (daeegg_cat.is_debug()) {
|
||||
daeegg_cat.debug()
|
||||
<< "Assigning texbinormal set " << binput->GetSet()
|
||||
<< " to semantic '" << material_semantic << "'\n";
|
||||
}
|
||||
tbsetname = materials->get_uvset_name(material_semantic,
|
||||
FUDaeGeometryInput::TEXBINORMAL, binput->GetSet());
|
||||
}
|
||||
string ttsetname ("");
|
||||
string ttsetname;
|
||||
if (materials != NULL && tinput != NULL) {
|
||||
daeegg_cat.debug() << "Assigning textangent set " << tinput->GetSet() << " to semantic '" << FROM_FSTRING(polygons->GetMaterialSemantic()) << "'\n";
|
||||
ttsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXTANGENT, tinput->GetSet());
|
||||
if (daeegg_cat.is_debug()) {
|
||||
daeegg_cat.debug()
|
||||
<< "Assigning textangent set " << tinput->GetSet()
|
||||
<< " to semantic '" << material_semantic << "'\n";
|
||||
}
|
||||
ttsetname = materials->get_uvset_name(material_semantic,
|
||||
FUDaeGeometryInput::TEXTANGENT, tinput->GetSet());
|
||||
}
|
||||
// Loop through the indices and add the vertices.
|
||||
for (size_t ix = 0; ix < pinput->GetIndexCount(); ++ix) {
|
||||
PT_EggVertex vertex = mesh_pool->make_new_vertex();
|
||||
const float* data = &vsource->GetData()[indices[ix]*3];
|
||||
vertex->set_pos(LPoint3d(data[0], data[1], data[2]));
|
||||
|
||||
if (character != NULL) {
|
||||
// If this is skinned geometry, add the vertex influences.
|
||||
character->influence_vertex(indices[ix], vertex);
|
||||
}
|
||||
|
||||
// Process the normal
|
||||
if (nsource != NULL && ninput != NULL) {
|
||||
assert(nsource->GetStride() == 3);
|
||||
|
|
@ -469,26 +662,26 @@ void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh*
|
|||
PT(EggPrimitive) primitive = NULL;
|
||||
// Create a primitive that matches the fcollada type
|
||||
switch (polygons->GetPrimitiveType()) {
|
||||
case FCDGeometryPolygons::LINES:
|
||||
primitive = new EggLine();
|
||||
break;
|
||||
case FCDGeometryPolygons::POLYGONS:
|
||||
primitive = new EggPolygon();
|
||||
break;
|
||||
case FCDGeometryPolygons::TRIANGLE_FANS:
|
||||
primitive = new EggTriangleFan();
|
||||
break;
|
||||
case FCDGeometryPolygons::TRIANGLE_STRIPS:
|
||||
primitive = new EggTriangleStrip();
|
||||
break;
|
||||
case FCDGeometryPolygons::POINTS:
|
||||
primitive = new EggPoint();
|
||||
break;
|
||||
case FCDGeometryPolygons::LINE_STRIPS:
|
||||
daeegg_cat.warning() << "Linestrips not yet supported!" << endl;
|
||||
break;
|
||||
default:
|
||||
daeegg_cat.warning() << "Unsupported primitive type found!" << endl;
|
||||
case FCDGeometryPolygons::LINES:
|
||||
primitive = new EggLine();
|
||||
break;
|
||||
case FCDGeometryPolygons::POLYGONS:
|
||||
primitive = new EggPolygon();
|
||||
break;
|
||||
case FCDGeometryPolygons::TRIANGLE_FANS:
|
||||
primitive = new EggTriangleFan();
|
||||
break;
|
||||
case FCDGeometryPolygons::TRIANGLE_STRIPS:
|
||||
primitive = new EggTriangleStrip();
|
||||
break;
|
||||
case FCDGeometryPolygons::POINTS:
|
||||
primitive = new EggPoint();
|
||||
break;
|
||||
case FCDGeometryPolygons::LINE_STRIPS:
|
||||
daeegg_cat.warning() << "Linestrips not yet supported!" << endl;
|
||||
break;
|
||||
default:
|
||||
daeegg_cat.warning() << "Unsupported primitive type found!" << endl;
|
||||
}
|
||||
if (primitive != NULL) {
|
||||
primitive_holders[gr]->add_child(primitive);
|
||||
|
|
@ -506,7 +699,8 @@ void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh*
|
|||
delete[] primitive_holders;
|
||||
}
|
||||
|
||||
void DAEToEggConverter::process_spline(PT(EggGroup) parent, const string group_name, FCDGeometrySpline* geometry_spline) {
|
||||
void DAEToEggConverter::
|
||||
process_spline(EggGroup *parent, const string group_name, FCDGeometrySpline* geometry_spline) {
|
||||
assert(geometry_spline != NULL);
|
||||
PT(EggGroup) result = new EggGroup(group_name);
|
||||
parent->add_child(result);
|
||||
|
|
@ -521,7 +715,8 @@ void DAEToEggConverter::process_spline(PT(EggGroup) parent, const string group_n
|
|||
}
|
||||
}
|
||||
|
||||
void DAEToEggConverter::process_spline(PT(EggGroup) parent, const FCDSpline* spline) {
|
||||
void DAEToEggConverter::
|
||||
process_spline(EggGroup *parent, const FCDSpline* spline) {
|
||||
assert(spline != NULL);
|
||||
nassertv(spline->GetSplineType() == FUDaeSplineType::NURBS);
|
||||
// Now load in the nurbs curve to the egg library
|
||||
|
|
@ -542,70 +737,26 @@ void DAEToEggConverter::process_spline(PT(EggGroup) parent, const FCDSpline* spl
|
|||
}
|
||||
}
|
||||
|
||||
void DAEToEggConverter::process_controller(PT(EggGroup) parent, const FCDControllerInstance* instance) {
|
||||
void DAEToEggConverter::
|
||||
process_controller(EggGroup *parent, const FCDControllerInstance *instance) {
|
||||
assert(instance != NULL);
|
||||
const FCDController* controller = (const FCDController*) instance->GetEntity();
|
||||
const FCDController* controller = (const FCDController *)instance->GetEntity();
|
||||
assert(controller != NULL);
|
||||
PT(EggVertexPool) vertex_pool = NULL;
|
||||
// Add the skin geometry
|
||||
const FCDGeometry* geometry = controller->GetBaseGeometry();
|
||||
if (geometry != NULL) {
|
||||
if (geometry->IsMesh()) {
|
||||
process_mesh(parent, geometry->GetMesh(), new DaeMaterials((const FCDGeometryInstance*) instance));
|
||||
|
||||
if (get_animation_convert() == AC_none) {
|
||||
// If we're exporting a static mesh, export the base geometry as-is.
|
||||
const FCDGeometryMesh *mesh = controller->GetBaseGeometry()->GetMesh();
|
||||
if (mesh != NULL) {
|
||||
PT(DaeMaterials) materials = new DaeMaterials(instance);
|
||||
daeegg_cat.spam() << "Processing mesh for controller\n";
|
||||
if (_vertex_pools.count(FROM_FSTRING(geometry->GetMesh()->GetDaeId()))) {
|
||||
daeegg_cat.debug() << "Using vertex pool " << FROM_FSTRING(geometry->GetMesh()->GetDaeId()) << "\n";
|
||||
vertex_pool = _vertex_pools[FROM_FSTRING(geometry->GetMesh()->GetDaeId())];
|
||||
}
|
||||
}
|
||||
if (geometry->IsSpline()) {
|
||||
process_spline(parent, FROM_FSTRING(geometry->GetName()), const_cast<FCDGeometrySpline*> (geometry->GetSpline()));
|
||||
}
|
||||
}
|
||||
// Add the joint hierarchy
|
||||
#if FCOLLADA_VERSION < 0x00030005
|
||||
FCDSceneNodeList roots = (const_cast<FCDControllerInstance*> (instance))->FindSkeletonNodes();
|
||||
#else
|
||||
FCDSceneNodeList roots;
|
||||
(const_cast<FCDControllerInstance*> (instance))->FindSkeletonNodes(roots);
|
||||
#endif
|
||||
for (FCDSceneNodeList::iterator it = roots.begin(); it != roots.end(); ++it) {
|
||||
process_node(DCAST(EggGroupNode, parent), *it, true);
|
||||
}
|
||||
if (controller->IsSkin()) {
|
||||
// Load in the vertex influences first
|
||||
pmap<int32, pvector<pair<PT_EggVertex, PN_stdfloat> > > influences;
|
||||
if (vertex_pool) {
|
||||
for (size_t in = 0; in < controller->GetSkinController()->GetInfluenceCount(); ++in) {
|
||||
assert(vertex_pool->has_vertex(in));
|
||||
for (size_t pa = 0; pa < controller->GetSkinController()->GetVertexInfluence(in)->GetPairCount(); ++pa) {
|
||||
const FCDJointWeightPair* jwpair = controller->GetSkinController()->GetVertexInfluence(in)->GetPair(pa);
|
||||
influences[jwpair->jointIndex].push_back(pair<PT_EggVertex, PN_stdfloat> (vertex_pool->get_vertex(in), jwpair->weight));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Loop through the joints in the vertex influences
|
||||
for (pmap<int32, pvector<pair<PT_EggVertex, PN_stdfloat> > >::iterator it = influences.begin(); it != influences.end(); ++it) {
|
||||
if (it->first == -1) {
|
||||
daeegg_cat.warning() << "Ignoring vertex influence with negative joint index\n";
|
||||
//FIXME: Why are there joints with index -1
|
||||
} else {
|
||||
const string joint_id = FROM_FSTRING(controller->GetSkinController()->GetJoint(it->first)->GetId());
|
||||
//TODO: what if the joints have just not been defined yet?
|
||||
if (_joints.count(joint_id) > 0) {
|
||||
if (_joints[joint_id]) {
|
||||
for (pvector<pair<PT_EggVertex, PN_stdfloat> >::iterator vi = it->second.begin(); vi != it->second.end(); ++vi) {
|
||||
_joints[joint_id]->ref_vertex(vi->first, vi->second);
|
||||
}
|
||||
} else {
|
||||
daeegg_cat.warning() << "Unprocessed joint being referenced: '" << joint_id << "'" << endl;
|
||||
}
|
||||
} else {
|
||||
daeegg_cat.warning() << "Unknown joint being referenced: '" << joint_id << "'" << endl;
|
||||
}
|
||||
}
|
||||
process_mesh(parent, mesh, materials);
|
||||
}
|
||||
} else {
|
||||
// Add a character for this to the table, the mesh is processed later
|
||||
PT(DaeCharacter) character = new DaeCharacter(parent, instance);
|
||||
_characters.push_back(character);
|
||||
}
|
||||
|
||||
if (controller->IsMorph()) {
|
||||
assert(controller != NULL);
|
||||
const FCDMorphController* morph_controller = controller->GetMorphController();
|
||||
|
|
@ -628,28 +779,25 @@ void DAEToEggConverter::process_controller(PT(EggGroup) parent, const FCDControl
|
|||
morph->add_child(target);
|
||||
}
|
||||
}
|
||||
|
||||
// Get a <Bundle> for the character and add it to the table
|
||||
PT(DaeCharacter) character = new DaeCharacter(parent->get_name(), instance);
|
||||
_table->add_child(character->as_egg_bundle());
|
||||
}
|
||||
|
||||
void DAEToEggConverter::process_extra(PT(EggGroup) group, const FCDExtra* extra) {
|
||||
void DAEToEggConverter::
|
||||
process_extra(EggGroup *group, const FCDExtra* extra) {
|
||||
if (extra == NULL) {
|
||||
return;
|
||||
}
|
||||
nassertv(group != NULL);
|
||||
|
||||
|
||||
const FCDEType* etype = extra->GetDefaultType();
|
||||
if (etype == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const FCDENode* enode = (const FCDENode*) etype->FindTechnique("PANDA3D");
|
||||
if (enode == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
FCDENodeList tags;
|
||||
enode->FindChildrenNodes("param", tags);
|
||||
for (FCDENodeList::iterator it = tags.begin(); it != tags.end(); ++it) {
|
||||
|
|
@ -660,18 +808,45 @@ void DAEToEggConverter::process_extra(PT(EggGroup) group, const FCDExtra* extra)
|
|||
}
|
||||
}
|
||||
|
||||
LMatrix4d DAEToEggConverter::convert_matrix(const FMMatrix44& matrix) {
|
||||
LMatrix4d result = LMatrix4d::zeros_mat();
|
||||
for (char x = 0; x < 4; ++x) {
|
||||
for (char y = 0; y < 4; ++y) {
|
||||
result(x, y) = matrix[x][y];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
LMatrix4d DAEToEggConverter::
|
||||
convert_matrix(const FMMatrix44 &matrix) {
|
||||
return LMatrix4d(
|
||||
matrix[0][0], matrix[0][1], matrix[0][2], matrix[0][3],
|
||||
matrix[1][0], matrix[1][1], matrix[1][2], matrix[1][3],
|
||||
matrix[2][0], matrix[2][1], matrix[2][2], matrix[2][3],
|
||||
matrix[3][0], matrix[3][1], matrix[3][2], matrix[3][3]);
|
||||
}
|
||||
|
||||
void DAEToEggConverter::apply_transform(const PT(EggGroup) to, const FCDTransform* from) {
|
||||
void DAEToEggConverter::
|
||||
apply_transform(EggGroup *to, const FCDTransform* from) {
|
||||
assert(from != NULL);
|
||||
assert(to != NULL);
|
||||
to->set_transform3d(convert_matrix(from->ToMatrix()) * to->get_transform3d());
|
||||
//to->set_transform3d(convert_matrix(from->ToMatrix()) * to->get_transform3d());
|
||||
switch (from->GetType()) {
|
||||
case FCDTransform::TRANSLATION:
|
||||
{
|
||||
const FCDTTranslation *trans = (const FCDTTranslation *)from;
|
||||
to->add_translate3d(TO_VEC3(trans->GetTranslation()));
|
||||
}
|
||||
break;
|
||||
|
||||
case FCDTransform::ROTATION:
|
||||
{
|
||||
const FCDTRotation *rot = (const FCDTRotation *)from;
|
||||
to->add_rotate3d(rot->GetAngle(), TO_VEC3(rot->GetAxis()));
|
||||
}
|
||||
break;
|
||||
|
||||
case FCDTransform::SCALE:
|
||||
{
|
||||
const FCDTScale *scale = (const FCDTScale *)from;
|
||||
to->add_scale3d(TO_VEC3(scale->GetScale()));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Either a matrix, or something we can't handle.
|
||||
to->add_matrix4(convert_matrix(from->ToMatrix()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "FMath/FMMatrix44.h"
|
||||
|
||||
#include "daeMaterials.h"
|
||||
#include "daeCharacter.h"
|
||||
#include "pvector.h" // Include last
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -47,39 +48,41 @@ public:
|
|||
DAEToEggConverter();
|
||||
DAEToEggConverter(const DAEToEggConverter ©);
|
||||
~DAEToEggConverter();
|
||||
|
||||
|
||||
virtual SomethingToEggConverter *make_copy();
|
||||
|
||||
|
||||
virtual string get_name() const;
|
||||
virtual string get_extension() const;
|
||||
|
||||
|
||||
virtual bool convert_file(const Filename &filename);
|
||||
virtual DistanceUnit get_input_units();
|
||||
|
||||
bool _invert_transparency;
|
||||
|
||||
private:
|
||||
string _unit_name;
|
||||
double _unit_meters;
|
||||
PT(EggTable) _table;
|
||||
FCDocument* _document;
|
||||
FUErrorSimpleHandler* _error_handler;
|
||||
pmap<const string, PT(EggGroup)> _joints;
|
||||
pmap<const string, PT(EggVertexPool)> _vertex_pools;
|
||||
pvector<string> _skeletons;
|
||||
int _frame_rate;
|
||||
|
||||
DaeCharacter::JointMap _joints;
|
||||
|
||||
typedef pvector<PT(DaeCharacter)> Characters;
|
||||
Characters _characters;
|
||||
|
||||
void process_asset();
|
||||
void preprocess(const FCDSceneNode* node = NULL);
|
||||
void process_node(PT(EggGroupNode) parent, const FCDSceneNode* node, bool forced = false);
|
||||
void process_instance(PT(EggGroup) parent, const FCDEntityInstance* instance);
|
||||
void process_mesh(PT(EggGroup) parent, const FCDGeometryMesh* mesh, PT(DaeMaterials) materials);
|
||||
void process_spline(PT(EggGroup) parent, const string group_name, FCDGeometrySpline* geometry_spline);
|
||||
void process_spline(PT(EggGroup) parent, const FCDSpline* spline);
|
||||
void process_controller(PT(EggGroup) parent, const FCDControllerInstance* instance);
|
||||
//void process_table_joint(PT(EggTable) parent, FCDSceneNode* node);
|
||||
void process_extra(PT(EggGroup) group, const FCDExtra* extra);
|
||||
|
||||
void process_node(EggGroupNode *parent, const FCDSceneNode* node, bool forced = false);
|
||||
void process_instance(EggGroup *parent, const FCDEntityInstance* instance);
|
||||
void process_mesh(EggGroup *parent, const FCDGeometryMesh* mesh,
|
||||
DaeMaterials *materials, DaeCharacter *character = NULL);
|
||||
void process_spline(EggGroup *parent, const string group_name, FCDGeometrySpline* geometry_spline);
|
||||
void process_spline(EggGroup *parent, const FCDSpline* spline);
|
||||
void process_controller(EggGroup *parent, const FCDControllerInstance* instance);
|
||||
void process_extra(EggGroup *group, const FCDExtra* extra);
|
||||
|
||||
static LMatrix4d convert_matrix(const FMMatrix44& matrix);
|
||||
void apply_transform(const PT(EggGroup) to, const FCDTransform* from);
|
||||
|
||||
void apply_transform(EggGroup *to, const FCDTransform* from);
|
||||
|
||||
friend class DaeCharacter;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@
|
|||
#error You must include pre_fcollada_include.h before including FCollada.h!
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
// FCollada expects LINUX to be defined on linux
|
||||
#ifdef IS_LINUX
|
||||
#ifndef LINUX
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ DAEToEgg::
|
|||
DAEToEgg():
|
||||
SomethingToEgg("COLLADA", ".dae")
|
||||
{
|
||||
add_animation_options();
|
||||
add_units_options();
|
||||
add_normals_options();
|
||||
add_transform_options();
|
||||
|
|
@ -42,6 +43,7 @@ DAEToEgg():
|
|||
("This program converts .dae files (COLLADA Digital Asset Exchange) to .egg.");
|
||||
|
||||
_coordinate_system = CS_yup_right;
|
||||
_animation_convert = AC_both;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -51,6 +53,12 @@ DAEToEgg():
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DAEToEgg::
|
||||
run() {
|
||||
if (_animation_convert != AC_both && _animation_convert != AC_none &&
|
||||
_animation_convert != AC_chan && _animation_convert != AC_model) {
|
||||
cerr << "Unsupported animation convert option.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nout << "Reading " << _input_filename << "\n";
|
||||
|
||||
_data->set_coordinate_system(_coordinate_system);
|
||||
|
|
|
|||
Loading…
Reference in New Issue