Merge r4618-4629 from trunk. Branch has now catched up to trunk again :-)
Fix memory access in d3dx mipmap generation. Thanks to hellflip for the hint. Developer documentation - adding a release checklist. Improve speed for finalizing skinned meshes (removal of unnecessary frames after loading) (thx @ichtyander for the testmodel) Down from ~20 seconds to ~0,5 seconds :-) Minor bugfix for my last check-in. dropBadKeys now finds some more broken frames. Changing calling convention for static lib release fast CPU to Cdecl because FastCall did not actually compile (conflicts with pnglib). Also the same setting is used when compiling as dll, so I guess this setting was simply not tested. Thanks @AReich for reporting. See thread for more info: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=49462 git-svn-id: http://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@4651 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
51e6ac4493
commit
36fc52fa0e
|
@ -3,6 +3,7 @@ Changes in 1.9 (not yet released)
|
|||
- Removed VS6 .dsw / .dsp project files - VS6 is no longer supported.
|
||||
|
||||
- Added support for PVR textures. Loader offer support for compressed DXT1-5, PVRTC/PVRTC-II, ETC1/ETC2 texture formats.
|
||||
- Improve speed for finalizing skinned meshes (removal of unnecessary frames after loading) (thx @ichtyander for the testmodel)
|
||||
- Collada loader now instantiates camera nodes which had been ignore so far (thx @NemoStein for the test .dae)
|
||||
- line2d::intersectWith has a new parameter to allow ignoring intersections with coincident lines
|
||||
- vector2d::equals now has an tolerance parameter for passing the epsilon (like vector3d had). Note that this changes the default
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace gui
|
|||
//! Validate when enter was pressed
|
||||
EGUI_SBV_ENTER = 2,
|
||||
//! Validate when the editbox loses the focus
|
||||
EGUI_SBV_LOSE_FOCUS = 4,
|
||||
EGUI_SBV_LOSE_FOCUS = 4
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -384,11 +384,13 @@ bool CD3D8Texture::createMipMaps(u32 level)
|
|||
{
|
||||
if (upperDesc.Format == D3DFMT_A1R5G5B5)
|
||||
copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
|
||||
upperDesc.Width, upperDesc.Height,
|
||||
lowerDesc.Width, lowerDesc.Height,
|
||||
upperlr.Pitch, lowerlr.Pitch);
|
||||
else
|
||||
if (upperDesc.Format == D3DFMT_A8R8G8B8)
|
||||
copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
|
||||
upperDesc.Width, upperDesc.Height,
|
||||
lowerDesc.Width, lowerDesc.Height,
|
||||
upperlr.Pitch, lowerlr.Pitch);
|
||||
else
|
||||
|
@ -440,65 +442,30 @@ ECOLOR_FORMAT CD3D8Texture::getColorFormatFromD3DFormat(D3DFORMAT format)
|
|||
|
||||
|
||||
void CD3D8Texture::copy16BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height,
|
||||
s32 pitchsrc, s32 pitchtgt) const
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const
|
||||
{
|
||||
u16 c;
|
||||
|
||||
for (int x=0; x<width; ++x)
|
||||
const s32 dy_max = (srcHeight==1?1:2);
|
||||
const s32 dx_max = (srcWidth==1?1:2);
|
||||
const s32 blockcount= dx_max*dy_max;
|
||||
for (s32 y=0; y<height; ++y)
|
||||
{
|
||||
for (int y=0; y<height; ++y)
|
||||
for (s32 x=0; x<width; ++x)
|
||||
{
|
||||
s32 a=0, r=0, g=0, b=0;
|
||||
|
||||
for (int dx=0; dx<2; ++dx)
|
||||
u32 a=0, r=0, g=0, b=0;
|
||||
for (s32 dy=0; dy<dy_max; ++dy)
|
||||
{
|
||||
for (int dy=0; dy<2; ++dy)
|
||||
const s32 tgy = (y*2)+dy;
|
||||
for (s32 dx=0; dx<dx_max; ++dx)
|
||||
{
|
||||
int tgx = (x*2)+dx;
|
||||
int tgy = (y*2)+dy;
|
||||
const s32 tgx = (x*2)+dx;
|
||||
|
||||
c = *(u16*)((void*)&src[(tgx*2)+(tgy*pitchsrc)]);
|
||||
|
||||
a += getAlpha(c);
|
||||
r += getRed(c);
|
||||
g += getGreen(c);
|
||||
b += getBlue(c);
|
||||
}
|
||||
}
|
||||
|
||||
a /= 4;
|
||||
r /= 4;
|
||||
g /= 4;
|
||||
b /= 4;
|
||||
|
||||
c = ((a & 0x1) <<15) | ((r & 0x1F)<<10) | ((g & 0x1F)<<5) | (b & 0x1F);
|
||||
*(u16*)((void*)&tgt[(x*2)+(y*pitchtgt)]) = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CD3D8Texture::copy32BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height,
|
||||
s32 pitchsrc, s32 pitchtgt) const
|
||||
{
|
||||
SColor c;
|
||||
|
||||
for (int x=0; x<width; ++x)
|
||||
{
|
||||
for (int y=0; y<height; ++y)
|
||||
{
|
||||
s32 a=0, r=0, g=0, b=0;
|
||||
|
||||
for (int dx=0; dx<2; ++dx)
|
||||
{
|
||||
for (int dy=0; dy<2; ++dy)
|
||||
{
|
||||
int tgx = (x*2)+dx;
|
||||
int tgy = (y*2)+dy;
|
||||
|
||||
c = *(u32*)((void*)&src[(tgx<<2)+(tgy*pitchsrc)]);
|
||||
SColor c;
|
||||
if (ColorFormat == ECF_A1R5G5B5)
|
||||
c = A1R5G5B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
|
||||
else
|
||||
c = R5G6B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
|
||||
|
||||
a += c.getAlpha();
|
||||
r += c.getRed();
|
||||
|
@ -507,13 +474,60 @@ void CD3D8Texture::copy32BitMipMap(char* src, char* tgt,
|
|||
}
|
||||
}
|
||||
|
||||
a >>= 2;
|
||||
r >>= 2;
|
||||
g >>= 2;
|
||||
b >>= 2;
|
||||
a /= blockcount;
|
||||
r /= blockcount;
|
||||
g /= blockcount;
|
||||
b /= blockcount;
|
||||
|
||||
c = ((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff);
|
||||
*(u32*)((void*)&tgt[(x*4)+(y*pitchtgt)]) = c.color;
|
||||
u16 c;
|
||||
if (ColorFormat == ECF_A1R5G5B5)
|
||||
c = RGBA16(r,g,b,a);
|
||||
else
|
||||
c = A8R8G8B8toR5G6B5(SColor(a,r,g,b).color);
|
||||
*(u16*)(&tgt[(x*2)+(y*pitchtgt)]) = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CD3D8Texture::copy32BitMipMap(char* src, char* tgt,
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const
|
||||
{
|
||||
const s32 dy_max = (srcHeight==1?1:2);
|
||||
const s32 dx_max = (srcWidth==1?1:2);
|
||||
const s32 blockcount= dx_max*dy_max;
|
||||
for (s32 y=0; y<height; ++y)
|
||||
{
|
||||
for (s32 x=0; x<width; ++x)
|
||||
{
|
||||
u32 a=0, r=0, g=0, b=0;
|
||||
SColor c;
|
||||
|
||||
for (s32 dy=0; dy<dy_max; ++dy)
|
||||
{
|
||||
const s32 tgy = (y*2)+dy;
|
||||
for (s32 dx=0; dx<dx_max; ++dx)
|
||||
{
|
||||
const s32 tgx = (x*2)+dx;
|
||||
|
||||
c = *(u32*)(&src[(tgx*4)+(tgy*pitchsrc)]);
|
||||
|
||||
a += c.getAlpha();
|
||||
r += c.getRed();
|
||||
g += c.getGreen();
|
||||
b += c.getBlue();
|
||||
}
|
||||
}
|
||||
|
||||
a /= blockcount;
|
||||
r /= blockcount;
|
||||
g /= blockcount;
|
||||
b /= blockcount;
|
||||
|
||||
c.set(a, r, g, b);
|
||||
*(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,10 +91,15 @@ private:
|
|||
bool createMipMaps(u32 level=1);
|
||||
|
||||
void copy16BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const;
|
||||
|
||||
//! Helper function for mipmap generation.
|
||||
void copy32BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const;
|
||||
|
||||
IDirect3DDevice8* Device;
|
||||
IDirect3DTexture8* Texture;
|
||||
|
|
|
@ -245,11 +245,13 @@ bool CD3D9Texture::createMipMaps(u32 level)
|
|||
{
|
||||
if ((upperDesc.Format == D3DFMT_A1R5G5B5) || (upperDesc.Format == D3DFMT_R5G6B5))
|
||||
copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
|
||||
upperDesc.Width, upperDesc.Height,
|
||||
lowerDesc.Width, lowerDesc.Height,
|
||||
upperlr.Pitch, lowerlr.Pitch);
|
||||
else
|
||||
if (upperDesc.Format == D3DFMT_A8R8G8B8)
|
||||
copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits,
|
||||
upperDesc.Width, upperDesc.Height,
|
||||
lowerDesc.Width, lowerDesc.Height,
|
||||
upperlr.Pitch, lowerlr.Pitch);
|
||||
else
|
||||
|
@ -565,19 +567,22 @@ bool CD3D9Texture::hasMipMaps() const
|
|||
|
||||
|
||||
void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height,
|
||||
s32 pitchsrc, s32 pitchtgt) const
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const
|
||||
{
|
||||
const s32 dy_max = (srcHeight==1?1:2);
|
||||
const s32 dx_max = (srcWidth==1?1:2);
|
||||
const s32 blockcount= dx_max*dy_max;
|
||||
for (s32 y=0; y<height; ++y)
|
||||
{
|
||||
for (s32 x=0; x<width; ++x)
|
||||
{
|
||||
u32 a=0, r=0, g=0, b=0;
|
||||
|
||||
for (s32 dy=0; dy<2; ++dy)
|
||||
for (s32 dy=0; dy<dy_max; ++dy)
|
||||
{
|
||||
const s32 tgy = (y*2)+dy;
|
||||
for (s32 dx=0; dx<2; ++dx)
|
||||
for (s32 dx=0; dx<dx_max; ++dx)
|
||||
{
|
||||
const s32 tgx = (x*2)+dx;
|
||||
|
||||
|
@ -594,10 +599,10 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
|
|||
}
|
||||
}
|
||||
|
||||
a /= 4;
|
||||
r /= 4;
|
||||
g /= 4;
|
||||
b /= 4;
|
||||
a /= blockcount;
|
||||
r /= blockcount;
|
||||
g /= blockcount;
|
||||
b /= blockcount;
|
||||
|
||||
u16 c;
|
||||
if (ColorFormat == ECF_A1R5G5B5)
|
||||
|
@ -611,9 +616,13 @@ void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
|
|||
|
||||
|
||||
void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height,
|
||||
s32 pitchsrc, s32 pitchtgt) const
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const
|
||||
{
|
||||
const s32 dy_max = (srcHeight==1?1:2);
|
||||
const s32 dx_max = (srcWidth==1?1:2);
|
||||
const s32 blockcount= dx_max*dy_max;
|
||||
for (s32 y=0; y<height; ++y)
|
||||
{
|
||||
for (s32 x=0; x<width; ++x)
|
||||
|
@ -621,10 +630,10 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
|
|||
u32 a=0, r=0, g=0, b=0;
|
||||
SColor c;
|
||||
|
||||
for (s32 dy=0; dy<2; ++dy)
|
||||
for (s32 dy=0; dy<dy_max; ++dy)
|
||||
{
|
||||
const s32 tgy = (y*2)+dy;
|
||||
for (s32 dx=0; dx<2; ++dx)
|
||||
for (s32 dx=0; dx<dx_max; ++dx)
|
||||
{
|
||||
const s32 tgx = (x*2)+dx;
|
||||
|
||||
|
@ -637,10 +646,10 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
|
|||
}
|
||||
}
|
||||
|
||||
a /= 4;
|
||||
r /= 4;
|
||||
g /= 4;
|
||||
b /= 4;
|
||||
a /= blockcount;
|
||||
r /= blockcount;
|
||||
g /= blockcount;
|
||||
b /= blockcount;
|
||||
|
||||
c.set(a, r, g, b);
|
||||
*(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color;
|
||||
|
|
|
@ -94,11 +94,15 @@ private:
|
|||
|
||||
//! Helper function for mipmap generation.
|
||||
void copy16BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const;
|
||||
|
||||
//! Helper function for mipmap generation.
|
||||
void copy32BitMipMap(char* src, char* tgt,
|
||||
s32 width, s32 height, s32 pitchsrc, s32 pitchtgt) const;
|
||||
const s32 srcWidth, const s32 srcHeight,
|
||||
const s32 width, const s32 height,
|
||||
const s32 pitchsrc, const s32 pitchtgt) const;
|
||||
|
||||
//! set Pitch based on the d3d format
|
||||
void setPitch(D3DFORMAT d3dformat);
|
||||
|
|
|
@ -10,6 +10,80 @@
|
|||
#include "IAnimatedMeshSceneNode.h"
|
||||
#include "os.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Frames must always be increasing, so we remove objects where this isn't the case
|
||||
// return number of kicked keys
|
||||
template <class T> // T = objects containing a "frame" variable
|
||||
irr::u32 dropBadKeys(irr::core::array<T>& array)
|
||||
{
|
||||
if (array.size()<2)
|
||||
return 0;
|
||||
|
||||
irr::u32 n=1; // new index
|
||||
for(irr::u32 j=1;j<array.size();++j)
|
||||
{
|
||||
if (array[j].frame < array[n-1].frame)
|
||||
continue; //bad frame, unneeded and may cause problems
|
||||
if ( n != j )
|
||||
array[n] = array[j];
|
||||
++n;
|
||||
}
|
||||
irr::u32 d = array.size()-n; // remove already copied keys
|
||||
if ( d > 0 )
|
||||
{
|
||||
array.erase(n, d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
// drop identical middle keys - we only need the first and last
|
||||
// return number of kicked keys
|
||||
template <class T, typename Cmp> // Cmp = comparison for keys of type T
|
||||
irr::u32 dropMiddleKeys(irr::core::array<T>& array, Cmp & cmp)
|
||||
{
|
||||
if ( array.size() < 3 )
|
||||
return 0;
|
||||
|
||||
irr::u32 s = 0; // old index for current key
|
||||
irr::u32 n = 1; // new index for next key
|
||||
for(irr::u32 j=1;j<array.size();++j)
|
||||
{
|
||||
if ( cmp(array[j], array[s]) )
|
||||
continue; // same key, handle later
|
||||
|
||||
if ( j > s+1 ) // had there been identical keys?
|
||||
array[n++] = array[j-1]; // keep the last
|
||||
array[n++] = array[j]; // keep the new one
|
||||
s = j;
|
||||
}
|
||||
if ( array.size() > s+1 ) // identical keys at the array end?
|
||||
array[n++] = array[array.size()-1]; // keep the last
|
||||
|
||||
irr::u32 d = array.size()-n; // remove already copied keys
|
||||
if ( d > 0 )
|
||||
{
|
||||
array.erase(n, d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
bool identicalPos(const irr::scene::ISkinnedMesh::SPositionKey& a, const irr::scene::ISkinnedMesh::SPositionKey& b)
|
||||
{
|
||||
return a.position == b.position;
|
||||
}
|
||||
|
||||
bool identicalScale(const irr::scene::ISkinnedMesh::SScaleKey& a, const irr::scene::ISkinnedMesh::SScaleKey& b)
|
||||
{
|
||||
return a.scale == b.scale;
|
||||
}
|
||||
|
||||
bool identicalRotation(const irr::scene::ISkinnedMesh::SRotationKey& a, const irr::scene::ISkinnedMesh::SRotationKey& b)
|
||||
{
|
||||
return a.rotation == b.rotation;
|
||||
}
|
||||
};
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
|
@ -881,10 +955,10 @@ void CSkinnedMesh::checkForAnimation()
|
|||
SkinnedLastFrame=false;
|
||||
}
|
||||
|
||||
|
||||
//! called by loader after populating with mesh and bone data
|
||||
void CSkinnedMesh::finalize()
|
||||
{
|
||||
os::Printer::log("Skinned Mesh - finalize", ELL_DEBUG);
|
||||
u32 i;
|
||||
|
||||
// Make sure we recalc the next frame
|
||||
|
@ -939,8 +1013,6 @@ void CSkinnedMesh::finalize()
|
|||
Vertices_Moved[i].set_used(LocalBuffers[i]->getVertexCount());
|
||||
}
|
||||
|
||||
//Todo: optimise keys here...
|
||||
|
||||
checkForAnimation();
|
||||
|
||||
if (HasAnimation)
|
||||
|
@ -952,76 +1024,42 @@ void CSkinnedMesh::finalize()
|
|||
core::array<SScaleKey> &ScaleKeys = AllJoints[i]->ScaleKeys;
|
||||
core::array<SRotationKey> &RotationKeys = AllJoints[i]->RotationKeys;
|
||||
|
||||
if (PositionKeys.size()>2)
|
||||
// drop identical middle keys - we only need the first and last frame
|
||||
irr::u32 dropped = dropMiddleKeys<SPositionKey>(PositionKeys, identicalPos);
|
||||
if ( dropped > 0 )
|
||||
{
|
||||
for(u32 j=0;j<PositionKeys.size()-2;++j)
|
||||
{
|
||||
if (PositionKeys[j].position == PositionKeys[j+1].position && PositionKeys[j+1].position == PositionKeys[j+2].position)
|
||||
{
|
||||
PositionKeys.erase(j+1); //the middle key is unneeded
|
||||
--j;
|
||||
}
|
||||
}
|
||||
os::Printer::log("Skinned Mesh - unneeded position frames kicked:", core::stringc(dropped).c_str(), ELL_DEBUG);
|
||||
}
|
||||
|
||||
if (PositionKeys.size()>1)
|
||||
|
||||
// drop frames with bad keys (frames out of order)
|
||||
dropped = dropBadKeys<SPositionKey>(PositionKeys);
|
||||
if ( dropped > 0 )
|
||||
{
|
||||
for(u32 j=0;j<PositionKeys.size()-1;++j)
|
||||
{
|
||||
if (PositionKeys[j].frame >= PositionKeys[j+1].frame) //bad frame, unneed and may cause problems
|
||||
{
|
||||
PositionKeys.erase(j+1);
|
||||
--j;
|
||||
}
|
||||
}
|
||||
irr::os::Printer::log("Skinned Mesh - bad position frames kicked:", irr::core::stringc(dropped).c_str(), irr::ELL_DEBUG);
|
||||
}
|
||||
|
||||
if (ScaleKeys.size()>2)
|
||||
|
||||
dropped = dropMiddleKeys<SScaleKey>(ScaleKeys, identicalScale);
|
||||
if ( dropped > 0 )
|
||||
{
|
||||
for(u32 j=0;j<ScaleKeys.size()-2;++j)
|
||||
{
|
||||
if (ScaleKeys[j].scale == ScaleKeys[j+1].scale && ScaleKeys[j+1].scale == ScaleKeys[j+2].scale)
|
||||
{
|
||||
ScaleKeys.erase(j+1); //the middle key is unneeded
|
||||
--j;
|
||||
}
|
||||
}
|
||||
os::Printer::log("Skinned Mesh - unneeded scale frames kicked:", core::stringc(dropped).c_str(), ELL_DEBUG);
|
||||
}
|
||||
|
||||
if (ScaleKeys.size()>1)
|
||||
|
||||
dropped = dropBadKeys<SScaleKey>(ScaleKeys);
|
||||
if ( dropped > 0 )
|
||||
{
|
||||
for(u32 j=0;j<ScaleKeys.size()-1;++j)
|
||||
{
|
||||
if (ScaleKeys[j].frame >= ScaleKeys[j+1].frame) //bad frame, unneed and may cause problems
|
||||
{
|
||||
ScaleKeys.erase(j+1);
|
||||
--j;
|
||||
}
|
||||
}
|
||||
irr::os::Printer::log("Skinned Mesh - bad scale frames kicked:", irr::core::stringc(dropped).c_str(), irr::ELL_DEBUG);
|
||||
}
|
||||
|
||||
if (RotationKeys.size()>2)
|
||||
|
||||
dropped = dropMiddleKeys<SRotationKey>(RotationKeys, identicalRotation);
|
||||
if ( dropped > 0 )
|
||||
{
|
||||
for(u32 j=0;j<RotationKeys.size()-2;++j)
|
||||
{
|
||||
if (RotationKeys[j].rotation == RotationKeys[j+1].rotation && RotationKeys[j+1].rotation == RotationKeys[j+2].rotation)
|
||||
{
|
||||
RotationKeys.erase(j+1); //the middle key is unneeded
|
||||
--j;
|
||||
}
|
||||
}
|
||||
os::Printer::log("Skinned Mesh - unneeded rotation frames kicked:", core::stringc(dropped).c_str(), ELL_DEBUG);
|
||||
}
|
||||
|
||||
if (RotationKeys.size()>1)
|
||||
|
||||
dropped = dropBadKeys<SRotationKey>(RotationKeys);
|
||||
if ( dropped > 0 )
|
||||
{
|
||||
for(u32 j=0;j<RotationKeys.size()-1;++j)
|
||||
{
|
||||
if (RotationKeys[j].frame >= RotationKeys[j+1].frame) //bad frame, unneed and may cause problems
|
||||
{
|
||||
RotationKeys.erase(j+1);
|
||||
--j;
|
||||
}
|
||||
}
|
||||
irr::os::Printer::log("Skinned Mesh - bad rotation frames kicked:", irr::core::stringc(dropped).c_str(), irr::ELL_DEBUG);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -704,7 +704,7 @@
|
|||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>
|
||||
</DebugInformationFormat>
|
||||
<CallingConvention>FastCall</CallingConvention>
|
||||
<CallingConvention>Cdecl</CallingConvention>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
|
Loading…
Reference in New Issue