Merge revisions r5604 through r5621 from trunk to ogl-es.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5622 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
67d3ffbc1f
commit
bdb412cd44
16
changes.txt
16
changes.txt
|
@ -9,6 +9,22 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
|
|||
|
||||
--------------------------
|
||||
Changes in 1.9 (not yet released)
|
||||
- CGUIComboBox uses now EGDS_SCROLLBAR_SIZE instead of EGDS_WINDOW_BUTTON_WIDTH for the width of the listbox button to allow changing that without changing window topbar height.
|
||||
Thanks @LunaRebirth for reporting. (Forum: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=52297&p=303682#p303682)
|
||||
- CGUIListbox, CGUITreeView and CGUITable now resize scrollbars when EGDS_SCROLLBAR_SIZE in the skin changes without having to re-create the elements.
|
||||
This also fixes the problem that drawing looked wrong when this value got changed after the elements were created.
|
||||
Thanks @LunaRebirth for reporting. (Forum: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=1&t=52297&p=303682#p303682)
|
||||
- Scrollbar buttons can no longer get larger than half the ScrollBar element to avoid them overlapping.
|
||||
- Add IVideoDriver::swapMaterialRenderers to allow swapping the renderer used to render a certain material.
|
||||
- IMeshManipulator functions createMeshWith1TCoords, createMeshWith2TCoords and createMeshWithTangents no longer weld vertices while converting meshes. Use IMeshManipulator::createMeshWelded if you need that welding.
|
||||
- Add ITerrainSceneNode::setFixedBorderLOD to handle connecting terrain nodes without gaps. Thanks @diho for the bugreport, testcase and a patch proposal (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=51220).
|
||||
- PLY loader now works with files which use "st" instead of "uv" for texture coordinates (like generated from Blender or Assimp). Thanks @JLouisB for patch (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=52261).
|
||||
- STL writer does now also write binary files when EMWF_WRITE_BINARY flag is used. Based on patch from JLouisB (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=52261).
|
||||
(EMWF_WRITE_COMPRESSED also still works for downward compatibility)
|
||||
- Improved PLY exporter. Thanks for Patch from JLouisB. (Forum: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=52261):
|
||||
- Support for UV and vertex colors.
|
||||
- Support for binary PLY files export with the EMWF_WRITE_BINARY flag
|
||||
- Fix for the meshes with 32 bits index
|
||||
- Fix wrong colors on big endian platforms with burnings renders. Thx @kas1e for reporting and @curaga for the patch (#318). Forum bug discussion at http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=52177.
|
||||
- Fix bug #440 where OpenGL driver enabled second texture for single-texture materials when setMaterial was called twice. Thx@ "number Zero" for bugreport and test-case.
|
||||
- Irrlicht icon now loaded with LR_DEFAULTSIZE to better support larger icon requests. Thx@ luthyr for report and bugfix.
|
||||
|
|
|
@ -29,7 +29,7 @@ using namespace gui;
|
|||
Some global variables used later on
|
||||
*/
|
||||
IrrlichtDevice *Device = 0;
|
||||
core::stringc StartUpModelFile;
|
||||
io::path StartUpModelFile;
|
||||
core::stringw MessageText;
|
||||
core::stringw Caption;
|
||||
scene::ISceneNode* Model = 0;
|
||||
|
@ -166,10 +166,8 @@ Function loadModel() loads a model and displays it using an
|
|||
addAnimatedMeshSceneNode and the scene manager. Nothing difficult. It also
|
||||
displays a short message box, if the model could not be loaded.
|
||||
*/
|
||||
void loadModel(const c8* fn)
|
||||
void loadModel(const io::path& filename)
|
||||
{
|
||||
io::path filename(fn);
|
||||
|
||||
io::path extension;
|
||||
core::getFileNameExtension(extension, filename);
|
||||
extension.make_lower();
|
||||
|
@ -440,7 +438,7 @@ public:
|
|||
// load the model file, selected in the file open dialog
|
||||
IGUIFileOpenDialog* dialog =
|
||||
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
|
||||
loadModel(core::stringc(dialog->getFileName()).c_str());
|
||||
loadModel(dialog->getFileNameP());
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -45,9 +45,12 @@ namespace scene
|
|||
EMWF_NONE = 0,
|
||||
|
||||
//! write lightmap textures out if possible
|
||||
//! Currently not used by any Irrlicht mesh-writer
|
||||
// (Note: User meshwriters can still use it)
|
||||
EMWF_WRITE_LIGHTMAPS = 0x1,
|
||||
|
||||
//! write in a way that consumes less disk space
|
||||
// (Note: Mainly there for user meshwriters)
|
||||
EMWF_WRITE_COMPRESSED = 0x2,
|
||||
|
||||
//! write in binary format rather than text
|
||||
|
|
|
@ -149,11 +149,11 @@ namespace gui
|
|||
//! Enumeration for default sizes.
|
||||
enum EGUI_DEFAULT_SIZE
|
||||
{
|
||||
//! default with / height of scrollbar
|
||||
//! default with / height of scrollbar. Also width of drop-down button in comboboxes.
|
||||
EGDS_SCROLLBAR_SIZE = 0,
|
||||
//! height of menu
|
||||
EGDS_MENU_HEIGHT,
|
||||
//! width of a window button
|
||||
//! width and height of a window titlebar button (like minimize/maximize/close buttons). The titlebar height is also calculated from that.
|
||||
EGDS_WINDOW_BUTTON_WIDTH,
|
||||
//! width of a checkbox check
|
||||
EGDS_CHECK_BOX_WIDTH,
|
||||
|
@ -163,7 +163,7 @@ namespace gui
|
|||
EGDS_MESSAGE_BOX_HEIGHT,
|
||||
//! width of a default button
|
||||
EGDS_BUTTON_WIDTH,
|
||||
//! height of a default button
|
||||
//! height of a default button (OK and cancel buttons)
|
||||
EGDS_BUTTON_HEIGHT,
|
||||
//! distance for text from background
|
||||
EGDS_TEXT_DISTANCE_X,
|
||||
|
|
|
@ -100,7 +100,9 @@ namespace scene
|
|||
virtual s32 getCurrentLODOfPatches(core::array<s32>& LODs) const =0;
|
||||
|
||||
//! Manually sets the LOD of a patch
|
||||
/** \param patchX Patch x coordinate.
|
||||
/** NOTE: Any values set here are overwritten again in the automatic
|
||||
recalculations when the camera changes.
|
||||
\param patchX Patch x coordinate.
|
||||
\param patchZ Patch z coordinate.
|
||||
\param LOD The level of detail to set the patch to. */
|
||||
virtual void setLODOfPatch(s32 patchX, s32 patchZ, s32 LOD=0) =0;
|
||||
|
@ -172,6 +174,12 @@ namespace scene
|
|||
video::SColor vertexColor=video::SColor(255,255,255,255),
|
||||
s32 smoothFactor=0) =0;
|
||||
|
||||
//! Force node to use a fixed LOD level at the borders of the terrain.
|
||||
/** This can be useful when several TerrainSceneNodes are connected.
|
||||
\param borderLOD When >= 0 all patches at the 4 borders will use the
|
||||
given LOD. When < 0 borders are just regular patches (that's default). */
|
||||
virtual void setFixedBorderLOD(irr::s32 borderLOD=0) = 0;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
|
|
@ -501,11 +501,15 @@ namespace video
|
|||
bool zeroTexels = false) const =0;
|
||||
|
||||
//! Creates a normal map from a height map texture.
|
||||
/** If the target texture has 32 bit, the height value is
|
||||
stored in the alpha component of the texture as addition. This
|
||||
value is used by the video::EMT_PARALLAX_MAP_SOLID material and
|
||||
similar materials.
|
||||
\param texture Texture whose alpha channel is modified.
|
||||
/** As input is considered to be a height map the texture is read like:
|
||||
- For a 32-bit texture only the red channel is regarded
|
||||
- For a 16-bit texture the rgb-values are averaged.
|
||||
Output channels red/green for X/Y and blue for up (Z).
|
||||
For a 32-bit texture we store additionally the height value in the
|
||||
alpha channel. This value is used by the video::EMT_PARALLAX_MAP_SOLID
|
||||
material and similar materials.
|
||||
On the borders the texture is considered to repeat.
|
||||
\param texture Height map texture which is converted to a normal map.
|
||||
\param amplitude Constant value by which the height
|
||||
information is multiplied.*/
|
||||
virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const =0;
|
||||
|
@ -1327,6 +1331,16 @@ namespace video
|
|||
\param name: New name of the material renderer. */
|
||||
virtual void setMaterialRendererName(s32 idx, const c8* name) =0;
|
||||
|
||||
//! Swap the material renderers used for certain id's
|
||||
/** Swap the IMaterialRenderers responsible for rendering specific
|
||||
material-id's. This means every SMaterial using a MaterialType
|
||||
with one of the indices involved here will now render differently.
|
||||
\param idx1 First material index to swap. It must already exist or nothing happens.
|
||||
\param idx2 Second material index to swap. It must already exist or nothing happens.
|
||||
\param swapNames When true the renderer names also swap
|
||||
When false the names will stay at the original index */
|
||||
virtual void swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames=true) = 0;
|
||||
|
||||
//! Creates material attributes list from a material
|
||||
/** This method is useful for serialization and more.
|
||||
Please note that the video driver will use the material
|
||||
|
|
|
@ -25,7 +25,9 @@ enum E_VERTEX_TYPE
|
|||
EVT_2TCOORDS,
|
||||
|
||||
//! Vertex with a tangent and binormal vector, video::S3DVertexTangents.
|
||||
/** Usually used for tangent space normal mapping. */
|
||||
/** Usually used for tangent space normal mapping.
|
||||
Usually tangent and binormal get send to shaders as texture coordinate sets 1 and 2.
|
||||
*/
|
||||
EVT_TANGENTS
|
||||
};
|
||||
|
||||
|
@ -181,7 +183,9 @@ struct S3DVertex2TCoords : public S3DVertex
|
|||
|
||||
|
||||
//! Vertex with a tangent and binormal vector.
|
||||
/** Usually used for tangent space normal mapping. */
|
||||
/** Usually used for tangent space normal mapping.
|
||||
Usually tangent and binormal get send to shaders as texture coordinate sets 1 and 2.
|
||||
*/
|
||||
struct S3DVertexTangents : public S3DVertex
|
||||
{
|
||||
//! default constructor
|
||||
|
|
|
@ -440,7 +440,7 @@ namespace video
|
|||
f32 BlendFactor;
|
||||
|
||||
//! Factor specifying how far the polygon offset should be made
|
||||
/** Specifying 0 disables the polygon offset. The direction is specified spearately.
|
||||
/** Specifying 0 disables the polygon offset. The direction is specified separately.
|
||||
The factor can be from 0 to 7.*/
|
||||
u8 PolygonOffsetFactor:3;
|
||||
|
||||
|
|
|
@ -236,22 +236,24 @@ namespace irr
|
|||
if (!Surface[i] && Texture[i])
|
||||
{
|
||||
IDirect3DTexture9* currentTexture = static_cast<CD3D9Texture*>(Texture[i])->getDX9Texture();
|
||||
|
||||
IDirect3DSurface9* currentSurface = 0;
|
||||
currentTexture->GetSurfaceLevel(0, ¤tSurface);
|
||||
|
||||
Surface[i] = currentSurface;
|
||||
if ( currentTexture )
|
||||
{
|
||||
IDirect3DSurface9* currentSurface = 0;
|
||||
currentTexture->GetSurfaceLevel(0, ¤tSurface);
|
||||
Surface[i] = currentSurface;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DepthStencilSurface && DepthStencil)
|
||||
{
|
||||
IDirect3DTexture9* currentTexture = static_cast<CD3D9Texture*>(DepthStencil)->getDX9Texture();
|
||||
|
||||
IDirect3DSurface9* currentSurface = 0;
|
||||
currentTexture->GetSurfaceLevel(0, ¤tSurface);
|
||||
|
||||
DepthStencilSurface = currentSurface;
|
||||
if ( currentTexture )
|
||||
{
|
||||
IDirect3DSurface9* currentSurface = 0;
|
||||
currentTexture->GetSurfaceLevel(0, ¤tSurface);
|
||||
DepthStencilSurface = currentSurface;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -353,13 +353,13 @@ void CD3D9Texture::generateRenderTarget()
|
|||
if (FAILED(hr))
|
||||
{
|
||||
if (D3DERR_INVALIDCALL == hr)
|
||||
os::Printer::log("Could not create render target texture", "Invalid Call");
|
||||
os::Printer::log("Could not create render target texture", "Invalid Call", irr::ELL_ERROR);
|
||||
else if (D3DERR_OUTOFVIDEOMEMORY == hr)
|
||||
os::Printer::log("Could not create render target texture", "Out of Video Memory");
|
||||
os::Printer::log("Could not create render target texture", "Out of Video Memory", irr::ELL_ERROR);
|
||||
else if (E_OUTOFMEMORY == hr)
|
||||
os::Printer::log("Could not create render target texture", "Out of Memory");
|
||||
os::Printer::log("Could not create render target texture", "Out of Memory", irr::ELL_ERROR);
|
||||
else
|
||||
os::Printer::log("Could not create render target texture");
|
||||
os::Printer::log("Could not create render target texture", irr::ELL_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,18 +33,7 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
|
||||
s32 width = 15;
|
||||
if (skin)
|
||||
width = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
|
||||
|
||||
core::rect<s32> r;
|
||||
r.UpperLeftCorner.X = rectangle.getWidth() - width - 2;
|
||||
r.LowerRightCorner.X = rectangle.getWidth() - 2;
|
||||
|
||||
r.UpperLeftCorner.Y = 2;
|
||||
r.LowerRightCorner.Y = rectangle.getHeight() - 2;
|
||||
|
||||
ListButton = Environment->addButton(r, this, -1, L"");
|
||||
ListButton = Environment->addButton(core::recti(0,0,1,1), this, -1, L"");
|
||||
if (skin && skin->getSpriteBank())
|
||||
{
|
||||
ListButton->setSpriteBank(skin->getSpriteBank());
|
||||
|
@ -55,12 +44,7 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
ListButton->setSubElement(true);
|
||||
ListButton->setTabStop(false);
|
||||
|
||||
r.UpperLeftCorner.X = 2;
|
||||
r.UpperLeftCorner.Y = 2;
|
||||
r.LowerRightCorner.X = RelativeRect.getWidth() - (ListButton->getAbsolutePosition().getWidth() + 2);
|
||||
r.LowerRightCorner.Y = RelativeRect.getHeight() - 2;
|
||||
|
||||
SelectedText = Environment->addStaticText(L"", r, false, false, this, -1, false);
|
||||
SelectedText = Environment->addStaticText(L"", core::recti(0,0,1,1), false, false, this, -1, false);
|
||||
SelectedText->setSubElement(true);
|
||||
SelectedText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
SelectedText->setTextAlignment(EGUIA_UPPERLEFT, EGUIA_CENTER);
|
||||
|
@ -68,6 +52,8 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
SelectedText->setOverrideColor(skin->getColor(EGDC_BUTTON_TEXT));
|
||||
SelectedText->enableOverrideColor(true);
|
||||
|
||||
updateListButtonWidth(skin ? skin->getSize(EGDS_SCROLLBAR_SIZE) : 15);
|
||||
|
||||
// this element can be tabbed to
|
||||
setTabStop(true);
|
||||
setTabOrder(-1);
|
||||
|
@ -377,6 +363,24 @@ void CGUIComboBox::sendSelectionChangedEvent()
|
|||
}
|
||||
}
|
||||
|
||||
void CGUIComboBox::updateListButtonWidth(s32 width)
|
||||
{
|
||||
if (ListButton->getRelativePosition().getWidth() != width)
|
||||
{
|
||||
core::rect<s32> r;
|
||||
r.UpperLeftCorner.X = RelativeRect.getWidth() - width - 2;
|
||||
r.LowerRightCorner.X = RelativeRect.getWidth() - 2;
|
||||
r.UpperLeftCorner.Y = 2;
|
||||
r.LowerRightCorner.Y = RelativeRect.getHeight() - 2;
|
||||
ListButton->setRelativePosition(r);
|
||||
|
||||
r.UpperLeftCorner.X = 2;
|
||||
r.UpperLeftCorner.Y = 2;
|
||||
r.LowerRightCorner.X = RelativeRect.getWidth() - (width + 2);
|
||||
r.LowerRightCorner.Y = RelativeRect.getHeight() - 2;
|
||||
SelectedText->setRelativePosition(r);
|
||||
}
|
||||
}
|
||||
|
||||
//! draws the element and its children
|
||||
void CGUIComboBox::draw()
|
||||
|
@ -386,6 +390,8 @@ void CGUIComboBox::draw()
|
|||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
|
||||
updateListButtonWidth(skin->getSize(EGDS_SCROLLBAR_SIZE));
|
||||
|
||||
// font changed while the listbox is open?
|
||||
if ( ActiveFont != skin->getFont() && ListBox )
|
||||
{
|
||||
|
|
|
@ -84,6 +84,7 @@ namespace gui
|
|||
|
||||
void openCloseMenu();
|
||||
void sendSelectionChangedEvent();
|
||||
void updateListButtonWidth(s32 width);
|
||||
|
||||
IGUIButton* ListButton;
|
||||
IGUIStaticText* SelectedText;
|
||||
|
|
|
@ -34,10 +34,9 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
#endif
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
const s32 s = skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
|
||||
ScrollBar = new CGUIScrollBar(false, Environment, this, -1,
|
||||
core::rect<s32>(RelativeRect.getWidth() - s, 0, RelativeRect.getWidth(), RelativeRect.getHeight()),
|
||||
ScrollBar = new CGUIScrollBar(false, Environment, this, -1,
|
||||
core::recti(0, 0, 1, 1),
|
||||
!clip);
|
||||
ScrollBar->setSubElement(true);
|
||||
ScrollBar->setTabStop(false);
|
||||
|
@ -45,6 +44,8 @@ CGUIListBox::CGUIListBox(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
ScrollBar->setVisible(false);
|
||||
ScrollBar->setPos(0);
|
||||
|
||||
updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE));
|
||||
|
||||
setNotClipped(!clip);
|
||||
|
||||
// this element can be tabbed to
|
||||
|
@ -149,8 +150,7 @@ void CGUIListBox::clear()
|
|||
ItemsIconWidth = 0;
|
||||
Selected = -1;
|
||||
|
||||
if (ScrollBar)
|
||||
ScrollBar->setPos(0);
|
||||
ScrollBar->setPos(0);
|
||||
|
||||
recalculateItemHeight();
|
||||
}
|
||||
|
@ -190,7 +190,6 @@ void CGUIListBox::recalculateItemHeight()
|
|||
ScrollBar->setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
//! returns id of selected item. returns -1 if no item is selected.
|
||||
s32 CGUIListBox::getSelected() const
|
||||
{
|
||||
|
@ -495,6 +494,7 @@ void CGUIListBox::draw()
|
|||
recalculateItemHeight(); // if the font changed
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE));
|
||||
|
||||
core::rect<s32>* clipRect = 0;
|
||||
|
||||
|
@ -507,7 +507,7 @@ void CGUIListBox::draw()
|
|||
clientClip.UpperLeftCorner.Y += 1;
|
||||
clientClip.UpperLeftCorner.X += 1;
|
||||
if (ScrollBar->isVisible())
|
||||
clientClip.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
clientClip.LowerRightCorner.X -= ScrollBar->getRelativePosition().getWidth();
|
||||
clientClip.LowerRightCorner.Y -= 1;
|
||||
clientClip.clipAgainst(AbsoluteClippingRect);
|
||||
|
||||
|
@ -520,7 +520,7 @@ void CGUIListBox::draw()
|
|||
frameRect = AbsoluteRect;
|
||||
frameRect.UpperLeftCorner.X += 1;
|
||||
if (ScrollBar->isVisible())
|
||||
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
frameRect.LowerRightCorner.X -= ScrollBar->getRelativePosition().getWidth();
|
||||
|
||||
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
|
||||
|
||||
|
@ -637,6 +637,14 @@ void CGUIListBox::recalculateScrollPos()
|
|||
}
|
||||
}
|
||||
|
||||
void CGUIListBox::updateScrollBarSize(s32 size)
|
||||
{
|
||||
if ( size != ScrollBar->getRelativePosition().getWidth() )
|
||||
{
|
||||
core::recti r(RelativeRect.getWidth() - size, 0, RelativeRect.getWidth(), RelativeRect.getHeight());
|
||||
ScrollBar->setRelativePosition(r);
|
||||
}
|
||||
}
|
||||
|
||||
void CGUIListBox::setAutoScrollEnabled(bool scroll)
|
||||
{
|
||||
|
|
|
@ -157,6 +157,7 @@ namespace gui
|
|||
void recalculateItemHeight();
|
||||
void selectNew(s32 ypos, bool onlyHover=false);
|
||||
void recalculateScrollPos();
|
||||
void updateScrollBarSize(s32 size);
|
||||
|
||||
// extracted that function to avoid copy&paste code
|
||||
void recalculateItemWidth(s32 icon);
|
||||
|
|
|
@ -466,10 +466,11 @@ void CGUIScrollBar::refreshControls()
|
|||
|
||||
if (Horizontal)
|
||||
{
|
||||
s32 h = RelativeRect.getHeight();
|
||||
const s32 h = RelativeRect.getHeight();
|
||||
const s32 w = (h < RelativeRect.getWidth() / 2) ? h : RelativeRect.getWidth() / 2;
|
||||
if (!UpButton)
|
||||
{
|
||||
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, h, h), NoClip);
|
||||
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, h), NoClip);
|
||||
UpButton->setSubElement(true);
|
||||
UpButton->setTabStop(false);
|
||||
}
|
||||
|
@ -479,11 +480,11 @@ void CGUIScrollBar::refreshControls()
|
|||
UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor);
|
||||
UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_LEFT), CurrentIconColor);
|
||||
}
|
||||
UpButton->setRelativePosition(core::rect<s32>(0,0, h, h));
|
||||
UpButton->setRelativePosition(core::rect<s32>(0,0, w, h));
|
||||
UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
if (!DownButton)
|
||||
{
|
||||
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h), NoClip);
|
||||
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(RelativeRect.getWidth()-w, 0, RelativeRect.getWidth(), h), NoClip);
|
||||
DownButton->setSubElement(true);
|
||||
DownButton->setTabStop(false);
|
||||
}
|
||||
|
@ -493,15 +494,16 @@ void CGUIScrollBar::refreshControls()
|
|||
DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor);
|
||||
DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_RIGHT), CurrentIconColor);
|
||||
}
|
||||
DownButton->setRelativePosition(core::rect<s32>(RelativeRect.getWidth()-h, 0, RelativeRect.getWidth(), h));
|
||||
DownButton->setRelativePosition(core::rect<s32>(RelativeRect.getWidth()-w, 0, RelativeRect.getWidth(), h));
|
||||
DownButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 w = RelativeRect.getWidth();
|
||||
const s32 w = RelativeRect.getWidth();
|
||||
const s32 h = (w < RelativeRect.getHeight() / 2) ? w : RelativeRect.getHeight() / 2;
|
||||
if (!UpButton)
|
||||
{
|
||||
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, w), NoClip);
|
||||
UpButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,0, w, h), NoClip);
|
||||
UpButton->setSubElement(true);
|
||||
UpButton->setTabStop(false);
|
||||
}
|
||||
|
@ -511,11 +513,11 @@ void CGUIScrollBar::refreshControls()
|
|||
UpButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor);
|
||||
UpButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_UP), CurrentIconColor);
|
||||
}
|
||||
UpButton->setRelativePosition(core::rect<s32>(0,0, w, w));
|
||||
UpButton->setRelativePosition(core::rect<s32>(0,0, w, h));
|
||||
UpButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
|
||||
if (!DownButton)
|
||||
{
|
||||
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()), NoClip);
|
||||
DownButton = new CGUIButton(Environment, this, -1, core::rect<s32>(0,RelativeRect.getHeight()-h, w, RelativeRect.getHeight()), NoClip);
|
||||
DownButton->setSubElement(true);
|
||||
DownButton->setTabStop(false);
|
||||
}
|
||||
|
@ -525,7 +527,7 @@ void CGUIScrollBar::refreshControls()
|
|||
DownButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor);
|
||||
DownButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), CurrentIconColor);
|
||||
}
|
||||
DownButton->setRelativePosition(core::rect<s32>(0,RelativeRect.getHeight()-w, w, RelativeRect.getHeight()));
|
||||
DownButton->setRelativePosition(core::rect<s32>(0,RelativeRect.getHeight()-h, w, RelativeRect.getHeight()));
|
||||
DownButton->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ CGUITable::CGUITable(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
ItemHeight(0), TotalItemHeight(0), TotalItemWidth(0), Selected(-1),
|
||||
CellHeightPadding(2), CellWidthPadding(5), ActiveTab(-1),
|
||||
CurrentOrdering(EGOM_NONE), DrawFlags(EGTDF_ROWS | EGTDF_COLUMNS | EGTDF_ACTIVE_ROW ),
|
||||
ScrollBarSize(0),
|
||||
OverrideFont(0)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
|
@ -436,7 +437,8 @@ void CGUITable::checkScrollbars()
|
|||
if ( !HorizontalScrollBar || !VerticalScrollBar || !skin)
|
||||
return;
|
||||
|
||||
s32 scrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
ScrollBarSize = skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
|
||||
bool wasHorizontalScrollBarVisible = HorizontalScrollBar->isVisible();
|
||||
bool wasVerticalScrollBarVisible = VerticalScrollBar->isVisible();
|
||||
HorizontalScrollBar->setVisible(false);
|
||||
|
@ -456,7 +458,7 @@ void CGUITable::checkScrollbars()
|
|||
// needs horizontal scroll be visible?
|
||||
if( TotalItemWidth > clientClip.getWidth() )
|
||||
{
|
||||
clientClip.LowerRightCorner.Y -= scrollBarSize;
|
||||
clientClip.LowerRightCorner.Y -= ScrollBarSize;
|
||||
HorizontalScrollBar->setVisible(true);
|
||||
HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth()));
|
||||
}
|
||||
|
@ -464,7 +466,7 @@ void CGUITable::checkScrollbars()
|
|||
// needs vertical scroll be visible?
|
||||
if( TotalItemHeight > clientClip.getHeight() )
|
||||
{
|
||||
clientClip.LowerRightCorner.X -= scrollBarSize;
|
||||
clientClip.LowerRightCorner.X -= ScrollBarSize;
|
||||
VerticalScrollBar->setVisible(true);
|
||||
VerticalScrollBar->setMax(core::max_(0,TotalItemHeight - clientClip.getHeight()));
|
||||
|
||||
|
@ -473,7 +475,7 @@ void CGUITable::checkScrollbars()
|
|||
{
|
||||
if( TotalItemWidth > clientClip.getWidth() )
|
||||
{
|
||||
clientClip.LowerRightCorner.Y -= scrollBarSize;
|
||||
clientClip.LowerRightCorner.Y -= ScrollBarSize;
|
||||
HorizontalScrollBar->setVisible(true);
|
||||
HorizontalScrollBar->setMax(core::max_(0,TotalItemWidth - clientClip.getWidth()));
|
||||
}
|
||||
|
@ -489,13 +491,13 @@ void CGUITable::checkScrollbars()
|
|||
if ( HorizontalScrollBar->isVisible() )
|
||||
{
|
||||
VerticalScrollBar->setRelativePosition(
|
||||
core::rect<s32>(RelativeRect.getWidth() - scrollBarSize, 1,
|
||||
RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+scrollBarSize) ) );
|
||||
core::rect<s32>(RelativeRect.getWidth() - ScrollBarSize, 1,
|
||||
RelativeRect.getWidth()-1, RelativeRect.getHeight()-(1+ScrollBarSize) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
VerticalScrollBar->setRelativePosition(
|
||||
core::rect<s32>(RelativeRect.getWidth() - scrollBarSize, 1,
|
||||
core::rect<s32>(RelativeRect.getWidth() - ScrollBarSize, 1,
|
||||
RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) );
|
||||
}
|
||||
}
|
||||
|
@ -508,11 +510,11 @@ void CGUITable::checkScrollbars()
|
|||
|
||||
if ( VerticalScrollBar->isVisible() )
|
||||
{
|
||||
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-(1+scrollBarSize), RelativeRect.getHeight()-1) );
|
||||
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - ScrollBarSize, RelativeRect.getWidth()-(1+ScrollBarSize), RelativeRect.getHeight()-1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - scrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) );
|
||||
HorizontalScrollBar->setRelativePosition( core::rect<s32>(1, RelativeRect.getHeight() - ScrollBarSize, RelativeRect.getWidth()-1, RelativeRect.getHeight()-1) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -864,15 +866,18 @@ void CGUITable::draw()
|
|||
if (!font)
|
||||
return;
|
||||
|
||||
if ( ScrollBarSize != skin->getSize(EGDS_SCROLLBAR_SIZE) )
|
||||
checkScrollbars();
|
||||
|
||||
// CAREFUL: near identical calculations for tableRect and clientClip are also done in checkScrollbars and selectColumnHeader
|
||||
// Area of table used for drawing without scrollbars
|
||||
core::rect<s32> tableRect(AbsoluteRect);
|
||||
tableRect.UpperLeftCorner.X += 1;
|
||||
tableRect.UpperLeftCorner.Y += 1;
|
||||
if ( VerticalScrollBar && VerticalScrollBar->isVisible() )
|
||||
tableRect.LowerRightCorner.X -= skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
tableRect.LowerRightCorner.X -= ScrollBarSize;
|
||||
if ( HorizontalScrollBar && HorizontalScrollBar->isVisible() )
|
||||
tableRect.LowerRightCorner.Y -= skin->getSize(EGDS_SCROLLBAR_SIZE);
|
||||
tableRect.LowerRightCorner.Y -= ScrollBarSize;
|
||||
|
||||
s32 headerBottom = tableRect.UpperLeftCorner.Y + ItemHeight;
|
||||
|
||||
|
@ -910,7 +915,7 @@ void CGUITable::draw()
|
|||
if (rowRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y &&
|
||||
rowRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y)
|
||||
{
|
||||
// draw row seperator
|
||||
// draw row separator
|
||||
if ( DrawFlags & EGTDF_ROWS )
|
||||
{
|
||||
core::rect<s32> lineRect(rowRect);
|
||||
|
@ -966,7 +971,7 @@ void CGUITable::draw()
|
|||
// draw column background
|
||||
skin->draw3DButtonPaneStandard(this, columnrect, &tableClip);
|
||||
|
||||
// draw column seperator
|
||||
// draw column separator
|
||||
if ( DrawFlags & EGTDF_COLUMNS )
|
||||
{
|
||||
columnSeparator.UpperLeftCorner.X = pos;
|
||||
|
|
|
@ -179,8 +179,8 @@ namespace gui
|
|||
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;
|
||||
|
||||
protected:
|
||||
virtual void refreshControls();
|
||||
virtual void checkScrollbars();
|
||||
void refreshControls();
|
||||
void checkScrollbars();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -240,6 +240,7 @@ namespace gui
|
|||
s32 ActiveTab;
|
||||
EGUI_ORDERING_MODE CurrentOrdering;
|
||||
s32 DrawFlags;
|
||||
s32 ScrollBarSize;
|
||||
|
||||
gui::IGUIFont* OverrideFont;
|
||||
};
|
||||
|
|
|
@ -432,6 +432,7 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
IndentWidth( 0 ),
|
||||
TotalItemHeight( 0 ),
|
||||
TotalItemWidth ( 0 ),
|
||||
ScrollBarSize( 0 ),
|
||||
Font( 0 ),
|
||||
OverrideFont( 0 ),
|
||||
IconFont( 0 ),
|
||||
|
@ -450,15 +451,15 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
#endif
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
s32 s = skin->getSize( EGDS_SCROLLBAR_SIZE );
|
||||
ScrollBarSize = skin->getSize( EGDS_SCROLLBAR_SIZE );
|
||||
|
||||
if ( scrollBarVertical )
|
||||
{
|
||||
ScrollBarV = new CGUIScrollBar( false, Environment, this, -1,
|
||||
core::rect<s32>( RelativeRect.getWidth() - s,
|
||||
core::rect<s32>( RelativeRect.getWidth() - ScrollBarSize,
|
||||
0,
|
||||
RelativeRect.getWidth(),
|
||||
RelativeRect.getHeight() - s
|
||||
RelativeRect.getHeight() - ScrollBarSize
|
||||
), !clip );
|
||||
ScrollBarV->drop();
|
||||
|
||||
|
@ -471,8 +472,8 @@ CGUITreeView::CGUITreeView(IGUIEnvironment* environment, IGUIElement* parent,
|
|||
{
|
||||
ScrollBarH = new CGUIScrollBar( true, Environment, this, -1,
|
||||
core::rect<s32>( 0,
|
||||
RelativeRect.getHeight() - s,
|
||||
RelativeRect.getWidth() - s,
|
||||
RelativeRect.getHeight() - ScrollBarSize,
|
||||
RelativeRect.getWidth() - ScrollBarSize,
|
||||
RelativeRect.getHeight()
|
||||
), !clip );
|
||||
ScrollBarH->drop();
|
||||
|
@ -640,6 +641,28 @@ void CGUITreeView::recalculateItemHeight()
|
|||
|
||||
}
|
||||
|
||||
void CGUITreeView::updateScrollBarSize(s32 size)
|
||||
{
|
||||
if ( size != ScrollBarSize )
|
||||
{
|
||||
ScrollBarSize = size;
|
||||
|
||||
if ( ScrollBarV )
|
||||
{
|
||||
core::recti r(RelativeRect.getWidth() - ScrollBarSize, 0,
|
||||
RelativeRect.getWidth(), RelativeRect.getHeight() - ScrollBarSize);
|
||||
ScrollBarV->setRelativePosition(r);
|
||||
}
|
||||
|
||||
if ( ScrollBarH )
|
||||
{
|
||||
core::recti r(0, RelativeRect.getHeight() - ScrollBarSize,
|
||||
RelativeRect.getWidth() - ScrollBarSize, RelativeRect.getHeight());
|
||||
ScrollBarH->setRelativePosition(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! called if an event happened.
|
||||
bool CGUITreeView::OnEvent( const SEvent &event )
|
||||
{
|
||||
|
@ -829,9 +852,11 @@ void CGUITreeView::draw()
|
|||
return;
|
||||
}
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
|
||||
updateScrollBarSize(skin->getSize(EGDS_SCROLLBAR_SIZE));
|
||||
recalculateItemHeight(); // if the font changed
|
||||
|
||||
IGUISkin* skin = Environment->getSkin();
|
||||
irr::video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
|
||||
core::rect<s32>* clipRect = 0;
|
||||
|
@ -876,9 +901,9 @@ void CGUITreeView::draw()
|
|||
clientClip.LowerRightCorner.Y -= 1;
|
||||
|
||||
if ( ScrollBarV )
|
||||
clientClip.LowerRightCorner.X -= skin->getSize( EGDS_SCROLLBAR_SIZE );
|
||||
clientClip.LowerRightCorner.X -= ScrollBarSize;
|
||||
if ( ScrollBarH )
|
||||
clientClip.LowerRightCorner.Y -= skin->getSize( EGDS_SCROLLBAR_SIZE );
|
||||
clientClip.LowerRightCorner.Y -= ScrollBarSize;
|
||||
|
||||
if( clipRect )
|
||||
{
|
||||
|
@ -886,7 +911,7 @@ void CGUITreeView::draw()
|
|||
}
|
||||
|
||||
frameRect = AbsoluteRect;
|
||||
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize( EGDS_SCROLLBAR_SIZE );
|
||||
frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - ScrollBarSize;
|
||||
frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight;
|
||||
|
||||
if ( ScrollBarV )
|
||||
|
|
|
@ -320,6 +320,9 @@ namespace gui
|
|||
//! calculates the heigth of an node and of all visible nodes.
|
||||
void recalculateItemHeight();
|
||||
|
||||
//! Resize scrollbars when their size in the skin has changed
|
||||
void updateScrollBarSize(s32 size);
|
||||
|
||||
//! executes an mouse action (like selectNew of CGUIListBox)
|
||||
void mouseAction( s32 xpos, s32 ypos, bool onlyHover = false );
|
||||
|
||||
|
@ -329,6 +332,7 @@ namespace gui
|
|||
s32 IndentWidth;
|
||||
s32 TotalItemHeight;
|
||||
s32 TotalItemWidth;
|
||||
s32 ScrollBarSize;
|
||||
IGUIFont* Font;
|
||||
gui::IGUIFont* OverrideFont;
|
||||
IGUIFont* IconFont;
|
||||
|
|
|
@ -951,75 +951,63 @@ IMesh* CMeshManipulator::createMeshWelded(IMesh *mesh, f32 tolerance) const
|
|||
// not yet 32bit
|
||||
IMesh* CMeshManipulator::createMeshWithTangents(IMesh* mesh, bool recalculateNormals, bool smooth, bool angleWeighted, bool calculateTangents) const
|
||||
{
|
||||
using namespace video;
|
||||
|
||||
if (!mesh)
|
||||
return 0;
|
||||
|
||||
// copy mesh and fill data into SMeshBufferTangents
|
||||
|
||||
SMesh* clone = new SMesh();
|
||||
const u32 meshBufferCount = mesh->getMeshBufferCount();
|
||||
|
||||
for (u32 b=0; b<meshBufferCount; ++b)
|
||||
{
|
||||
const IMeshBuffer* const original = mesh->getMeshBuffer(b);
|
||||
const u32 idxCnt = original->getIndexCount();
|
||||
const u16* idx = original->getIndices();
|
||||
|
||||
SMeshBufferTangents* buffer = new SMeshBufferTangents();
|
||||
|
||||
// copy material
|
||||
buffer->Material = original->getMaterial();
|
||||
buffer->Vertices.reallocate(idxCnt);
|
||||
buffer->Indices.reallocate(idxCnt);
|
||||
|
||||
core::map<video::S3DVertexTangents, int> vertMap;
|
||||
int vertLocation;
|
||||
// copy indices
|
||||
const u32 idxCnt = original->getIndexCount();
|
||||
const u16* indices = original->getIndices();
|
||||
buffer->Indices.reallocate(idxCnt);
|
||||
for (u32 i=0; i < idxCnt; ++i)
|
||||
buffer->Indices.push_back(indices[i]);
|
||||
|
||||
// copy vertices
|
||||
const u32 vtxCnt = original->getVertexCount();
|
||||
buffer->Vertices.reallocate(vtxCnt);
|
||||
|
||||
const video::E_VERTEX_TYPE vType = original->getVertexType();
|
||||
video::S3DVertexTangents vNew;
|
||||
for (u32 i=0; i<idxCnt; ++i)
|
||||
const E_VERTEX_TYPE vType = original->getVertexType();
|
||||
switch(vType)
|
||||
{
|
||||
switch(vType)
|
||||
case video::EVT_STANDARD:
|
||||
{
|
||||
case video::EVT_STANDARD:
|
||||
{
|
||||
const video::S3DVertex* v =
|
||||
(const video::S3DVertex*)original->getVertices();
|
||||
vNew = video::S3DVertexTangents(
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
const video::S3DVertex2TCoords* v =
|
||||
(const video::S3DVertex2TCoords*)original->getVertices();
|
||||
vNew = video::S3DVertexTangents(
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
{
|
||||
const video::S3DVertexTangents* v =
|
||||
(const video::S3DVertexTangents*)original->getVertices();
|
||||
vNew = v[idx[i]];
|
||||
}
|
||||
break;
|
||||
}
|
||||
core::map<video::S3DVertexTangents, int>::Node* n = vertMap.find(vNew);
|
||||
if (n)
|
||||
{
|
||||
vertLocation = n->getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
vertLocation = buffer->Vertices.size();
|
||||
buffer->Vertices.push_back(vNew);
|
||||
vertMap.insert(vNew, vertLocation);
|
||||
}
|
||||
const S3DVertex* v = (const S3DVertex*)original->getVertices();
|
||||
|
||||
// create new indices
|
||||
buffer->Indices.push_back(vertLocation);
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back( S3DVertexTangents(
|
||||
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
const S3DVertex2TCoords* v =(const S3DVertex2TCoords*)original->getVertices();
|
||||
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back( S3DVertexTangents(
|
||||
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
{
|
||||
const S3DVertexTangents* v =(const S3DVertexTangents*)original->getVertices();
|
||||
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back(v[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->recalculateBoundingBox();
|
||||
|
||||
|
@ -1347,11 +1335,12 @@ donehere:
|
|||
free(accel);
|
||||
}
|
||||
|
||||
|
||||
//! Creates a copy of the mesh, which will only consist of S3DVertex2TCoords vertices.
|
||||
// not yet 32bit
|
||||
IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
|
||||
{
|
||||
using namespace video;
|
||||
|
||||
if (!mesh)
|
||||
return 0;
|
||||
|
||||
|
@ -1363,63 +1352,50 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
|
|||
for (u32 b=0; b<meshBufferCount; ++b)
|
||||
{
|
||||
const IMeshBuffer* const original = mesh->getMeshBuffer(b);
|
||||
const u32 idxCnt = original->getIndexCount();
|
||||
const u16* idx = original->getIndices();
|
||||
|
||||
SMeshBufferLightMap* buffer = new SMeshBufferLightMap();
|
||||
buffer->Material = original->getMaterial();
|
||||
buffer->Vertices.reallocate(idxCnt);
|
||||
buffer->Indices.reallocate(idxCnt);
|
||||
|
||||
core::map<video::S3DVertex2TCoords, int> vertMap;
|
||||
int vertLocation;
|
||||
// copy material
|
||||
buffer->Material = original->getMaterial();
|
||||
|
||||
// copy indices
|
||||
const u32 idxCnt = original->getIndexCount();
|
||||
const u16* indices = original->getIndices();
|
||||
buffer->Indices.reallocate(idxCnt);
|
||||
for (u32 i=0; i < idxCnt; ++i)
|
||||
buffer->Indices.push_back(indices[i]);
|
||||
|
||||
// copy vertices
|
||||
const u32 vtxCnt = original->getVertexCount();
|
||||
buffer->Vertices.reallocate(vtxCnt);
|
||||
|
||||
const video::E_VERTEX_TYPE vType = original->getVertexType();
|
||||
video::S3DVertex2TCoords vNew;
|
||||
for (u32 i=0; i<idxCnt; ++i)
|
||||
switch(vType)
|
||||
{
|
||||
switch(vType)
|
||||
case video::EVT_STANDARD:
|
||||
{
|
||||
case video::EVT_STANDARD:
|
||||
{
|
||||
const video::S3DVertex* v =
|
||||
(const video::S3DVertex*)original->getVertices();
|
||||
vNew = video::S3DVertex2TCoords(
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
const video::S3DVertex2TCoords* v =
|
||||
(const video::S3DVertex2TCoords*)original->getVertices();
|
||||
vNew = v[idx[i]];
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
{
|
||||
const video::S3DVertexTangents* v =
|
||||
(const video::S3DVertexTangents*)original->getVertices();
|
||||
vNew = video::S3DVertex2TCoords(
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
}
|
||||
core::map<video::S3DVertex2TCoords, int>::Node* n = vertMap.find(vNew);
|
||||
if (n)
|
||||
{
|
||||
vertLocation = n->getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
vertLocation = buffer->Vertices.size();
|
||||
buffer->Vertices.push_back(vNew);
|
||||
vertMap.insert(vNew, vertLocation);
|
||||
}
|
||||
const S3DVertex* v = (const S3DVertex*)original->getVertices();
|
||||
|
||||
// create new indices
|
||||
buffer->Indices.push_back(vertLocation);
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back( video::S3DVertex2TCoords(
|
||||
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords, v[i].TCoords));
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
const S3DVertex2TCoords* v =(const S3DVertex2TCoords*)original->getVertices();
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back(v[i]);
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
{
|
||||
const S3DVertexTangents* v =(const S3DVertexTangents*)original->getVertices();
|
||||
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back( S3DVertex2TCoords(
|
||||
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords, v[i].TCoords) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
buffer->recalculateBoundingBox();
|
||||
|
||||
|
@ -1437,6 +1413,8 @@ IMesh* CMeshManipulator::createMeshWith2TCoords(IMesh* mesh) const
|
|||
// not yet 32bit
|
||||
IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
|
||||
{
|
||||
using namespace video;
|
||||
|
||||
if (!mesh)
|
||||
return 0;
|
||||
|
||||
|
@ -1446,64 +1424,54 @@ IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const
|
|||
|
||||
for (u32 b=0; b<meshBufferCount; ++b)
|
||||
{
|
||||
IMeshBuffer* original = mesh->getMeshBuffer(b);
|
||||
const u32 idxCnt = original->getIndexCount();
|
||||
const u16* idx = original->getIndices();
|
||||
|
||||
const IMeshBuffer* const original = mesh->getMeshBuffer(b);
|
||||
SMeshBuffer* buffer = new SMeshBuffer();
|
||||
buffer->Material = original->getMaterial();
|
||||
buffer->Vertices.reallocate(idxCnt);
|
||||
buffer->Indices.reallocate(idxCnt);
|
||||
|
||||
core::map<video::S3DVertex, int> vertMap;
|
||||
int vertLocation;
|
||||
// copy material
|
||||
buffer->Material = original->getMaterial();
|
||||
|
||||
// copy indices
|
||||
const u32 idxCnt = original->getIndexCount();
|
||||
const u16* indices = original->getIndices();
|
||||
buffer->Indices.reallocate(idxCnt);
|
||||
for (u32 i=0; i < idxCnt; ++i)
|
||||
buffer->Indices.push_back(indices[i]);
|
||||
|
||||
// copy vertices
|
||||
const video::E_VERTEX_TYPE vType = original->getVertexType();
|
||||
video::S3DVertex vNew;
|
||||
for (u32 i=0; i<idxCnt; ++i)
|
||||
{
|
||||
switch(vType)
|
||||
{
|
||||
case video::EVT_STANDARD:
|
||||
{
|
||||
video::S3DVertex* v =
|
||||
(video::S3DVertex*)original->getVertices();
|
||||
vNew = v[idx[i]];
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
video::S3DVertex2TCoords* v =
|
||||
(video::S3DVertex2TCoords*)original->getVertices();
|
||||
vNew = video::S3DVertex(
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
{
|
||||
video::S3DVertexTangents* v =
|
||||
(video::S3DVertexTangents*)original->getVertices();
|
||||
vNew = video::S3DVertex(
|
||||
v[idx[i]].Pos, v[idx[i]].Normal, v[idx[i]].Color, v[idx[i]].TCoords);
|
||||
}
|
||||
break;
|
||||
}
|
||||
core::map<video::S3DVertex, int>::Node* n = vertMap.find(vNew);
|
||||
if (n)
|
||||
{
|
||||
vertLocation = n->getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
vertLocation = buffer->Vertices.size();
|
||||
buffer->Vertices.push_back(vNew);
|
||||
vertMap.insert(vNew, vertLocation);
|
||||
}
|
||||
const u32 vtxCnt = original->getVertexCount();
|
||||
buffer->Vertices.reallocate(vtxCnt);
|
||||
|
||||
// create new indices
|
||||
buffer->Indices.push_back(vertLocation);
|
||||
const video::E_VERTEX_TYPE vType = original->getVertexType();
|
||||
switch(vType)
|
||||
{
|
||||
case video::EVT_STANDARD:
|
||||
{
|
||||
const S3DVertex* v = (const S3DVertex*)original->getVertices();
|
||||
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back( v[i] );
|
||||
}
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
{
|
||||
const S3DVertex2TCoords* v =(const S3DVertex2TCoords*)original->getVertices();
|
||||
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back( S3DVertex(
|
||||
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
|
||||
}
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
{
|
||||
const S3DVertexTangents* v =(const S3DVertexTangents*)original->getVertices();
|
||||
|
||||
for (u32 i=0; i < vtxCnt; ++i)
|
||||
buffer->Vertices.push_back( S3DVertex(
|
||||
v[i].Pos, v[i].Normal, v[i].Color, v[i].TCoords) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
buffer->recalculateBoundingBox();
|
||||
// add new buffer
|
||||
clone->addMeshBuffer(buffer);
|
||||
|
|
|
@ -2087,6 +2087,15 @@ void CNullDriver::setMaterialRendererName(s32 idx, const char* name)
|
|||
MaterialRenderers[idx].Name = name;
|
||||
}
|
||||
|
||||
void CNullDriver::swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames)
|
||||
{
|
||||
if ( idx1 < MaterialRenderers.size() && idx2 < MaterialRenderers.size() )
|
||||
{
|
||||
irr::core::swap(MaterialRenderers[idx1].Renderer, MaterialRenderers[idx2].Renderer);
|
||||
if ( swapNames )
|
||||
irr::core::swap(MaterialRenderers[idx1].Name, MaterialRenderers[idx2].Name);
|
||||
}
|
||||
}
|
||||
|
||||
//! Creates material attributes list from a material, usable for serialization and more.
|
||||
io::IAttributes* CNullDriver::createAttributesFromMaterial(const video::SMaterial& material,
|
||||
|
|
|
@ -612,6 +612,9 @@ namespace video
|
|||
//! Sets the name of a material renderer.
|
||||
virtual void setMaterialRendererName(s32 idx, const char* name) _IRR_OVERRIDE_;
|
||||
|
||||
//! Swap the material renderers used for certain id's
|
||||
virtual void swapMaterialRenderers(u32 idx1, u32 idx2, bool swapNames) _IRR_OVERRIDE_;
|
||||
|
||||
//! Creates material attributes list from a material, usable for serialization and more.
|
||||
virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material,
|
||||
io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;
|
||||
|
|
|
@ -571,7 +571,7 @@ public:
|
|||
|
||||
//! Compare material to current cache and update it when there are differences
|
||||
// Some material renderers do change the cache beyond the original material settings
|
||||
// This correct the material to represent the current cache state again.
|
||||
// This corrects the material to represent the current cache state again.
|
||||
void correctCacheMaterial(irr::video::SMaterial& material)
|
||||
{
|
||||
// Fix textures which got removed
|
||||
|
|
|
@ -324,9 +324,10 @@ bool CPLYMeshFileLoader::readVertex(const SPLYElement &Element, scene::CDynamicM
|
|||
vert.Normal.Y = getFloat(t);
|
||||
result=true;
|
||||
}
|
||||
else if (Element.Properties[i].Name == "u")
|
||||
// there isn't a single convention for the UV, some software like Blender or Assimp uses "st" instead of "uv"
|
||||
else if (Element.Properties[i].Name == "u" || Element.Properties[i].Name == "s")
|
||||
vert.TCoords.X = getFloat(t);
|
||||
else if (Element.Properties[i].Name == "v")
|
||||
else if (Element.Properties[i].Name == "v" || Element.Properties[i].Name == "t")
|
||||
vert.TCoords.Y = getFloat(t);
|
||||
else if (Element.Properties[i].Name == "red")
|
||||
{
|
||||
|
|
|
@ -39,11 +39,21 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
|
|||
|
||||
os::Printer::log("Writing mesh", file->getFileName());
|
||||
|
||||
// write PLY header
|
||||
core::stringc header =
|
||||
"ply\n"
|
||||
"format ascii 1.0\n"
|
||||
"comment Irrlicht Engine ";
|
||||
// write PLY header
|
||||
core::stringc header = "ply\n";
|
||||
|
||||
if (flags & scene::EMWF_WRITE_BINARY)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN__
|
||||
header += "format binary_big_endian 1.0\n";
|
||||
#else
|
||||
header += "format binary_little_endian 1.0\n";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
header += "format ascii 1.0\n";
|
||||
|
||||
header += "comment Irrlicht Engine ";
|
||||
header += IRRLICHT_SDK_VERSION;
|
||||
|
||||
// get vertex and triangle counts
|
||||
|
@ -66,16 +76,12 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
|
|||
"property float z\n"
|
||||
"property float nx\n"
|
||||
"property float ny\n"
|
||||
"property float nz\n";
|
||||
// todo: writer flags for extended (r,g,b,u,v) and non-standard (alpha,u1,uv,tx,ty,tz) properties
|
||||
// "property uchar red\n"
|
||||
// "property uchar green\n"
|
||||
// "property uchar blue\n"
|
||||
// "property uchar alpha\n"
|
||||
// "property float u\n"
|
||||
// "property float v\n";
|
||||
// "property float u1\n
|
||||
// "property float v1\n"
|
||||
"property float nz\n"
|
||||
"property float s\n"
|
||||
"property float t\n"
|
||||
"property uchar red\n"
|
||||
"property uchar green\n"
|
||||
"property uchar blue\n";
|
||||
// "property float tx\n"
|
||||
// "property float ty\n"
|
||||
// "property float tz\n"
|
||||
|
@ -97,38 +103,61 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
|
|||
|
||||
for (u32 i=0; i < mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
|
||||
const scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
|
||||
u32 vertexSize = 0;
|
||||
switch(mb->getVertexType())
|
||||
{
|
||||
case video::EVT_STANDARD:
|
||||
vertexSize = sizeof(video::S3DVertex);
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
vertexSize = sizeof(video::S3DVertex2TCoords);
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
vertexSize = sizeof(video::S3DVertexTangents);
|
||||
break;
|
||||
}
|
||||
u8 *vertices = (u8*)mb->getVertices() ;
|
||||
|
||||
for (u32 j=0; j < mb->getVertexCount(); ++j)
|
||||
{
|
||||
const core::vector3df& pos = mb->getPosition(j);
|
||||
const core::vector3df& n = mb->getNormal(j);
|
||||
// const core::vector2df& tc = mb->getTCoords(j);
|
||||
u8 *buf = vertices + j * vertexSize;
|
||||
const video::S3DVertex* vertex = ( (video::S3DVertex*)buf );
|
||||
const core::vector3df& pos = vertex->Pos;
|
||||
const core::vector3df& n = vertex->Normal;
|
||||
const core::vector2df& uv = vertex->TCoords;
|
||||
const video::SColor& color = vertex->Color;
|
||||
|
||||
u8 *buf = (u8*)mb->getVertices();
|
||||
switch(mb->getVertexType())
|
||||
if (flags & scene::EMWF_WRITE_BINARY)
|
||||
{
|
||||
case video::EVT_STANDARD:
|
||||
buf += sizeof(video::S3DVertex)*j;
|
||||
break;
|
||||
case video::EVT_2TCOORDS:
|
||||
buf += sizeof(video::S3DVertex2TCoords)*j;
|
||||
break;
|
||||
case video::EVT_TANGENTS:
|
||||
buf += sizeof(video::S3DVertexTangents)*j;
|
||||
break;
|
||||
// Y and Z are flipped
|
||||
file->write(&pos.X, 4);
|
||||
file->write(&pos.Z, 4);
|
||||
file->write(&pos.Y, 4);
|
||||
|
||||
file->write(&n.X, 4);
|
||||
file->write(&n.Z, 4);
|
||||
file->write(&n.Y, 4);
|
||||
|
||||
file->write(&uv, 8);
|
||||
|
||||
const u32 r = color.getRed(), g = color.getGreen(), b = color.getBlue();
|
||||
file->write(&r, 1);
|
||||
file->write(&g, 1);
|
||||
file->write(&b, 1);
|
||||
}
|
||||
// video::SColor &col = ( (video::S3DVertex*)buf )->Color;
|
||||
else
|
||||
{
|
||||
// x y z nx ny nz u v red green blue [u1 v1 | tx ty tz]\n
|
||||
snprintf_irr(outLine, 1024,
|
||||
"%f %f %f %f %f %f %f %f %d %d %d\n",// %u %u %u %u %f %f\n",
|
||||
pos.X, pos.Z, pos.Y, // Y and Z are flipped
|
||||
n.X, n.Z, n.Y,
|
||||
uv.X, uv.Y,
|
||||
color.getRed(), color.getGreen(), color.getBlue());
|
||||
|
||||
// x y z nx ny nz red green blue alpha u v [u1 v1 | tx ty tz]\n
|
||||
snprintf_irr(outLine, 1024,
|
||||
"%f %f %f %f %f %f\n",// %u %u %u %u %f %f\n",
|
||||
pos.X, pos.Z, pos.Y, // Y and Z are flipped
|
||||
n.X, n.Z, n.Y);
|
||||
/*col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha(),
|
||||
tc.X, tc.Y);*/
|
||||
|
||||
// write the line
|
||||
file->write(outLine, strlen(outLine));
|
||||
file->write(outLine, strlen(outLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,6 +165,7 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
|
|||
u32 StartOffset = 0;
|
||||
|
||||
// write triangles
|
||||
const unsigned char nbIndicesParFace = 3;
|
||||
for (u32 i=0; i < mesh->getMeshBufferCount(); ++i)
|
||||
{
|
||||
scene::IMeshBuffer* mb = mesh->getMeshBuffer(i);
|
||||
|
@ -155,15 +185,24 @@ bool CPLYMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
|
|||
break;
|
||||
case video::EIT_32BIT:
|
||||
a += ((u32*)mb->getIndices()) [j+0];
|
||||
c += ((u32*)mb->getIndices()) [j+0];
|
||||
b += ((u32*)mb->getIndices()) [j+0];
|
||||
c += ((u32*)mb->getIndices()) [j+1];
|
||||
b += ((u32*)mb->getIndices()) [j+2];
|
||||
break;
|
||||
}
|
||||
|
||||
// count a b c\n
|
||||
snprintf_irr(outLine, 1024, "3 %u %u %u\n", a, b, c);
|
||||
// write the line
|
||||
file->write(outLine, strlen(outLine));
|
||||
if (flags & scene::EMWF_WRITE_BINARY)
|
||||
{
|
||||
file->write(&nbIndicesParFace, 1);
|
||||
file->write(&a, 4);
|
||||
file->write(&b, 4);
|
||||
file->write(&c, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// count a b c\n
|
||||
snprintf_irr(outLine, 1024, "3 %u %u %u\n", a, b, c);
|
||||
file->write(outLine, strlen(outLine));
|
||||
}
|
||||
}
|
||||
|
||||
// increment offset
|
||||
|
|
|
@ -54,7 +54,7 @@ bool CSTLMeshWriter::writeMesh(io::IWriteFile* file, scene::IMesh* mesh, s32 fla
|
|||
|
||||
os::Printer::log("Writing mesh", file->getFileName());
|
||||
|
||||
if (flags & scene::EMWF_WRITE_COMPRESSED)
|
||||
if (flags & (scene::EMWF_WRITE_BINARY|scene::EMWF_WRITE_COMPRESSED) )
|
||||
return writeMeshBinary(file, mesh, flags);
|
||||
else
|
||||
return writeMeshASCII(file, mesh, flags);
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace scene
|
|||
TerrainData(patchSize, maxLOD, position, rotation, scale), RenderBuffer(0),
|
||||
VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false),
|
||||
OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(true),
|
||||
FixedBorderLOD(-1),
|
||||
CameraMovementDelta(10.0f), CameraRotationDelta(1.0f),CameraFOVDelta(0.1f),
|
||||
TCoordScale1(1.0f), TCoordScale2(1.0f), SmoothFactor(0), FileSystem(fs)
|
||||
{
|
||||
|
@ -640,7 +641,18 @@ namespace scene
|
|||
{
|
||||
const f32 distance = cameraPosition.getDistanceFromSQ(TerrainData.Patches[j].Center);
|
||||
|
||||
if ( FixedBorderLOD >= 0 )
|
||||
{
|
||||
TerrainData.Patches[j].CurrentLOD = FixedBorderLOD;
|
||||
if (j < TerrainData.PatchCount
|
||||
|| j >= (count - TerrainData.PatchCount)
|
||||
|| (j % TerrainData.PatchCount) == 0
|
||||
|| (j % TerrainData.PatchCount) == TerrainData.PatchCount-1)
|
||||
continue;
|
||||
}
|
||||
|
||||
TerrainData.Patches[j].CurrentLOD = 0;
|
||||
|
||||
for (s32 i = TerrainData.MaxLOD - 1; i>0; --i)
|
||||
{
|
||||
if (distance >= TerrainData.LODDistanceThreshold[i])
|
||||
|
|
|
@ -202,6 +202,12 @@ namespace scene
|
|||
//! Scales the two textures
|
||||
virtual void scaleTexture(f32 scale = 1.0f, f32 scale2 = 0.0f) _IRR_OVERRIDE_;
|
||||
|
||||
//! Force node to use a fixed LOD level at the borders of the terrain.
|
||||
virtual void setFixedBorderLOD(irr::s32 borderLOD) _IRR_OVERRIDE_
|
||||
{
|
||||
FixedBorderLOD = borderLOD;
|
||||
}
|
||||
|
||||
//! Returns type of the scene node
|
||||
virtual ESCENE_NODE_TYPE getType() const _IRR_OVERRIDE_ {return ESNT_TERRAIN;}
|
||||
|
||||
|
@ -303,6 +309,7 @@ namespace scene
|
|||
bool OverrideDistanceThreshold;
|
||||
bool UseDefaultRotationPivot;
|
||||
bool ForceRecalculation;
|
||||
s32 FixedBorderLOD;
|
||||
|
||||
core::vector3df OldCameraPosition;
|
||||
core::vector3df OldCameraRotation;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue