diff options
187 files changed, 69195 insertions, 0 deletions
diff --git a/goodies/inc/agapidll.hxx b/goodies/inc/agapidll.hxx new file mode 100644 index 000000000000..5be1d87ac46e --- /dev/null +++ b/goodies/inc/agapidll.hxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * $RCSfile: agapidll.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _AGAPIDLL_HXX +#define _AGAPIDLL_HXX + +#include "tools/agapi.hxx" +#include "agsdkdll.hxx" + +class ChannelList; +class ChannelAgentItem; +class INetURLObject; +class Library; + +class AgentApiDll : public AgentApi +{ + Library* pAgentDll; + ChannelApiFncs aChannelApiFncs; + + FncInitAgent fncInitAgent; + FncShutDownAgent fncShutDownAgent; + FncNewDataPermission fncNewDataPermission; + FncNewData fncNewData; + FncNotifyChannelObjFile fncNotifyChannelObjFile; + FncNotifyChannelObjData fncNotifyChannelObjData; + FncRegisterChannels fncRegisterChannels; + FncRegisterUpdateTransmitter fncRegisterUpdateTransmitter; + +protected: + friend class ChannelList; + virtual BOOL StartAgent(); + +public: + AgentApiDll(ChannelAgentItem* pAgent); + ~AgentApiDll(); + + virtual void InitAgent(); + virtual void ShutDownAgent(); + + virtual BOOL NewDataPermission(const String& rChannelName); + virtual void NewData(const String& rChannelName, const INetURLObject& rURL); + + virtual void NotifyChannelObjFile(const INetURLObject& rURL, + const String& rFileName); + virtual void NotifyChannelObjData(const INetURLObject& rURL, + void* pBuffer, long nOffset, long nLen, long nTotalLen); + + virtual void RegisterChannels(); + virtual void RegisterUpdateTransmitter(); +}; + +#endif //_AGAPIDLL_HXX + diff --git a/goodies/inc/agsdkdll.hxx b/goodies/inc/agsdkdll.hxx new file mode 100644 index 000000000000..d2f0f2b86526 --- /dev/null +++ b/goodies/inc/agsdkdll.hxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * $RCSfile: agsdkdll.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _AGSDKDLL_HXX +#define _AGSDKDLL_HXX + +#ifndef _SV_CALL +#if defined(WIN) || defined(WNT) || ( defined(OS2) && !defined( ICC )) +#define _SV_CALL _cdecl +#elif defined( ICC ) && defined( OS2 ) +#define _SV_CALL __cdecl +#else +#define _SV_CALL +#endif +#endif + +#define AGSDKDLL_VERSION 2 + +typedef void* AgentInst; + +//////////////////////////////////////////////////////////////////////////////// +// Channel API Functions +// + +enum AgentStreamType { + AS_LOCAL_FILE = 1, + AS_MEMORY = 2 +}; + +typedef void (_SV_CALL *FncChShutDownAgent)(AgentInst pAg); + +typedef void (_SV_CALL *FncChSetLastSuccUpd)(AgentInst pAg); + +typedef void (_SV_CALL *FncChGetChannelObj)(AgentInst pAg, const char* pURL, + AgentStreamType eStreamType, const char* pFileName); + +typedef void (_SV_CALL *FncChAddChannelItem)(AgentInst pAg, const char* pName, + const char* pTransmitter, const char* pChannel, unsigned short nUpdPeriode, + const char* pAgentName ); + +typedef void (_SV_CALL *FncChDelChannelItem)(AgentInst pAg, const char* pChName); + +typedef void (_SV_CALL *FncChSetTransmitter)(AgentInst pAg, const char* pChName, + const char* pURL); + +typedef void (_SV_CALL *FncChSetChannel)(AgentInst pAg, const char* pChName, + const char* pRelURL); + +typedef void (_SV_CALL *FncChSetChannelName)(AgentInst pAg, const char* pChName, + const char* pNewChName); + +typedef void (_SV_CALL *FncChSetUpdPeriode)(AgentInst pAg, const char* pChName, + unsigned short nUpdPeriode); + +typedef void (_SV_CALL *FncChSetChannelAgentName)(AgentInst pAg, const char* pChName, + const char* pAgName); + +typedef void (_SV_CALL *FncChSetUpdateTransmitter)(AgentInst pAg, + const char* pTransmitter); + +typedef const char* (_SV_CALL *FncChGetAgentSourceURL)(AgentInst pAg); + +struct ChannelApiFncs +{ + unsigned short nVersion; + FncChShutDownAgent fncShutDownAgent; + FncChSetLastSuccUpd fncSetLastSuccUpd; + FncChGetChannelObj fncGetChannelObj; + FncChAddChannelItem fncAddChannelItem; + FncChDelChannelItem fncDelChannelItem; + FncChSetTransmitter fncSetTransmitter; + FncChSetChannel fncSetChannel; + FncChSetChannelName fncSetChannelName; + FncChSetUpdPeriode fncSetUpdPeriode; + FncChSetChannelAgentName fncSetChannelAgentName; + FncChSetUpdateTransmitter fncSetUpdateTransmitter; + FncChGetAgentSourceURL fncGetAgentSourceURL; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Agent API Functions +// + +#if defined(WIN) || defined(WNT) || defined(OS2) || defined(UNX) || defined(MAC) +extern "C" { +#endif + +typedef void (_SV_CALL *FncInitAgent)(AgentInst, ChannelApiFncs*); +void _SV_CALL InitAgent(AgentInst, ChannelApiFncs*); + +typedef void (_SV_CALL *FncShutDownAgent)(); +void _SV_CALL ShutDownAgent(); + +// NewDataPermission +// ChannelName +typedef unsigned char (_SV_CALL *FncNewDataPermission)(const char*); +unsigned char _SV_CALL NewDataPermission(const char*); + +// NewData +// ChannelName, URL +typedef void (_SV_CALL *FncNewData)(const char*, const char*); +void _SV_CALL NewData(const char*, const char*); + +// NotifyChannelObjFile +// URL, abs. Filename +typedef void (_SV_CALL *FncNotifyChannelObjFile)(const char*, const char*); +void _SV_CALL NotifyChannelObjFile(const char*, const char*); + +// NotifyChannelObjData +// URL, Buffer, Offset, Len, TotalLen +typedef void (_SV_CALL *FncNotifyChannelObjData)(const char*, void*, long, long, long); +void _SV_CALL NotifyChannelObjData(const char*, void*, long, long, long); + +typedef void (_SV_CALL *FncRegisterChannels)(AgentInst, ChannelApiFncs*); +void _SV_CALL RegisterChannels(AgentInst, ChannelApiFncs*); + +typedef void (_SV_CALL *FncRegisterUpdateTransmitter)(AgentInst, ChannelApiFncs*); +void _SV_CALL RegisterUpdateTransmitter(AgentInst, ChannelApiFncs*); + +#if defined(WIN) || defined(WNT) || defined(OS2) || defined(UNX) || defined(MAC) +} +#endif + +#endif //_AGSDKDLL_HXX + + diff --git a/goodies/inc/b3dtex.hxx b/goodies/inc/b3dtex.hxx new file mode 100644 index 000000000000..3aeecdb85de1 --- /dev/null +++ b/goodies/inc/b3dtex.hxx @@ -0,0 +1,385 @@ +/************************************************************************* + * + * $RCSfile: b3dtex.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DTEX_HXX +#define _B3D_B3DTEX_HXX + +#ifndef _SV_OPENGL_HXX +#include <vcl/opengl.hxx> +#endif + +#ifndef _SV_BITMAP_HXX +#include <vcl/bitmap.hxx> +#endif + +#ifndef _SV_COLOR_HXX +#include <vcl/color.hxx> +#endif + +#ifndef _SV_SALBTYPE_HXX +#include <vcl/salbtype.hxx> +#endif + +// Vorausdeklarationen +class BitmapReadAccess; +class BitmapColor; + +/************************************************************************* +|* +|* define fuer die Ueberlebensdauer einer Textur +|* +\************************************************************************/ + +#define B3D_TEXTURE_LIFETIME (200) + +/************************************************************************* +|* +|* Long-Zeiger fuer OpenGL Texturdatenuebergabe +|* +\************************************************************************/ + +#ifdef WIN +typedef UINT8 huge* GL_UINT8; +#else +typedef UINT8* GL_UINT8; +#endif + +/************************************************************************* +|* +|* Art der Pixeldaten der Textur +|* +\************************************************************************/ + +enum Base3DTextureKind +{ + Base3DTextureLuminance = 1, + Base3DTextureIntensity, + Base3DTextureColor +}; + +/************************************************************************* +|* +|* Modus der Textur +|* +\************************************************************************/ + +enum Base3DTextureMode +{ + Base3DTextureReplace = 1, + Base3DTextureModulate, + Base3DTextureBlend +}; + +/************************************************************************* +|* +|* Filtermodus der Textur +|* +\************************************************************************/ + +enum Base3DTextureFilter +{ + Base3DTextureNearest = 1, + Base3DTextureLinear +}; + +/************************************************************************* +|* +|* Wrapping-Modus +|* +\************************************************************************/ + +enum Base3DTextureWrap +{ + Base3DTextureClamp = 1, + Base3DTextureRepeat, + Base3DTextureSingle +}; + +/************************************************************************* +|* +|* Defines fuer Maskenbildung um Entscheidung innerhalb von ModifyColor +|* zu beschleunigen +|* +\************************************************************************/ + +#define B3D_TXT_KIND_LUM 0x00 +#define B3D_TXT_KIND_INT 0x01 +#define B3D_TXT_KIND_COL 0x02 + +#define B3D_TXT_MODE_REP 0x04 +#define B3D_TXT_MODE_MOD 0x08 +#define B3D_TXT_MODE_BND 0x0C + +#define B3D_TXT_FLTR_NEA 0x10 + +/************************************************************************* +|* +|* Klassen fuer TexturAttribute beim Anfordern von Texturen +|* +\************************************************************************/ + +#define TEXTURE_ATTRIBUTE_TYPE_BITMAP 0x0000 +#define TEXTURE_ATTRIBUTE_TYPE_GRADIENT 0x0001 +#define TEXTURE_ATTRIBUTE_TYPE_HATCH 0x0002 + +class TextureAttributes +{ +private: +public: + TextureAttributes(); + + virtual BOOL operator==(const TextureAttributes&) const =0; + virtual UINT16 GetTextureAttributeType() const =0; +}; + +class TextureAttributesBitmap : public TextureAttributes +{ +private: + Bitmap aBitmapAttribute; + +public: + TextureAttributesBitmap(Bitmap aBmp); + + virtual BOOL operator==(const TextureAttributes&) const; + virtual UINT16 GetTextureAttributeType() const; + + Bitmap GetBitmapAttribute() { return aBitmapAttribute; } +}; + +class TextureAttributesGradient : public TextureAttributes +{ +private: + void* pFill; + void* pStepCount; + +public: + TextureAttributesGradient(void* pF, void *pSC); + + virtual BOOL operator==(const TextureAttributes&) const; + virtual UINT16 GetTextureAttributeType() const; + + void* GetFillAttribute() { return pFill; } + void* GetStepCountAttribute() { return pStepCount; } +}; + +class TextureAttributesHatch : public TextureAttributes +{ +private: + void* pFill; + +public: + TextureAttributesHatch(void* pF); + + virtual BOOL operator==(const TextureAttributes&) const; + virtual UINT16 GetTextureAttributeType() const; + + void* GetHatchFillAttribute() { return pFill; } +}; + +/************************************************************************* +|* +|* Klasse fuer Texturen in Base3D +|* +\************************************************************************/ + +class B3dTexture +{ +protected: + // Die Bitmap der Textur + Bitmap aBitmap; + BitmapReadAccess* pReadAccess; + + // Attribute bei der Generierung + TextureAttributes* pAttributes; + + // Gibt die Haeufigkeit der Benutzung wieder + UINT16 nUsageCount; + + // Farbe fuer Base3DTextureBlend - Modus + BitmapColor aColBlend; + + // Farbe, wenn keine Textur an einer Stelle liegt + BitmapColor aColTexture; + + // Art der Textur + Base3DTextureKind eKind; + + // Modus der Textur + Base3DTextureMode eMode; + + // Filter + Base3DTextureFilter eFilter; + + // Wrapping-Modes fuer beide Freiheitsgrade + Base3DTextureWrap eWrapS; + Base3DTextureWrap eWrapT; + + // Entscheidungsvariable + UINT8 nSwitchVal; + + // Vorbestimmbare interne booleans + unsigned bTextureKindChanged : 1; + + // Konstruktor / Destruktor + B3dTexture(TextureAttributes& rAtt, + Bitmap& rBmp, + Base3DTextureKind=Base3DTextureColor, + Base3DTextureMode=Base3DTextureReplace, + Base3DTextureFilter=Base3DTextureNearest, + Base3DTextureWrap eS=Base3DTextureSingle, + Base3DTextureWrap eT=Base3DTextureSingle); + virtual ~B3dTexture(); + + // Interne Zugriffsfunktion auf die BitMapFarben + inline const BitmapColor GetBitmapColor(long nX, long nY); + + // Verwaltung UsageCount + void Touch() { nUsageCount=B3D_TEXTURE_LIFETIME; } + void DecrementUsageCount() { if(nUsageCount) nUsageCount--; } + UINT16 GetUsageCount() { return nUsageCount; }; + void SetSwitchVal(); + +public: + // Zugriff auf die Attribute der Textur + TextureAttributes& GetAttributes(); + + // Zugriff auf Bitmap + Bitmap& GetBitmap() { return aBitmap; } + const Size GetBitmapSize() { return aBitmap.GetSizePixel(); } + + // Texturfunktion + void ModifyColor(Color& rCol, double fS, double fT); + + // Art der Pixeldaten lesen/bestimmen + void SetTextureKind(Base3DTextureKind eNew); + Base3DTextureKind GetTextureKind() { return eKind; } + + // Texturmodus lesen/bestimmen + void SetTextureMode(Base3DTextureMode eNew); + Base3DTextureMode GetTextureMode() { return eMode; } + + // Filtermodus lesen/bestimmen + void SetTextureFilter(Base3DTextureFilter eNew); + Base3DTextureFilter GetTextureFilter() { return eFilter; } + + // Wrapping fuer beide Freiheitsgrade lesen/bestimmen + void SetTextureWrapS(Base3DTextureWrap eNew); + Base3DTextureWrap GetTextureWrapS() { return eWrapS; } + void SetTextureWrapT(Base3DTextureWrap eNew); + Base3DTextureWrap GetTextureWrapT() { return eWrapT; } + + // Blend-Color lesen/bestimmen + void SetBlendColor(Color rNew); + Color GetBlendColor(); + + // Textur-Ersatz-Color lesen/bestimmen + void SetTextureColor(Color rNew); + Color GetTextureColor(); + +protected: + // Zugriff auf Konstruktor/Destruktor nur fuer die verwaltenden Klassen + friend class Base3D; + friend class Base3DOpenGL; + friend class B3dTextureStore; +}; + +/************************************************************************* +|* +|* erweiterte Klasse fuer Texturen in Base3DOpenGL +|* +\************************************************************************/ + +class B3dTextureOpenGL : public B3dTexture +{ +private: + // Name dieser Textur in OpenGL + GLuint nTextureName; + + // Konstruktor / Destruktor + B3dTextureOpenGL(TextureAttributes& rAtt, + Bitmap& rBmp, + OpenGL& rOGL, + Base3DTextureKind=Base3DTextureColor, + Base3DTextureMode=Base3DTextureReplace, + Base3DTextureFilter=Base3DTextureNearest, + Base3DTextureWrap eS=Base3DTextureClamp, + Base3DTextureWrap eT=Base3DTextureClamp); + virtual ~B3dTextureOpenGL(); + + // In OpenGL die Textur zerstoeren + void DestroyOpenGLTexture(OpenGL&); + +public: + // Setze diese Textur in OpenGL als aktuelle Textur + void MakeCurrentTexture(OpenGL&); + + // Erzeuge diese Textur als OpenGL-Textur + void CreateOpenGLTexture(OpenGL&); + +protected: + // Zugriff auf Konstruktor/Destruktor nur fuer die verwaltenden Klassen + friend class Base3D; + friend class Base3DOpenGL; + friend class B3dTextureStore; +}; + + +#endif // _B3D_B3DTEX_HXX diff --git a/goodies/inc/b3dtrans.hxx b/goodies/inc/b3dtrans.hxx new file mode 100644 index 000000000000..75e393515e42 --- /dev/null +++ b/goodies/inc/b3dtrans.hxx @@ -0,0 +1,371 @@ +/************************************************************************* + * + * $RCSfile: b3dtrans.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DTRANS_HXX +#define _B3D_B3DTRANS_HXX + +#ifndef _B3D_HMATRIX_HXX +#include "hmatrix.hxx" +#endif + +// Zu verwendender DephRange des Z-Buffers +#define ZBUFFER_DEPTH_RANGE (256.0 * 256.0 * 256.0) + +// Vorausdeklarationen +class Base3D; +class B3dVolume; + +/************************************************************************* +|* +|* Unterstuetzte Methoden, um das Seitenverhaeltnis einzuhalten +|* +\************************************************************************/ + +enum Base3DRatio +{ + Base3DRatioGrow = 1, + Base3DRatioShrink, + Base3DRatioMiddle +}; + +/************************************************************************* +|* +|* Typ der Projektion +|* +\************************************************************************/ + +enum Base3DProjectionType +{ + Base3DProjectionTypeParallel = 1, + Base3DProjectionTypePerspective +}; + +/************************************************************************* +|* +|* Transformationen fuer alle 3D Ausgaben +|* +\************************************************************************/ + +class B3dTransformationSet +{ +private: + // Object Matrix Object -> World + Matrix4D aObjectTrans; + Matrix4D aInvObjectTrans; + + // Orientation Matrix + Matrix4D aOrientation; + Matrix4D aInvOrientation; + + // Projection Matrix + Matrix4D aProjection; + Matrix4D aInvProjection; + + // Texture Matrices + Matrix4D aTexture; + + // Speziell zum Umwandeln von Punkten Objekt -> Device + Matrix4D aObjectToDevice; + + // Transponierte Inverse fuer Vectortransformationen + Matrix4D aInvTransObjectToEye; + + // Transformation World->View + Matrix4D aMatFromWorldToView; + Matrix4D aInvMatFromWorldToView; + + // Parameters for ViewportTransformation + Vector3D aScale; + Vector3D aTranslate; + + // ViewPlane DeviceRectangle (vom Benutzer gesetzt) + double fLeftBound; + double fRightBound; + double fBottomBound; + double fTopBound; + + // Near and far clipping planes + double fNearBound; + double fFarBound; + + // Seitenverhaeltnis der 3D Abbildung (Y / X) + // default ist 1:1 -> 1.0 + // Deaktivieren mit 0.0 als Wert + double fRatio; + + // Der gesetzte Ausgabebereich (in logischen Koordinaten) + // und der dazugehoerige sichtbare Bereich + Rectangle aViewportRectangle; + Rectangle aVisibleRectangle; + + // Die tatsaechlich von CalcViewport gesetzten Abmessungen + // des sichtbaren Bereichs (in logischen Koordinaten) + Rectangle aSetBound; + + // Methode zur Aufrechterhaltung des Seitenverhaeltnisses + // default ist Base3DRatioGrow + Base3DRatio eRatio; + + // Flags + unsigned bPerspective : 1; + unsigned bWorldToViewValid : 1; + unsigned bInvTransObjectToEyeValid : 1; + unsigned bObjectToDeviceValid : 1; + unsigned bProjectionValid : 1; + +public: + B3dTransformationSet(); + + // Zurueck auf Standard + void Reset(); + + // ObjectTrans + void SetObjectTrans(Matrix4D& rObj); + const Matrix4D& GetObjectTrans() { return aObjectTrans; } + const Matrix4D& GetInvObjectTrans() { return aInvObjectTrans; } + + // Orientation +#ifndef ICC + void SetOrientation(Vector3D& aVRP = Vector3D(0.0,0.0,1.0), + Vector3D& aVPN = Vector3D(0.0,0.0,1.0), + Vector3D& aVUP = Vector3D(0.0,1.0,0.0)); +#else + void SetOrientation(Vector3D aVRP = Vector3D(0.0,0.0,1.0), + Vector3D aVPN = Vector3D(0.0,0.0,1.0), + Vector3D aVUP = Vector3D(0.0,1.0,0.0)); +#endif + void SetOrientation(Matrix4D& mOrient); + const Matrix4D& GetOrientation() { return aOrientation; } + const Matrix4D& GetInvOrientation() { return aInvOrientation; } + + // Projection + void SetProjection(Matrix4D& mProject); + const Matrix4D& GetProjection(); + const Matrix4D& GetInvProjection(); + + // Texture + void SetTexture(Matrix4D& rTxt); + const Matrix4D& GetTexture() { return aTexture; } + + // Seitenverhaeltnis und Modus zu dessen Aufrechterhaltung + double GetRatio() { return fRatio; } + void SetRatio(double fNew=1.0); + Base3DRatio GetRatioMode() { return eRatio; } + void SetRatioMode(Base3DRatio eNew=Base3DRatioGrow); + + // Parameter der ViewportTransformation + void SetDeviceRectangle(double fL=-1.0, double fR=1.0, double fB=-1.0, double fT=1.0, + BOOL bBroadCastChange=TRUE); + void SetDeviceVolume(const B3dVolume& rVol, BOOL bBroadCastChange=TRUE); + void GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT); + B3dVolume GetDeviceVolume(); + double GetDeviceRectangleWidth() const { return fRightBound - fLeftBound; } + double GetDeviceRectangleHeight() const { return fTopBound - fBottomBound; } + void SetFrontClippingPlane(double fF=0.0); + double GetFrontClippingPlane() { return fNearBound; } + void SetBackClippingPlane(double fB=1.0); + double GetBackClippingPlane() { return fFarBound; } + void SetPerspective(BOOL bNew); + BOOL GetPerspective() { return bPerspective; } + void SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible); + void SetViewportRectangle(Rectangle& rRect) { SetViewportRectangle(rRect, rRect); } + const Rectangle& GetViewportRectangle() { return aViewportRectangle; } + void CalcViewport(); + + // Spezielle Matritzen anfordern + Matrix4D GetMatFromObjectToView(); + + // Transponierte Inverse fuer Vectortransformationen + const Matrix4D& GetInvTransObjectToEye(); + + // Speziell zum Umwandeln von Punkten Objekt -> Device + const Matrix4D& GetObjectToDevice(); + + // Speziell zum Umwandeln von Punkten World -> View + const Matrix4D& GetMatFromWorldToView(); + const Matrix4D& GetInvMatFromWorldToView(); + + // Bounds des Viewports lesen + const Rectangle& GetLogicalViewportBounds(); + const Vector3D& GetScale(); + const Vector3D& GetTranslate(); + + // Direkter Zugriff auf verschiedene Transformationen + const Vector3D WorldToEyeCoor(const Vector3D& rVec); + const Vector3D EyeToWorldCoor(const Vector3D& rVec); + const Vector3D EyeToViewCoor(const Vector3D& rVec); + const Vector3D ViewToEyeCoor(const Vector3D& rVec); + const Vector3D WorldToViewCoor(const Vector3D& rVec); + const Vector3D ViewToWorldCoor(const Vector3D& rVec); + const Vector3D DeviceToViewCoor(const Vector3D& rVec); + const Vector3D ViewToDeviceCoor(const Vector3D& rVec); + const Vector3D ObjectToWorldCoor(const Vector3D& rVec); + const Vector3D WorldToObjectCoor(const Vector3D& rVec); + const Vector3D ObjectToViewCoor(const Vector3D& rVec); + const Vector3D ViewToObjectCoor(const Vector3D& rVec); + const Vector3D ObjectToEyeCoor(const Vector3D& rVec); + const Vector3D EyeToObjectCoor(const Vector3D& rVec); + const Vector3D DeviceToEyeCoor(const Vector3D& rVec); + const Vector3D EyeToDeviceCoor(const Vector3D& rVec); + + const Vector3D InvTransObjectToEye(const Vector3D& rVec); + const Vector3D TransTextureCoor(const Vector3D& rVec); + +protected: + void PostSetObjectTrans(); + void PostSetOrientation(); + void PostSetProjection(); + void PostSetTexture(); + void PostSetViewport(); + + void CalcMatObjectToDevice(); + void CalcMatFromWorldToView(); + void CalcMatInvTransObjectToEye(); + + virtual void DeviceRectangleChange(); +}; + +/************************************************************************* +|* +|* Viewport fuer B3D +|* +|* Verwendet wird hier ein vereinfachtes System, bei dem der abzubildende +|* Punkt durch VRP repraesentiert wird +|* +\************************************************************************/ + +class B3dViewport : public B3dTransformationSet +{ +private: + Vector3D aVRP; // View Reference Point + Vector3D aVPN; // View Plane Normal + Vector3D aVUV; // View Up Vector + +public: + B3dViewport(); + + void SetVRP(const Vector3D& rNewVRP); + void SetVPN(const Vector3D& rNewVPN); + void SetVUV(const Vector3D& rNewVUV); + void SetViewportValues( + const Vector3D& rNewVRP, + const Vector3D& rNewVPN, + const Vector3D& rNewVUV); + + const Vector3D& GetVRP() const { return aVRP; } + const Vector3D& GetVPN() const { return aVPN; } + const Vector3D& GetVUV() const { return aVUV; } + +protected: + void CalcOrientation(); +}; + +/************************************************************************* +|* +|* Kamera fuer B3D +|* +\************************************************************************/ + +class B3dCamera : public B3dViewport +{ +private: + Vector3D aPosition; + Vector3D aCorrectedPosition; + Vector3D aLookAt; + double fFocalLength; + double fBankAngle; + + unsigned bUseFocalLength : 1; + +public: + B3dCamera(const Vector3D& rPos = Vector3D(0.0, 0.0, 1.0), + const Vector3D& rLkAt = Vector3D(0.0, 0.0, 0.0), + double fFocLen = 35.0, double fBnkAng = 0.0, + BOOL bUseFocLen = FALSE); + + // Positionen + void SetPosition(const Vector3D& rNewPos); + const Vector3D& GetPosition() const { return aPosition; } + void SetLookAt(const Vector3D& rNewLookAt); + const Vector3D& GetLookAt() const { return aLookAt; } + void SetPositionAndLookAt(const Vector3D& rNewPos, const Vector3D& rNewLookAt); + + // Brennweite in mm + void SetFocalLength(double fLen); + double GetFocalLength() const { return fFocalLength; } + + // Neigung links/rechts + void SetBankAngle(double fAngle); + double GetBankAngle() const { return fBankAngle; } + + // FocalLength Flag + void SetUseFocalLength(BOOL bNew); + BOOL GetUseFocalLength() const { return (BOOL)bUseFocalLength; } + +protected: + void CalcNewViewportValues(); + BOOL CalcFocalLength(); + + virtual void DeviceRectangleChange(); +}; + + +#endif // _B3D_B3DTRANS_HXX diff --git a/goodies/inc/b3dvolum.hxx b/goodies/inc/b3dvolum.hxx new file mode 100644 index 000000000000..61bf6b7eedf2 --- /dev/null +++ b/goodies/inc/b3dvolum.hxx @@ -0,0 +1,119 @@ +/************************************************************************* + * + * $RCSfile: b3dvolum.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_VOLUM_HXX +#define _B3D_VOLUM_HXX + +#ifndef _SVX_VECTOR3D_HXX +#include "vector3d.hxx" +#endif + +#ifndef _INC_FLOAT +#include <float.h> +#endif + +#ifndef _STREAM_HXX +#include <tools/stream.hxx> +#endif + +/************************************************************************* +|* +|* dreidimensionales Volumen, symmetrisch zu den Koordinatenachsen +|* +\************************************************************************/ + +class B3dVolume +{ + friend class Vol3DPointIterator; + + protected: + Vector3D aMinVec; + Vector3D aMaxVec; + + public: + B3dVolume(const Vector3D& rPos, const Vector3D& r3DSize, + BOOL bPosIsCenter = TRUE); + B3dVolume(); + + void Reset(); + BOOL IsValid() const; + + B3dVolume& Union(const B3dVolume& rVol2); + B3dVolume& Union(const Vector3D& rVec); + + const Vector3D& MinVec() const { return aMinVec; } + Vector3D& MinVec() { return aMinVec; } + + const Vector3D& MaxVec() const { return aMaxVec; } + Vector3D& MaxVec() { return aMaxVec; } + + double GetWidth() const { return aMaxVec.X() - aMinVec.X(); } + double GetHeight() const { return aMaxVec.Y() - aMinVec.Y(); } + double GetDepth() const { return aMaxVec.Z() - aMinVec.Z(); } + Vector3D GetSize() const; + BOOL IsInside(const Vector3D& rVec); + + friend SvStream& operator>>(SvStream& rIStream, B3dVolume&); + friend SvStream& operator<<(SvStream& rOStream, const B3dVolume&); +}; + + +#endif // _B3D_VOLUM_HXX diff --git a/goodies/inc/chagent.hxx b/goodies/inc/chagent.hxx new file mode 100644 index 000000000000..c0c1a70fbcac --- /dev/null +++ b/goodies/inc/chagent.hxx @@ -0,0 +1,234 @@ +/************************************************************************* + * + * $RCSfile: chagent.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CHAGENT_HXX +#define _CHAGENT_HXX + +#ifndef _LIST_HXX //autogen +#include <tools/list.hxx> +#endif +#ifndef _URLOBJ_HXX +#include <tools/urlobj.hxx> +#endif + +#include <tools/agitem.hxx> + +class ChannelAgentItem; +class ChannelItem; + +DECLARE_LIST(ChannelAgentItemList,ChannelAgentItem*) + +enum AgentType +{ + AG_TYP_DONTKNOW = 0, + AG_TYP_DLL = 1, + AG_TYP_BASIC = 2, + AG_TYP_JAVA = 3 +}; + +#define STR_AG_TYP_DLL "DLL" +#define STR_AG_TYP_BASIC "BASIC" +#define STR_AG_TYP_JAVA "JAVA" + +class ChannelAgentItem : public AgentItem +{ + AgentType eAgentType; + String aChAgentName; + INetURLObject aLocation; + ULONG nLastSuccUpdDate; + long nLastSuccUpdTime; + INetURLObject aSource; + BOOL bEnabled; + DateTime aLastCheckDate; + + // runtime + BOOL bIsActive; + BOOL bIsInUpdate; + BOOL bRestartAfterUpdate; + + ULONG nChObjDate; + long nChObjTime; + ChannelItem* pActChannel; + AgentApi* pAgentApi; + ChannelApi* pChannelApi; + INetURLObject aSourceURL; + + Link aBTXShutdownCallback; + +protected: + friend class ChannelApi; + void DeleteApis(); + +public: + ChannelAgentItem(); + ~ChannelAgentItem(); + + // Set / Get AgentType + void SetChannelAgentType(AgentType eNew) + { eAgentType = eNew; } + AgentType GetChannelAgentType() const + { return eAgentType; } + + // Set / Get ChAgentName + void SetChAgentName(const String& rNew) + { aChAgentName = rNew; } + virtual const String& GetChAgentName() const + { return aChAgentName; } + + // Set / Get Location + void SetLocation(const INetURLObject& rNew) + { aLocation = rNew; } + virtual const INetURLObject& GetLocation() const + { return aLocation; } + + // Set / Get LastSuccUpdDate + void SetLastSuccUpdDate(ULONG nNew) + { nLastSuccUpdDate = nNew; } + ULONG GetLastSuccUpdDate() const + { return nLastSuccUpdDate; } + + // Set / Get LastSuccUpdTime + void SetLastSuccUpdTime(ULONG nNew) + { nLastSuccUpdTime = nNew; } + ULONG GetLastSuccUpdTime() const + { return nLastSuccUpdTime; } + + // Set / Get LastCheckDate + void SetLastCheckDate( const DateTime& rNew ) + { aLastCheckDate = rNew; } + const DateTime& GetLastCheckDate() + { return aLastCheckDate; } + + // Set / Get Source + void SetSource(const INetURLObject& rNew) + { aSource = rNew; } + const INetURLObject& GetSource() const + { return aSource; } + + // Set / Get Enabled + virtual void SetEnabled(BOOL bNew = TRUE) + { bEnabled = bNew; } + virtual BOOL IsEnabled() const + { return bEnabled; } + + // Set / Get IsActive + virtual void SetIsActive(BOOL bNew) + { bIsActive = bNew; } + virtual BOOL IsActive() const + { return bIsActive; } + + // runtime //////////////////////////////////////////////////////////////// + + const INetURLObject& GetAgentSourceURL() const + { return aSourceURL; } + void SetAgentSourceURL(const INetURLObject& rNew) + { aSourceURL = rNew; } + + // Set / Get ActiveChannel + void SetActiveChannel(ChannelItem* pChItem) + { pActChannel = pChItem; } + ChannelItem* GetActiveChannel() const + { return pActChannel; } + + // Set / Get IsInUpdate + void SetIsInUpdate( BOOL bNew ) + { bIsInUpdate = bNew; } + BOOL IsInUpdate() const + { return bIsInUpdate; } + + // Set / Get RestartAfterUpdate + void SetRestartAfterUpdate( BOOL bNew ) + { bRestartAfterUpdate = bNew; } + BOOL RestartAfterUpdate() const + { return bRestartAfterUpdate; } + + // AgentAPI + void SetApi(AgentApi* pNew ) + { pAgentApi = pNew; } + virtual AgentApi* GetApi() const + { return pAgentApi; } + + // ChannelAPI + void SetChApi(ChannelApi* pNew ) + { pChannelApi = pNew; } + virtual ChApi* GetChApi() const + { return (ChApi*)pChannelApi; } + + // Set / Get ChObjDate + void SetChObjDate(ULONG nNew) + { nChObjDate = nNew; } + ULONG GetChObjDate() const + { return nChObjDate; } + + // Set / Get ChObjTime + void SetChObjTime(long nNew) + { nChObjTime = nNew; } + long GetChObjTime() const + { return nChObjTime; } + + void SetBTXShutDownCallBack(const Link& rLnk ) + { aBTXShutdownCallback = rLnk; } + const Link& GetBTXShutDownCallBack() + { return aBTXShutdownCallback; } + +}; + +#endif // _CHAGENT_HXX diff --git a/goodies/inc/chanapi.hxx b/goodies/inc/chanapi.hxx new file mode 100644 index 000000000000..6831b15505bd --- /dev/null +++ b/goodies/inc/chanapi.hxx @@ -0,0 +1,117 @@ +/************************************************************************* + * + * $RCSfile: chanapi.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CHANAPI_HXX +#define _CHANAPI_HXX + + +#ifndef _LIST_HXX //autogen +#include <tools/list.hxx> +#endif +#include <tools/chapi.hxx> + +#ifndef _INETSES_HXX //autogen +#include <inet/inetsess.hxx> +#endif + +class ChannelAgentItem; +class ChannelList; +class INetURLObject; +class GetChannelObj; + +DECLARE_LIST(GetChObjList, GetChannelObj*); + +class ChannelApi : public ChApi +{ + INetSessionRef xINetSession; + + ChannelAgentItem* pChAgent; + ChannelList* pChannelList; + + GetChObjList* pGetChObjList; + + DECL_LINK(CloseAgentEvt, void*); + DECL_LINK(CloseChannelObjEvt, void*); + DECL_LINK(GetChannelObjNotify, GetChannelObj*); +public: + ChannelApi( ChannelAgentItem* pAgent, INetSession* pISess, + ChannelList* pChLst ); + ~ChannelApi(); + + void ShutDownAgent(); + void SetLastSuccUpd(); + + void GetChannelObject( const INetURLObject& rURL, RequestType eStreamType, + const String& rFileName ); + void AddChannelItem( const String& aChName, const INetURLObject& aTransmitter, + const String& aChannel, USHORT nUpdPeriode, + const String& rChAgentName ); + void DelChannelItem( const String& aChName ); + void SetChTransmitter( const String& aChName, const String& rNewVal ); + void SetChannel( const String& aChName, const String& rNewVal ); + void SetChannelName( const String& aChName, const String& rNewVal ); + void SetChUpdPeriode( const String& aChName, USHORT nUpdPeriode ); + void SetChannelAgentName( const String& aChName, const String& rNewVal ); + + void SetUpdateTransmitter(ChannelAgentItem* pAgent, const INetURLObject& rTransmitter); +}; + +#endif //_CHANAPI_HXX diff --git a/goodies/inc/channel.hxx b/goodies/inc/channel.hxx new file mode 100644 index 000000000000..90ab84a3fd48 --- /dev/null +++ b/goodies/inc/channel.hxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * $RCSfile: channel.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CHANNEL_HXX +#define _CHANNEL_HXX + +#ifndef _LIST_HXX //autogen +#include <tools/list.hxx> +#endif +#ifndef _URLOBJ_HXX +#include <tools/urlobj.hxx> +#endif + +class ChannelItem; +DECLARE_LIST(ChannelItemList,ChannelItem*) + +class ChannelItem +{ + INetURLObject aTransmitter; + String aChannel; + String aChannelName; + String aChannelAgentName; + ULONG nUpdatePeriode; + ULONG nLastTimerTick; + ULONG nLastSuccUpdDate; + long nLastSuccUpdTime; + + BOOL bAgentUpdChannel; + +public: + ChannelItem(); + ~ChannelItem(); + + // Set / Get Transmitter + void SetTransmitter(const INetURLObject& rNew) + { aTransmitter = rNew; } + const INetURLObject& GetTransmitter() const + { return aTransmitter; } + + // Set / Get Channel + void SetChannel(const String& rNew) + { aChannel = rNew; } + const String& GetChannel() const + { return aChannel; } + + // Set / Get ChannelName + void SetChannelName(const String& rNew) + { aChannelName = rNew; } + const String& GetChannelName() const + { return aChannelName; } + + // Set / Get ChannelAgentName + void SetChannelAgentName(const String& rNew) + { aChannelAgentName = rNew; } + const String& GetChannelAgentName() const + { return aChannelAgentName; } + + // Set / Get UpdatePeriode + void SetUpdatePeriode(ULONG nNew) + { nUpdatePeriode = nNew; } + ULONG GetUpdatePeriode() const + { return nUpdatePeriode; } + + // Set / Get LastTimerTick + void SetLastTimerTick(ULONG nNew) + { nLastTimerTick = nNew; } + ULONG GetLastTimerTick() const + { return nLastTimerTick; } + + // Set / Get LastSuccUpdDate + void SetLastSuccUpdDate(ULONG nNew) + { nLastSuccUpdDate = nNew; } + ULONG GetLastSuccUpdDate() const + { return nLastSuccUpdDate; } + + // Set / Get LastSuccUpdTime + void SetLastSuccUpdTime(long nNew) + { nLastSuccUpdTime = nNew; } + long GetLastSuccUpdTime() const + { return nLastSuccUpdTime; } + + // Set / Get AgentUpdChannel + void SetAgentUpdChannel(BOOL bNew) + { bAgentUpdChannel = bNew; } + BOOL GetAgentUpdChannel() const + { return bAgentUpdChannel; } +}; + +#endif // _CHANNEL_HXX + diff --git a/goodies/inc/chlist.hxx b/goodies/inc/chlist.hxx new file mode 100644 index 000000000000..1178e4f05cb0 --- /dev/null +++ b/goodies/inc/chlist.hxx @@ -0,0 +1,266 @@ +/************************************************************************* + * + * $RCSfile: chlist.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CHLIST_HXX +#define _CHLIST_HXX + +#ifndef _URLOBJ_HXX //autogen +#include <tools/urlobj.hxx> +#endif +#ifndef _DATETIME_HXX //autogen +#include <tools/datetime.hxx> +#endif +#ifndef _STRING_HXX //autogen +#include <tools/string.hxx> +#endif +#ifndef _TIMER_HXX //autogen +#include <vcl/timer.hxx> +#endif +#ifndef _LIST_HXX //autogen +#include <tools/list.hxx> +#endif +#ifndef _INETSES_HXX //autogen +#include <inet/inetsess.hxx> +#endif + +class Downloader; +class ChannelAgentItem; +class ChannelItem; +class ChannelItemList; +class ChannelAgentItemList; +class ChannelTuner; +class ChannelApi; +class GetChannelObj; +class GetChObjList; +class NotifyItem; +class Date; +class Time; +class ResMgr; + +struct UiAgentItem +{ + String aName; + ULONG aUpdPeriode; + DateTime aLastDataDate; + DateTime aLastUpdDate; + BOOL bUnregister; + BOOL bIsEnabled; +}; + +DECLARE_LIST(UiAgentList, UiAgentItem*) +DECLARE_LIST(NotifyList, NotifyItem*) + +#ifndef STRING_LIST +#define STRING_LIST +#if SUPD >= 380 +#define _TOOLS_STRINGLIST +#ifndef _SSTRING_HXX +#include <tools/sstring.hxx> +#endif +#else +DECLARE_LIST(StringList, String*) +#endif +#endif + +/////////////////////////////////////////////////////////////////////////////// +// +// +#define JOBID_DOWNLOAD_AGENT 1 +#define JOBID_UPDATE_AGENT 2 +#define JOBID_CHECK_TRANSMITTER 3 + +struct BTXResponse +{ + USHORT nJobId; + BOOL bFinish; + ULONG nTransferStatus; + String aLocalFileName; +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// +class ChannelList +{ + ResMgr* pResMgr; + ChannelAgentItemList* pAgentList; + ChannelItemList* pChannelList; + NotifyList* pNotifyList; + GetChObjList* pGetChObjList; + UiAgentList* pUiAgentList; + + ChannelTuner* pChannelTuner; + + String aAgentPath; + AutoTimer aTimer; + INetSessionRef xINetSession; + + Link aNotifyPermissionHdl; + Link aCheckFinishHdl; + // wird von der ChannelList gehandelt; sollte ausgebaut werden; auch im SFX + Link aAgentUpdateHdl; + Downloader* pBTXDecoder; + + void MakeGodChannel(ChannelAgentItem* pAgent); + void DeleteUiAgentList(); + + BOOL StartAgent(ChannelAgentItem* pAgent); + + void DoNotifyAgents(); + void NotifyAgent(ChannelAgentItem* pAgent, ULONG nNotifyItemIdx); + + void UpdateAgent(ChannelAgentItem* pAgent, ULONG nNotifyItemIdx); + void SendItemToTuner(ChannelItem* pItem); + + BOOL ParseDateTime(const String& rSrc, Date& rDate, Time& rTime); + + void UnZipAgent(ChannelAgentItem* pAgent); + static void EnumFilesCallBack(char *pFile, void *pObject); + + DECL_LINK(CheckChannels, void*); + DECL_LINK(CloseChannelObjEvt, void*); + DECL_LINK(GetChannelObjNotify, GetChannelObj*); +protected: + friend class ChannelApi; + friend class ChannelTuner; + + ChannelItem* GetChannelItemByName(const String& rName); + ChannelAgentItem* GetAgentItemByName(const String& rName); + + void ReadChannelList(); + void ReadAgentList(); + void WriteChannelItem(ChannelItem* pItem); + void WriteAgentItem(ChannelAgentItem* pChAgent); + void SetLastSuccUpdChannel(ChannelAgentItem* pChAgent); + void SetLastSuccUpdAgent(ChannelAgentItem* pChAgent); + void SetEnabledAgent(ChannelAgentItem* pChAgent); + + void DeleteAgentItem(ChannelAgentItem* pItem); + void DeleteChannelItem(ChannelItem* pItem); + void RegisterNewChannelItem(ChannelItem* pItem); + + void CancelBTX(); + Downloader* GetBTXDecoder() const { return pBTXDecoder; } + ResMgr* GetResMgr() const { return pResMgr; } + + DECL_LINK(CheckBTXFinishHdl, void*); + + void NotifyTransmitterMsg(const String& rStr); + +public: + ChannelList(const String& rAgentPath); + ~ChannelList(); + + void SubscribeNewAgent(const INetURLObject& rURL); + + void SetINetSession(INetSession* pNewSess); + void SetBTXDecoder(Downloader* pDecoder); + + void SetNotifyPermissionHdl(const Link& rHdl) { aNotifyPermissionHdl = rHdl; } + void SetAgentUpdateHdl(const Link& rHdl) { aAgentUpdateHdl = rHdl; } + + void SetTimerInterval(ULONG nNew); + void StartCheckChannels(); + void StopCheckChannels(); + + void CheckAgentNow(const String& rAgName, BOOL bCheckGOD = FALSE); + void SetCheckFinishHdl(const Link& rHdl) { aCheckFinishHdl = rHdl; } + const Link& GetCheckFinishHdl() const { return aCheckFinishHdl;}; + + UiAgentList* GetUiAgentList(); + void JoinUiAgentList(); +}; + +/////////////////////////////////////////////////////////////////////////////// +// +// +class NotifyItem +{ + ChannelItem* pChItem; + + USHORT nGMTOffset; + ULONG nDateLastUpd; + long nTimeLastUpd; + INetURLObject aChObjURL; + String aChName; +public: + NotifyItem( ChannelItem* pItem, short nGMTOff, ULONG nLastDate, + ULONG nLastTime, const INetURLObject& rChObjURL, + const String& rChName); + ~NotifyItem(); + + ChannelItem* GetChannelItem() const { return pChItem; } + + const String& GetChannelName() const { return aChName; } + const INetURLObject GetChannelObjURL() const { return aChObjURL; } + + void SetDateLastUpd(ULONG nNew) { nDateLastUpd = nNew; } + ULONG GetDateLastUpd() const { return nDateLastUpd; } + + void SetTimeLastUpd(long nNew) { nTimeLastUpd = nNew; } + long GetTimeLastUpd() const { return nTimeLastUpd; } + + const String& GetChAgentName() const; + +}; + +#endif // _CHLIST_HXX + diff --git a/goodies/inc/chresid.hxx b/goodies/inc/chresid.hxx new file mode 100644 index 000000000000..91e23ab6fbc1 --- /dev/null +++ b/goodies/inc/chresid.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * $RCSfile: chresid.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _CHRESID_HXX +#define _CHRESID_HXX + +/////////////////////////////////////////////////////////////////////////////// +// legt den ResourceManager fuer die ChannelList in den APPDaten ab. +// +class ChannelResDll +{ +public: + ChannelResDll(); + ~ChannelResDll(); +}; + +#endif //_CHRESID_HXX + diff --git a/goodies/inc/chtuner.hxx b/goodies/inc/chtuner.hxx new file mode 100644 index 000000000000..feedeafdb7de --- /dev/null +++ b/goodies/inc/chtuner.hxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * $RCSfile: chtuner.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CHTUNER_HXX +#define _CHTUNER_HXX + +#ifndef _SV_TIMER_HXX //autogen +#include <vcl/timer.hxx> +#endif +#ifndef _LIST_HXX //autogen +#include <tools/list.hxx> +#endif +#ifndef _INETSESS_HXX +#include <inet/inetsess.hxx> +#endif + + +#ifndef _SFXLSTNER_HXX //autogen +#include <svtools/lstner.hxx> +#endif + +class ChannelItem; +class ChannelList; +class INetRequest; +class Downloader; +class StringList; + +struct RetryInformation +{ + String aURL; + Time aErrorTime; +}; + +DECLARE_LIST(ReqList,INetRequest*) +DECLARE_LIST(RetryList,RetryInformation*) + +class ChannelTuner : public SfxListener +{ + ChannelList* pChannelList; + INetSessionRef xINetSession; + ReqList* pReqList; + + Link aBTXCallBack; + Downloader* pBTXDecoder; + String aBTXFileName; + + AutoTimer aRetryTimer; + RetryList* pRetryList; + + void SendHttpReq(const INetURLObject& rURL); + void SendFtpReq(const INetURLObject& rURL); + void SendBTXReq(const INetURLObject& rURL); + void GetFileTrans(const INetURLObject& rURL); + + void RemoveRequest(INetRequest* pReq); + void NotifyChannelList(String& rStr); + + virtual void SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType, + const SfxHint& rHint, const TypeId& rHintType); + + DECL_LINK(RetryCallBack, void*); + DECL_LINK(BTXCallBack, void*); +public: + ChannelTuner(INetSession* pSess, ChannelList* pChList); + ~ChannelTuner(); + + BOOL RequestChannel(ChannelItem* pItem, const Link& rBTXCallBack); + + void SetINetSession(INetSession* pNewSess); + void SetBTXDecoder(Downloader* pDecoder); +}; + +#endif // _CHTUNER_HXX diff --git a/goodies/inc/crypt.hxx b/goodies/inc/crypt.hxx new file mode 100644 index 000000000000..195398f415ea --- /dev/null +++ b/goodies/inc/crypt.hxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * $RCSfile: crypt.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +// include --------------------------------------------------------------- +#include <tools/gen.hxx> + +// define ---------------------------------------------------------------- + +#define nInOfs 0x00010000UL +#define nOutOfs 0x00020000UL + +// cryptit --------------------------------------------------------------- + +extern "C" +{ +//ULONG testdll(const String& ,const String& , const String&, BOOL DoCrypt ); +//ULONG __EXPORT testdll(const char* pCrInName, const char* pCrOutName, +// const char* pCrKey, BOOL DoCrypt=1); +#if defined (MAC) || defined (UNX) +extern ULONG cryptit(const char* pCrInName, const char* pCrOutName, +#else +#ifdef WNT +extern ULONG __stdcall cryptit(const char* pCrInName, const char* pCrOutName, +#else +#if defined( MTW ) || defined( ICC ) +extern ULONG cryptit(const char* pCrInName, const char* pCrOutName, +#else +extern ULONG __pascal cryptit(const char* pCrInName, const char* pCrOutName, +#endif +#endif +#endif + const char* pCrKey, USHORT DoCrypt); +} + + diff --git a/goodies/inc/goodies.hrc b/goodies/inc/goodies.hrc new file mode 100644 index 000000000000..1ed0c04d9fcb --- /dev/null +++ b/goodies/inc/goodies.hrc @@ -0,0 +1,91 @@ +/************************************************************************* + * + * $RCSfile: goodies.hrc,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:08 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _GOODIES_HRC +#define _GOODIES_HRC + +#ifndef _SOLAR_HRC +#include <svtools/solar.hrc> +#endif + +// Dialoge --------------------------------------------------------------- + +#define DLG_EXPORT_EPCT (RID_GOODIES_START+ 0) +#define DLG_EXPORT_GIF (RID_GOODIES_START+ 1) +#define DLG_EXPORT_EMET (RID_GOODIES_START+ 2) +#define DLG_EXPORT_JPG (RID_GOODIES_START+ 3) +#define DLG_IMPORT_PCD (RID_GOODIES_START+ 4) +#define DLG_EXPORT_EPNG (RID_GOODIES_START+ 5) +#define DLG_EXPORT_EPS (RID_GOODIES_START+ 8) +#define DLG_EXPORT_EPBM (RID_GOODIES_START+ 9) +#define DLG_EXPORT_EPGM (RID_GOODIES_START+ 10) +#define DLG_EXPORT_EPPM (RID_GOODIES_START+ 11) +#define DLG_SSL_NEWCERT (RID_GOODIES_START+ 12) +#define DLG_SSL_INFCERT (RID_GOODIES_START+ 13) +#define PAGE_SSL_NEWCERT_OPEN (RID_GOODIES_START+ 14) +#define PAGE_SSL_NEWCERT_SHOWCERT (RID_GOODIES_START+ 15) +#define PAGE_SSL_NEWCERT_ACCEPTCERT (RID_GOODIES_START+ 16) +#define PAGE_SSL_NEWCERT_WARNCERT (RID_GOODIES_START+ 17) +#define PAGE_SSL_NEWCERT_READYCERT (RID_GOODIES_START+ 18) +#define WIN_SSL_INFCERT (RID_GOODIES_START+ 19) +#define WIN_SSL_INFCERT_EDIT (RID_GOODIES_START+ 20) + +#endif + diff --git a/goodies/inc/grfmgr.hxx b/goodies/inc/grfmgr.hxx new file mode 100644 index 000000000000..1d0fb3f78d02 --- /dev/null +++ b/goodies/inc/grfmgr.hxx @@ -0,0 +1,453 @@ +/************************************************************************* + * + * $RCSfile: grfmgr.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:09 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _GRFMGR_HXX +#define _GRFMGR_HXX + +#ifndef _SV_GRAPH_HXX +#include <vcl/graph.hxx> +#endif + +// ----------- +// - Defines - +// ----------- + +#define GRFMGR_DRAW_NOTCACHED 0x00000000UL +#define GRFMGR_DRAW_CACHED 0x00000001UL +#define GRFMGR_DRAW_BILINEAR 0x00000002UL +#define GRFMGR_DRAW_STANDARD (GRFMGR_DRAW_CACHED|GRFMGR_DRAW_BILINEAR) + +// -------------------- +// - AutoSwap Defines - +// -------------------- + +#define GRFMGR_AUTOSWAPSTREAM_LINK ((SvStream*)0x00000000UL) +#define GRFMGR_AUTOSWAPSTREAM_LOADED ((SvStream*)0xfffffffdUL) +#define GRFMGR_AUTOSWAPSTREAM_TEMP ((SvStream*)0xfffffffeUL) +#define GRFMGR_AUTOSWAPSTREAM_NONE ((SvStream*)0xffffffffUL) + +// ---------------------- +// - Adjustment Defines - +// ---------------------- + +#define ADJUSTMENT_NONE 0x00000000UL +#define ADJUSTMENT_DRAWMODE 0x00000001UL +#define ADJUSTMENT_COLORS 0x00000002UL +#define ADJUSTMENT_MIRROR 0x00000004UL +#define ADJUSTMENT_ROTATE 0x00000008UL +#define ADJUSTMENT_TRANSPARENCY 0x00000010UL +#define ADJUSTMENT_ALL 0xFFFFFFFFUL + +// --------- +// - Enums - +// --------- + +enum GraphicDrawMode +{ + GRAPHICDRAWMODE_STANDARD = 0, + GRAPHICDRAWMODE_GREYS = 1, + GRAPHICDRAWMODE_MONO = 2, + GRAPHICDRAWMODE_WATERMARK = 3 +}; + +// ------------ +// - Forwards - +// ------------ + +class GraphicManager; +class SvStream; +class BitmapWriteAccess; +class GraphicCache; +struct GrfSimpleCacheObj; + +// --------------- +// - GraphicAttr - +// --------------- + +class GraphicAttr +{ +private: + + Size maLogSize; + double mfGamma; + ULONG mnMirrFlags; + long mnLeftCrop; + long mnTopCrop; + long mnRightCrop; + long mnBottomCrop; + USHORT mnRotate10; + short mnContPercent; + short mnLumPercent; + short mnRPercent; + short mnGPercent; + short mnBPercent; + BOOL mbInvert; + BYTE mcTransparency; + GraphicDrawMode meDrawMode; + Rectangle maCropRect; + + void* mpDummy; + +public: + + GraphicAttr(); + ~GraphicAttr(); + + BOOL operator==( const GraphicAttr& rAttr ) const; + BOOL operator!=( const GraphicAttr& rAttr ) const { return !( *this == rAttr ); } + + void SetDrawMode( GraphicDrawMode eDrawMode ) { meDrawMode = eDrawMode; } + GraphicDrawMode GetDrawMode() const { return meDrawMode; } + + void SetMirrorFlags( ULONG nMirrFlags ) { mnMirrFlags = nMirrFlags; } + ULONG GetMirrorFlags() const { return mnMirrFlags; } + + void SetCrop( long nLeft_100TH_MM, long nTop_100TH_MM, long nRight_100TH_MM, long nBottom_100TH_MM ) + { + mnLeftCrop = nLeft_100TH_MM; mnTopCrop = nTop_100TH_MM; + mnRightCrop = nRight_100TH_MM; mnBottomCrop = nBottom_100TH_MM; + } + long GetLeftCrop() const { return mnLeftCrop; } + long GetTopCrop() const { return mnTopCrop; } + long GetRightCrop() const { return mnRightCrop; } + long GetBottomCrop() const { return mnBottomCrop; } + + void SetRotation( USHORT nRotate10, const Size& rUnrotatedSize ) { mnRotate10 = nRotate10; maLogSize = rUnrotatedSize; } + USHORT GetRotation() const { return mnRotate10; } + + void SetLuminance( short nLuminancePercent ) { mnLumPercent = nLuminancePercent; } + short GetLuminance() const { return mnLumPercent; } + + void SetContrast( short nContrastPercent ) { mnContPercent = nContrastPercent; } + short GetContrast() const { return mnContPercent; } + + void SetChannelR( short nChannelRPercent ) { mnRPercent = nChannelRPercent; } + short GetChannelR() const { return mnRPercent; } + + void SetChannelG( short nChannelGPercent ) { mnGPercent = nChannelGPercent; } + short GetChannelG() const { return mnGPercent; } + + void SetChannelB( short nChannelBPercent ) { mnBPercent = nChannelBPercent; } + short GetChannelB() const { return mnBPercent; } + + void SetGamma( double fGamma ) { mfGamma = fGamma; } + double GetGamma() const { return mfGamma; } + + void SetInvert( BOOL bInvert ) { mbInvert = bInvert; } + BOOL IsInvert() const { return mbInvert; } + + void SetTransparency( BYTE cTransparency ) { mcTransparency = cTransparency; } + BYTE GetTransparency() const { return mcTransparency; } + + const Size& GetUntransformedSize() const { return maLogSize; } + + BOOL IsSpecialDrawMode() const { return( meDrawMode != GRAPHICDRAWMODE_STANDARD ); } + BOOL IsMirrored() const { return( mnMirrFlags != 0UL ); } + BOOL IsCropped() const + { + return( mnLeftCrop != 0 || mnTopCrop != 0 || + mnRightCrop != 0 || mnBottomCrop != 0 ); + } + BOOL IsRotated() const { return( ( mnRotate10 % 3600 ) != 0 ); } + BOOL IsTransparent() const { return( mcTransparency > 0 ); } + BOOL IsAdjusted() const + { + return( mnLumPercent != 0 || mnContPercent != 0 || mnRPercent != 0 || + mnGPercent != 0 || mnBPercent != 0 || mfGamma != 1.0 || mbInvert ); + } + + friend SvStream& operator<<( SvStream& rOStm, const GraphicAttr& rAttr ); + friend SvStream& operator>>( SvStream& rIStm, GraphicAttr& rAttr ); +}; + +// ----------------- +// - GraphicObject - +// ----------------- + +class GraphicObject : public SvDataCopyStream +{ + friend class GraphicManager; + +private: + + static GraphicManager* mpGlobalMgr; + + Graphic maGraphic; + GraphicAttr maAttr; + Size maPrefSize; + MapMode maPrefMapMode; + ULONG mnSizeBytes; + GraphicType meType; + GraphicManager* mpMgr; + String* mpLink; + Link* mpSwapStreamHdl; + void* mpDummy1; + Timer* mpSwapOutTimer; + GrfSimpleCacheObj* mpSimpleCache; + void* mpDummy2; + BOOL mbAutoSwapped : 1; + BOOL mbTransparent : 1; + BOOL mbAnimated : 1; + BOOL mbEPS : 1; + BOOL mbIsInSwapIn : 1; + BOOL mbIsInSwapOut : 1; + BOOL mbDummyFlag7 : 1; + BOOL mbDummyFlag8 : 1; + +#if __PRIVATE + + void ImplConstruct(); + void ImplAssignGraphicData(); + void ImplSetGraphicManager( const GraphicManager* pMgr, const ByteString* pID = NULL ); + void ImplAutoSwapIn( BOOL bIgnoreSwapState ); + BOOL ImplIsAutoSwapped() const { return mbAutoSwapped; } + + DECL_LINK( ImplAutoSwapOutHdl, void* ); + +#endif // __PRIVATE + +protected: + + virtual void GraphicManagerDestroyed(); + virtual SvStream* GetSwapStream() const; + + // !!! to be removed + virtual ULONG GetReleaseFromCache() const; + + virtual void Load( SvStream& ); + virtual void Save( SvStream& ); + virtual void Assign( const SvDataCopyStream& ); + +public: + + TYPEINFO(); + + GraphicObject( const GraphicManager* pMgr = NULL ); + GraphicObject( const Graphic& rGraphic, const GraphicManager* pMgr = NULL ); + GraphicObject( const Graphic& rGraphic, const String& rLink, const GraphicManager* pMgr = NULL ); + GraphicObject( const GraphicObject& rCacheObj, const GraphicManager* pMgr = NULL ); + GraphicObject( const ByteString& rUniqueID, const GraphicManager* pMgr = NULL ); + ~GraphicObject(); + + GraphicObject& operator=( const GraphicObject& rCacheObj ); + BOOL operator==( const GraphicObject& rCacheObj ) const; + BOOL operator!=( const GraphicObject& rCacheObj ) const { return !( *this == rCacheObj ); } + + BOOL HasSwapStreamHdl() const { return( mpSwapStreamHdl != NULL && mpSwapStreamHdl->IsSet() ); } + void SetSwapStreamHdl(); + void SetSwapStreamHdl( const Link& rHdl, const ULONG nSwapOutTimeout = 0UL ); + Link GetSwapStreamHdl() const; + ULONG GetSwapOutTimeout() const { return( mpSwapOutTimer ? mpSwapOutTimer->GetTimeout() : 0 ); } + + void FireSwapInRequest(); + void FireSwapOutRequest(); + + void SetGraphicManager( const GraphicManager& rMgr ); + GraphicManager& GetGraphicManager() const { return *mpMgr; } + + BOOL IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz, + const GraphicAttr* pAttr = NULL, ULONG nFlags = GRFMGR_DRAW_STANDARD) const; + void ReleaseFromCache(); + + const Graphic& GetGraphic() const; + void SetGraphic( const Graphic& rGraphic ); + void SetGraphic( const Graphic& rGraphic, const String& rLink ); + + Graphic GetTransformedGraphic( const GraphicAttr* pAttr = NULL ) const; + + void SetAttr( const GraphicAttr& rAttr ); + const GraphicAttr& GetAttr() const { return maAttr; } + + BOOL HasLink() const { return( mpLink != NULL && mpLink->Len() > 0 ); } + void SetLink(); + void SetLink( const String& rLink ); + String GetLink() const; + + ByteString GetUniqueID() const; + + GraphicType GetType() const { return meType; } + const Size& GetPrefSize() const { return maPrefSize; } + const MapMode& GetPrefMapMode() const { return maPrefMapMode; } + ULONG GetSizeBytes() const { return mnSizeBytes; } + ULONG GetChecksum() const; + BOOL IsTransparent() const { return mbTransparent; } + BOOL IsAnimated() const { return mbAnimated; } + BOOL IsEPS() const { return mbEPS; } + + void ResetAnimationLoopCount(); + List* GetAnimationInfoList() const; + Link GetAnimationNotifyHdl() const { return maGraphic.GetAnimationNotifyHdl(); } + void SetAnimationNotifyHdl( const Link& rLink ); + + BOOL SwapOut(); + BOOL SwapOut( SvStream* pOStm ); + BOOL SwapIn(); + BOOL SwapIn( SvStream* pIStm ); + + BOOL IsInSwapIn() const { return mbIsInSwapIn; } + BOOL IsInSwapOut() const { return mbIsInSwapOut; } + BOOL IsInSwap() const { return( mbIsInSwapOut || mbIsInSwapOut ); } + BOOL IsSwappedOut() const { return maGraphic.IsSwapOut(); } + + BOOL Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz, + const GraphicAttr* pAttr = NULL, ULONG nFlags = GRFMGR_DRAW_STANDARD ); + + BOOL StartAnimation( OutputDevice* pOut, const Point& rPt, const Size& rSz, long nExtraData = 0L, + const GraphicAttr* pAttr = NULL, ULONG nFlags = GRFMGR_DRAW_STANDARD, + OutputDevice* pFirstFrameOutDev = NULL ); + + void StopAnimation( OutputDevice* pOut = NULL, long nExtraData = 0L ); + + friend SvStream& operator<<( SvStream& rOStm, const GraphicObject& rGraphicObj ); + friend SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj ); +}; + +// ------------------ +// - GraphicManager - +// ------------------ + +class GraphicManager +{ + friend class GraphicObject; + friend class GraphicDisplayCacheEntry; + +private: + + List maObjList; + GraphicCache* mpCache; + + GraphicManager( const GraphicManager& rGraphicManager ) {} + GraphicManager& operator=( const GraphicManager& rGraphicManager ) { return *this; } + +#if __PRIVATE + + BOOL ImplDraw( OutputDevice* pOut, const Point& rPt, + const Size& rSz, GraphicObject& rObj, + const GraphicAttr& rAttr, BOOL& rCached ); + + BOOL ImplCreateOutput( OutputDevice* pOut, const Point& rPt, const Size& rSz, + const BitmapEx& rBmpEx, const GraphicAttr& rAttr, + BitmapEx* pBmpEx = NULL ); + BOOL ImplCreateOutput( OutputDevice* pOut, const Point& rPt, const Size& rSz, + const GDIMetaFile& rMtf, const GraphicAttr& rAttr, + GDIMetaFile* pMtf = NULL ); + + BOOL ImplCreateScaled( const BitmapEx& rBmpEx, + long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY, + long nStartX, long nEndX, long nStartY, long nEndY, + BitmapEx& rOutBmpEx ); + + BOOL ImplCreateRotatedScaled( const BitmapEx& rBmpEx, + USHORT nRot10, const Size& rOutSzPix, const Size& rUntSzPix, + long* pMapIX, long* pMapFX, long* pMapIY, long* pMapFY, + long nStartX, long nEndX, long nStartY, long nEndY, + BitmapEx& rOutBmpEx ); + + static void ImplAdjust( BitmapEx& rBmpEx, const GraphicAttr& rAttr, ULONG nAdjustmentFlags ); + static void ImplAdjust( GDIMetaFile& rMtf, const GraphicAttr& rAttr, ULONG nAdjustmentFlags ); + static void ImplAdjust( Animation& rAnimation, const GraphicAttr& rAttr, ULONG nAdjustmentFlags ); + + static void ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz, + const BitmapEx& rBmpEx, const GraphicAttr& rAttr ); + static void ImplDraw( OutputDevice* pOut, const Point& rPt, const Size& rSz, + const GDIMetaFile& rMtf, const GraphicAttr& rAttr ); + + // Only used by GraphicObject's Ctor's and Dtor's + void ImplRegisterObj( const GraphicObject& rObj, Graphic& rSubstitute, const ByteString* pID ); + void ImplUnregisterObj( const GraphicObject& rObj ); + inline BOOL ImplHasObjects() const { return( maObjList.Count() > 0UL ); } + + // Only used in swap case by GraphicObject + void ImplGraphicObjectWasSwappedOut( const GraphicObject& rObj ); + BOOL ImplFillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute ); + void ImplGraphicObjectWasSwappedIn( const GraphicObject& rObj ); + + ByteString ImplGetUniqueID( const GraphicObject& rObj ) const; + +#endif // __PRIVATE + +public: + + GraphicManager( ULONG nCacheSize = 10000000UL, ULONG nMaxObjCacheSize = 2400000UL ); + ~GraphicManager(); + + void SetMaxCacheSize( ULONG nNewCacheSize ); + ULONG GetMaxCacheSize() const; + + void SetMaxObjCacheSize( ULONG nNewMaxObjSize, BOOL bDestroyGreaterCached = FALSE ); + ULONG GetMaxObjCacheSize() const; + + ULONG GetUsedCacheSize() const; + ULONG GetFreeCacheSize() const; + + void ClearCache(); + + void ReleaseFromCache( const GraphicObject& rObj ); + + BOOL IsInCache( OutputDevice* pOut, const Point& rPt, const Size& rSz, + const GraphicObject& rObj, const GraphicAttr& rAttr ) const; + + BOOL DrawObj( OutputDevice* pOut, const Point& rPt, const Size& rSz, + GraphicObject& rObj, const GraphicAttr& rAttr, + const ULONG nFlags, BOOL& rCached ); +}; + +#endif // _GRFMGR_HXX diff --git a/goodies/inc/mailenum.hxx b/goodies/inc/mailenum.hxx new file mode 100644 index 000000000000..ab1542256ca6 --- /dev/null +++ b/goodies/inc/mailenum.hxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * $RCSfile: mailenum.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:09 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _MAILENUM_HXX +#define _MAILENUM_HXX + +// enum ------------------------------------------------------------------ + +enum MailState +{ + MAIL_STATE_SUCCESS = 0, + MAIL_STATE_FAILURE, + MAIL_STATE_ATTACHED_NOT_FOUND, + MAIL_STATE_NO_MEMORY, + MAIL_STATE_LOGIN_FAILURE, + MAIL_STATE_RECEIVER_NOT_FOUND, + MAIL_STATE_TOO_MANY_FILES, + MAIL_STATE_TOO_MANY_RECEIVERS, + MAIL_STATE_NO_RECEIVERS, + MAIL_STATE_USER_CANCEL, + MAIL_STATE_DRIVER_NOT_AVAILABLE +}; + +enum MailDriver +{ + MAIL_DRIVER_DETECT = 0, + MAIL_DRIVER_BEGIN, + MAIL_DRIVER_VIM = MAIL_DRIVER_BEGIN, + MAIL_DRIVER_MAPI, + MAIL_DRIVER_CMC, + MAIL_DRIVER_SMP, + MAIL_DRIVER_UNIX, + MAIL_DRIVER_SMTP, + MAIL_DRIVER_END +}; + +enum MailPriority +{ + MAIL_PRIORITY_LOW = 0, + MAIL_PRIORITY_NORMAL, + MAIL_PRIORITY_URGENT +}; + +enum MailReceiverRole +{ + MAIL_RECEIVER_TO = 0, + MAIL_RECEIVER_CC, + MAIL_RECEIVER_BCC, + MAIL_RECEIVER_NEWSGROUP +}; + +enum MailAction +{ + MAIL_ACTION_DYING, // Server stirbt + MAIL_ACTION_SEND, // Mail wurde versendet + MAIL_ACTION_READ, // Mail wurde als gelesen gekennzeichnet + MAIL_ACTION_REMOVED, // Mail wurde gel"oscht + MAIL_ACTION_UPDATED, // alle Mails wurden neu eingelesen + MAIL_ACTION_NEXT, // Sprung zur n"achsten Mail + MAIL_ACTION_PREV // Sprung zur vorherigen Mail +}; + +// Textformat zum Versenden von Nachrichten ------------------------------ + +#define TXTFORMAT_ASCII ((BYTE)0x01) +#define TXTFORMAT_HTML ((BYTE)0x02) +#define TXTFORMAT_RTF ((BYTE)0x04) +#define TXTFORMAT_OFFICE ((BYTE)0x08) + + +#endif + diff --git a/goodies/inc/vector3d.hxx b/goodies/inc/vector3d.hxx new file mode 100644 index 000000000000..685a1c31051e --- /dev/null +++ b/goodies/inc/vector3d.hxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * $RCSfile: vector3d.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:09 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVX_VECTOR3D_HXX +#define _SVX_VECTOR3D_HXX + +#ifndef _SOLAR_H +#include <tools/solar.h> +#endif + +#ifndef _INC_MATH +#include <math.h> +#endif + +class Point; +class SvStream; + +/************************************************************************* +|* +|* 3D-Vektor +|* +\************************************************************************/ + +class Vector3D +{ + protected: + double V[3]; + + public: + Vector3D(double fX = 0, double fY = 0, double fZ = 0) + { V[0] = fX; V[1] = fY; V[2] = fZ; } + Vector3D(const Point& rPnt, double fZ = 0); + const double& X() const { return V[0]; } + const double& Y() const { return V[1]; } + const double& Z() const { return V[2]; } + double& X() { return V[0]; } + double& Y() { return V[1]; } + double& Z() { return V[2]; } + const double& operator[] (int nPos) const { return V[nPos]; } + double& operator[] (int nPos) { return V[nPos]; } + + double GetLength(void) const; + double GetXYLength(void) const; + double GetXZLength(void) const; + double GetYZLength(void) const; + + void Normalize(); + void Min(const Vector3D& rVec); + void Max(const Vector3D& rVec); + void Abs(); + + void CalcInBetween(const Vector3D& rOld1, const Vector3D& rOld2, double t); + void CalcMiddle(const Vector3D& rOld1, const Vector3D& rOld2); + void CalcMiddle(const Vector3D& rOld1, const Vector3D& rOld2, Vector3D& rOld3); + + Vector3D GetPerpendicular2D() const; + + Vector3D& operator+= (const Vector3D&); + Vector3D& operator-= (const Vector3D&); + Vector3D operator+ (const Vector3D&) const; + Vector3D operator- (const Vector3D&) const; + Vector3D operator- (void) const; + + // Kreuzprodukt mittels operator| (wie: Senkrecht) + Vector3D& operator|= (const Vector3D&); + Vector3D operator| (const Vector3D&) const; + + // Skalarprodukt als Methode, um Verwechslungen zu vermeiden + double Scalar(const Vector3D&) const; + + Vector3D& operator/= (const Vector3D&); + Vector3D operator/ (const Vector3D&) const; + Vector3D& operator*= (const Vector3D&); + Vector3D operator* (const Vector3D&) const; + + Vector3D& operator*= (double); + Vector3D operator* (double) const; + Vector3D& operator/= (double); + Vector3D operator/ (double) const; + + BOOL operator== (const Vector3D&) const; + BOOL operator!= (const Vector3D&) const; + + friend SvStream& operator>>(SvStream& rIStream, Vector3D&); + friend SvStream& operator<<(SvStream& rOStream, const Vector3D&); +}; + +#endif // _SVX_VECTOR3D_HXX diff --git a/goodies/prj/d.lst b/goodies/prj/d.lst new file mode 100644 index 000000000000..1d1aeba3e5e3 --- /dev/null +++ b/goodies/prj/d.lst @@ -0,0 +1,116 @@ +..\%__SRC%\lib\mail.lib %_DEST%\lib%_EXT%\mail.lib +..\%__SRC%\lib\crypt.lib %_DEST%\lib%_EXT%\crypt.lib +..\%__SRC%\lib\icrp.lib %_DEST%\lib%_EXT%\icrp.lib +..\%__SRC%\lib\igo.lib %_DEST%\lib%_EXT%\go.lib +..\%__SRC%\lib\igo.lib %_DEST%\lib%_EXT%\igo.lib +..\%__SRC%\slb\go.lib %_DEST%\lib%_EXT%\xgo.lib +..\%__SRC%\slb\gol.lib %_DEST%\lib%_EXT%\gol.lib +..\%__SRC%\srs\mail.srs %_DEST%\res%_EXT%\mail.srs +..\%__SRC%\srs\dialog.srs %_DEST%\res%_EXT%\godialog.srs +..\%__SRC%\misc\goodies.hid %_DEST%\bin%_EXT%\goodies.hid +..\%__SRC%\bin\ma?????.* %_DEST%\bin%_EXT%\ma?????.* +..\%__SRC%\bin\tfu?????.dll %_DEST%\bin%_EXT%\tfu?????.dll +..\%__SRC%\bin\tfu?????.sym %_DEST%\bin%_EXT%\tfu?????.sym +..\%__SRC%\bin\crp?????.dll %_DEST%\bin%_EXT%\crp?????.dll +..\%__SRC%\bin\crp?????.sym %_DEST%\bin%_EXT%\crp?????.sym +..\%__SRC%\bin\solarvim.dll %_DEST%\bin%_EXT%\solarvim.dll +..\%__SRC%\misc\*.map %_DEST%\bin%_EXT%\*.map +..\%__SRC%\bin\ept%UPD%*.dll %_DEST%\bin%_EXT%\ept%UPD%*.dll +..\%__SRC%\bin\ept%UPD%*.sym %_DEST%\bin%_EXT%\ept%UPD%*.sym +..\%__SRC%\bin\eme%UPD%*.dll %_DEST%\bin%_EXT%\eme%UPD%*.dll +..\%__SRC%\bin\eme%UPD%*.sym %_DEST%\bin%_EXT%\eme%UPD%*.sym +..\%__SRC%\bin\egi%UPD%*.dll %_DEST%\bin%_EXT%\egi%UPD%*.dll +..\%__SRC%\bin\egi%UPD%*.sym %_DEST%\bin%_EXT%\egi%UPD%*.sym +..\%__SRC%\bin\epn%UPD%*.dll %_DEST%\bin%_EXT%\epn%UPD%*.dll +..\%__SRC%\bin\epn%UPD%*.sym %_DEST%\bin%_EXT%\epn%UPD%*.sym +..\%__SRC%\bin\eti%UPD%*.dll %_DEST%\bin%_EXT%\eti%UPD%*.dll +..\%__SRC%\bin\eti%UPD%*.sym %_DEST%\bin%_EXT%\eti%UPD%*.sym +..\%__SRC%\bin\ecg%UPD%*.dll %_DEST%\bin%_EXT%\ecg%UPD%*.dll +..\%__SRC%\bin\ecg%UPD%*.sym %_DEST%\bin%_EXT%\ecg%UPD%*.sym +..\%__SRC%\bin\era%UPD%*.dll %_DEST%\bin%_EXT%\era%UPD%*.dll +..\%__SRC%\bin\era%UPD%*.sym %_DEST%\bin%_EXT%\era%UPD%*.sym +..\%__SRC%\bin\eps%UPD%*.dll %_DEST%\bin%_EXT%\eps%UPD%*.dll +..\%__SRC%\bin\eps%UPD%*.sym %_DEST%\bin%_EXT%\eps%UPD%*.sym +..\%__SRC%\bin\exp%UPD%*.dll %_DEST%\bin%_EXT%\exp%UPD%*.dll +..\%__SRC%\bin\exp%UPD%*.sym %_DEST%\bin%_EXT%\exp%UPD%*.sym +..\%__SRC%\bin\epb%UPD%*.dll %_DEST%\bin%_EXT%\epb%UPD%*.dll +..\%__SRC%\bin\epb%UPD%*.sym %_DEST%\bin%_EXT%\epb%UPD%*.sym +..\%__SRC%\bin\epg%UPD%*.dll %_DEST%\bin%_EXT%\epg%UPD%*.dll +..\%__SRC%\bin\epg%UPD%*.sym %_DEST%\bin%_EXT%\epg%UPD%*.sym +..\%__SRC%\bin\epp%UPD%*.dll %_DEST%\bin%_EXT%\epp%UPD%*.dll +..\%__SRC%\bin\epp%UPD%*.sym %_DEST%\bin%_EXT%\epp%UPD%*.sym +..\%__SRC%\bin\ime%UPD%*.dll %_DEST%\bin%_EXT%\ime%UPD%*.dll +..\%__SRC%\bin\ime%UPD%*.sym %_DEST%\bin%_EXT%\ime%UPD%*.sym +..\%__SRC%\bin\ipt%UPD%*.dll %_DEST%\bin%_EXT%\ipt%UPD%*.dll +..\%__SRC%\bin\ipt%UPD%*.sym %_DEST%\bin%_EXT%\ipt%UPD%*.sym +..\%__SRC%\bin\icd%UPD%*.dll %_DEST%\bin%_EXT%\icd%UPD%*.dll +..\%__SRC%\bin\icd%UPD%*.sym %_DEST%\bin%_EXT%\icd%UPD%*.sym +..\%__SRC%\bin\ipx%UPD%*.dll %_DEST%\bin%_EXT%\ipx%UPD%*.dll +..\%__SRC%\bin\ipx%UPD%*.sym %_DEST%\bin%_EXT%\ipx%UPD%*.sym +..\%__SRC%\bin\icg%UPD%*.dll %_DEST%\bin%_EXT%\icg%UPD%*.dll +..\%__SRC%\bin\icg%UPD%*.sym %_DEST%\bin%_EXT%\icg%UPD%*.sym +..\%__SRC%\bin\ira%UPD%*.dll %_DEST%\bin%_EXT%\ira%UPD%*.dll +..\%__SRC%\bin\ira%UPD%*.sym %_DEST%\bin%_EXT%\ira%UPD%*.sym +..\%__SRC%\bin\itg%UPD%*.dll %_DEST%\bin%_EXT%\itg%UPD%*.dll +..\%__SRC%\bin\itg%UPD%*.sym %_DEST%\bin%_EXT%\itg%UPD%*.sym +..\%__SRC%\bin\ipd%UPD%*.dll %_DEST%\bin%_EXT%\ipd%UPD%*.dll +..\%__SRC%\bin\ipd%UPD%*.sym %_DEST%\bin%_EXT%\ipd%UPD%*.sym +..\%__SRC%\bin\ips%UPD%*.dll %_DEST%\bin%_EXT%\ips%UPD%*.dll +..\%__SRC%\bin\ips%UPD%*.sym %_DEST%\bin%_EXT%\ips%UPD%*.sym +..\%__SRC%\bin\ipb%UPD%*.dll %_DEST%\bin%_EXT%\ipb%UPD%*.dll +..\%__SRC%\bin\ipb%UPD%*.sym %_DEST%\bin%_EXT%\ipb%UPD%*.sym +..\%__SRC%\bin\iti%UPD%*.dll %_DEST%\bin%_EXT%\iti%UPD%*.dll +..\%__SRC%\bin\iti%UPD%*.sym %_DEST%\bin%_EXT%\iti%UPD%*.sym +..\%__SRC%\bin\igi%UPD%*.dll %_DEST%\bin%_EXT%\igi%UPD%*.dll +..\%__SRC%\bin\igi%UPD%*.sym %_DEST%\bin%_EXT%\igi%UPD%*.sym +..\%__SRC%\bin\idx%UPD%*.dll %_DEST%\bin%_EXT%\idx%UPD%*.dll +..\%__SRC%\bin\idx%UPD%*.sym %_DEST%\bin%_EXT%\idx%UPD%*.sym +..\%__SRC%\bin\ixb%UPD%*.dll %_DEST%\bin%_EXT%\ixb%UPD%*.dll +..\%__SRC%\bin\ixb%UPD%*.sym %_DEST%\bin%_EXT%\ixb%UPD%*.sym +..\%__SRC%\bin\jpg%UPD%*.dll %_DEST%\bin%_EXT%\jpg%UPD%*.dll +..\%__SRC%\bin\jpg%UPD%*.sym %_DEST%\bin%_EXT%\jpg%UPD%*.sym +..\%__SRC%\bin\go%UPD%*.dll %_DEST%\bin%_EXT%\go%UPD%*.dll +..\%__SRC%\bin\go%UPD%*.sym %_DEST%\bin%_EXT%\go%UPD%*.sym +..\%__SRC%\bin\gol%UPD%*.dll %_DEST%\bin%_EXT%\gol%UPD%*.dll +..\%__SRC%\bin\gol%UPD%*.sym %_DEST%\bin%_EXT%\gol%UPD%*.sym + +..\%__SRC%\lib\lib*%UPD%*.* %_DEST%\lib%_EXT%\lib*%UPD%*.* +..\%__SRC%\lib\*.a %_DEST%\lib%_EXT%\*.a +..\%__SRC%\bin\*.res %_DEST%\bin%_EXT%\*.res + +mkdir: %_DEST%\inc%_EXT%\goodies +hedabu: ..\inc\grfmgr.hxx %_DEST%\inc%_EXT%\goodies\grfmgr.hxx +hedabu: ..\inc\mailenum.hxx %_DEST%\inc%_EXT%\goodies\mailenum.hxx +hedabu: ..\inc\mailbook.hxx %_DEST%\inc%_EXT%\goodies\mailbook.hxx +hedabu: ..\inc\mailbody.hxx %_DEST%\inc%_EXT%\goodies\mailbody.hxx +hedabu: ..\inc\mailsrv.hxx %_DEST%\inc%_EXT%\goodies\mailsrv.hxx +hedabu: ..\inc\mailread.hxx %_DEST%\inc%_EXT%\goodies\mailread.hxx +hedabu: ..\inc\mailbrw.hxx %_DEST%\inc%_EXT%\goodies\mailbrw.hxx +hedabu: ..\inc\mailfmgr.hxx %_DEST%\inc%_EXT%\goodies\mailfmgr.hxx +hedabu: ..\inc\maillog.hxx %_DEST%\inc%_EXT%\goodies\maillog.hxx +hedabu: ..\inc\vector3d.hxx %_DEST%\inc%_EXT%\goodies\vector3d.hxx +hedabu: ..\inc\point3d.hxx %_DEST%\inc%_EXT%\goodies\point3d.hxx +hedabu: ..\inc\hmatrix.hxx %_DEST%\inc%_EXT%\goodies\hmatrix.hxx +hedabu: ..\inc\matrix3d.hxx %_DEST%\inc%_EXT%\goodies\matrix3d.hxx +hedabu: ..\inc\point4d.hxx %_DEST%\inc%_EXT%\goodies\point4d.hxx +hedabu: ..\inc\base3d.hxx %_DEST%\inc%_EXT%\goodies\base3d.hxx +hedabu: ..\inc\b3dlight.hxx %_DEST%\inc%_EXT%\goodies\b3dlight.hxx +hedabu: ..\inc\vector3d.hxx %_DEST%\inc%_EXT%\goodies\vector3d.hxx +hedabu: ..\inc\matril3d.hxx %_DEST%\inc%_EXT%\goodies\matril3d.hxx +hedabu: ..\inc\bucket.hxx %_DEST%\inc%_EXT%\goodies\bucket.hxx +hedabu: ..\inc\point3d.hxx %_DEST%\inc%_EXT%\goodies\point3d.hxx +hedabu: ..\inc\b3dentty.hxx %_DEST%\inc%_EXT%\goodies\b3dentty.hxx +hedabu: ..\inc\b3dcolor.hxx %_DEST%\inc%_EXT%\goodies\b3dcolor.hxx +hedabu: ..\inc\b3dcompo.hxx %_DEST%\inc%_EXT%\goodies\b3dcompo.hxx +hedabu: ..\inc\b3dtex.hxx %_DEST%\inc%_EXT%\goodies\b3dtex.hxx +hedabu: ..\inc\b3dgeom.hxx %_DEST%\inc%_EXT%\goodies\b3dgeom.hxx +hedabu: ..\inc\b3dvolum.hxx %_DEST%\inc%_EXT%\goodies\b3dvolum.hxx +hedabu: ..\inc\b3dtrans.hxx %_DEST%\inc%_EXT%\goodies\b3dtrans.hxx +hedabu: ..\inc\b2dmbase.hxx %_DEST%\inc%_EXT%\goodies\b2dmbase.hxx +hedabu: ..\inc\b2dmbmp.hxx %_DEST%\inc%_EXT%\goodies\b2dmbmp.hxx +hedabu: ..\inc\b2dmline.hxx %_DEST%\inc%_EXT%\goodies\b2dmline.hxx +hedabu: ..\inc\b2dmpnt.hxx %_DEST%\inc%_EXT%\goodies\b2dmpnt.hxx +hedabu: ..\inc\b2dmtri.hxx %_DEST%\inc%_EXT%\goodies\b2dmtri.hxx +hedabu: ..\inc\bxdintpo.hxx %_DEST%\inc%_EXT%\goodies\bxdintpo.hxx +hedabu: ..\inc\agsdkdll.hxx %_DEST%\inc%_EXT%\goodies\agsdkdll.hxx + diff --git a/goodies/source/base3d/b3dcolor.cxx b/goodies/source/base3d/b3dcolor.cxx new file mode 100644 index 000000000000..8cb9b0087c94 --- /dev/null +++ b/goodies/source/base3d/b3dcolor.cxx @@ -0,0 +1,364 @@ +/************************************************************************* + * + * $RCSfile: b3dcolor.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +#ifndef _B3D_B3DCOLOR_HXX +#include "b3dcolor.hxx" +#endif + +/************************************************************************* +|* +|* Farbwert interpolieren +|* +\************************************************************************/ + +void B3dColor::CalcInBetween(Color& rOld1, Color& rOld2, double t) +{ + if(rOld1 != rOld2) + { + UINT16 nFac = (UINT16)(t * 256.0); + UINT16 nNegFac = 256 - nFac; + SetRed((UINT8)(((nFac * (UINT16)rOld2.GetRed()) + + (nNegFac * (UINT16)rOld1.GetRed())) >> 8)); + SetGreen((UINT8)(((nFac * (UINT16)rOld2.GetGreen()) + + (nNegFac * (UINT16)rOld1.GetGreen())) >> 8)); + SetBlue((UINT8)(((nFac * (UINT16)rOld2.GetBlue()) + + (nNegFac * (UINT16)rOld1.GetBlue())) >> 8)); + SetTransparency((UINT8)(((nFac * (UINT16)rOld2.GetTransparency()) + + (nNegFac * (UINT16)rOld1.GetTransparency())) >> 8)); + } + else + { + SetColor(rOld1.GetColor()); + } +} + +/************************************************************************* +|* +|* Farbwert Mittelwert finden mit 2 Farben +|* +\************************************************************************/ + +void B3dColor::CalcMiddle(Color& rOld1, Color& rOld2) +{ + if(rOld1 != rOld2) + { + SetRed((UINT8)(((UINT16)rOld1.GetRed() + + (UINT16)rOld2.GetRed())>>1)); + SetGreen((UINT8)(((UINT16)rOld1.GetGreen() + + (UINT16)rOld2.GetGreen())>>1)); + SetBlue((UINT8)(((UINT16)rOld1.GetBlue() + + (UINT16)rOld2.GetBlue())>>1)); + SetTransparency((UINT8)(((UINT16)rOld1.GetTransparency() + + (UINT16)rOld2.GetTransparency())>>1)); + } + else + { + SetColor(rOld1.GetColor()); + } +} + +/************************************************************************* +|* +|* Farbwert Mittelwert finden mit 3 Farben +|* +\************************************************************************/ + +void B3dColor::CalcMiddle(Color& rOld1, Color& rOld2, Color& rOld3) +{ + if(rOld1 != rOld2) + { + if(rOld1 != rOld3) + { + // alle 3 unterschiedlich + SetRed((UINT8)(((UINT16)rOld1.GetRed() + + (UINT16)rOld2.GetRed() + + (UINT16)rOld3.GetRed()) / 3L)); + SetGreen((UINT8)(((UINT16)rOld1.GetGreen() + + (UINT16)rOld2.GetGreen() + + (UINT16)rOld3.GetGreen()) / 3L)); + SetBlue((UINT8)(((UINT16)rOld1.GetBlue() + + (UINT16)rOld2.GetBlue() + + (UINT16)rOld3.GetBlue()) / 3L)); + SetTransparency((UINT8)(((UINT16)rOld1.GetTransparency() + + (UINT16)rOld2.GetTransparency() + + (UINT16)rOld3.GetTransparency()) / 3L)); + } + else + { + // 1 != 2, 1 == 3 + CalcMiddle(rOld1, rOld2); + } + } + else + { + // 1 == 2 + if(rOld1 != rOld3) + { + CalcMiddle(rOld1, rOld3); + } + else + { + // 1==2, 1==3 -> alle gleich + SetColor(rOld1.GetColor()); + } + } +} + +/************************************************************************* +|* +|* Ermittle den Abstand der beiden Farben im Farbraum +|* Dies geschieht OHNE Wurzelziehen, d.h. es wird als Metrik im RGB +|* Farbraum hier das Quadrat der 'echten' (gewohnten) Entfernung benutzt +|* +\************************************************************************/ + +ULONG B3dColor::GetDistance(Color& rOld) +{ + // Bei Gleichheit kein Abstand + if(*this == rOld) + return 0L; + + // Abstand ermitteln + long nDistRed = rOld.GetRed() > GetRed() ? + rOld.GetRed() - GetRed() : + GetRed() - rOld.GetRed(); + long nDistGreen = rOld.GetGreen() > GetGreen() ? + rOld.GetGreen() - GetGreen() : + GetGreen() - rOld.GetGreen(); + long nDistBlue = rOld.GetBlue() > GetBlue() ? + rOld.GetBlue() - GetBlue() : + GetBlue() - rOld.GetBlue(); + return (ULONG)(nDistRed * nDistRed + + nDistGreen * nDistGreen + + nDistBlue * nDistBlue); +} + +/************************************************************************* +|* +|* Farbaddition mit clamping +|* +\************************************************************************/ + +B3dColor& B3dColor::operator+= (const B3dColor& rCol) +{ + UINT16 nZwi; + if(rCol.GetRed()) + { + nZwi = (UINT16)GetRed() + (UINT16)rCol.GetRed(); + if(nZwi > 255) + nZwi = 255; + SetRed((UINT8)nZwi); + } + if(rCol.GetGreen()) + { + nZwi = (UINT16)GetGreen() + (UINT16)rCol.GetGreen(); + if(nZwi > 255) + nZwi = 255; + SetGreen((UINT8)nZwi); + } + if(rCol.GetBlue()) + { + nZwi = (UINT16)GetBlue() + (UINT16)rCol.GetBlue(); + if(nZwi > 255) + nZwi = 255; + SetBlue((UINT8)nZwi); + } + if(rCol.GetTransparency()) + { + nZwi = (UINT16)GetTransparency() + (UINT16)rCol.GetTransparency(); + if(nZwi > 255) + nZwi = 255; + SetTransparency((UINT8)nZwi); + } + return *this; +} + +/************************************************************************* +|* +|* Farbsubtraktion mit clamping +|* +\************************************************************************/ + +B3dColor& B3dColor::operator-= (const B3dColor& rCol) +{ + INT16 nZwi; + if(rCol.GetRed()) + { + nZwi = (INT16)GetRed() - (INT16)rCol.GetRed(); + if(nZwi < 0) + nZwi = 0; + SetRed((UINT8)nZwi); + } + if(rCol.GetGreen()) + { + nZwi = (INT16)GetGreen() - (INT16)rCol.GetGreen(); + if(nZwi < 0) + nZwi = 0; + SetGreen((UINT8)nZwi); + } + if(rCol.GetBlue()) + { + nZwi = (INT16)GetBlue() - (INT16)rCol.GetBlue(); + if(nZwi < 0) + nZwi = 0; + SetBlue((UINT8)nZwi); + } + if(rCol.GetTransparency()) + { + nZwi = (INT16)GetTransparency() - (INT16)rCol.GetTransparency(); + if(nZwi < 0) + nZwi = 0; + SetTransparency((UINT8)nZwi); + } + return *this; +} + +/************************************************************************* +|* +|* Farbaddition mit clamping, neue Farbe erzeugen +|* +\************************************************************************/ + +B3dColor B3dColor::operator+ (const B3dColor& rCol) const +{ + B3dColor aSum = *this; + aSum += rCol; + return aSum; +} + +/************************************************************************* +|* +|* Farbsubtraktion mit clamping, neue Farbe erzeugen +|* +\************************************************************************/ + +B3dColor B3dColor::operator- (const B3dColor& rCol) const +{ + B3dColor aSub = *this; + aSub -= rCol; + return aSub; +} + +/************************************************************************* +|* +|* Farbmultiplikation, d.h. Gewichtung der Farben aneinander +|* +\************************************************************************/ + +B3dColor& B3dColor::operator*= (const B3dColor& rCol) +{ + // urspruengliches Objekt ist die Farbe, rCol die zu berechnende + // Gewichtung + SetRed((UINT8)(((((UINT16)GetRed())+1) + * (UINT16)rCol.GetRed()) >> 8)); + SetGreen((UINT8)(((((UINT16)GetGreen())+1) + * (UINT16)rCol.GetGreen()) >> 8)); + SetBlue((UINT8)(((((UINT16)GetBlue())+1) + * (UINT16)rCol.GetBlue()) >> 8)); + SetTransparency((UINT8)(((((UINT16)GetTransparency())+1) + * (UINT16)rCol.GetTransparency()) >> 8)); + return *this; +} + +/************************************************************************* +|* +|* Farbmultiplikation, neue Farbe erzeugen +|* +\************************************************************************/ + +B3dColor B3dColor::operator* (const B3dColor& rCol) const +{ + B3dColor aMul = *this; + aMul *= rCol; + return aMul; +} + +/************************************************************************* +|* +|* Farbmultiplikation mit Faktor im Bereich [0.0 .. 1.0] +|* +\************************************************************************/ + +B3dColor& B3dColor::operator*= (const double fVal) +{ + ULONG nVal = (ULONG)(fVal * 65536.0); + SetRed((UINT8)(((ULONG)GetRed() * nVal) >> 16)); + SetGreen((UINT8)(((ULONG)GetGreen() * nVal) >> 16)); + SetBlue((UINT8)(((ULONG)GetBlue() * nVal) >> 16)); + SetTransparency((UINT8)(((ULONG)GetTransparency() * nVal) >> 16)); + return *this; +} + +/************************************************************************* +|* +|* Farbmultiplikation mit Faktor, neue Farbe erzeugen +|* +\************************************************************************/ + +B3dColor B3dColor::operator* (const double fVal) const +{ + B3dColor aMul = *this; + aMul *= fVal; + return aMul; +} + diff --git a/goodies/source/base3d/b3dcommn.cxx b/goodies/source/base3d/b3dcommn.cxx new file mode 100644 index 000000000000..759c8c2032ee --- /dev/null +++ b/goodies/source/base3d/b3dcommn.cxx @@ -0,0 +1,1415 @@ +/************************************************************************* + * + * $RCSfile: b3dcommn.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop + +#ifndef _B3D_B3DCOMMN_HXX +#include "b3dcommn.hxx" +#endif + +#ifndef _B3D_B3DTRANS_HXX +#include "b3dtrans.hxx" +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _SV_OUTDEV_HXX +#include <vcl/outdev.hxx> +#endif + +/************************************************************************* +|* +|* Bucket fuer Index +|* +\************************************************************************/ + +BASE3D_IMPL_BUCKET(UINT32, Bucket) + +/************************************************************************* +|* +|* Konstruktor Base3DCommon +|* +\************************************************************************/ + +Base3DCommon::Base3DCommon(OutputDevice* pOutDev) +: Base3D(pOutDev), + aBuffers(12) // 4K +{ +} + +/************************************************************************* +|* +|* Destruktor Base3DCommon +|* +\************************************************************************/ + +Base3DCommon::~Base3DCommon() +{ +} + +/************************************************************************* +|* +|* Start der Szenenbeschreibung: +|* +\************************************************************************/ + +void Base3DCommon::StartScene() +{ +} + +/************************************************************************* +|* +|* Ende der Szenenbeschreibung: +|* +\************************************************************************/ + +void Base3DCommon::EndScene() +{ +} + +/************************************************************************* +|* +|* Neuen freien Eintrag fuer naechste geometrische Daten liefern +|* +\************************************************************************/ + +B3dEntity& Base3DCommon::ImplGetFreeEntity() +{ + aBuffers.Append(); + return (aBuffers[aBuffers.Count() - 1]); +} + +/************************************************************************* +|* +|* Beleuchtung setzen/lesen +|* +\************************************************************************/ + +void Base3DCommon::SetLightGroup(B3dLightGroup* pSet, BOOL bSetGlobal) +{ + // call parent + Base3D::SetLightGroup(pSet, bSetGlobal); + + if(GetLightGroup()) + { + Matrix4D aOldObjectTrans; + Matrix4D aEmptyTrans; + if(GetTransformationSet() && bSetGlobal) + { + aOldObjectTrans = GetTransformationSet()->GetObjectTrans(); + GetTransformationSet()->SetObjectTrans(aEmptyTrans); + } + + for(UINT16 i=0;i<BASE3D_MAX_NUMBER_LIGHTS;i++) + { + B3dLight& rLight = GetLightGroup()-> + GetLightObject((Base3DLightNumber)(Base3DLight0 + i)); + if(rLight.IsDirectionalSource()) + { + Vector3D aDirection = rLight.GetPosition(); + if(GetTransformationSet()) + aDirection = GetTransformationSet()->InvTransObjectToEye(aDirection); + aDirection.Normalize(); + rLight.SetPositionEye(aDirection); + } + else + { + Vector3D aPosition = rLight.GetPosition(); + if(GetTransformationSet()) + aPosition = GetTransformationSet()->ObjectToEyeCoor(aPosition); + rLight.SetPositionEye(aPosition); + + Vector3D aDirection = rLight.GetSpotDirection(); + if(GetTransformationSet()) + aDirection = GetTransformationSet()->InvTransObjectToEye(aDirection); + aDirection.Normalize(); + rLight.SetSpotDirectionEye(aDirection); + } + } + + if(GetTransformationSet() && bSetGlobal) + GetTransformationSet()->SetObjectTrans(aOldObjectTrans); + } +} + +/************************************************************************* +|* +|* entsprechend der impliziten Topologie auf den neuen Punkt reagieren +|* +\************************************************************************/ + +void Base3DCommon::ImplPostAddVertex(B3dEntity& rEntity) +{ + B3dTransformationSet* pSet = GetTransformationSet(); + if(pSet) + { + // Positionen transformieren in ClippingCoordinates + rEntity.Point() *= pSet->GetObjectToDevice(); + + // Normalen transformieren in EyeCoordinates + if((GetLightGroup() && GetLightGroup()->IsLightingEnabled()) && rEntity.IsNormalUsed()) + { + if(GetForceFlat() || GetShadeModel() == Base3DFlat) + rEntity.Normal() = pSet->InvTransObjectToEye(rEntity.PlaneNormal()); + else + rEntity.Normal() = pSet->InvTransObjectToEye(rEntity.Normal()); + } + + // Texturkoordinaten transformieren anhand der Texturmatrix + if(rEntity.IsTexCoorUsed()) + { + // Multiplikation mittels Point4D, um die Translationen zu + // beruecksichtigen. Die Koordinaten werden bei GetVector3D() + // homogenisiert. + rEntity.TexCoor() = pSet->TransTextureCoor(rEntity.TexCoor()); + } + } + + // Aktuelle Farbe in diesen B3dEntity eintragen + rEntity.Color() = GetColor(); + + // Jetzt Topologie beachten und evtl. ein Primitiv ausspucken + UINT32 aCount = aBuffers.Count(); + switch(GetObjectMode()) + { + case Base3DPoints: + { + Create3DPoint(0); + aBuffers.Erase(); + break; + } + case Base3DLines: + { + if(aCount == 2) + { + Create3DLine(0, 1); + aBuffers.Erase(); + } + break; + } + case Base3DLineLoop: + case Base3DLineStrip: + { + if(aCount > 1) + Create3DLine(aCount - 2, aCount - 1); + break; + } + case Base3DTriangles: + { + if(aCount == 3) + { + Create3DTriangle(0, 1, 2); + aBuffers.Erase(); + } + break; + } + case Base3DTriangleStrip: + { + if(aCount > 2) + { + if(aCount % 2) + Create3DTriangle(aCount - 3, aCount - 2, aCount - 1); + else + Create3DTriangle(aCount - 2, aCount - 3, aCount - 1); + } + break; + } + case Base3DTriangleFan: + { + if(aCount > 2) + Create3DTriangle(0, aCount - 2, aCount - 1); + break; + } + case Base3DQuads: + { + if(aCount == 4) + { + // Spezielle Behandlung, da die inneren Kanten + // eines Quads NICHT sichtbar sein sollen + B3dEntity& rEnt2 = aBuffers[2]; + B3dEntity& rEnt0 = aBuffers[0]; + + BOOL bZwi = rEnt2.IsEdgeVisible(); + rEnt2.SetEdgeVisible(FALSE); + Create3DTriangle(0, 1, 2); + rEnt2.SetEdgeVisible(bZwi); + + bZwi = rEnt0.IsEdgeVisible(); + rEnt0.SetEdgeVisible(FALSE); + Create3DTriangle(0, 2, 3); + rEnt0.SetEdgeVisible(bZwi); + + aBuffers.Erase(); + } + break; + } + case Base3DQuadStrip: + { + if(aCount > 2) + { + B3dEntity& rEnt = aBuffers[aCount - 2]; + BOOL bZwi = rEnt.IsEdgeVisible(); + rEnt.SetEdgeVisible(FALSE); + if(aCount % 2) + Create3DTriangle(aCount - 2, aCount - 1, aCount - 3); + else + Create3DTriangle(aCount - 3, aCount - 1, aCount - 2); + rEnt.SetEdgeVisible(bZwi); + } + break; + } + case Base3DPolygon: + { + if(aCount > 2) + { + B3dEntity& rEnt = aBuffers[aCount - 1]; + BOOL bZwi = rEnt.IsEdgeVisible(); + rEnt.SetEdgeVisible(FALSE); + Create3DTriangle(0, aCount - 2, aCount - 1); + rEnt.SetEdgeVisible(bZwi); + // Ab jetzt nie wieder eine Kante vom 1. Punkt (0) + // ausgehend generieren + if(aCount == 3) + aBuffers[0].SetEdgeVisible(FALSE); + } + break; + } + } +} + +/************************************************************************* +|* +|* Ein neues Primitiv, leere die jetzigen buffer +|* +\************************************************************************/ + +void Base3DCommon::ImplStartPrimitive() +{ + // Buffer leeren + aBuffers.Erase(); +} + +/************************************************************************* +|* +|* Primitiv abgeschlossen +|* +\************************************************************************/ + +void Base3DCommon::ImplEndPrimitive() +{ + // Topologie beachten und evtl. ein Primitiv ausspucken + UINT32 aCount = aBuffers.Count(); + switch(GetObjectMode()) + { + case Base3DLineLoop: + { + if(aCount > 2) + Create3DLine(aCount - 1, 0); + break; + } + case Base3DPolygon: + { + // Letzte schliessende Linie erzeugen, falls + // es um das Erzeugen von Linien ging und + // das letzte Primitiv auch wirklich zur Ausgabe + // gelangt ist + if(GetRenderMode() == Base3DRenderLine + && !WasLastPrimitiveRejected()) + { + if(aCount > 2) + Create3DLine(aCount - 1, 0); + } + break; + } + } +} + +/************************************************************************* +|* +|* Funktion fuer Primitiv Punkt +|* Clipping und Ausgabe, falls noch was ueber ist +|* +\************************************************************************/ + +void Base3DCommon::Create3DPoint(UINT32 nInd) +{ + bLastPrimitiveRejected = TRUE; + if(GetRenderMode() != Base3DRenderNone) + { + // Sicherstellen, dass die Koordinaten in + // ClipCoordinates vorliegen + aBuffers[nInd].To3DCoor(GetTransformationSet()); + + // Punkt an Einheitswuerfel clippen + if(Clip3DPoint(nInd)) + Create3DPointClipped(nInd); + } +} + +void Base3DCommon::Create3DPointClipped(UINT32 nInd) +{ + // einige Beleuchtungsdinge koennen hier schon geklaert + // werden + if(GetLightGroup() && GetLightGroup()->IsLightingEnabled()) + { + B3dEntity& rEnt = aBuffers[nInd]; + if(rEnt.IsNormalUsed() && GetLightGroup()) + { + // Beleuchtungsmodell loesen, Normale loeschen + SolveColorModel(rEnt.Color(), rEnt.Normal(), rEnt.Point().GetVector3D()); + } + rEnt.SetNormalUsed(FALSE); + } + + // Punkt wird dargestellt, weiterreichen + if(GetPointSize() != 1.0) + { + // Punkt als Kreis mit dem Durchmesser GetPointSize() ausgeben + // Hole den Original-Punkt + B3dEntity& rEnt1 = aBuffers[nInd]; + + // Umrechnen auf DeviceCoor + rEnt1.ToDeviceCoor(GetTransformationSet()); + + // Radius holen + // Logische Koordinaten nach Pixel + Point aPnt((long)(GetLineWidth() + 0.5), 0); + double fRadius = ((double)(( + GetOutputDevice()->PixelToLogic(aPnt).X() - + GetOutputDevice()->PixelToLogic(Point()).X()) + 0.5)) / 2.0; + + // Bereite neue Punkte vor + // Hole die neuen Punkte + UINT32 nNew1 = aBuffers.Count(); + aBuffers.Append(rEnt1); + B3dEntity& rNew1 = aBuffers[nNew1]; + + UINT32 nNew2 = aBuffers.Count(); + aBuffers.Append(rEnt1); + B3dEntity& rNew2 = aBuffers[nNew2]; + + UINT32 nNew3 = aBuffers.Count(); + aBuffers.Append(rEnt1); + B3dEntity& rNew3 = aBuffers[nNew3]; + + // Schleife drehen + Base3DRenderMode eRenderMode = GetRenderMode(); + SetRenderMode(Base3DRenderFill); + BOOL bPolyOffset = GetPolygonOffset(Base3DPolygonOffsetFill); + SetPolygonOffset(Base3DPolygonOffsetFill, TRUE); + + for(double fWink=0.0;fWink<F_2PI-(F_2PI/24.0);fWink+=F_2PI/12.0) + { + rNew2.Point().X() = rNew1.Point().X() + (cos(fWink) * fRadius); + rNew2.Point().Y() = rNew1.Point().Y() + (sin(fWink) * fRadius); + + rNew3.Point().X() = rNew1.Point().X() + (cos(fWink+(F_2PI/12.0)) * fRadius); + rNew3.Point().Y() = rNew1.Point().Y() + (sin(fWink+(F_2PI/12.0)) * fRadius); + + // Dreieck Zeichnen + Create3DTriangle(nNew1, nNew3, nNew2); + } + + SetRenderMode(eRenderMode); + SetPolygonOffset(Base3DPolygonOffsetFill, bPolyOffset); + + bLastPrimitiveRejected = FALSE; + } + else + { + Clipped3DPoint(nInd); + bLastPrimitiveRejected = FALSE; + } +} + +/************************************************************************* +|* +|* Funktion fuer Primitiv Linie +|* Clipping und Ausgabe, falls noch was ueber ist +|* +\************************************************************************/ + +void Base3DCommon::Create3DLine(UINT32 nInd1, UINT32 nInd2) +{ + bLastPrimitiveRejected = TRUE; + if(GetRenderMode() != Base3DRenderNone) + { + // Sicherstellen, dass die Koordinaten in + // ClipCoordinates vorliegen + aBuffers[nInd1].To3DCoor(GetTransformationSet()); + aBuffers[nInd2].To3DCoor(GetTransformationSet()); + + if(AreEqual(nInd1, nInd2)) + return; + + // Linie an Einheitswuerfel clippen, dabei kann eine + // der Indexvariablen (werden als Referenz uegergeben) + // veraendert werden + + // Alte Buffergroesse merken + ULONG nCount = aBuffers.Count(); + + if(Clip3DLine(nInd1, nInd2)) + { + // EdgeFlag beachten + if(aBuffers[nInd1].IsEdgeVisible()) + Create3DLineClipped(nInd1, nInd2); + } + + // Alte Buffergroesse wiederherstellen, um fortgesetzte + // Primitive nicht zu zerstoeren + while(aBuffers.Count() > nCount) + aBuffers.Remove(); + } +} + +void Base3DCommon::Create3DLineClipped(UINT32 nInd1, UINT32 nInd2) +{ + // einige Beleuchtungsdinge koennen hier schon geklaert + // werden + if(GetLightGroup() && GetLightGroup()->IsLightingEnabled()) + { + if(GetShadeModel() == Base3DFlat) + { + // Beleuchtuungsmodell fuer gemittelte Normale + // loesen, Normalen loeschen + B3dEntity& rEnt1 = aBuffers[nInd1]; + B3dEntity& rEnt2 = aBuffers[nInd2]; + if(rEnt1.IsNormalUsed() && rEnt2.IsNormalUsed() && GetLightGroup()) + { + Vector3D aNormal = rEnt1.Normal() + rEnt2.Normal(); + aNormal.Normalize(); + Vector3D aPoint = (rEnt1.Point().GetVector3D() + rEnt2.Point().GetVector3D()) / 2.0; + SolveColorModel(rEnt1.Color(), aNormal, aPoint); + rEnt2.Color() = rEnt1.Color(); + } + rEnt1.SetNormalUsed(FALSE); + rEnt2.SetNormalUsed(FALSE); + } + } + else + { + if(GetShadeModel() == Base3DFlat) + { + B3dEntity& rEnt1 = aBuffers[nInd1]; + B3dEntity& rEnt2 = aBuffers[nInd2]; + B3dColor aCol; + aCol.CalcMiddle(rEnt1.Color(), rEnt2.Color()); + rEnt1.Color() = aCol; + rEnt2.Color() = aCol; + } + } + + if(GetRenderMode() == Base3DRenderPoint) + { + // Als Punkte ausgeben + Create3DPointClipped(nInd1); + Create3DPointClipped(nInd2); + } + else + { + if(GetLineWidth() != 1.0) + { + // Linie als Polygon mit der Breite GetLineWidth() ausgeben + // Hole die Original-Punkte + B3dEntity& rEnt1 = aBuffers[nInd1]; + B3dEntity& rEnt2 = aBuffers[nInd2]; + + // Umrechnen auf DeviceCoor + rEnt1.ToDeviceCoor(GetTransformationSet()); + rEnt2.ToDeviceCoor(GetTransformationSet()); + + // Bereite neue Punkte vor + // Hole die neuen Punkte + UINT32 nNew1 = aBuffers.Count(); + aBuffers.Append(rEnt1); + B3dEntity& rNew1 = aBuffers[nNew1]; + + UINT32 nNew2 = aBuffers.Count(); + aBuffers.Append(rEnt1); + B3dEntity& rNew2 = aBuffers[nNew2]; + + UINT32 nNew3 = aBuffers.Count(); + aBuffers.Append(rEnt2); + B3dEntity& rNew3 = aBuffers[nNew3]; + + UINT32 nNew4 = aBuffers.Count(); + aBuffers.Append(rEnt2); + B3dEntity& rNew4 = aBuffers[nNew4]; + + // Berechnen + Vector3D aEntVector = rEnt2.Point().GetVector3D() - rEnt1.Point().GetVector3D(); + Vector3D aTurned(-aEntVector.Y(), aEntVector.X(), 0.0); + aTurned.Normalize(); + + // Logische Koordinaten nach Pixel + Point aPnt((long)(GetLineWidth() + 0.5), 0); + double fFac = ((double)(( + GetOutputDevice()->PixelToLogic(aPnt).X() - + GetOutputDevice()->PixelToLogic(Point()).X()) + 0.5)) / 2.0; + + // Aufmuliplizieren + aTurned *= fFac; + + rNew1.Point().X() += aTurned.X(); + rNew1.Point().Y() += aTurned.Y(); + rNew2.Point().X() -= aTurned.X(); + rNew2.Point().Y() -= aTurned.Y(); + + rNew3.Point().X() += aTurned.X(); + rNew3.Point().Y() += aTurned.Y(); + rNew4.Point().X() -= aTurned.X(); + rNew4.Point().Y() -= aTurned.Y(); + + // Ausgeben + Base3DRenderMode eRenderMode = GetRenderMode(); + SetRenderMode(Base3DRenderFill); + BOOL bPolyOffset = GetPolygonOffset(Base3DPolygonOffsetFill); + SetPolygonOffset(Base3DPolygonOffsetFill, TRUE); + + Create3DTriangle(nNew2, nNew1, nNew3); + Create3DTriangle(nNew2, nNew3, nNew4); + + SetRenderMode(eRenderMode); + SetPolygonOffset(Base3DPolygonOffsetFill, bPolyOffset); + + bLastPrimitiveRejected = FALSE; + } + else + { + // Linie ausgeben + Clipped3DLine(nInd1,nInd2); + bLastPrimitiveRejected = FALSE; + } + } +} + +/************************************************************************* +|* +|* Funktion fuer Primitiv Dreieck +|* Clipping und Ausgabe, falls noch was ueber ist +|* +\************************************************************************/ + +void Base3DCommon::Create3DTriangle(UINT32 nInd1, UINT32 nInd2, UINT32 nInd3) +{ + bLastPrimitiveRejected = TRUE; + + // Sicherstellen, dass die Koordinaten in + // ClipCoordinates vorliegen + aBuffers[nInd1].To3DCoor(GetTransformationSet()); + aBuffers[nInd2].To3DCoor(GetTransformationSet()); + aBuffers[nInd3].To3DCoor(GetTransformationSet()); + + if(AreEqual(nInd1, nInd2) + || AreEqual(nInd1, nInd3) + || AreEqual(nInd2, nInd3)) + return; + + // Normale vorbereiten, die echte Ebenennormale der Geometrie + // im Device-Koordinatensystem. Verzerrungen durch perspektivische + // Projektion sind somit bereits beruecksichtigt. + const Vector3D& rPnt1 = aBuffers[nInd1].Point().GetVector3D(); + const Vector3D& rPnt2 = aBuffers[nInd2].Point().GetVector3D(); + const Vector3D& rPnt3 = aBuffers[nInd3].Point().GetVector3D(); + Vector3D aNormal = (rPnt2 - rPnt3)|(rPnt2 - rPnt1); + aNormal.Normalize(); + + if(GetCullMode() != Base3DCullNone) + { + // Normale ermitteln, eventuell gar nicht zeichnen + if(GetCullMode() == Base3DCullFront) + { + if(aNormal.Z() > 0.0) + return; + } + else + { + if(aNormal.Z() < 0.0) + return; + } + } + + // allgemeines Polygon vorbereiten + UINT32Bucket aEdgeIndex(8); + aEdgeIndex.Append(nInd1); + aEdgeIndex.Append(nInd2); + aEdgeIndex.Append(nInd3); + + // Alte Buffergroesse merken + ULONG nCount = aBuffers.Count(); + + // Dreieck an Einheitswuerfel clippen + if(Clip3DPolygon(aEdgeIndex)) + { + UINT32 nNumPoints = aEdgeIndex.Count(); + + // einige Beleuchtungsdinge koennen hier schon geklaert + // werden + if(GetLightGroup() && GetLightGroup()->IsLightingEnabled() && nNumPoints != 0) + { + if(GetShadeModel() == Base3DFlat) + { + B3dEntity& rEnt = aBuffers[nInd1]; + B3dColor aColFlatMode; + + // #63505# + aNormal.X() = -aNormal.X(); + aNormal.Y() = -aNormal.Y(); + + SolveColorModel(aColFlatMode, aNormal, rEnt.Point().GetVector3D()); + + // Vorberechnete Farbe in Eckpunkten setzen + for(UINT32 i=0;i<nNumPoints;i++) + { + B3dEntity& rEnt = aBuffers[aEdgeIndex[i]]; + rEnt.Color() = aColFlatMode; + rEnt.SetNormalUsed(FALSE); + } + } + } + else + { + if(GetShadeModel() == Base3DFlat && nNumPoints != 0) + { + UINT16 aRed(0), aGreen(0), aBlue(0), aAlpha(0); + UINT32 i; + for(i=0;i<nNumPoints;i++) + { + B3dEntity& rEnt = aBuffers[aEdgeIndex[i]]; + aRed += (UINT16)rEnt.Color().GetRed(); + aGreen += (UINT16)rEnt.Color().GetGreen(); + aBlue += (UINT16)rEnt.Color().GetBlue(); + aAlpha += (UINT16)rEnt.Color().GetTransparency(); + } + B3dColor aCol((UINT8)(aAlpha / nNumPoints), + (UINT8)(aRed / nNumPoints), + (UINT8)(aGreen / nNumPoints), + (UINT8)(aBlue / nNumPoints)); + for(i=0;i<nNumPoints;i++) + { + aBuffers[aEdgeIndex[i]].Color() = aCol; + } + } + } + + // Ausgeben, je nach Modus + Base3DMaterialMode eMat = Base3DMaterialFront; + if(aNormal.Z() < 0.0 + && (GetLightGroup() && GetLightGroup()->GetModelTwoSide())) + eMat = Base3DMaterialBack; + Base3DRenderMode eMode = GetRenderMode(eMat); + + if(eMode == Base3DRenderPoint) + { + // Als Punktmenge ausgeben + for(UINT32 i=0;i<nNumPoints;i++) + { + Create3DPointClipped(aEdgeIndex[i]); + } + } + else if(eMode == Base3DRenderLine) + { + // Als Linien ausgeben + UINT32 i2, i3; + for(UINT32 i=0;i<nNumPoints;i++) + { + i2 = i+1; + if(i2 == nNumPoints) + i2 = 0; + i3 = aEdgeIndex[i]; + i2 = aEdgeIndex[i2]; + + // EdgeFlag beachten + if(aBuffers[i3].IsEdgeVisible()) + Create3DLineClipped(i3, i2); + } + } + else + { + // after clipping the triangle can be a multi-sided, but + // convex polygon. Render it by dividing it into triangles + // again. Cause' it is clipped now, no more taking care is + // necessary. Just give hints which flags are truly edges + // to allow further computations. + if(nNumPoints > 2) + { + for(UINT32 i=2;i < nNumPoints; i++) + { + Clipped3DTriangle( + aEdgeIndex[0], + aEdgeIndex[i-1], + aEdgeIndex[i]); + bLastPrimitiveRejected = FALSE; + } + } + } + } + // Alte Buffergroesse wiederherstellen, um fortgesetzte + // Primitive nicht zu zerstoeren + while(aBuffers.Count() > nCount) + aBuffers.Remove(); +} + +/************************************************************************* +|* +|* Punkt am canonical view volume clippen +|* +\************************************************************************/ + +BOOL Base3DCommon::Clip3DPoint(UINT32 nInd) +{ + return (!(BOOL)GetClipFlags(nInd)); +} + +/************************************************************************* +|* +|* Vergleicht, ob die beiden Entities geometrisch gleich sind +|* +\************************************************************************/ + +BOOL Base3DCommon::AreEqual(UINT32 nInd1, UINT32 nInd2) +{ + const Vector3D& rVec1 = aBuffers[nInd1].Point().GetVector3D(); + const Vector3D& rVec2 = aBuffers[nInd2].Point().GetVector3D(); + + if(fabs(rVec1.X() - rVec2.X()) < SMALL_DVALUE) + if(fabs(rVec1.Y() - rVec2.Y()) < SMALL_DVALUE) + if(fabs(rVec1.Z() - rVec2.Z()) < SMALL_DVALUE) + return TRUE; + return FALSE; +} + +/************************************************************************* +|* +|* Linie am canonical view volume clippen +|* +\************************************************************************/ + +BOOL Base3DCommon::Clip3DLine(UINT32& nInd1,UINT32& nInd2) +{ + UINT16 nFlag0, nFlag1; + do + { + nFlag0 = GetClipFlags(nInd1); + nFlag1 = GetClipFlags(nInd2); + + // Beide Endpunkte drin? + if(!(nFlag0 | nFlag1)) + return TRUE; + + // Linie komplett draussen? + if(nFlag0 & nFlag1) + return FALSE; + + // Es muss geclippt werden, bereite einen neuen Punkt vor + UINT32 nNewIndex = aBuffers.Count(); + aBuffers.Append(); + + if((nFlag0 | nFlag1) & (CLIPFLAG_FRONT | CLIPFLAG_BACK)) + { + // clippen in Z + if(nFlag0 & (CLIPFLAG_FRONT | CLIPFLAG_BACK)) + { + if(nFlag0 & CLIPFLAG_FRONT) + CalcNewPoint(nNewIndex, nInd2, nInd1, 2, -1.0); + else + CalcNewPoint(nNewIndex, nInd1, nInd2, 2, 1.0); + nInd1 = nNewIndex; + } + else + { + if(nFlag1 & CLIPFLAG_FRONT) + CalcNewPoint(nNewIndex, nInd1, nInd2, 2, -1.0); + else + CalcNewPoint(nNewIndex, nInd2, nInd1, 2, 1.0); + nInd2 = nNewIndex; + } + } + else if((nFlag0 | nFlag1) & (CLIPFLAG_LEFT | CLIPFLAG_RIGHT)) + { + // clippen in X + if(nFlag0 & (CLIPFLAG_LEFT | CLIPFLAG_RIGHT)) + { + if(nFlag0 & CLIPFLAG_LEFT) + CalcNewPoint(nNewIndex, nInd2, nInd1, 0, -1.0); + else + CalcNewPoint(nNewIndex, nInd1, nInd2, 0, 1.0); + nInd1 = nNewIndex; + } + else + { + if(nFlag1 & CLIPFLAG_LEFT) + CalcNewPoint(nNewIndex, nInd1, nInd2, 0, -1.0); + else + CalcNewPoint(nNewIndex, nInd2, nInd1, 0, 1.0); + nInd2 = nNewIndex; + } + } + else + { + // clippen in Y + if(nFlag0 & (CLIPFLAG_BOTTOM | CLIPFLAG_TOP)) + { + if(nFlag0 & CLIPFLAG_BOTTOM) + CalcNewPoint(nNewIndex, nInd2, nInd1, 1, -1.0); + else + CalcNewPoint(nNewIndex, nInd1, nInd2, 1, 1.0); + nInd1 = nNewIndex; + } + else + { + if(nFlag1 & CLIPFLAG_BOTTOM) + CalcNewPoint(nNewIndex, nInd1, nInd2, 1, -1.0); + else + CalcNewPoint(nNewIndex, nInd2, nInd1, 1, 1.0); + nInd2 = nNewIndex; + } + } + } while(nFlag0 | nFlag1); + return TRUE; +} + +/************************************************************************* +|* +|* ClipFlags eines Punktes ermitteln und zurueckgeben +|* +\************************************************************************/ + +UINT16 Base3DCommon::GetClipFlags(UINT32 nInd) +{ + UINT16 nRetval(0); + Point4D& rPoint = aBuffers[nInd].Point(); + rPoint.Homogenize(); + + if(rPoint[0] < -(1.0 + SMALL_DVALUE)) + nRetval |= CLIPFLAG_LEFT; + if(rPoint[0] > 1.0 + SMALL_DVALUE) + nRetval |= CLIPFLAG_RIGHT; + + if(rPoint[1] < -(1.0 + SMALL_DVALUE)) + nRetval |= CLIPFLAG_BOTTOM; + if(rPoint[1] > 1.0 + SMALL_DVALUE) + nRetval |= CLIPFLAG_TOP; + + if(rPoint[2] < -(1.0 + SMALL_DVALUE)) + nRetval |= CLIPFLAG_FRONT; + if(rPoint[2] > 1.0 + SMALL_DVALUE) + nRetval |= CLIPFLAG_BACK; + + return nRetval; +} + +/************************************************************************* +|* +|* Dreieck am canonical view volume clippen +|* Ergebnis steht indirekt ueber eine Indizierungstabelle in +|* aEdgeIndex[nEdgeDestination][0 .. aEdgeIndexFree[nEdgeDestination]] +|* +\************************************************************************/ + +BOOL Base3DCommon::Clip3DPolygon(UINT32Bucket& rEdgeIndex) +{ + UINT32 i; + UINT16 nAllFlagsOr, nAllFlagsAnd; + + do + { + // ClipFlags holen + nAllFlagsOr = 0; + nAllFlagsAnd = CLIPFLAG_ALL; + + for(i=0; i < rEdgeIndex.Count(); i++) + { + UINT16 nFlag = GetClipFlags(rEdgeIndex[i]); + nAllFlagsOr |= nFlag; + nAllFlagsAnd &= nFlag; + } + + // Alle Endpunkte drin? + if(!nAllFlagsOr) + return TRUE; + + // Dreieck komplett draussen? + if(nAllFlagsAnd) + return FALSE; + + if(nAllFlagsOr & (CLIPFLAG_FRONT|CLIPFLAG_BACK)) + { + // clippen in Z + if(nAllFlagsOr & CLIPFLAG_FRONT) + { + ClipPoly(rEdgeIndex, 2, TRUE); + } + else + { + ClipPoly(rEdgeIndex, 2, FALSE); + } + } + else if(nAllFlagsOr & (CLIPFLAG_LEFT|CLIPFLAG_RIGHT)) + { + // clippen in X + if(nAllFlagsOr & CLIPFLAG_LEFT) + { + ClipPoly(rEdgeIndex, 0, TRUE); + } + else + { + ClipPoly(rEdgeIndex, 0, FALSE); + } + } + else + { + // clippen in Y + if(nAllFlagsOr & CLIPFLAG_BOTTOM) + { + ClipPoly(rEdgeIndex, 1, TRUE); + } + else + { + ClipPoly(rEdgeIndex, 1, FALSE); + } + } + } while(nAllFlagsOr); + return TRUE; +} + +/************************************************************************* +|* +|* Testen, ob die Entitaet nInd innerhalb des canonical view volume liegt +|* +\************************************************************************/ + +BOOL Base3DCommon::IsInside(UINT32 nInd, UINT32 nDim, BOOL bLow) +{ + B3dEntity& aEntity = aBuffers[nInd]; + if(bLow) + { + if(aEntity.Point()[nDim] < -1.0) + return FALSE; + } + else + { + if(aEntity.Point()[nDim] > 1.0) + return FALSE; + } + return TRUE; +} + +/************************************************************************* +|* +|* Macht einen Clippingdurchgang eines Polygons in der angegebenen +|* Dimension. Es werden eventuell neue Punkte erzeugt. +|* +\************************************************************************/ + +void Base3DCommon::ClipPoly(UINT32Bucket& rEdgeIndex, UINT16 nDim, BOOL bLow) +{ + UINT32 nNumEdges = rEdgeIndex.Count(); + UINT32 nCurrentInd = rEdgeIndex[0]; + BOOL bCurrentInside = IsInside(nCurrentInd, nDim, bLow); + UINT32 nNextInd; + BOOL bNextInside; + UINT32Bucket aEdgeIndex(8); + + for(UINT32 i=0;i<nNumEdges;i++) + { + // hole naechsten Eckpunkt + nNextInd = i+1; + if(nNextInd == nNumEdges) + nNextInd = 0; + nNextInd = rEdgeIndex[nNextInd]; + bNextInside = IsInside(nNextInd, nDim, bLow); + + // behandle die Kante nCurrentInd, nNextInd in der Dimension + // nDim gegen die Grenze -1.0 + if(bCurrentInside) + { + // aktuellen Punkt hinzufuegen + aEdgeIndex.Append(nCurrentInd); + if(!bNextInside) + { + // drin -> draussen + // Platz fuer Schnittpunkt allokieren + UINT32 nNewIndex = aBuffers.Count(); + aBuffers.Append(); + + // Schnittpunkt berechnen + if(bLow) + CalcNewPoint(nNewIndex, nCurrentInd, nNextInd, nDim, -1.0); + else + CalcNewPoint(nNewIndex, nNextInd, nCurrentInd, nDim, 1.0); + + // EdgeFlag behandeln, beim Verlassen zuruecksetzen + if(aBuffers[nCurrentInd].IsEdgeVisible()) + aBuffers[nNewIndex].SetEdgeVisible(FALSE); + + // Schnittpunkt hinzufuegen + aEdgeIndex.Append(nNewIndex); + } + } + else + { + if(bNextInside) + { + // draussen -> drin + // Platz fuer Schnittpunkt allokieren + UINT32 nNewIndex = aBuffers.Count(); + aBuffers.Append(); + + // Schnittpunkt berechnen + if(bLow) + CalcNewPoint(nNewIndex, nNextInd, nCurrentInd, nDim, -1.0); + else + CalcNewPoint(nNewIndex, nCurrentInd, nNextInd, nDim, 1.0); + + // EdgeFlag behandeln, selber Wert wie Vorgaenger + aBuffers[nNewIndex].SetEdgeVisible(aBuffers[nCurrentInd].IsEdgeVisible()); + + // Schnittpunkt hinzufuegen + aEdgeIndex.Append(nNewIndex); + } + } + + // bereite naechste Kante vor + nCurrentInd = nNextInd; + bCurrentInside = bNextInside; + } + + // Indices kopieren + rEdgeIndex = aEdgeIndex; +} + +/************************************************************************* +|* +|* Die Entitaet nNew muss berechnet werden in der angegebenen +|* Dimension an der Grenze fBound. +|* +\************************************************************************/ + +void Base3DCommon::CalcNewPoint(UINT32 nNew, UINT32 nHigh, UINT32 nLow, + UINT16 nDim, double fBound) +{ + B3dEntity& aNew = aBuffers[nNew]; + B3dEntity& aHigh = aBuffers[nHigh]; + B3dEntity& aLow = aBuffers[nLow]; + aNew.Reset(); + + double fFactor = 1.0; + if(aLow.Point()[nDim] != aHigh.Point()[nDim]) + fFactor = (fBound - aHigh.Point()[nDim]) + / (aLow.Point()[nDim] - aHigh.Point()[nDim]); + +#ifdef DBG_UTIL + if(fFactor > 1.0 || fFactor < 0.0) + DBG_ERROR("Wrong clipping factor (out of range)!"); + if(fFactor == 1.0 || fFactor == 0.0) + DBG_ERROR("Wrong clipping factor (on boundary)!"); +#endif + + // Neuen Punkt berechnen, aber Reihenfolge der + // Punkte aufrecht erhalten um die Sichtbarkeit + // der Kanten zu retten + aLow.ForceEqualBase(GetTransformationSet(), aHigh); + if(fBound < 0.0) + aNew.CalcInBetween(aLow, aHigh, 1.0 - fFactor); + else + aNew.CalcInBetween(aHigh, aLow, fFactor); + + // WICHTIG fuer die Numerik beim Clippen: Die betroffene + // Koordinate wirklich auf fBound setzen, nicht berechnen. + // Beim Berechnen koennen nur wieder Ungenauigkeiten auftreten, + // die bei der Bestimmung der Clipping-Grenzen zu + // Endlosschleifen fuehren koennen. + aNew.Point()[nDim] = fBound; +} + +/************************************************************************* +|* +|* Beleuchtungsmodell (ColorModel) in einem Punkt loesen +|* Dabei das Ergebnis in rCol ablegen, d.h. wirklich modifizieren +|* +\************************************************************************/ + +void Base3DCommon::SolveColorModel(B3dColor& rCol, Vector3D& rVec, + const Vector3D& rPnt) +{ + if(GetLightGroup() && GetLightGroup()->IsLightingEnabled()) + { + B3dMaterial& rMat = GetMaterialObject(); + BOOL bDoSolve(TRUE); + + // Welches Material? Zeigt der Vektor vom Betrachter + // weg oder auf diesen? + if(rVec.Z() < 0.0) + { + // Rueckseite, soll diese dargestellt werden? + if(GetLightGroup() && GetLightGroup()->GetModelTwoSide()) + { + rMat = GetMaterialObject(Base3DMaterialBack); + } + else + { + bDoSolve = FALSE; + } + } + if(bDoSolve) + rCol = SolveColorModel(rMat, rVec, rPnt); + } +} + +B3dColor Base3DCommon::SolveColorModel(B3dMaterial& rMat, Vector3D& rVec, const Vector3D& rPnt) +{ + // Material emission einbeziehen + B3dColor aNew = rMat.GetMaterial(Base3DMaterialEmission); + + // global ambient light beachten + aNew += (B3dColor)rMat.GetMaterial(Base3DMaterialAmbient) + * (B3dColor)GetLightGroup()->GetGlobalAmbientLight(); + + if(GetTransformationSet()) + { + // Die Punktkoordinate liegt in ClipCoordinates vor, wird + // aber zur Farbberechnung in EyeCoordinates benoetigt. + // Fuehre eine Ruecktransformation durch. + Vector3D aPnt(rPnt); + aPnt = GetTransformationSet()->DeviceToEyeCoor(aPnt); + + // Falls die Normale vom Betrachter weg zeigt und das Beleuchtungs- + // modell doppelseitig ist, Normale umdrehen + Vector3D aVec(rVec); + if(rVec.Z() < 0.0 && GetLightGroup()->GetModelTwoSide()) + aVec = -rVec; + + // Die einzelnen Lichtquellen einbeziehen + for(UINT16 i=Base3DLight0; i <= Base3DLight7; i++) + { + if(GetLightGroup()->IsEnabled((Base3DLightNumber)i)) + { + aNew += SolveColorModel( + GetLightGroup()->GetLightObject((Base3DLightNumber)i), + rMat, aVec, aPnt); + } + } + + // Transparenz aus der Diffuse (=Objekt-) Farbe uebernehmen + aNew.SetTransparency(rMat.GetMaterial(Base3DMaterialDiffuse).GetTransparency()); + } + return aNew; +} + +/************************************************************************* +|* +|* Beleuchtungsmodell (ColorModel) fuer eine Lichtquelle loesen +|* +\************************************************************************/ + +B3dColor Base3DCommon::SolveColorModel(B3dLight& rLight, B3dMaterial& rMat, + Vector3D& rVec, const Vector3D& rPnt) +{ + B3dColor aRetval(255, 0, 0, 0); + if(rLight.IsEnabled()) + { + // Faktor mit Attenuation 1.0 initialisieren, falls + // IsDirectionalSource() == TRUE + double fFac = 1.0; + Vector3D aLightToVertex; + BOOL bLightToVertex(FALSE); + + if(!rLight.IsDirectionalSource()) + { + // positional light + // echten attenuation Faktor ermitteln + fFac = rLight.GetConstantAttenuation(); + if(rLight.IsLinearOrQuadratic()) + { + // jetzt wird die Entfernung zwischen Lichtposition + // und Punkt benoetigt + aLightToVertex = rPnt - rLight.GetPositionEye(); + bLightToVertex = TRUE; + double fLen = aLightToVertex.GetLength(); + aLightToVertex.Normalize(); + + fFac += rLight.GetLinearAttenuation() * fLen; + fFac += rLight.GetQuadraticAttenuation() * fLen * fLen; + } + // Kehrwert bilden + if(fFac != 1.0 && fFac != 0.0) + fFac = 1.0 / fFac; + + if(rLight.IsSpot()) + { + // Spotlight it immer ein positional light + // Spotlight effect, wird auf den Faktor multipliziert + if(!bLightToVertex) + { + aLightToVertex = rPnt - rLight.GetPositionEye(); + aLightToVertex.Normalize(); + bLightToVertex = TRUE; + } + double fCosAngle = aLightToVertex.Scalar(rLight.GetSpotDirection()); + // innerhalb des konus? + if(fCosAngle <= rLight.GetCosSpotCutoff()) + { + if(fCosAngle > 0.000001) + { + if(rLight.GetSpotExponent() != 0.0) + fCosAngle = pow(fCosAngle, rLight.GetSpotExponent()); + fFac *= fCosAngle; + } + else + { + fFac = 0.0; + } + } + else + { + // Ausserhalb des Konus, keine Beleuchtung + fFac = 0.0; + } + } + } + + // falls es etwas zu beleuchten gibt... + if(fFac != 0.0) + { + // Ambient term + if(rLight.IsAmbient()) + { + aRetval += (B3dColor)rLight.GetIntensity(Base3DMaterialAmbient) + * (B3dColor)rMat.GetMaterial(Base3DMaterialAmbient); + } + + if(rLight.IsDiffuse() || rLight.IsSpecular()) + { + if(bLightToVertex) + { + // Falls hier schon berechnet, handelt es sich + // auch um ein positional light + aLightToVertex = -aLightToVertex; + } + else + { + if(rLight.IsDirectionalSource()) + { + // Vektor direkt nehmen + aLightToVertex = rLight.GetPosition(); + } + else + { + // Umgerechnete Lichtposition nehmen + aLightToVertex = rLight.GetPositionEye(); + // Betrachtete Position abziehen -> Einheitsvektor + // vom Punkt zur Lichtquelle + aLightToVertex -= rPnt; + } + aLightToVertex.Normalize(); + } + double fCosFac = aLightToVertex.Scalar(rVec); + + if(fCosFac > 0.000001) + { + if(rLight.IsDiffuse()) + { + // Diffuse term + aRetval += (B3dColor)rLight.GetIntensity(Base3DMaterialDiffuse) + * (B3dColor)rMat.GetMaterial(Base3DMaterialDiffuse) + * fCosFac; + } + if(rLight.IsSpecular()) + { + // Specular term + if(GetLightGroup()->GetLocalViewer()) + { + // use vector 0,0,1 + aLightToVertex.Z() += 1.0; + } + else + { + // vector Vertex to Viewpoint berechnen in + // Augkoordinaten, ist 0 - rPnt + aLightToVertex -= rPnt; + } + aLightToVertex.Normalize(); + fCosFac = aLightToVertex.Scalar(rVec); + if(fCosFac > 0.000001) + { + if(rMat.GetShininess()) + fCosFac = pow(fCosFac, rMat.GetShininess()); + aRetval += (B3dColor)rLight.GetIntensity(Base3DMaterialSpecular) + * (B3dColor)rMat.GetMaterial(Base3DMaterialSpecular) + * fCosFac; + } + } + } + } + + // jetzt fFac aufrechnen + if(fFac != 1.0) + aRetval *= fFac; + } + } + return aRetval; +} + + diff --git a/goodies/source/base3d/b3dcommn.hxx b/goodies/source/base3d/b3dcommn.hxx new file mode 100644 index 000000000000..300c84e6cf21 --- /dev/null +++ b/goodies/source/base3d/b3dcommn.hxx @@ -0,0 +1,165 @@ +/************************************************************************* + * + * $RCSfile: b3dcommn.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DCOMMN_HXX +#define _B3D_B3DCOMMN_HXX + +#ifndef _B3D_BASE3D_HXX +#include "base3d.hxx" +#endif + +#ifndef _B3D_B3DGEOM_HXX +#include "b3dgeom.hxx" +#endif + +// Defines fuer clipping flags (nFlag0,1) +#define CLIPFLAG_LEFT 0x0001 +#define CLIPFLAG_RIGHT 0x0002 +#define CLIPFLAG_BOTTOM 0x0004 +#define CLIPFLAG_TOP 0x0008 +#define CLIPFLAG_FRONT 0x0010 +#define CLIPFLAG_BACK 0x0020 +#define CLIPFLAG_ALL (CLIPFLAG_LEFT|CLIPFLAG_RIGHT| \ + CLIPFLAG_BOTTOM|CLIPFLAG_TOP| \ + CLIPFLAG_FRONT|CLIPFLAG_BACK) + +/************************************************************************* +|* +|* Bucket fuer Indices +|* +\************************************************************************/ + +BASE3D_DECL_BUCKET(UINT32, Bucket) + +/************************************************************************* +|* +|* Die Basisklasse fuer Standard 3D Ausgaben auf StarView Basis +|* +\************************************************************************/ + +#define BUFFER_OVERHEAD (20) + +class Base3DCommon : public Base3D +{ +protected: + // Buffers fuer temporaere geometrische Daten + B3dEntityBucket aBuffers; + + // Remember if last primitive was rejected + BOOL bLastPrimitiveRejected : 1; + +public: + Base3DCommon(OutputDevice* pOutDev); + virtual ~Base3DCommon(); + + // Beleuchtung setzen/lesen + virtual void SetLightGroup(B3dLightGroup* pSet, BOOL bSetGlobal=TRUE); + + // Info if last primitive was rejected + BOOL WasLastPrimitiveRejected() + { return bLastPrimitiveRejected; } + + // Szenenverwaltung + virtual void StartScene(); + virtual void EndScene(); + +protected: + // Geometrische Daten uebergeben + virtual B3dEntity& ImplGetFreeEntity(); + + virtual void ImplStartPrimitive(); + virtual void ImplEndPrimitive(); + virtual void ImplPostAddVertex(B3dEntity& rEnt); + + void Create3DPoint(UINT32 nInd); + void Create3DPointClipped(UINT32 nInd); + void Create3DLine(UINT32 nInd1, UINT32 nInd2); + void Create3DLineClipped(UINT32 nInd1, UINT32 nInd2); + void Create3DTriangle(UINT32 nInd1, UINT32 nInd2, UINT32 nInd3); + + virtual void Clipped3DPoint(UINT32 nInd) = 0; + virtual void Clipped3DLine(UINT32 nInd1,UINT32 nInd2) = 0; + virtual void Clipped3DTriangle(UINT32 nInd1,UINT32 nInd2, UINT32 nInd3) = 0; + + // clipping functions + BOOL AreEqual(UINT32 nInd1, UINT32 nInd2); + BOOL Clip3DPoint(UINT32 nInd); + BOOL Clip3DLine(UINT32& nInd1,UINT32& nInd2); + BOOL Clip3DPolygon(UINT32Bucket& rEdgeIndex); + UINT16 GetClipFlags(UINT32 nInd); + BOOL IsInside(UINT32 nInd, UINT32 nDim, BOOL bLow); + void ClipPoly(UINT32Bucket& rEdgeIndex, UINT16 nDim,BOOL bLow); + void CalcNewPoint(UINT32 nNew,UINT32 nHigh,UINT32 nLow, + UINT16 nDim, double fBound); + + // Beleuchtungsmodell (ColorModel) in einem Punkt loesen + // Punkt MUSS in ClipCoordinates vorliegen ! + void SolveColorModel(B3dColor&, Vector3D&, const Vector3D&); + B3dColor SolveColorModel(B3dMaterial& rMat, Vector3D& rVec, + const Vector3D& rPnt); + + // Beleuchtungsmodell (ColorModel) fuer eine Lichtquelle loesen + B3dColor SolveColorModel(B3dLight& rLight, B3dMaterial& rMat, + Vector3D& rVec, const Vector3D& rPnt); +}; + + +#endif // _B3D_B3DCOMMN_HXX diff --git a/goodies/source/base3d/b3dcompo.cxx b/goodies/source/base3d/b3dcompo.cxx new file mode 100644 index 000000000000..2b8094a28581 --- /dev/null +++ b/goodies/source/base3d/b3dcompo.cxx @@ -0,0 +1,1180 @@ +/************************************************************************* + * + * $RCSfile: b3dcompo.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DCOMPO_HXX +#include "b3dcompo.hxx" +#endif + +#ifndef _B3D_BASE3D_HXX +#include "base3d.hxx" +#endif + +#ifndef _B3D_B3DGEOM_HXX +#include "b3dgeom.hxx" +#endif + +#ifndef _INC_FLOAT +#include <float.h> +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +/************************************************************************* +|* +|* Vergleiche fuer doubles mit bound +|* +\************************************************************************/ + +#define DOUBLE_EQUAL(a,b) (fabs(a-b) < SMALL_DVALUE) +#define DOUBLE_NOT_EQUAL(a,b) (fabs(a-b) > SMALL_DVALUE) +#define DOUBLE_SMALLER(a,b) ((a + (SMALL_DVALUE / 2.0)) < b) +#define DOUBLE_BIGGER(a,b) ((a - (SMALL_DVALUE / 2.0)) > b) + +/************************************************************************* +|* +|* Bucket fuer Kantenliste, vertikaler Teil +|* +\************************************************************************/ + +BASE3D_IMPL_BUCKET(B3dEdgeList, Bucket) + +/************************************************************************* +|* +|* Bucket fuer Kantenliste, horizontaler Teil +|* +\************************************************************************/ + +BASE3D_IMPL_BUCKET(B3dEdgeEntry, Bucket) + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +B3dComplexPolygon::B3dComplexPolygon() +: aEntityBuffer(14), // 16K + aEdgeList(12), // 4K + aEdgeEntry(12) // 4K +{ + EmptyBuffers(); + bTestForCut = TRUE; + nHighestEdge = 0L; + pBase3D = NULL; + pGeometry = NULL; + pLastVertex = NULL; +} + +/************************************************************************* +|* +|* Gib einen neuen freien Eintrag zurueck +|* +\************************************************************************/ + +B3dEntity &B3dComplexPolygon::GetFreeEntity() +{ + aEntityBuffer.Append(); + return aEntityBuffer[aEntityBuffer.Count() - 1]; +} + +/************************************************************************* +|* +|* Ein neuer Punkt ist ausgefuellt +|* +\************************************************************************/ + +void B3dComplexPolygon::PostAddVertex(B3dEntity &rVertex) +{ + if(pLastVertex) + { + if(ArePointsEqual(*pLastVertex, rVertex)) + { + aEntityBuffer.Remove(); + return; + } + if(!nNewPolyStart) + { + if(nHighestEdge) + TestHighestEdge(rVertex); + else + nHighestEdge = aEntityBuffer.Count(); + } + } + + // Zeiger auf letzten hinzugefuegten Punkt setzen + pLastVertex = &rVertex; +} + +/************************************************************************* +|* +|* Testet, ob die neue Edge in allen Freiheitsgraden groesser ist +|* als die momentane +|* +\************************************************************************/ + +void B3dComplexPolygon::TestHighestEdge(B3dEntity& rVertex) +{ + B3dEntity& rHighest = aEntityBuffer[nHighestEdge - 1]; + if(rVertex.GetX() <= rHighest.GetX()) + { + if(rVertex.GetX() < rHighest.GetX()) + { + nHighestEdge = aEntityBuffer.Count(); + } + else + { + if(rVertex.GetY() <= rHighest.GetY()) + { + if(rVertex.GetY() < rHighest.GetY()) + { + nHighestEdge = aEntityBuffer.Count(); + } + else + { + if(rVertex.GetZ() < rHighest.GetZ()) + { + nHighestEdge = aEntityBuffer.Count(); + } + } + } + } + } +} + +/************************************************************************* +|* +|* Vergleicht zwei Punkte auf ihren INHALT +|* und fuellt die 2D-Koordinaten aus +|* +\************************************************************************/ + +BOOL B3dComplexPolygon::ArePointsEqual(B3dEntity& rFirst, + B3dEntity& rSecond) +{ + // Wenn der Punkt dem letzten gleich ist, gar nicht behandeln + if(rFirst.Point().GetVector3D() == rSecond.Point().GetVector3D()) + return TRUE; + return FALSE; +} + +/************************************************************************* +|* +|* Alles auf Startzustand, buffer leeren +|* +\************************************************************************/ + +void B3dComplexPolygon::EmptyBuffers() +{ + aEntityBuffer.Erase(); + nNewPolyStart = 0; + bOrientationValid = FALSE; + bNormalValid = FALSE; + + // EdgeList und EdgeEntries leeren + pEdgeList = NULL; + aEdgeList.Erase(); + aEdgeEntry.Erase(); +} + +/************************************************************************* +|* +|* Neues Teilpolygon beginnen +|* +\************************************************************************/ + +void B3dComplexPolygon::StartPrimitive() +{ + // Bisherige Punkte verarbeiten + if(aEntityBuffer.Count() > nNewPolyStart) + ComputeLastPolygon(); + + // Zeiger auf letzten Punkt loeschen + pLastVertex = NULL; + + // Hoechten Punkt vergesset + nHighestEdge = 0L; +} + +/************************************************************************* +|* +|* Teilpolygon abschliessen +|* +\************************************************************************/ + +void B3dComplexPolygon::ComputeLastPolygon(BOOL bIsLast) +{ + // Letzten Punkt mit erstem vergleichen, evtl + // wegschmeissen + if(pLastVertex) + { + if(ArePointsEqual(aEntityBuffer[nNewPolyStart], *pLastVertex)) + { + // HighestEdge korrigieren, falls dieser geloescht werden soll + if(nHighestEdge && nHighestEdge == aEntityBuffer.Count()) + nHighestEdge = nNewPolyStart + 1; + + aEntityBuffer.Remove(); + } + } + + // Sind noch genug Punkte da? + if(aEntityBuffer.Count() < nNewPolyStart + 3) + { + // Geometrie ausgeben, obwohl zuwenig Punkte fuer ein Polygon + if(pBase3D) + { + pBase3D->StartPrimitive(Base3DPolygon); + for(UINT32 a=0; a < aEntityBuffer.Count(); a++) + { + pBase3D->SetEdgeFlag(aEntityBuffer[a].IsEdgeVisible()); + pBase3D->AddVertex(aEntityBuffer[a]); + } + pBase3D->EndPrimitive(); + } + else if(pGeometry) + { + pGeometry->StartComplexPrimitive(); + for(UINT32 a=0; a < aEntityBuffer.Count(); a++) + pGeometry->AddComplexVertex(aEntityBuffer[a], aEntityBuffer[a].IsEdgeVisible()); + pGeometry->EndComplexPrimitive(); + } + } + else + { + if(!nNewPolyStart && bIsLast && IsConvexPolygon()) + { + // Falls das PolyPolygon nur aus einem Polygon besteht + // und es Konvex ist, ist man fertig. + // Um die Qualitaet zu verbessern, wird fuer + // Polygone ab einer gewissen Punktzahl ein + // abschliessender Mittelpunkt generiert. + if(pBase3D) + { + pBase3D->StartPrimitive(Base3DPolygon); + if(aEntityBuffer.Count() > 4) + { + B3dEntity aNew; + aNew.CalcMiddle(aEntityBuffer[0], aEntityBuffer[aEntityBuffer.Count() / 2]); + pBase3D->SetEdgeFlag(FALSE); + pBase3D->AddVertex(aNew); + for(UINT32 a=0; a < aEntityBuffer.Count(); a++) + { + pBase3D->SetEdgeFlag(aEntityBuffer[a].IsEdgeVisible()); + pBase3D->AddVertex(aEntityBuffer[a]); + } + pBase3D->SetEdgeFlag(FALSE); + pBase3D->AddVertex(aEntityBuffer[0]); + } + else + { + for(UINT32 a=0; a < aEntityBuffer.Count(); a++) + { + pBase3D->SetEdgeFlag(aEntityBuffer[a].IsEdgeVisible()); + pBase3D->AddVertex(aEntityBuffer[a]); + } + } + pBase3D->EndPrimitive(); + } + else if(pGeometry) + { + pGeometry->StartComplexPrimitive(); + if(aEntityBuffer.Count() > 4) + { + B3dEntity aNew; + aNew.CalcMiddle(aEntityBuffer[0], aEntityBuffer[aEntityBuffer.Count() / 2]); + pGeometry->AddComplexVertex(aNew, FALSE); + for(UINT32 a=0; a < aEntityBuffer.Count(); a++) + pGeometry->AddComplexVertex(aEntityBuffer[a], aEntityBuffer[a].IsEdgeVisible()); + pGeometry->AddComplexVertex(aEntityBuffer[0], FALSE); + } + else + { + for(UINT32 a=0; a < aEntityBuffer.Count(); a++) + pGeometry->AddComplexVertex(aEntityBuffer[a], aEntityBuffer[a].IsEdgeVisible()); + } + pGeometry->EndComplexPrimitive(); + } + } + else + { + if(!bNormalValid) + ChooseNormal(); + + // Einsortieren + UINT32 nUpperBound = aEntityBuffer.Count(); + + // Als Polygon behandeln + if(GetTestForCut()) + { + UINT32 a; + for(a=nNewPolyStart + 1; a < nUpperBound; a++) + AddEdgeCut(&aEntityBuffer[a-1], &aEntityBuffer[a]); + + // Polygon schliessen + AddEdgeCut(&aEntityBuffer[a-1], &aEntityBuffer[nNewPolyStart]); + } + else + { + UINT32 a; + for(a=nNewPolyStart + 1; a < nUpperBound; a++) + AddEdge(&aEntityBuffer[a-1], &aEntityBuffer[a]); + + // Polygon schliessen + AddEdge(&aEntityBuffer[a-1], &aEntityBuffer[nNewPolyStart]); + } + + // Hier setzen, da evtl. bereits neue Punkte + // durch Schnitte hinzugekommen sind + nNewPolyStart = aEntityBuffer.Count(); + } + } +} + +/************************************************************************* +|* +|* Orientierung des ersten Polygons ermitteln +|* +\************************************************************************/ + +void B3dComplexPolygon::ChooseNormal() +{ + if(nHighestEdge) + { + UINT32 nHigh = nHighestEdge - 1; + UINT32 nPrev = (nHigh != 0) ? nHigh - 1 : aEntityBuffer.Count() - 1; + UINT32 nNext = (nHigh + 1 != aEntityBuffer.Count()) ? nHigh + 1 : nNewPolyStart; + + // Punkt, Vorgaenger und Nachfolger holen + const Vector3D& rHigh = aEntityBuffer[nHigh].Point().GetVector3D(); + const Vector3D& rPrev = aEntityBuffer[nPrev].Point().GetVector3D(); + const Vector3D& rNext = aEntityBuffer[nNext].Point().GetVector3D(); + + // Normale bilden + aNormal = (rPrev - rHigh)|(rNext - rHigh); + if(aNormal != Vector3D()) + aNormal.Normalize(); + else + aNormal = Vector3D(0.0, 0.0, -1.0); + } + bNormalValid = TRUE; +} + +/************************************************************************* +|* +|* Komplexes Polygon ausgeben +|* +\************************************************************************/ + +void B3dComplexPolygon::EndPrimitive(Base3D* pB3D) +{ + // Funktionszeiger setzen + pBase3D = pB3D; + + // Letztes angefangenes Poly verarbeiten + ComputeLastPolygon(TRUE); + + // Wenn es Kanten gibt + if(pEdgeList) + { + // Dreiecke generieren und ausgeben + pBase3D->StartPrimitive(Base3DTriangles); + while(pEdgeList) + ExtractTriangle(); + pBase3D->EndPrimitive(); + } + + // Buffer leeren + EmptyBuffers(); + + // Zeiger wieder loeschen + pBase3D = NULL; +} + +void B3dComplexPolygon::EndPrimitive(B3dGeometry *pGeom) +{ + // Funktionszeiger setzen + pGeometry = pGeom; + + // Letztes angefangenes Poly verarbeiten + ComputeLastPolygon(TRUE); + + // Dreiecke generieren und ausgeben + while(pEdgeList) + ExtractTriangle(); + + // Buffer leeren + EmptyBuffers(); + + // Zeiger wieder loeschen + pGeometry = NULL; +} + +/************************************************************************* +|* +|* Teste aktuelles Polygon (0..aEntityBuffer.Count()) auf Konvexitaet +|* +\************************************************************************/ + +BOOL B3dComplexPolygon::IsConvexPolygon() +{ + B3dEntity* pFirst = &aEntityBuffer[aEntityBuffer.Count() - 2]; + B3dEntity* pSecond = &aEntityBuffer[aEntityBuffer.Count() - 1]; + B3dEntity* pThird = &aEntityBuffer[0]; + BOOL bDirection = IsLeft(pSecond, pFirst, pThird); + BOOL bOrder = CompareOrder(pSecond, pThird); + UINT16 nDirChanges(0); + + for(UINT32 a = 1; nDirChanges <= 2 && a < aEntityBuffer.Count(); a++) + { + pFirst = pSecond; + pSecond = pThird; + pThird = &aEntityBuffer[a]; + + if(IsLeft(pSecond, pFirst, pThird) != bDirection) + return FALSE; + + if(CompareOrder(pSecond, pThird) != bOrder) + { + nDirChanges++; + bOrder = !bOrder; + } + } + // Zuviele aenderungen der Ordnung, auf keinen Fall Convex + if(nDirChanges > 2) + return FALSE; + + return TRUE; +} + +/************************************************************************* +|* +|* Lexikografische Ordnung der beiden Punkte +|* +\************************************************************************/ + +BOOL B3dComplexPolygon::CompareOrder(B3dEntity* pFirst, B3dEntity* pSecond) +{ + if(pFirst->GetX() < pSecond->GetX()) + return FALSE; + if(pFirst->GetX() > pSecond->GetX()) + return TRUE; + if(pFirst->GetY() < pSecond->GetY()) + return FALSE; + return TRUE; +} + +/************************************************************************* +|* +|* Teste, ob die Punkte der Kante getauscht werden muessen +|* +\************************************************************************/ + +BOOL B3dComplexPolygon::DoSwap(B3dEntity* pStart, B3dEntity* pEnd) +{ + if(DOUBLE_EQUAL(pStart->GetY(), pEnd->GetY())) + { + if(pStart->GetX() > pEnd->GetX()) + return TRUE; + } + else + { + if(pStart->GetY() > pEnd->GetY()) + return TRUE; + } + return FALSE; +} + +/************************************************************************* +|* +|* Kante nInd1, nInd2 zu Kantenliste hinzufuegen +|* +\************************************************************************/ + +B3dEdgeEntry* B3dComplexPolygon::AddEdge(B3dEntity* pStart, B3dEntity* pEnd) +{ + if(DoSwap(pStart, pEnd)) + return InsertEdge(GetList(pEnd), pStart, TRUE); + return InsertEdge(GetList(pStart), pEnd, TRUE); +} + +/************************************************************************* +|* +|* Einen Listeneintrag suchen oder neu anlegen +|* Liefert immer einen Listeneintrag zurueck +|* +\************************************************************************/ + +B3dEdgeList* B3dComplexPolygon::GetList(B3dEntity* pStart) +{ + B3dEdgeList* pList = pEdgeList; + B3dEdgeList* pLast = NULL; + + while(pList && pList->GetStart() != pStart && DoSwap(pStart, pList->GetStart())) + { + pLast = pList; + pList = pList->GetDown(); + } + + if(pList) + { + if(pList->GetStart() != pStart) + { + if(DOUBLE_NOT_EQUAL(pStart->GetX(), pList->GetXPos()) || DOUBLE_NOT_EQUAL(pStart->GetY(), pList->GetYPos())) + { + // Auf jeden Fall ein neuer Eintrag + aEdgeList.Append(); + B3dEdgeList* pNewList = &aEdgeList[aEdgeList.Count() - 1]; + pNewList->Reset(); + pNewList->SetStart(pStart); + + // vor pList einhaengen + // pLast KANN NULL SEIN! + pNewList->SetDown(pList); + pList->SetParent(pNewList); + if(pLast) + { + pNewList->SetParent(pLast); + pLast->SetDown(pNewList); + } + else + { + pEdgeList = pNewList; + } + + // Returnwert setzen + pList = pNewList; + } + else + { + // pList->GetStart() != pStart, aber + // die Koordinaten sind praktisch identisch! + // Gib diese Liste zurueck, d.h. + // tue gar nichts + } + } + } + else + { + // pLast->GetYPos() < pStart->GetY(), + // Hinten anhaengen + aEdgeList.Append(); + pList = &aEdgeList[aEdgeList.Count() - 1]; + pList->Reset(); + pList->SetStart(pStart); + if(pLast) + { + pList->SetParent(pLast); + pLast->SetDown(pList); + } + else + { + pEdgeList = pList; + } + } + return pList; +} + +/************************************************************************* +|* +|* Eine Kante in eine Kantenliste einsortieren +|* Die Kante wird dabei neu erzeugt +|* +\************************************************************************/ + +B3dEdgeEntry* B3dComplexPolygon::InsertEdge(B3dEdgeList* pList, + B3dEntity* pEnd, BOOL bEdgeVisible) +{ + B3dEdgeEntry* pEntry = pList->GetEntries(); + + // Immer ein neuer Eintrag + aEdgeEntry.Append(); + B3dEdgeEntry* pNewEntry = &aEdgeEntry[aEdgeEntry.Count() - 1]; + pNewEntry->Reset(); + pNewEntry->SetEnd(pEnd); + pNewEntry->SetParent(pList); + pNewEntry->SetEdgeVisible(bEdgeVisible); + + if(pEntry) + { + B3dEdgeEntry* pLast = NULL; + double fSlant = GetSlant(pNewEntry); + while(pEntry + && GetSlant(pEntry) < fSlant) + { + pLast = pEntry; + pEntry = pEntry->GetRight(); + } + + if(pEntry) + { + // GetSlant(pEntry) < fSlant + // GetSlant(pLast) >= fSlant + // Neuen Eintrag hinter pLast einfuegen + // pLast KANN NULL SEIN! + pNewEntry->SetRight(pEntry); + if(pLast) + { + pLast->SetRight(pNewEntry); + } + else + { + pList->SetEntries(pNewEntry); + } + } + else + { + // GetSlant(pEntry) >= fSlant + // Neuen Eintrag am Ende anhaengen + pLast->SetRight(pNewEntry); + } + } + else + { + pList->SetEntries(pNewEntry); + } + // Returnwert + return pNewEntry; +} + +/************************************************************************* +|* +|* Steigung der Kante liefern +|* +\************************************************************************/ + +double B3dComplexPolygon::GetSlant(B3dEdgeEntry* pEdge) +{ + double fDivisor = pEdge->GetYPos() - pEdge->GetParent()->GetYPos(); + if(fabs(fDivisor) < SMALL_DVALUE) + return DBL_MAX; + return (pEdge->GetXPos() - pEdge->GetParent()->GetXPos()) / fDivisor; +} + +/************************************************************************* +|* +|* Auf Schnitt mit einer vorhandenen Kante testen +|* +\************************************************************************/ + +void B3dComplexPolygon::TestForCut(B3dEdgeEntry* pEntry) +{ + // pEntry: die bereits eingefuegte neue Kante, die mit allen + // aelteren Kanten geschnitten werden soll + B3dEdgeList* pList = pEdgeList; + + while(pList && DOUBLE_SMALLER(pList->GetYPos(), pEntry->GetYPos())) + { + // nur in Gruppen mit anderem Startpunkt suchen + if(pList != pEntry->GetParent()) + { + B3dEdgeEntry* pTestEntry = pList->GetEntries(); + + while(pTestEntry) + { + if(DOUBLE_BIGGER(pTestEntry->GetYPos(), pEntry->GetParent()->GetYPos())) + { + // es existiert eine vertikale Bereichsueberschneidung + // Min/Max fuer pEntry holen + double fXMin = pEntry->GetXPos(); + double fXMax = pEntry->GetParent()->GetXPos(); + if(fXMin > fXMax) + { + double fSwap = fXMin; + fXMin = fXMax; + fXMax = fSwap; + } + + // Min/Max in X fuer Kandidat holen + double fTestXMin = pTestEntry->GetXPos(); + double fTestXMax = pList->GetXPos(); + if(fTestXMin > fTestXMax) + { + double fSwap = fTestXMin; + fTestXMin = fTestXMax; + fTestXMax = fSwap; + } + + if(fTestXMin < fXMax && fTestXMax > fXMin) + { + // es existiert eine horizontale Bereichsueberschneidung + // ein Schnitt ist moeglich + double fCut = FindCut(pEntry, pTestEntry); + + if(fCut != 0.0) + { + // Schnitt existiert! fCut ist aus dem Parameterbereich + // der ersten Kante, also pEntry. Neuen Punkt erzeugen. + B3dEntity& rNew = GetFreeEntity(); + rNew.CalcInBetween(*pEntry->GetParent()->GetStart(), *pEntry->GetEnd(), fCut); + + // Neuen Punkt und neue von diesem ausgehende Kanten erzeugen + B3dEdgeList* pNewPointList = GetList(&rNew); + B3dEdgeEntry* pEntry2 = InsertEdge(pNewPointList, pEntry->GetEnd(), pEntry->IsEdgeVisible()); + InsertEdge(pNewPointList, pTestEntry->GetEnd(), pTestEntry->IsEdgeVisible()); + + // Beteiligte Entries kuerzen + pEntry->SetEnd(&rNew); + pTestEntry->SetEnd(&rNew); + + // Das neue Ende von pEntry kann weitere Linien + // schneiden, also geht der test mit diesem weiter + TestForCut(pEntry2); + + // Test mit gekuerztem pEntry fortsetzen + } + } + } + + // naechster Entry + pTestEntry = pTestEntry->GetRight(); + } + } + + // naechste Liste + pList = pList->GetDown(); + } +} + +/************************************************************************* +|* +|* Berechne den Schnitt zwischen den beiden Kanten und gib den +|* Schnittpunkt im Parameterbereich der 1. Kante zurueck +|* +\************************************************************************/ + +double B3dComplexPolygon::FindCut(B3dEdgeEntry* pEdge1, B3dEdgeEntry* pEdge2) +{ + double fRetval = 0.0; + double fDeltaEdge2Y = pEdge2->GetYPos() - pEdge2->GetParent()->GetYPos(); + double fDeltaEdge2X = pEdge2->GetXPos() - pEdge2->GetParent()->GetXPos(); + double fDeltaEdge1X = pEdge1->GetXPos() - pEdge1->GetParent()->GetXPos(); + double fDeltaEdge1Y = pEdge1->GetYPos() - pEdge1->GetParent()->GetYPos(); + + // Dynamische Grenze fuer parallelitaet berechnen + double fSmallValue = fabs((fDeltaEdge2Y + fDeltaEdge2X + fDeltaEdge1X + fDeltaEdge1Y) * (SMALL_DVALUE / 4.0)); + double fZwi = (fDeltaEdge1X * fDeltaEdge2Y) - (fDeltaEdge1Y * fDeltaEdge2X); + + if(fabs(fZwi) > fSmallValue) + { + fZwi = (fDeltaEdge2Y * (pEdge2->GetParent()->GetXPos() - pEdge1->GetParent()->GetXPos()) + + fDeltaEdge2X * (pEdge1->GetParent()->GetYPos() - pEdge2->GetParent()->GetYPos())) / fZwi; + + // Im Parameterbereich der ersten Kante (ohne Punkte) ? + if(fZwi > fSmallValue && fZwi < 1.0 - fSmallValue) + { + // Schnitt liegt im Parameterbereich der ersten + // Linie, aber auch in dem der zweiten? + if(fabs(fDeltaEdge2X) > fSmallValue && fabs(fDeltaEdge2X) > fabs(fDeltaEdge2Y)) + { + fDeltaEdge2Y = (pEdge1->GetParent()->GetXPos() + fZwi + * fDeltaEdge1X - pEdge2->GetParent()->GetXPos()) / fDeltaEdge2X; + + // Parameterbereich der zweiten schliesst Start/Ende mit ein! + if(fDeltaEdge2Y > -fSmallValue && fDeltaEdge2Y < 1.0 + fSmallValue) + { + // Ja. Zuweisen. + fRetval = fZwi; + } + } + else if(fabs(fDeltaEdge2Y) > fSmallValue) + { + fDeltaEdge2X = (pEdge1->GetParent()->GetYPos() + fZwi + * fDeltaEdge1Y - pEdge2->GetParent()->GetYPos()) / fDeltaEdge2Y; + + // Parameterbereich der zweiten schliesst Start/Ende mit ein! + if(fDeltaEdge2X > -fSmallValue && fDeltaEdge2X < 1.0 + fSmallValue) + { + // Ja. Zuweisen. + fRetval = fZwi; + } + } + } + } + return fRetval; +} + +/************************************************************************* +|* +|* Testet, ob die angegebene Kante schon existiert +|* Ja: Entfernen +|* Nein: Einfuegen +|* +\************************************************************************/ + +BOOL B3dComplexPolygon::SwitchEdgeExistance(B3dEntity* pStart, + B3dEntity* pEnd) +{ + if(DoSwap(pStart, pEnd)) + { + B3dEntity* pZwi = pStart; + pStart = pEnd; + pEnd = pZwi; + } + + if(pEdgeList) + { + // Suchen + B3dEdgeList* pList = pEdgeList; + while(pList && pList->GetStart() != pStart) + pList = pList->GetDown(); + + if(pList && pList->GetStart() == pStart) + { + // Liste gefunden, Eintrag mit Endpunkt + // pEnd finden + B3dEdgeEntry* pEntry = pList->GetEntries(); + B3dEdgeEntry* pLeft = NULL; + + while(pEntry) + { + if(pEntry->GetEnd() == pEnd) + { + // Kante existiert, austragen + // Liste ist pList + // Links ist pLeft + if(pLeft) + { + pLeft->SetRight(pEntry->GetRight()); + } + else + { + if(pEntry->GetRight()) + pList->SetEntries(pEntry->GetRight()); + else + RemoveEdgeList(pList); + } + // fertig + return TRUE; + } + + // naechste Kante + pLeft = pEntry; + pEntry = pEntry->GetRight(); + } + + // Liste existiert, aber der EdgeEintrag nicht. + // Fuege diesen hinzu + InsertEdge(pList, pEnd, FALSE); + + // fertig + return FALSE; + } + } + // Liste und Eintrag existieren nicht + // Erzeuge beides + InsertEdge(GetList(pStart), pEnd, FALSE); + + return FALSE; +} + +/************************************************************************* +|* +|* Entferne die Kante aus der Kantenliste. Tue alles weitere, +|* um die Struktur weiter aufzuloesen +|* +\************************************************************************/ + +void B3dComplexPolygon::RemoveFirstEdge(B3dEdgeList* pList) +{ + if(pList->GetEntries()->GetRight()) + pList->SetEntries(pList->GetEntries()->GetRight()); + else + RemoveEdgeList(pList); +} + +/************************************************************************* +|* +|* Entferne die Kantenliste. Tue alles weitere, +|* um die Struktur weiter aufzuloesen +|* +\************************************************************************/ + +void B3dComplexPolygon::RemoveEdgeList(B3dEdgeList* pList) +{ + if(pList->GetDown()) + pList->GetDown()->SetParent(pList->GetParent()); + if(pList->GetParent()) + pList->GetParent()->SetDown(pList->GetDown()); + else + { + // Es gibt keinen parent mehr + pEdgeList = pList->GetDown(); + } +} + +/************************************************************************* +|* +|* Extrahiere das naechste Dreieck aus der Kantenliste +|* und zeichne es +|* +\************************************************************************/ + +void B3dComplexPolygon::ExtractTriangle() +{ + B3dEdgeEntry* pLeft = pEdgeList->GetEntries(); + B3dEdgeEntry* pRight = pLeft->GetRight(); + + if(!pRight) + { +// DBG_ASSERT(0, "AW: Einzelne Kante als Startpunkt!"); + RemoveFirstEdge(pEdgeList); + return; + } + + B3dEdgeList* pList = FindStartInTriangle(); + BOOL bNotAllAligned = (fabs(GetSlant(pLeft) - GetSlant(pRight)) > SMALL_DVALUE); + BOOL bStartIsEdgePoint = FALSE; + if(pList) + { + const Vector3D& rListStart = pList->GetStart()->Point().GetVector3D(); + if((rListStart - pEdgeList->GetStart()->Point().GetVector3D()).GetLength() < SMALL_DVALUE) + bStartIsEdgePoint = TRUE; + else if((rListStart - pLeft->GetEnd()->Point().GetVector3D()).GetLength() < SMALL_DVALUE) + bStartIsEdgePoint = TRUE; + else if((rListStart - pRight->GetEnd()->Point().GetVector3D()).GetLength() < SMALL_DVALUE) + bStartIsEdgePoint = TRUE; + } + + if(pList && bNotAllAligned && !bStartIsEdgePoint) + { + // Zerlegen in 2 Teildreiecke + // Erstes Teildreieck + InsertEdge(pEdgeList, pList->GetStart(), FALSE); + ExtractTriangle(); + + // Zweites Teildreieck + InsertEdge(pEdgeList, pList->GetStart(), FALSE); + ExtractTriangle(); + } + else + { + B3dEntity* pEntLeft = pLeft->GetEnd(); + B3dEntity* pEntRight = pRight->GetEnd(); + B3dEntity* pEntTop = pEdgeList->GetStart(); + BOOL bLeftVisible = pLeft->IsEdgeVisible(); + BOOL bRightVisible = pRight->IsEdgeVisible(); + + RemoveFirstEdge(pEdgeList); + RemoveFirstEdge(pEdgeList); + + if(pEntLeft != pEntRight) + { + // Merken, ob die Abschlusslinie existiert hat oder nicht + BOOL bDidEdgeExist = SwitchEdgeExistance(pEntLeft, pEntRight); + + if(DOUBLE_NOT_EQUAL(pEntLeft->GetY(), pEntTop->GetY()) + || DOUBLE_NOT_EQUAL(pEntRight->GetY(), pEntTop->GetY())) + { + if(!bOrientationValid) + { + // Anhand des ersten Dreiecks entscheiden, + // in welcher Orientierung die Dreiecke + // auszugeben sind + Vector3D aTmpNormal = + (pEntLeft->Point().GetVector3D() - pEntTop->Point().GetVector3D()) + |(pEntRight->Point().GetVector3D() - pEntTop->Point().GetVector3D()); + + bOrientation = (aNormal.Scalar(aTmpNormal) > 0.0) ? TRUE : FALSE; + bOrientationValid = TRUE; + } + + // Dreieck ausgeben + if(pBase3D) + { + if(bOrientation) + { + // Rechtsrum + pBase3D->SetEdgeFlag(bRightVisible); + pBase3D->AddVertex(*pEntTop); + pBase3D->SetEdgeFlag(bDidEdgeExist); + pBase3D->AddVertex(*pEntRight); + pBase3D->SetEdgeFlag(bLeftVisible); + pBase3D->AddVertex(*pEntLeft); + } + else + { + // Linksrum + pBase3D->SetEdgeFlag(bLeftVisible); + pBase3D->AddVertex(*pEntTop); + pBase3D->SetEdgeFlag(bDidEdgeExist); + pBase3D->AddVertex(*pEntLeft); + pBase3D->SetEdgeFlag(bRightVisible); + pBase3D->AddVertex(*pEntRight); + } + } + else if(pGeometry) + { + pGeometry->StartComplexPrimitive(); + if(bOrientation) + { + // Rechtsrum + pGeometry->AddComplexVertex(*pEntTop, bRightVisible); + pGeometry->AddComplexVertex(*pEntRight, bDidEdgeExist); + pGeometry->AddComplexVertex(*pEntLeft, bLeftVisible); + } + else + { + // Linksrum + pGeometry->AddComplexVertex(*pEntTop, bLeftVisible); + pGeometry->AddComplexVertex(*pEntLeft, bDidEdgeExist); + pGeometry->AddComplexVertex(*pEntRight, bRightVisible); + } + pGeometry->EndComplexPrimitive(); + } + } + } + } +} + +/************************************************************************* +|* +|* Suche nach einem fremden Startpunkt innerhalb des zu zeichnenden +|* naechsten Dreiecks +|* +\************************************************************************/ + +B3dEdgeList* B3dComplexPolygon::FindStartInTriangle() +{ + B3dEdgeList* pList = pEdgeList->GetDown(); + if(pList) + { + B3dEdgeEntry* pLeft = pEdgeList->GetEntries(); + B3dEdgeEntry* pRight = pLeft->GetRight(); + + double fYMax = pLeft->GetYPos(); + double fZwi = pRight->GetYPos(); + if(fZwi > fYMax) + fYMax = fZwi; + + if(pList->GetYPos() <= fYMax) + { + B3dEntity* pTop = pEdgeList->GetStart(); + double fXMin = pLeft->GetXPos(); + double fXMax = pRight->GetXPos(); + if(fXMin > fXMax) + { + fZwi = fXMin; + fXMin = fXMax; + fXMax = fZwi; + } + + double fXTop = pTop->GetX(); + if(fXMin > fXTop) + fXMin = fXTop; + if(fXMax < fXTop) + fXMax = fXTop; + + while(pList + && pList->GetYPos() <= fYMax) + { + if(pList->GetXPos() > fXMin && pList->GetXPos() < fXMax) + { + if(pList->GetStart() != pLeft->GetEnd() + && pList->GetStart() != pRight->GetEnd()) + { + if(IsLeft(pTop, pLeft->GetEnd(), pList->GetStart())) + { + if(DOUBLE_NOT_EQUAL(pList->GetXPos(), pLeft->GetXPos()) + || DOUBLE_NOT_EQUAL(pList->GetYPos(), pLeft->GetYPos())) + { + if(IsLeft(pRight->GetEnd(), pTop, pList->GetStart())) + { + if(DOUBLE_NOT_EQUAL(pList->GetXPos(), pRight->GetXPos()) + || DOUBLE_NOT_EQUAL(pList->GetYPos(), pRight->GetYPos())) + { + if(IsLeft(pLeft->GetEnd(), pRight->GetEnd(), + pList->GetStart())) + { + return pList; + } + } + } + } + } + } + } + // naechste Liste + pList = pList->GetDown(); + } + } + } + return NULL; +} + +/************************************************************************* +|* +|* Testen, auf welcher Seite pPoint von der Linie pTop, pDirection liegt +|* +\************************************************************************/ + +BOOL B3dComplexPolygon::IsLeft(B3dEntity* pTop, B3dEntity* pDirection, + B3dEntity* pPoint) +{ + double fDirX = pDirection->GetX() - pTop->GetX(); + double fDirY = pDirection->GetY() - pTop->GetY(); + double fPntX = pPoint->GetX() - pTop->GetX(); + double fPntY = pPoint->GetY() - pTop->GetY(); + + return ((fDirX * fPntY - fDirY * fPntX) <= 0.0); +} + diff --git a/goodies/source/base3d/b3ddeflt.cxx b/goodies/source/base3d/b3ddeflt.cxx new file mode 100644 index 000000000000..a626ad797406 --- /dev/null +++ b/goodies/source/base3d/b3ddeflt.cxx @@ -0,0 +1,1786 @@ +/************************************************************************* + * + * $RCSfile: b3ddeflt.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DDEFLT_HXX +#include "b3ddeflt.hxx" +#endif + +#ifndef _B3D_B3DTRANS_HXX +#include "b3dtrans.hxx" +#endif + +#ifndef _SV_OUTDEV_HXX +#include <vcl/outdev.hxx> +#endif + +#ifndef _SV_BMPACC_HXX +#include <vcl/bmpacc.hxx> +#endif + +#ifndef _SV_BITMAPEX_HXX +#include <vcl/bitmapex.hxx> +#endif + +#ifndef _B3D_B3DTEX_HXX +#include "b3dtex.hxx" +#endif + +/************************************************************************* +|* +|* Konstruktor Base3DDefault +|* +\************************************************************************/ + +Base3DDefault::Base3DDefault(OutputDevice* pOutDev) +: Base3DCommon(pOutDev), + aZBuffer(), + aPicture(), + aMonoTransparence(), + aAlphaTransparence(), + aClearValue(Color(0x00ffffff)), + pZBufferWrite(NULL), + pPictureWrite(NULL), + pTransparenceWrite(NULL), + fDetail(1.0), + bReducedDetail(FALSE), + bDetailBackedup(FALSE), + fDetailBackup( -1.0 ), + nMaxPixels(500000) +{ +} + +/************************************************************************* +|* +|* Destruktor Base3DDefault +|* +\************************************************************************/ + +Base3DDefault::~Base3DDefault() +{ + // Alle Bitmap-Zugriffe freigeben + ReleaseAccess(); +} + +/************************************************************************* +|* +|* Typbestimmung +|* +\************************************************************************/ + +UINT16 Base3DDefault::GetBase3DType() +{ + return BASE3D_TYPE_DEFAULT; +} + +/************************************************************************* +|* +|* Darstellungsqualitaet setzen +|* +\************************************************************************/ + +void Base3DDefault::SetDisplayQuality(UINT8 nNew) +{ + // Entsprechende PixelGrenze setzen + SetMaxPixels(((long)nNew * 3500) + 3500); + + // call parent + Base3D::SetDisplayQuality(nNew); +} + +/************************************************************************* +|* +|* Vergroeberungsstufe setzen +|* +\************************************************************************/ + +void Base3DDefault::SetDetail(double fNew) +{ + // nach unten begrenzen + if(fNew > 1.0) + fNew = 1.0; + + fDetail = fNew; + if(fDetail < 1.0) + { + bReducedDetail = TRUE; + } + else + { + bReducedDetail = FALSE; + } +} + +/************************************************************************* +|* +|* BitmapAccess holen +|* +\************************************************************************/ + +void Base3DDefault::AcquireAccess() +{ + // Alle accesses holen + pZBufferWrite = aZBuffer.AcquireWriteAccess(); + pPictureWrite = aPicture.AcquireWriteAccess(); + pTransparenceWrite = (GetTransparentPartsContainedHint()) + ? aAlphaTransparence.AcquireWriteAccess() + : aMonoTransparence.AcquireWriteAccess(); +} + +/************************************************************************* +|* +|* BitmapAccess freigeben +|* +\************************************************************************/ + +void Base3DDefault::ReleaseAccess() +{ + // Alle accesses wieder freigeben + if(pZBufferWrite) + { + delete pZBufferWrite; + pZBufferWrite = NULL; + } + + if(pPictureWrite) + { + delete pPictureWrite; + pPictureWrite = NULL; + } + + if(pTransparenceWrite) + { + delete pTransparenceWrite; + pTransparenceWrite = NULL; + } +} + +/************************************************************************* +|* +|* Start der Szenenbeschreibung: +|* +\************************************************************************/ + +void Base3DDefault::StartScene() +{ + // Zugriffe freigeben + ReleaseAccess(); + + // Groesse der Bitmaps anpassen? + BOOL bSizeHasChanged = (aLocalSizePixel.GetSize() != aPicture.GetSizePixel()); + + // Neue BitMaps fuer ZBuffer und Picture allokieren + if(bSizeHasChanged || !aZBuffer || !aPicture) + { + aZBuffer = Bitmap(aLocalSizePixel.GetSize(), 24); + aPicture = Bitmap(aLocalSizePixel.GetSize(), 24); + } + + // ZBuffer loeschen + aZBuffer.Erase(aClearValue); + + // Bild loeschen + aPicture.Erase( GetOutputDevice()->GetBackground().GetColor() ); + + // Neue Transparenz-Bitmap allokieren + if(GetTransparentPartsContainedHint()) + { + // Alpha-Channel + if(bSizeHasChanged || !aAlphaTransparence) + { + aAlphaTransparence = AlphaMask(aLocalSizePixel.GetSize()); + if(!!aMonoTransparence) + aMonoTransparence = Bitmap(); + } + + // zu Beginn alles transparent + aAlphaTransparence.Erase(BYTE(0xff)); + } + else + { + // Mono-Channel + if(bSizeHasChanged || !aMonoTransparence) + { + aMonoTransparence = Bitmap(aLocalSizePixel.GetSize(), 1); + if(!!aAlphaTransparence) + aAlphaTransparence = AlphaMask(); + } + + // zu Beginn alles transparent + Color aEraseCol(COL_WHITE); + aMonoTransparence.Erase(aEraseCol); + } + + // Zugriffe wieder holen + AcquireAccess(); + + // lokale ClipRegion anpassen + if(IsScissorRegionActive()) + { + // Default specifics for scissoring + aDefaultScissorRectangle = GetScissorRegionPixel(); + aDefaultScissorRectangle -= aSizePixel.TopLeft(); + + // Detailstufe beachten + if(bReducedDetail && fDetail != 0.0) + { + long nReducedWidth = (long)((double)(aDefaultScissorRectangle.GetWidth() - 1) * fDetail); + long nReducedHeight = (long)((double)(aDefaultScissorRectangle.GetHeight() - 1)* fDetail); + aDefaultScissorRectangle.SetSize(Size(nReducedWidth + 1, nReducedHeight + 1)); + } + } + + // call parent + Base3DCommon::StartScene(); +} + +/************************************************************************* +|* +|* Ende der Szenenbeschreibung: +|* +\************************************************************************/ + +void Base3DDefault::EndScene() +{ + // Zugriffe freigeben + ReleaseAccess(); + + // Ausgabe der erzeugten BitMap + BitmapEx aBitmapEx; + + if(GetTransparentPartsContainedHint()) + { + // Alpha-Transparenz + aBitmapEx = BitmapEx(aPicture, aAlphaTransparence); + } + else + { + // Mono-Transparenz + aBitmapEx = BitmapEx(aPicture, aMonoTransparence); + } + + // Dithern + UINT16 nBitCount = GetOutputDevice()->GetBitCount(); + if( GetOutputDevice()->GetOutDevType() != OUTDEV_PRINTER && nBitCount <= 16 && GetDither()) + { + aBitmapEx.Dither(nBitCount <= 8 + ? BMP_DITHER_MATRIX + : BMP_DITHER_FLOYD_16); + } + + if(GetOutputDevice()->GetConnectMetaFile() != NULL) + { + Rectangle aLogicRect; + aLogicRect = GetOutputDevice()->PixelToLogic(aSizePixel); + aBitmapEx.Draw(GetOutputDevice(), aLogicRect.TopLeft(), aLogicRect.GetSize()); + } + else + { + BOOL bWasEnabled = GetOutputDevice()->IsMapModeEnabled(); + GetOutputDevice()->EnableMapMode(FALSE); + +#ifdef DBG_UTIL // draw for testing + static BOOL bDoDrawBitmapForTesting(FALSE); + if(bDoDrawBitmapForTesting) + { + Bitmap aBmp( aBitmapEx.GetMask() ); + aBmp.Convert( BMP_CONVERSION_4BIT_COLORS ); + aBmp.Replace( COL_WHITE, COL_LIGHTRED ); + GetOutputDevice()->DrawBitmap( aSizePixel.TopLeft(), aSizePixel.GetSize(), aBmp ); + GetOutputDevice()->SetFillColor( COL_LIGHTRED ); + GetOutputDevice()->SetLineColor( COL_LIGHTRED ); + GetOutputDevice()->DrawRect( aSizePixel ); + } +#endif + + aBitmapEx.Draw(GetOutputDevice(), aSizePixel.TopLeft(), aSizePixel.GetSize()); + GetOutputDevice()->EnableMapMode(bWasEnabled); + } + + // Zugriffe wieder holen + AcquireAccess(); + + // eventuelle temporaere Reduzierung der Aufloesung zuruecknehmen + if(bDetailBackedup) + { + SetDetail(fDetailBackup); + bDetailBackedup = FALSE; + } + + // call parent + Base3DCommon::EndScene(); +} + +/************************************************************************* +|* +|* Callbacks bei Matrixaenderungen +|* +|* Ausgaberechteck innerhalb des OutputDevice festlegen. Die Koordinaten +|* sind device-spezifisch, muessen also evtl. erst auf pixelkoordinaten +|* umgerechnet werden +|* +\************************************************************************/ + +void Base3DDefault::SetTransformationSet(B3dTransformationSet* pSet) +{ + // call parent + Base3DCommon::SetTransformationSet(pSet); + + if(GetTransformationSet()) + { + // eventuelle temporaere Reduzierung der Aufloesung zuruecknehmen + if(bDetailBackedup) + { + SetDetail(fDetailBackup); + bDetailBackedup = FALSE; + } + + // Neue Groesse fuer die Ausgabe + aSizePixel = GetOutputDevice()->LogicToPixel( + GetTransformationSet()->GetLogicalViewportBounds()); + + // Eventuell durch ClipRegion eingeschraenkt? Dies + // muss beachtet werden + if(IsScissorRegionActive()) + { + // draw region even smaller + aSizePixel.Intersection(GetScissorRegionPixel()); + } + + // Testen, ob die Bitmap zu gross wird + aLocalSizePixel = aSizePixel; + long nQuadSize = aLocalSizePixel.GetWidth() * aLocalSizePixel.GetHeight(); + + if(nQuadSize > GetMaxPixels()) + { + // Groesse reduzieren + double fFactor = sqrt((double)GetMaxPixels() / (double)nQuadSize); + + // Bei Druckjobs die Reduzierung einschraenken + if(fFactor < 0.25 && GetOutputDevice()->GetOutDevType() == OUTDEV_PRINTER) + fFactor = 0.25; + + // Wird hier mehr reduziert als sowieso schon eingestellt ist? + if(fFactor < fDetail) + { + fDetailBackup = GetDetail(); + bDetailBackedup = TRUE; + SetDetail(fFactor); + } + } + + // Detailstufe beachten + if(bReducedDetail && fDetail != 0.0) + { + long nReducedWidth = (long)((double)(aLocalSizePixel.GetWidth() - 1) * fDetail); + long nReducedHeight = (long)((double)(aLocalSizePixel.GetHeight() - 1)* fDetail); + aLocalSizePixel.SetSize(Size(nReducedWidth + 1, nReducedHeight + 1)); + } + + // Falls die Groesse null ist, groesse auf 1,1 setzen + if(aLocalSizePixel.GetSize().Width() < 1) + aLocalSizePixel.SetSize(Size(1 , aLocalSizePixel.GetSize().Height())); + if(aLocalSizePixel.GetSize().Height() < 1) + aLocalSizePixel.SetSize(Size(aLocalSizePixel.GetSize().Width(), 1)); + } +} + +/************************************************************************* +|* +|* Pixelkoordinaten des Punktes innerhalb der Bitmap holen +|* +\************************************************************************/ + +Point Base3DDefault::GetPixelCoor(B3dEntity& rEntity) +{ + if(bReducedDetail && fDetail != 0.0) + { + Point aRetval = GetOutputDevice()->LogicToPixel( + Point((long)(rEntity.Point().X()), + (long)(rEntity.Point().Y()))) - aSizePixel.TopLeft(); + aRetval.X() = (long)((double)aRetval.X() * fDetail); + aRetval.Y() = (long)((double)aRetval.Y() * fDetail); + return aRetval; + } + else + { + return GetOutputDevice()->LogicToPixel( + Point((long)(rEntity.Point().X()), + (long)(rEntity.Point().Y()))) - aSizePixel.TopLeft(); + } +} + +/************************************************************************* +|* +|* 3DPunkt aus Pixelkoordinaten und Tiefe rekonstruieren +|* +\************************************************************************/ + +Vector3D Base3DDefault::Get3DCoor(Point& rPnt, double fDepth) +{ + if(bReducedDetail && fDetail != 0.0) + { + Point aPnt(rPnt); + aPnt.X() = (long)((double)aPnt.X() / fDetail); + aPnt.Y() = (long)((double)aPnt.Y() / fDetail); + aPnt = GetOutputDevice()->PixelToLogic(aPnt + aSizePixel.TopLeft()); + return Vector3D(aPnt.X(), aPnt.Y(), fDepth); + } + else + { + Point aPnt = GetOutputDevice()->PixelToLogic(rPnt + aSizePixel.TopLeft()); + return Vector3D(aPnt.X(), aPnt.Y(), fDepth); + } +} + +/************************************************************************* +|* +|* ZBuffer Sichtbarkeitstest +|* +\************************************************************************/ + +BOOL Base3DDefault::IsVisibleAndScissor(long nX, long nY, UINT32 nDepth) +{ + if(!IsScissorRegionActive() || IsInScissorRegion(nX, nY)) + { + const BitmapColor& rBmCol = pZBufferWrite->GetPixel(nY, nX); + Color aColor(rBmCol.GetRed(), rBmCol.GetGreen(), rBmCol.GetBlue()); + return (aColor.GetColor() >= nDepth); + } + return FALSE; +} + +/************************************************************************* +|* +|* Scissoring Sichtbarkeitstest +|* +\************************************************************************/ + +BOOL Base3DDefault::IsInScissorRegion(long nX, long nY) +{ + if(nX < aDefaultScissorRectangle.Left()) + return FALSE; + if(nY < aDefaultScissorRectangle.Top()) + return FALSE; + if(nX > aDefaultScissorRectangle.Right()) + return FALSE; + if(nY > aDefaultScissorRectangle.Bottom()) + return FALSE; + return TRUE; +} + +/************************************************************************* +|* +|* Pixel setzen in allen Buffern +|* +\************************************************************************/ + +void Base3DDefault::WritePixel(long nX, long nY, Color aColor, UINT32 nDepth) +{ + // In Transparenz-Map eintragen + if(GetTransparentPartsContainedHint()) + { + if(aColor.GetTransparency()) + { + BYTE nOldTrans = pTransparenceWrite->GetPixel(nY, nX).GetIndex(); + + if(nOldTrans != (BYTE)0xff) + { + // Farbe mischen + BitmapColor aOldCol = pPictureWrite->GetPixel(nY, nX); + UINT16 nNegTrans = 0x0100 - (UINT16)aColor.GetTransparency(); + aColor.SetRed((BYTE)((((UINT16)aOldCol.GetRed() * (UINT16)aColor.GetTransparency()) + + (aColor.GetRed() * nNegTrans)) >> 8)); + aColor.SetGreen((BYTE)((((UINT16)aOldCol.GetGreen() * (UINT16)aColor.GetTransparency()) + + (aColor.GetGreen() * nNegTrans)) >> 8)); + aColor.SetBlue((BYTE)((((UINT16)aOldCol.GetBlue() * (UINT16)aColor.GetTransparency()) + + (aColor.GetBlue() * nNegTrans)) >> 8)); + pPictureWrite->SetPixel(nY, nX, aColor); + + // Transparenz mischen + pTransparenceWrite->SetPixel(nY, nX, + (BYTE)(((UINT16)(nOldTrans+1) * (UINT16)aColor.GetTransparency()) >> 8)); + } + else + { + // Pixel setzen + pPictureWrite->SetPixel(nY, nX, aColor); + + // Alpha-Wert setzen + pTransparenceWrite->SetPixel(nY, nX, aColor.GetTransparency()); + } + } + else + { + // Pixel setzen + pPictureWrite->SetPixel(nY, nX, aColor); + + // Alpha-Wert setzen + pTransparenceWrite->SetPixel(nY, nX, (BYTE)0x00); + + // Z-Buffer setzen + Color aZBufCol(nDepth); + pZBufferWrite->SetPixel(nY, nX, aZBufCol); + } + } + else + { + // Dieser Punkt in der Mono-Transparenz ist nicht transparent + BitmapColor aColBlack(BYTE(0)); + pTransparenceWrite->SetPixel(nY, nX, aColBlack); + + // Pixel setzen + pPictureWrite->SetPixel(nY, nX, aColor); + + // Z-Buffer setzen + Color aZBufCol(nDepth); + pZBufferWrite->SetPixel(nY, nX, aZBufCol); + } +} + +/************************************************************************* +|* +|* Zeichenfunktionen; alle Objekte sind geclippt +|* Einzelner Punkt +|* +\************************************************************************/ + +#define POLYGONOFFSET_VALUE (120) + +void Base3DDefault::Clipped3DPoint(UINT32 nInd) +{ + B3dEntity& rEntity = aBuffers[nInd]; + + // Geometrie holen + rEntity.ToDeviceCoor(GetTransformationSet()); + Point aOutPoint = GetPixelCoor(rEntity); + UINT32 nDepth = (UINT32)rEntity.Point().Z(); + + // PolygonOffset beachten + if(GetPolygonOffset(Base3DPolygonOffsetPoint)) + { + if(nDepth >= POLYGONOFFSET_VALUE) + nDepth -= POLYGONOFFSET_VALUE; + else + nDepth = 0; + } + + // Zeichnen + if(IsVisibleAndScissor(aOutPoint.X(), aOutPoint.Y(), nDepth)) + WritePixel(aOutPoint.X(), aOutPoint.Y(), rEntity.Color(), nDepth); +} + +/************************************************************************* +|* +|* Zeichenfunktionen; alle Objekte sind geclippt +|* Linie +|* +\************************************************************************/ + +void Base3DDefault::Clipped3DLine(UINT32 nInd1, UINT32 nInd2) +{ + B3dEntity& rEntity1 = aBuffers[nInd1]; + B3dEntity& rEntity2 = aBuffers[nInd2]; + bNormalsUsed = rEntity1.IsNormalUsed() && rEntity2.IsNormalUsed(); + bTextureUsed = IsTextureActive() && rEntity1.IsTexCoorUsed() && rEntity2.IsTexCoorUsed(); + + // ColorModel fuer diese Punkte anwenden, falls Normale vorhanden + // Danach Normale als ungueltig markieren, da nur noch die berechnete + // Farbe bei Aufteilungen weiter interpoliert wird + if(bNormalsUsed) + { + // Vektoren normalisieren + rEntity1.Normal().Normalize(); + rEntity2.Normal().Normalize(); + + if(GetShadeModel() != Base3DPhong) + { + // Farben auswerten + rEntity1.Color() = SolveColorModel(GetMaterialObject(), + rEntity1.Normal(), rEntity1.Point().GetVector3D()); + rEntity2.Color() = SolveColorModel(GetMaterialObject(), + rEntity2.Normal(), rEntity2.Point().GetVector3D()); + + // Die Normalen NICHT ungueltig machen, da die Entities + // eventuell noch fuer weitere Primitive benutzt werden. + // Aber lokal merken, dass die Normalen bereits ausgewertet sind + bNormalsUsed = FALSE; + } + } + + // Geometrie holen + rEntity1.ToDeviceCoor(GetTransformationSet()); + rEntity2.ToDeviceCoor(GetTransformationSet()); + Rectangle aPrimitiveArea; + + aOutPointTop = GetPixelCoor(rEntity1); + aOutPointLeft = GetPixelCoor(rEntity2); + + if(IsScissorRegionActive()) + { + aPrimitiveArea.Union(Rectangle(aOutPointTop, aOutPointTop)); + aPrimitiveArea.Union(Rectangle(aOutPointLeft, aOutPointLeft)); + } + + if(!IsScissorRegionActive() + || (IsScissorRegionActive() + && !aDefaultScissorRectangle.GetIntersection(aPrimitiveArea).IsEmpty())) + { + if(bTextureUsed) + { + fTexWidth = (double)GetActiveTexture()->GetBitmapSize().Width(); + fTexHeight = (double)GetActiveTexture()->GetBitmapSize().Height(); + } + + // Punkt, Farbe und Z-Wert interpolieren und die Linie gererieren + long nDx = aOutPointLeft.X() - aOutPointTop.X(); + long nDy = aOutPointLeft.Y() - aOutPointTop.Y(); + long nCount; + + // Werte fuer Schleife vorbereiten + if(abs(nDx) > abs(nDy)) + // ueber X gehen + nCount = abs(nDx); + else + // ueber Y gehen + nCount = abs(nDy); + + if(nCount) + { + // Interpolatoren vorbereiten + aIntXPosLeft.Load(aOutPointTop.X(), aOutPointLeft.X(), nCount); + aIntXPosRight.Load(aOutPointTop.Y(), aOutPointLeft.Y(), nCount); + UINT32 nDepth; + + // PolygonOffset beachten + if(GetPolygonOffset()) + { + double fDepthLeft = rEntity1.Point().Z(); + double fDepthRight = rEntity2.Point().Z(); + + if(fDepthLeft >= double(POLYGONOFFSET_VALUE)) + fDepthLeft -= double(POLYGONOFFSET_VALUE); + else + fDepthLeft = 0.0; + + if(fDepthRight >= double(POLYGONOFFSET_VALUE)) + fDepthRight -= double(POLYGONOFFSET_VALUE); + else + fDepthRight = 0.0; + + aIntDepthLine.Load(fDepthLeft, fDepthRight, nCount); + } + else + { + aIntDepthLine.Load(rEntity1.Point().Z(), rEntity2.Point().Z(), nCount); + } + + // Texturkoordinateninterpolation? + if(bTextureUsed) + { + aIntTexSLine.Load( + rEntity1.TexCoor().X() * fTexWidth, + rEntity2.TexCoor().X() * fTexWidth, + nCount); + aIntTexTLine.Load( + rEntity1.TexCoor().Y() * fTexHeight, + rEntity2.TexCoor().Y() * fTexHeight, + nCount); + } + + if(bNormalsUsed && GetShadeModel() == Base3DPhong) + { + // Normalen und Geometrie interpolieren + if(GetTransformationSet()) + { + Vector3D aInvTrans = GetTransformationSet()->GetTranslate(); + Vector3D aInvScale = GetTransformationSet()->GetScale(); + + // Tiefe und Normale vorbereiten + aIntVectorLine.Load(rEntity1.Normal(), rEntity2.Normal(), nCount); + + // Linie zeichnen + if(bTextureUsed) + { + while(nCount--) + { + // weiterer Punkt + nDx = aIntXPosLeft.GetLongValue(); + nDy = aIntXPosRight.GetLongValue(); + nDepth = aIntDepthLine.GetUINT32Value(); + + if(IsVisibleAndScissor(nDx, nDy, nDepth)) + { + Point aTmpPoint(nDx, nDy); + Vector3D aPoint = Get3DCoor(aTmpPoint, nDepth); + aPoint -= aInvTrans; + aPoint /= aInvScale; + Vector3D aNormal; + aIntVectorLine.GetVector3DValue(aNormal); + aNormal.Normalize(); + Color aCol = SolveColorModel(GetMaterialObject(), aNormal, aPoint); + GetActiveTexture()->ModifyColor(aCol, + aIntTexSLine.GetDoubleValue(), + aIntTexTLine.GetDoubleValue()); + WritePixel(nDx, nDy, aCol, nDepth); + } + + if(nCount) + { + // Weiterschalten + aIntXPosLeft.Increment(); + aIntXPosRight.Increment(); + aIntDepthLine.Increment(); + aIntVectorLine.Increment(); + aIntTexSLine.Increment(); + aIntTexTLine.Increment(); + } + } + } + else + { + while(nCount--) + { + // weiterer Punkt + nDx = aIntXPosLeft.GetLongValue(); + nDy = aIntXPosRight.GetLongValue(); + nDepth = aIntDepthLine.GetUINT32Value(); + + if(IsVisibleAndScissor(nDx, nDy, nDepth)) + { + Point aTmpPoint(nDx, nDy); + Vector3D aPoint = Get3DCoor(aTmpPoint, nDepth); + aPoint -= aInvTrans; + aPoint /= aInvScale; + Vector3D aNormal; + aIntVectorLine.GetVector3DValue(aNormal); + aNormal.Normalize(); + Color aCol = SolveColorModel(GetMaterialObject(), aNormal, aPoint); + WritePixel(nDx, nDy, aCol, nDepth); + } + + if(nCount) + { + // Weiterschalten + aIntXPosLeft.Increment(); + aIntXPosRight.Increment(); + aIntDepthLine.Increment(); + aIntVectorLine.Increment(); + } + } + } + } + } + else + { + if(rEntity1.Color() != rEntity2.Color()) + { + // Farbe und Geometrie interpolieren + // Tiefe und Farbe vorbereiten + aIntColorLine.Load(rEntity1.Color(), rEntity2.Color(), nCount); + + // Linie zeichnen + if(bTextureUsed) + { + while(nCount--) + { + // weiterer Punkt + nDx = aIntXPosLeft.GetLongValue(); + nDy = aIntXPosRight.GetLongValue(); + nDepth = aIntDepthLine.GetUINT32Value(); + + if(IsVisibleAndScissor(nDx, nDy, nDepth)) + { + Color aCol = aIntColorLine.GetColorValue(); + GetActiveTexture()->ModifyColor(aCol, + aIntTexSLine.GetDoubleValue(), + aIntTexTLine.GetDoubleValue()); + WritePixel(nDx, nDy, aCol, nDepth); + } + + if(nCount) + { + // Weiterschalten + aIntXPosLeft.Increment(); + aIntXPosRight.Increment(); + aIntDepthLine.Increment(); + aIntColorLine.Increment(); + aIntTexSLine.Increment(); + aIntTexTLine.Increment(); + } + } + } + else + { + while(nCount--) + { + // weiterer Punkt + nDx = aIntXPosLeft.GetLongValue(); + nDy = aIntXPosRight.GetLongValue(); + nDepth = aIntDepthLine.GetUINT32Value(); + + if(IsVisibleAndScissor(nDx, nDy, nDepth)) + WritePixel(nDx, nDy, aIntColorLine.GetColorValue(), nDepth); + + if(nCount) + { + // Weiterschalten + aIntXPosLeft.Increment(); + aIntXPosRight.Increment(); + aIntDepthLine.Increment(); + aIntColorLine.Increment(); + } + } + } + } + else + { + // Nur die Geometrie interpolieren + // Linie zeichnen + if(bTextureUsed) + { + while(nCount--) + { + // weiterer Punkt + nDx = aIntXPosLeft.GetLongValue(); + nDy = aIntXPosRight.GetLongValue(); + nDepth = aIntDepthLine.GetUINT32Value(); + + if(IsVisibleAndScissor(nDx, nDy, nDepth)) + { + Color aCol = rEntity1.Color(); + GetActiveTexture()->ModifyColor(aCol, + aIntTexSLine.GetDoubleValue(), + aIntTexTLine.GetDoubleValue()); + WritePixel(nDx, nDy, aCol, nDepth); + } + + if(nCount) + { + // Weiterschalten + aIntXPosLeft.Increment(); + aIntXPosRight.Increment(); + aIntDepthLine.Increment(); + aIntTexSLine.Increment(); + aIntTexTLine.Increment(); + } + } + } + else + { + while(nCount--) + { + // weiterer Punkt + nDx = aIntXPosLeft.GetLongValue(); + nDy = aIntXPosRight.GetLongValue(); + nDepth = aIntDepthLine.GetUINT32Value(); + + if(IsVisibleAndScissor(nDx, nDy, nDepth)) + WritePixel(nDx, nDy, rEntity1.Color(), nDepth); + + if(nCount) + { + // Weiterschalten + aIntXPosLeft.Increment(); + aIntXPosRight.Increment(); + aIntDepthLine.Increment(); + aIntTexSLine.Increment(); + aIntTexTLine.Increment(); + } + } + } + } + } + } + } +} + +/************************************************************************* +|* +|* Zeichenfunktionen; alle Objekte sind geclippt +|* Polygon +|* +\************************************************************************/ + +void Base3DDefault::Clipped3DTriangle(UINT32 nInd1, UINT32 nInd2, UINT32 nInd3) +{ + B3dEntity& rEntity1 = aBuffers[nInd1]; + B3dEntity& rEntity2 = aBuffers[nInd2]; + B3dEntity& rEntity3 = aBuffers[nInd3]; + bNormalsUsed = rEntity1.IsNormalUsed() && rEntity2.IsNormalUsed() && rEntity3.IsNormalUsed(); + bTextureUsed = IsTextureActive() && rEntity1.IsTexCoorUsed() && rEntity2.IsTexCoorUsed() && rEntity3.IsTexCoorUsed(); + Base3DMaterialMode eMode = Base3DMaterialFront; + + // ColorModel fuer diese Punkte anwenden, falls Normale vorhanden + // Danach Normale als ungueltig markieren, da nur noch die berechnete + // Farbe bei Aufteilungen weiter interpoliert wird + if(bNormalsUsed) + { + // Vektoren normalisieren + rEntity1.Normal().Normalize(); + rEntity2.Normal().Normalize(); + rEntity3.Normal().Normalize(); + + if(GetShadeModel() != Base3DPhong) + { + // Normale berechnen, Farben auswerten + if(rEntity1.PlaneNormal().Z() < 0.0 && (GetLightGroup() && GetLightGroup()->GetModelTwoSide())) + eMode = Base3DMaterialBack; + + rEntity1.Color() = SolveColorModel( + GetMaterialObject(eMode), + rEntity1.Normal(), rEntity1.Point().GetVector3D()); + rEntity2.Color() = SolveColorModel( + GetMaterialObject(eMode), + rEntity2.Normal(), rEntity2.Point().GetVector3D()); + rEntity3.Color() = SolveColorModel( + GetMaterialObject(eMode), + rEntity3.Normal(), rEntity3.Point().GetVector3D()); + + // Die Normalen NICHT ungueltig machen, da die Entities + // eventuell noch fuer weitere Primitive benutzt werden. + // Aber lokal merken, dass die Normalen bereits ausgewertet sind + bNormalsUsed = FALSE; + } + } + + // Geometrie holen + rEntity1.ToDeviceCoor(GetTransformationSet()); + rEntity2.ToDeviceCoor(GetTransformationSet()); + rEntity3.ToDeviceCoor(GetTransformationSet()); + + // Punkte ordnen. Oberster nach pEntTop + if(rEntity1.Point().Y() < rEntity2.Point().Y() + && rEntity1.Point().Y() < rEntity3.Point().Y()) + { + // rEntity1 ist der oberste + pEntTop = &rEntity1; + + // Left, Right erst mal zuweisen + pEntRight = &rEntity3; + pEntLeft = &rEntity2; + } + else + { + if(rEntity2.Point().Y() < rEntity3.Point().Y()) + { + // rEntity2 ist der oberste + pEntTop = &rEntity2; + + // Left, Right erst mal zuweisen + pEntRight = &rEntity1; + pEntLeft = &rEntity3; + } + else + { + // rEntity3 ist der oberste + pEntTop = &rEntity3; + + // Left, Right erst mal zuweisen + pEntRight = &rEntity2; + pEntLeft = &rEntity1; + } + } + + // Werte holen + Rectangle aPrimitiveArea; + + aOutPointTop = GetPixelCoor(*pEntTop); + aOutPointLeft = GetPixelCoor(*pEntLeft); + aOutPointRight = GetPixelCoor(*pEntRight); + + if(IsScissorRegionActive()) + { + aPrimitiveArea.Union(Rectangle(aOutPointTop, aOutPointTop)); + aPrimitiveArea.Union(Rectangle(aOutPointLeft, aOutPointLeft)); + aPrimitiveArea.Union(Rectangle(aOutPointRight, aOutPointRight)); + } + + if(!IsScissorRegionActive() + || (IsScissorRegionActive() + && !aDefaultScissorRectangle.GetIntersection(aPrimitiveArea).IsEmpty())) + { + if(bTextureUsed) + { + fTexWidth = (double)GetActiveTexture()->GetBitmapSize().Width(); + fTexHeight = (double)GetActiveTexture()->GetBitmapSize().Height(); + } + + // Links und rechts ordnen + long nDeltaYLeft = aOutPointLeft.Y() - aOutPointTop.Y(); + long nDeltaYRight = aOutPointRight.Y() - aOutPointTop.Y(); + long nYLine; + + if((aOutPointLeft.X() - aOutPointTop.X()) * nDeltaYRight + - nDeltaYLeft * (aOutPointRight.X() - aOutPointTop.X()) > 0) + { + // Links und rechts vertauschen + // Punkte + nYLine = aOutPointLeft.X(); + aOutPointLeft.X() = aOutPointRight.X(); + aOutPointRight.X() = nYLine; + nYLine = aOutPointLeft.Y(); + aOutPointLeft.Y() = aOutPointRight.Y(); + aOutPointRight.Y() = nYLine; + + // Deltas + nYLine = nDeltaYLeft; nDeltaYLeft = nDeltaYRight; nDeltaYRight = nYLine; + + // Zeiger auf Entities + B3dEntity* pTmp = pEntLeft; pEntLeft = pEntRight; pEntRight = pTmp; + } + + // YStart, Links und rechts laden + nYLine = aOutPointTop.Y(); + aIntXPosLeft.Load(aOutPointTop.X(), aOutPointLeft.X(), nDeltaYLeft); + aIntDepthLeft.Load(pEntTop->Point().Z(), pEntLeft->Point().Z(), nDeltaYLeft); + aIntXPosRight.Load(aOutPointTop.X(), aOutPointRight.X(), nDeltaYRight); + aIntDepthRight.Load(pEntTop->Point().Z(), pEntRight->Point().Z(), nDeltaYRight); + if(bTextureUsed) + { + aIntTexSLeft.Load( + pEntTop->TexCoor().X() * fTexWidth, + pEntLeft->TexCoor().X() * fTexWidth, nDeltaYLeft); + aIntTexTLeft.Load( + pEntTop->TexCoor().Y() * fTexHeight, + pEntLeft->TexCoor().Y() * fTexHeight, nDeltaYLeft); + aIntTexSRight.Load( + pEntTop->TexCoor().X() * fTexWidth, + pEntRight->TexCoor().X() * fTexWidth, nDeltaYRight); + aIntTexTRight.Load( + pEntTop->TexCoor().Y() * fTexHeight, + pEntRight->TexCoor().Y() * fTexHeight, nDeltaYRight); + } + + if(bNormalsUsed && GetShadeModel() == Base3DPhong) + { + // Normalen und Geometrie interpolieren + aIntVectorLeft.Load(pEntTop->Normal(), pEntLeft->Normal(), nDeltaYLeft); + aIntVectorRight.Load(pEntTop->Normal(), pEntRight->Normal(), nDeltaYRight); + B3dMaterial& rMat = GetMaterialObject(eMode); + + if(bTextureUsed) + { + // Schleife + while(nDeltaYLeft || nDeltaYRight) + { + // Zeile ausgeben + DrawLinePhongTexture(nYLine, rMat); + + // naechste Zeile vorbereiten rechts + if(!nDeltaYRight && nDeltaYLeft) + { + // Rechts ist zuende, lade neu mit Rest nach links + nDeltaYRight = nDeltaYLeft; + LoadRightTexture(nDeltaYRight); + aIntVectorRight.Load(pEntRight->Normal(), pEntLeft->Normal(), nDeltaYRight); + } + + // naechste Zeile vorbereiten links + if(!nDeltaYLeft && nDeltaYRight) + { + // Links ist zuende, lade neu mit Rest nach rechts + nDeltaYLeft = nDeltaYRight; + LoadLeftTexture(nDeltaYLeft); + aIntVectorLeft.Load(pEntLeft->Normal(), pEntRight->Normal(), nDeltaYLeft); + } + + // naechste Zeile rechts + if(nDeltaYRight || nDeltaYLeft) + { + nDeltaYRight--; + NextStepRightTexture(); + aIntVectorRight.Increment(); + + nDeltaYLeft--; + NextStepLeftTexture(); + aIntVectorLeft.Increment(); + + nYLine++; + } + } + } + else + { + // Schleife + while(nDeltaYLeft || nDeltaYRight) + { + // Zeile ausgeben + DrawLinePhong(nYLine, rMat); + + // naechste Zeile vorbereiten rechts + if(!nDeltaYRight && nDeltaYLeft) + { + // Rechts ist zuende, lade neu mit Rest nach links + nDeltaYRight = nDeltaYLeft; + LoadRight(nDeltaYRight); + aIntVectorRight.Load(pEntRight->Normal(), pEntLeft->Normal(), nDeltaYRight); + } + + // naechste Zeile vorbereiten links + if(!nDeltaYLeft && nDeltaYRight) + { + // Links ist zuende, lade neu mit Rest nach rechts + nDeltaYLeft = nDeltaYRight; + LoadLeft(nDeltaYLeft); + aIntVectorLeft.Load(pEntLeft->Normal(), pEntRight->Normal(), nDeltaYLeft); + } + + // naechste Zeile rechts + if(nDeltaYRight || nDeltaYLeft) + { + nDeltaYRight--; + NextStepRight(); + aIntVectorRight.Increment(); + + nDeltaYLeft--; + NextStepLeft(); + aIntVectorLeft.Increment(); + + nYLine++; + } + } + } + } + else + { + if(!(rEntity1.Color() == rEntity2.Color() && rEntity1.Color() == rEntity3.Color())) + { + // Farbe und Geometrie interpolieren + aIntColorLeft.Load(pEntTop->Color(), pEntLeft->Color(), nDeltaYLeft); + aIntColorRight.Load(pEntTop->Color(), pEntRight->Color(), nDeltaYRight); + + if(bTextureUsed) + { + // Schleife + while(nDeltaYLeft || nDeltaYRight) + { + // Zeile ausgeben + DrawLineColorTexture(nYLine); + + // naechste Zeile vorbereiten rechts + if(!nDeltaYRight && nDeltaYLeft) + { + // Rechts ist zuende, lade neu mit Rest nach links + nDeltaYRight = nDeltaYLeft; + LoadRightTexture(nDeltaYRight); + aIntColorRight.Load(pEntRight->Color(), pEntLeft->Color(), nDeltaYRight); + } + + // naechste Zeile vorbereiten links + if(!nDeltaYLeft && nDeltaYRight) + { + // Links ist zuende, lade neu mit Rest nach rechts + nDeltaYLeft = nDeltaYRight; + LoadLeftTexture(nDeltaYLeft); + aIntColorLeft.Load(pEntLeft->Color(), pEntRight->Color(), nDeltaYLeft); + } + + // naechste Zeile rechts + if(nDeltaYRight || nDeltaYLeft) + { + nDeltaYRight--; + NextStepRightTexture(); + aIntColorRight.Increment(); + + nDeltaYLeft--; + NextStepLeftTexture(); + aIntColorLeft.Increment(); + + nYLine++; + } + } + } + else + { + // Schleife + while(nDeltaYLeft || nDeltaYRight) + { + // Zeile ausgeben + DrawLineColor(nYLine); + + // naechste Zeile vorbereiten rechts + if(!nDeltaYRight && nDeltaYLeft) + { + // Rechts ist zuende, lade neu mit Rest nach links + nDeltaYRight = nDeltaYLeft; + LoadRight(nDeltaYRight); + aIntColorRight.Load(pEntRight->Color(), pEntLeft->Color(), nDeltaYRight); + } + + // naechste Zeile vorbereiten links + if(!nDeltaYLeft && nDeltaYRight) + { + // Links ist zuende, lade neu mit Rest nach rechts + nDeltaYLeft = nDeltaYRight; + LoadLeft(nDeltaYLeft); + aIntColorLeft.Load(pEntLeft->Color(), pEntRight->Color(), nDeltaYLeft); + } + + // naechste Zeile rechts + if(nDeltaYRight || nDeltaYLeft) + { + nDeltaYRight--; + NextStepRight(); + aIntColorRight.Increment(); + + nDeltaYLeft--; + NextStepLeft(); + aIntColorLeft.Increment(); + + nYLine++; + } + } + } + } + else + { + // Nur die Geometrie interpolieren + if(bTextureUsed) + { + // Schleife + while(nDeltaYLeft || nDeltaYRight) + { + // Zeile ausgeben + DrawLineTexture(nYLine, pEntTop->Color()); + + // naechste Zeile vorbereiten rechts + if(!nDeltaYRight && nDeltaYLeft) + { + // Rechts ist zuende, lade neu mit Rest nach links + nDeltaYRight = nDeltaYLeft; + LoadRightTexture(nDeltaYRight); + } + + // naechste Zeile vorbereiten links + if(!nDeltaYLeft && nDeltaYRight) + { + // Links ist zuende, lade neu mit Rest nach rechts + nDeltaYLeft = nDeltaYRight; + LoadLeftTexture(nDeltaYLeft); + } + + // naechste Zeile rechts + if(nDeltaYRight || nDeltaYLeft) + { + nDeltaYRight--; + NextStepRightTexture(); + + nDeltaYLeft--; + NextStepLeftTexture(); + + nYLine++; + } + } + } + else + { + // Schleife + while(nDeltaYLeft || nDeltaYRight) + { + // Zeile ausgeben + DrawLine(nYLine, pEntTop->Color()); + + // naechste Zeile vorbereiten rechts + if(!nDeltaYRight && nDeltaYLeft) + { + // Rechts ist zuende, lade neu mit Rest nach links + nDeltaYRight = nDeltaYLeft; + LoadRight(nDeltaYRight); + } + + // naechste Zeile vorbereiten links + if(!nDeltaYLeft && nDeltaYRight) + { + // Links ist zuende, lade neu mit Rest nach rechts + nDeltaYLeft = nDeltaYRight; + LoadLeft(nDeltaYLeft); + } + + // naechste Zeile rechts + if(nDeltaYRight || nDeltaYLeft) + { + nDeltaYRight--; + NextStepRight(); + + nDeltaYLeft--; + NextStepLeft(); + + nYLine++; + } + } + } + } + } + } +} + +void Base3DDefault::DrawLinePhongTexture(long nYPos, B3dMaterial& rMat) +{ + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && (nYPos < aDefaultScissorRectangle.Top() + || nYPos > aDefaultScissorRectangle.Bottom())) + return; + + // Von links bis rechts zeichnen + long nXLineStart = aIntXPosLeft.GetLongValue(); + long nXLineDelta = aIntXPosRight.GetLongValue() - nXLineStart; + + if(nXLineDelta > 0) + { + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && ( nXLineStart+nXLineDelta < aDefaultScissorRectangle.Left() + || nXLineStart > aDefaultScissorRectangle.Right())) + return; + + Vector3D aVectorLeft; + aIntVectorLeft.GetVector3DValue(aVectorLeft); + Vector3D aVectorRight; + aIntVectorRight.GetVector3DValue(aVectorRight); + aIntVectorLine.Load(aVectorLeft, aVectorRight, nXLineDelta); + aIntDepthLine.Load(aIntDepthLeft.GetDoubleValue(), aIntDepthRight.GetDoubleValue(), nXLineDelta); + + // Texturkoordinateninterpolation? + if(bTextureUsed) + { + aIntTexSLine.Load(aIntTexSLeft.GetDoubleValue(), aIntTexSRight.GetDoubleValue(), nXLineDelta); + aIntTexTLine.Load(aIntTexTLeft.GetDoubleValue(), aIntTexTRight.GetDoubleValue(), nXLineDelta); + } + + if(GetTransformationSet()) + { + Vector3D aInvTrans = GetTransformationSet()->GetTranslate(); + Vector3D aInvScale = GetTransformationSet()->GetScale(); + + while(nXLineDelta--) + { + // Werte vorbereiten + UINT32 nDepth = aIntDepthLine.GetUINT32Value(); + + // Punkt ausgeben + if(IsVisibleAndScissor(nXLineStart, nYPos, nDepth)) + { + Point aTmpPoint(nXLineStart, nYPos); + Vector3D aPoint = Get3DCoor(aTmpPoint, nDepth); + aPoint -= aInvTrans; + aPoint /= aInvScale; + Vector3D aNormal; + aIntVectorLine.GetVector3DValue(aNormal); + aNormal.Normalize(); + Color aCol = SolveColorModel(rMat, aNormal, aPoint); + + // Texturkoordinateninterpolation? + if(bTextureUsed) + { + GetActiveTexture()->ModifyColor(aCol, + aIntTexSLine.GetDoubleValue(), + aIntTexTLine.GetDoubleValue()); + } + WritePixel(nXLineStart, nYPos, aCol, nDepth); + } + + if(nXLineDelta) + { + // naechste Spalte + nXLineStart++; + + // naechste Tiefe und Farbe + aIntDepthLine.Increment(); + aIntVectorLine.Increment(); + + // Texturkoordinateninterpolation? + if(bTextureUsed) + { + aIntTexSLine.Increment(); + aIntTexTLine.Increment(); + } + } + } + } + } +} + +void Base3DDefault::DrawLinePhong(long nYPos, B3dMaterial& rMat) +{ + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && (nYPos < aDefaultScissorRectangle.Top() + || nYPos > aDefaultScissorRectangle.Bottom())) + return; + + // Von links bis rechts zeichnen + long nXLineStart = aIntXPosLeft.GetLongValue(); + long nXLineDelta = aIntXPosRight.GetLongValue() - nXLineStart; + + if(nXLineDelta > 0) + { + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && ( nXLineStart+nXLineDelta < aDefaultScissorRectangle.Left() + || nXLineStart > aDefaultScissorRectangle.Right())) + return; + + Vector3D aVectorLeft; + aIntVectorLeft.GetVector3DValue(aVectorLeft); + Vector3D aVectorRight; + aIntVectorRight.GetVector3DValue(aVectorRight); + aIntVectorLine.Load(aVectorLeft, aVectorRight, nXLineDelta); + aIntDepthLine.Load(aIntDepthLeft.GetDoubleValue(), aIntDepthRight.GetDoubleValue(), nXLineDelta); + + if(GetTransformationSet()) + { + Vector3D aInvTrans = GetTransformationSet()->GetTranslate(); + Vector3D aInvScale = GetTransformationSet()->GetScale(); + while(nXLineDelta--) + { + // Werte vorbereiten + UINT32 nDepth = aIntDepthLine.GetUINT32Value(); + + // Punkt ausgeben + if(IsVisibleAndScissor(nXLineStart, nYPos, nDepth)) + { + Point aTmpPoint(nXLineStart, nYPos); + Vector3D aPoint = Get3DCoor(aTmpPoint, nDepth); + aPoint -= aInvTrans; + aPoint /= aInvScale; + Vector3D aNormal; + aIntVectorLine.GetVector3DValue(aNormal); + aNormal.Normalize(); + Color aCol = SolveColorModel(rMat, aNormal, aPoint); + WritePixel(nXLineStart, nYPos, aCol, nDepth); + } + + if(nXLineDelta) + { + // naechste Spalte + nXLineStart++; + + // naechste Tiefe und Farbe + aIntDepthLine.Increment(); + aIntVectorLine.Increment(); + } + } + } + } +} + +void Base3DDefault::DrawLineColorTexture(long nYPos) +{ + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && (nYPos < aDefaultScissorRectangle.Top() + || nYPos > aDefaultScissorRectangle.Bottom())) + return; + + // Von links bis rechts zeichnen + long nXLineStart = aIntXPosLeft.GetLongValue(); + long nXLineDelta = aIntXPosRight.GetLongValue() - nXLineStart; + + if(nXLineDelta > 0) + { + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && ( nXLineStart+nXLineDelta < aDefaultScissorRectangle.Left() + || nXLineStart > aDefaultScissorRectangle.Right())) + return; + + aIntColorLine.Load(aIntColorLeft.GetColorValue(), aIntColorRight.GetColorValue(), nXLineDelta); + aIntTexSLine.Load(aIntTexSLeft.GetDoubleValue(), aIntTexSRight.GetDoubleValue(), nXLineDelta); + aIntTexTLine.Load(aIntTexTLeft.GetDoubleValue(), aIntTexTRight.GetDoubleValue(), nXLineDelta); + aIntDepthLine.Load(aIntDepthLeft.GetDoubleValue(), aIntDepthRight.GetDoubleValue(), nXLineDelta); + + while(nXLineDelta--) + { + // Werte vorbereiten + UINT32 nDepth = aIntDepthLine.GetUINT32Value(); + + // Punkt ausgeben + if(IsVisibleAndScissor(nXLineStart, nYPos, nDepth)) + { + Color aCol = aIntColorLine.GetColorValue(); + GetActiveTexture()->ModifyColor(aCol, + aIntTexSLine.GetDoubleValue(), + aIntTexTLine.GetDoubleValue()); + WritePixel(nXLineStart, nYPos, aCol, nDepth); + } + + if(nXLineDelta) + { + // naechste Spalte + nXLineStart++; + + // naechste Tiefe und Farbe + aIntDepthLine.Increment(); + aIntColorLine.Increment(); + aIntTexSLine.Increment(); + aIntTexTLine.Increment(); + } + } + } +} + +void Base3DDefault::DrawLineColor(long nYPos) +{ + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && (nYPos < aDefaultScissorRectangle.Top() + || nYPos > aDefaultScissorRectangle.Bottom())) + return; + + // Von links bis rechts zeichnen + long nXLineStart = aIntXPosLeft.GetLongValue(); + long nXLineDelta = aIntXPosRight.GetLongValue() - nXLineStart; + + if(nXLineDelta > 0) + { + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && ( nXLineStart+nXLineDelta < aDefaultScissorRectangle.Left() + || nXLineStart > aDefaultScissorRectangle.Right())) + return; + + aIntColorLine.Load(aIntColorLeft.GetColorValue(), aIntColorRight.GetColorValue(), nXLineDelta); + aIntDepthLine.Load(aIntDepthLeft.GetDoubleValue(), aIntDepthRight.GetDoubleValue(), nXLineDelta); + + while(nXLineDelta--) + { + // Werte vorbereiten + UINT32 nDepth = aIntDepthLine.GetUINT32Value(); + + // Punkt ausgeben + if(IsVisibleAndScissor(nXLineStart, nYPos, nDepth)) + WritePixel(nXLineStart, nYPos, aIntColorLine.GetColorValue(), nDepth); + + if(nXLineDelta) + { + // naechste Spalte + nXLineStart++; + + // naechste Tiefe und Farbe + aIntDepthLine.Increment(); + aIntColorLine.Increment(); + } + } + } +} + +void Base3DDefault::DrawLineTexture(long nYPos, Color& rCol) +{ + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && (nYPos < aDefaultScissorRectangle.Top() + || nYPos > aDefaultScissorRectangle.Bottom())) + return; + + // Von links bis rechts zeichnen + long nXLineStart = aIntXPosLeft.GetLongValue(); + long nXLineDelta = aIntXPosRight.GetLongValue() - nXLineStart; + + if(nXLineDelta > 0) + { + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && ( nXLineStart+nXLineDelta < aDefaultScissorRectangle.Left() + || nXLineStart > aDefaultScissorRectangle.Right())) + return; + + aIntTexSLine.Load(aIntTexSLeft.GetDoubleValue(), aIntTexSRight.GetDoubleValue(), nXLineDelta); + aIntTexTLine.Load(aIntTexTLeft.GetDoubleValue(), aIntTexTRight.GetDoubleValue(), nXLineDelta); + aIntDepthLine.Load(aIntDepthLeft.GetDoubleValue(), aIntDepthRight.GetDoubleValue(), nXLineDelta); + + while(nXLineDelta--) + { + // Werte vorbereiten + UINT32 nDepth = aIntDepthLine.GetUINT32Value(); + + // Punkt ausgeben + if(IsVisibleAndScissor(nXLineStart, nYPos, nDepth)) + { + // Texturkoordinateninterpolation? + Color aCol = rCol; + GetActiveTexture()->ModifyColor(aCol, + aIntTexSLine.GetDoubleValue(), + aIntTexTLine.GetDoubleValue()); + WritePixel(nXLineStart, nYPos, aCol, nDepth); + } + + if(nXLineDelta) + { + // naechste Spalte + nXLineStart++; + + // naechste Tiefe und Farbe + aIntDepthLine.Increment(); + aIntTexSLine.Increment(); + aIntTexTLine.Increment(); + } + } + } +} + +void Base3DDefault::DrawLine(long nYPos, Color& rCol) +{ + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && (nYPos < aDefaultScissorRectangle.Top() + || nYPos > aDefaultScissorRectangle.Bottom())) + return; + + // Von links bis rechts zeichnen + long nXLineStart = aIntXPosLeft.GetLongValue(); + long nXLineDelta = aIntXPosRight.GetLongValue() - nXLineStart; + + if(nXLineDelta > 0) + { + // Ausserhalb des Clipping-Bereichs? + if(IsScissorRegionActive() + && ( nXLineStart+nXLineDelta < aDefaultScissorRectangle.Left() + || nXLineStart > aDefaultScissorRectangle.Right())) + return; + + aIntDepthLine.Load(aIntDepthLeft.GetDoubleValue(), aIntDepthRight.GetDoubleValue(), nXLineDelta); + + while(nXLineDelta--) + { + // Werte vorbereiten + UINT32 nDepth = aIntDepthLine.GetUINT32Value(); + + // Punkt ausgeben + if(IsVisibleAndScissor(nXLineStart, nYPos, nDepth)) + WritePixel(nXLineStart, nYPos, rCol, nDepth); + + if(nXLineDelta) + { + // naechste Spalte + nXLineStart++; + + // naechste Tiefe und Farbe + aIntDepthLine.Increment(); + } + } + } +} + +void Base3DDefault::LoadLeftTexture(long nSize) +{ + aIntXPosLeft.Load(aOutPointLeft.X(), aOutPointRight.X(), nSize); + aIntDepthLeft.Load(pEntLeft->Point().Z(), pEntRight->Point().Z(), nSize); + aIntTexSLeft.Load( + pEntLeft->TexCoor().X() * fTexWidth, + pEntRight->TexCoor().X() * fTexWidth, nSize); + aIntTexTLeft.Load( + pEntLeft->TexCoor().Y() * fTexHeight, + pEntRight->TexCoor().Y() * fTexHeight, nSize); +} + +void Base3DDefault::LoadLeft(long nSize) +{ + aIntXPosLeft.Load(aOutPointLeft.X(), aOutPointRight.X(), nSize); + aIntDepthLeft.Load(pEntLeft->Point().Z(), pEntRight->Point().Z(), nSize); +} + +void Base3DDefault::LoadRightTexture(long nSize) +{ + aIntXPosRight.Load(aOutPointRight.X(), aOutPointLeft.X(), nSize); + aIntDepthRight.Load(pEntRight->Point().Z(), pEntLeft->Point().Z(), nSize); + aIntTexSRight.Load( + pEntRight->TexCoor().X() * fTexWidth, + pEntLeft->TexCoor().X() * fTexWidth, nSize); + aIntTexTRight.Load( + pEntRight->TexCoor().Y() * fTexHeight, + pEntLeft->TexCoor().Y() * fTexHeight, nSize); +} + +void Base3DDefault::LoadRight(long nSize) +{ + aIntXPosRight.Load(aOutPointRight.X(), aOutPointLeft.X(), nSize); + aIntDepthRight.Load(pEntRight->Point().Z(), pEntLeft->Point().Z(), nSize); +} + +void Base3DDefault::NextStepRightTexture() +{ + aIntXPosRight.Increment(); + aIntDepthRight.Increment(); + aIntTexSRight.Increment(); + aIntTexTRight.Increment(); +} + +void Base3DDefault::NextStepRight() +{ + aIntXPosRight.Increment(); + aIntDepthRight.Increment(); +} + +void Base3DDefault::NextStepLeftTexture() +{ + aIntXPosLeft.Increment(); + aIntDepthLeft.Increment(); + aIntTexSLeft.Increment(); + aIntTexTLeft.Increment(); +} + +void Base3DDefault::NextStepLeft() +{ + aIntXPosLeft.Increment(); + aIntDepthLeft.Increment(); +} + diff --git a/goodies/source/base3d/b3ddeflt.hxx b/goodies/source/base3d/b3ddeflt.hxx new file mode 100644 index 000000000000..be022af8b0f2 --- /dev/null +++ b/goodies/source/base3d/b3ddeflt.hxx @@ -0,0 +1,233 @@ +/************************************************************************* + * + * $RCSfile: b3ddeflt.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DDEFLT_HXX +#define _B3D_B3DDEFLT_HXX + +#ifndef _B3D_B3DCOMMN_HXX +#include "b3dcommn.hxx" +#endif + +#ifndef _SV_BITMAP_HXX +#include <vcl/bitmap.hxx> +#endif + +#ifndef _SV_SALBTYPE_HXX +#include <vcl/salbtype.hxx> +#endif + +#ifndef _SV_ALPHA_HXX +#include <vcl/alpha.hxx> +#endif + +#ifndef _BXD_INTERPOLATOR_HXX +#include "bxdintpo.hxx" +#endif + +/************************************************************************* +|* +|* Die Basisklasse fuer Standard 3D Ausgaben auf StarView Basis +|* +\************************************************************************/ + +class Base3DDefault : public Base3DCommon +{ +private: + // ZBuffer auch als BitMap + Bitmap aZBuffer; + + // Bitmap zum Zeichnen im Hintergrund + Bitmap aPicture; + + // Bitmaps fuer die Transparenz + Bitmap aMonoTransparence; + AlphaMask aAlphaTransparence; + + // Position der oberen linken Ecke aus ImplSetViewport + Rectangle aSizePixel; + + // Mit faktoren umgerechnete echte Bitmap-Groesse + Rectangle aLocalSizePixel; + + // ZBuffer loeschwert + BitmapColor aClearValue; + + // Zugriffe auf die BitMaps + BitmapWriteAccess* pZBufferWrite; + BitmapWriteAccess* pPictureWrite; + BitmapWriteAccess* pTransparenceWrite; + + // Vergroeberungsstufe und dazugehoerige Variablen + double fDetail; + double fDetailBackup; + long nMaxPixels; + + // Groesse der Textur, falls benutzt + double fTexWidth; + double fTexHeight; + + // Punktkoodinaten fuer Primitive + Point aOutPointTop; + Point aOutPointLeft; + Point aOutPointRight; + + // Zeiger auf die Ursprungsdaten + B3dEntity* pEntTop; + B3dEntity* pEntLeft; + B3dEntity* pEntRight; + + // benoetigte Interpolatoren + BxdInterpolator aIntXPosLeft; + BxdInterpolator aIntXPosRight; + BxdInterpolator aIntDepthLeft; + BxdInterpolator aIntDepthRight; + BxdInterpolator aIntDepthLine; + BxdInterpolator aIntTexSLeft; + BxdInterpolator aIntTexSRight; + BxdInterpolator aIntTexTLeft; + BxdInterpolator aIntTexTRight; + BxdInterpolator aIntTexSLine; + BxdInterpolator aIntTexTLine; + B3dVectorInterpolator aIntVectorLeft; + B3dVectorInterpolator aIntVectorRight; + B3dVectorInterpolator aIntVectorLine; + BxdColorInterpolator aIntColorLeft; + BxdColorInterpolator aIntColorRight; + BxdColorInterpolator aIntColorLine; + + // Lokale Scissor Region (ohne TopLeft) + Rectangle aDefaultScissorRectangle; + + // Booleans fuer Zeichenoperationen + unsigned bNormalsUsed : 1; + unsigned bTextureUsed : 1; + + // Bool fuer Detailreduzierung + unsigned bReducedDetail : 1; + unsigned bDetailBackedup : 1; + + // Funktionen fuer erlangen/freigeben der BitmapAccesses + void AcquireAccess(); + void ReleaseAccess(); + + // Umrechnung auf PixelCoor der Bitmaps und zurueck + Point GetPixelCoor(B3dEntity& rEntity); + Vector3D Get3DCoor(Point& rPnt, double fDepth); + + // ZBuffer funktionen + inline BOOL IsInScissorRegion(long nX, long nY); + inline BOOL IsVisibleAndScissor(long nX, long nY, UINT32 nDepth); + inline void WritePixel(long nX, long nY, Color aColor, UINT32 nDepth); + + // Zeilenerzeuger fuer Polygon + /*inline*/ void DrawLinePhongTexture(long nYPos, B3dMaterial& rMat); + /*inline*/ void DrawLinePhong(long nYPos, B3dMaterial& rMat); + /*inline*/ void DrawLineColorTexture(long nYPos); + /*inline*/ void DrawLineColor(long nYPos); + /*inline*/ void DrawLineTexture(long nYPos, Color& rCol); + /*inline*/ void DrawLine(long nYPos, Color& rCol); + + inline void LoadLeft(long nSize); + inline void LoadLeftTexture(long nSize); + inline void LoadRight(long nSize); + inline void LoadRightTexture(long nSize); + + inline void NextStepRight(); + inline void NextStepRightTexture(); + inline void NextStepLeft(); + inline void NextStepLeftTexture(); + +public: + Base3DDefault(OutputDevice* pOutDev); + virtual ~Base3DDefault(); + + // Typbestimmung + virtual UINT16 GetBase3DType(); + + // Szenenverwaltung + virtual void StartScene(); + virtual void EndScene(); + + // Nullwert des ZBuffers setzen + void SetClearValue(UINT32 nNew) { aClearValue = Color(nNew); } + + // Detailstufe/Vergroeberung der Ausgabe setzen/lesen + void SetDetail(double fNew=1.0); + double GetDetail() { return fDetail; } + void SetMaxPixels(long nNew=500000) { nMaxPixels = nNew; } + long GetMaxPixels() { return nMaxPixels; } + virtual void SetDisplayQuality(UINT8 nNew); + + // Callbacks bei Matrixaenderungen + virtual void SetTransformationSet(B3dTransformationSet* pSet); + +protected: + + // Geometrie + virtual void Clipped3DPoint(UINT32 nInd); + virtual void Clipped3DLine(UINT32 nInd1, UINT32 nInd2); + virtual void Clipped3DTriangle(UINT32 nInd1, UINT32 nInd2, + UINT32 nInd3); +}; + + + +#endif // _B3D_B3DDEFLT_HXX diff --git a/goodies/source/base3d/b3dentty.cxx b/goodies/source/base3d/b3dentty.cxx new file mode 100644 index 000000000000..f3ad576cfdce --- /dev/null +++ b/goodies/source/base3d/b3dentty.cxx @@ -0,0 +1,366 @@ +/************************************************************************* + * + * $RCSfile: b3dentty.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DENTITY_HXX +#include "b3dentty.hxx" +#endif + +#ifndef _B3D_B3DCOMMN_HXX +#include "b3dcommn.hxx" +#endif + +#ifndef _B3D_B3DTRANS_HXX +#include "b3dtrans.hxx" +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +/************************************************************************* +|* +|* Kopieren eine 3DEntity +|* +\************************************************************************/ + +void B3dEntity::Copy(B3dEntity& rEnt) +{ + aPoint = rEnt.Point(); + bDeviceCoor = rEnt.IsDeviceCoor(); + bValid = rEnt.IsValid(); + bEdgeFlag = rEnt.IsEdgeVisible(); + aPlaneNormal = rEnt.PlaneNormal(); + + if(bNormalUsed = rEnt.IsNormalUsed()) + aNormal = rEnt.Normal(); + + if(bTexCoorUsed = rEnt.IsTexCoorUsed()) + aTexCoor = rEnt.TexCoor(); + + aColor = rEnt.Color(); +} + +/************************************************************************* +|* +|* Flags auf Ausgangsposition +|* +\************************************************************************/ + +void B3dEntity::Reset() +{ + bValid = bNormalUsed = bTexCoorUsed = bDeviceCoor = FALSE; + bEdgeFlag = TRUE; +} + +/************************************************************************* +|* +|* Device Koordinaten des Punktes berechnen +|* +\************************************************************************/ + +void B3dEntity::ImplToDeviceCoor(B3dTransformationSet* pSet) +{ + if(pSet && !bDeviceCoor) + { + const Vector3D& rScale = pSet->GetScale(); + const Vector3D& rTrans = pSet->GetTranslate(); + + aPoint.Homogenize(); + aPoint[0] = (aPoint[0] * rScale[0]) + rTrans[0]; + aPoint[1] = (aPoint[1] * rScale[1]) + rTrans[1]; + aPoint[2] = (aPoint[2] * rScale[2]) + rTrans[2]; + + bDeviceCoor = TRUE; + } +} + +/************************************************************************* +|* +|* aus Device Koordinaten des Punktes 3D Koor im canonical view volume +|* berechnen +|* +\************************************************************************/ + +void B3dEntity::ImplTo3DCoor(B3dTransformationSet* pSet) +{ + if(pSet && bDeviceCoor) + { + const Vector3D& rScale = pSet->GetScale(); + const Vector3D& rTrans = pSet->GetTranslate(); + + aPoint.Homogenize(); + if(rScale[0] != 0.0) + aPoint[0] = (aPoint[0] - rTrans[0]) / rScale[0]; + if(rScale[1] != 0.0) + aPoint[1] = (aPoint[1] - rTrans[1]) / rScale[1]; + if(rScale[2] != 0.0) + aPoint[2] = (aPoint[2] - rTrans[2]) / rScale[2]; + + bDeviceCoor = FALSE; + } +} + +/************************************************************************* +|* +|* Garantiere eine gemeinsame Datenbasis (ClipKoordinaten oder +|* Devicekoordinaten) +|* +\************************************************************************/ + +void B3dEntity::ForceEqualBase(B3dTransformationSet* pSet, B3dEntity& rOld) +{ + if(IsDeviceCoor() && rOld.IsDeviceCoor()) + { + SetDeviceCoor(); + } + else + { + if(IsDeviceCoor()) + To3DCoor(pSet); + if(rOld.IsDeviceCoor()) + rOld.To3DCoor(pSet); + } +} + +/************************************************************************* +|* +|* Garantiere eine gemeinsame Datenbasis (ClipKoordinaten oder +|* Devicekoordinaten) +|* +\************************************************************************/ + +void B3dEntity::ForceEqualBase(B3dTransformationSet* pSet, B3dEntity& rOld1, + B3dEntity& rOld2) +{ + if(!IsDeviceCoor() && rOld1.IsDeviceCoor() && rOld2.IsDeviceCoor()) + { + if(IsDeviceCoor()) + To3DCoor(pSet); + if(rOld1.IsDeviceCoor()) + rOld1.To3DCoor(pSet); + if(rOld2.IsDeviceCoor()) + rOld2.To3DCoor(pSet); + } +} + +/************************************************************************* +|* +|* Neuen Punkt an der stelle t des parametrisierten Vektors rOld1, rOld2 +|* berechnen und fuellen +|* +\************************************************************************/ + +void B3dEntity::CalcInBetween(B3dEntity& rOld1, B3dEntity& rOld2, double t) +{ + // DeviceCoor der ersten Quelle benutzen, die Basis sollte + // vorher abgeglichen sein + SetDeviceCoor(rOld1.IsDeviceCoor()); + + // Punktkoordinaten berechnen + aPoint.CalcInBetween(rOld1.Point(), rOld2.Point(), t); + SetValid(); + + // PlaneNormal Koordinaten berechnen + rOld1.PlaneNormal().Normalize(); + rOld2.PlaneNormal().Normalize(); + aPlaneNormal.CalcInBetween(rOld1.PlaneNormal(), rOld2.PlaneNormal(), t); + aPlaneNormal.Normalize(); + + // Vektor berechnen + if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed()) + { + rOld1.Normal().Normalize(); + rOld2.Normal().Normalize(); + aNormal.CalcInBetween(rOld1.Normal(), rOld2.Normal(), t); + aNormal.Normalize(); + SetNormalUsed(); + } + + // Texturkoordinaten berechnen + if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed()) + { + aTexCoor.CalcInBetween(rOld1.TexCoor(), rOld2.TexCoor(), t); + SetTexCoorUsed(); + } + + // EdgeVisible berechnen + SetEdgeVisible(rOld1.IsEdgeVisible()); + + // Farbe berechnen + aColor.CalcInBetween(rOld1.Color(), rOld2.Color(), t); +} + +/************************************************************************* +|* +|* Neuen Punkt in der Mitte des parametrisierten Vektors rOld1, rOld2 +|* berechnen und fuellen +|* +\************************************************************************/ + +void B3dEntity::CalcMiddle(B3dEntity& rOld1, B3dEntity& rOld2) +{ + // DeviceCoor der ersten Quelle benutzen, die Basis sollte + // vorher abgeglichen sein + SetDeviceCoor(rOld1.IsDeviceCoor()); + + // Punktkoordinaten berechnen + aPoint.CalcMiddle(rOld1.Point(), rOld2.Point()); + SetValid(); + + // PlaneNormal Koordinaten berechnen + rOld1.PlaneNormal().Normalize(); + rOld2.PlaneNormal().Normalize(); + aPlaneNormal.CalcMiddle(rOld1.PlaneNormal(), rOld2.PlaneNormal()); + aPlaneNormal.Normalize(); + + // Vektor berechnen + if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed()) + { + rOld1.Normal().Normalize(); + rOld2.Normal().Normalize(); + aNormal.CalcMiddle(rOld1.Normal(), rOld2.Normal()); + aNormal.Normalize(); + SetNormalUsed(); + } + + // Texturkoordinaten berechnen + if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed()) + { + aTexCoor.CalcMiddle(rOld1.TexCoor(), rOld2.TexCoor()); + SetTexCoorUsed(); + } + + // EdgeVisible berechnen + SetEdgeVisible(rOld1.IsEdgeVisible()); + + // Farbe berechnen + aColor.CalcMiddle(rOld1.Color(), rOld2.Color()); +} + +/************************************************************************* +|* +|* Neuen Punkt in der Mitte des Dreiecks rOld1, rOld2, rOld3 +|* berechnen und fuellen +|* +\************************************************************************/ + +void B3dEntity::CalcMiddle(B3dEntity& rOld1, B3dEntity& rOld2, + B3dEntity& rOld3) +{ + // DeviceCoor der ersten Quelle benutzen, die Basis sollte + // vorher abgeglichen sein + SetDeviceCoor(rOld1.IsDeviceCoor()); + + // Punktkoordinaten berechnen + aPoint.CalcMiddle(rOld1.Point(), rOld2.Point(), rOld3.Point()); + SetValid(); + + // PlaneNormal Koordinaten berechnen + rOld1.PlaneNormal().Normalize(); + rOld2.PlaneNormal().Normalize(); + rOld3.PlaneNormal().Normalize(); + aPlaneNormal.CalcMiddle(rOld1.PlaneNormal(), rOld2.PlaneNormal(), rOld3.PlaneNormal()); + aPlaneNormal.Normalize(); + + // Vektor berechnen + if(rOld1.IsNormalUsed() && rOld2.IsNormalUsed() && rOld3.IsNormalUsed()) + { + rOld1.Normal().Normalize(); + rOld2.Normal().Normalize(); + rOld3.Normal().Normalize(); + aNormal.CalcMiddle(rOld1.Normal(), rOld2.Normal(), rOld3.Normal()); + aNormal.Normalize(); + SetNormalUsed(); + } + + // Texturkoordinaten berechnen + if(rOld1.IsTexCoorUsed() && rOld2.IsTexCoorUsed() && rOld3.IsTexCoorUsed()) + { + aTexCoor.CalcMiddle(rOld1.TexCoor(), rOld2.TexCoor(), rOld3.TexCoor()); + SetTexCoorUsed(); + } + + // Farbe berechnen + aColor.CalcMiddle(rOld1.Color(), rOld2.Color(), rOld3.Color()); +} + +/************************************************************************* +|* +|* Eine beliebige Transformation auf die Geometrie anwenden +|* +\************************************************************************/ + +void B3dEntity::Transform(const Matrix4D& rMat) +{ + aPoint *= rMat; + if(bNormalUsed) + rMat.RotateAndNormalize(aNormal); +} + +/************************************************************************* +|* +|* Bucket fuer geometrische Daten +|* +\************************************************************************/ + +BASE3D_IMPL_BUCKET(B3dEntity, Bucket) + + diff --git a/goodies/source/base3d/b3dgeom.cxx b/goodies/source/base3d/b3dgeom.cxx new file mode 100644 index 000000000000..a9f4c271a506 --- /dev/null +++ b/goodies/source/base3d/b3dgeom.cxx @@ -0,0 +1,982 @@ +/************************************************************************* + * + * $RCSfile: b3dgeom.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DGEOM_HXX +#include "b3dgeom.hxx" +#endif + +#ifndef _B3D_B3DCOMPO_HXX +#include "b3dcompo.hxx" +#endif + +#ifndef _B3D_HMATRIX_HXX +#include "hmatrix.hxx" +#endif + +#ifndef _B3D_BASE3D_HXX +#include "base3d.hxx" +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _INC_MATH +#include <math.h> +#endif + +/************************************************************************* +|* +|* Bucket fuer Index +|* +\************************************************************************/ + +BASE3D_IMPL_BUCKET(GeometryIndexValue, Bucket) + +/************************************************************************* +|* +|* Konstruktor +|* +\************************************************************************/ + +B3dGeometry::B3dGeometry() +: pComplexPolygon(NULL), + aEntityBucket(14), // 16K + aIndexBucket(8) // 256Byte +{ + Reset(); +} + +/************************************************************************* +|* +|* Ausgangszustand der Variablen herstellen +|* +\************************************************************************/ + +void B3dGeometry::Reset() +{ + bHintIsComplex = FALSE; + if(pComplexPolygon) + delete pComplexPolygon; + pComplexPolygon = NULL; +} + +/************************************************************************* +|* +|* Freien Eintrag zum fuellen holen +|* +\************************************************************************/ + +B3dEntity& B3dGeometry::GetFreeEntity() +{ + aEntityBucket.Append(); + return aEntityBucket[aEntityBucket.Count() - 1]; +} + +/************************************************************************* +|* +|* Inhalte loeschen +|* +\************************************************************************/ + +void B3dGeometry::Erase() +{ + aEntityBucket.Erase(); + aIndexBucket.Erase(); + Reset(); +} + +/************************************************************************* +|* +|* Inhalte loeschen und Speicher freigeben +|* +\************************************************************************/ + +void B3dGeometry::Empty() +{ + aEntityBucket.Empty(); + aIndexBucket.Empty(); + Reset(); +} + +/************************************************************************* +|* +|* Start der Geometriebeschreibung +|* +\************************************************************************/ + +void B3dGeometry::StartDescription() +{ + Erase(); +} + +/************************************************************************* +|* +|* Ende der Geometriebeschreibung +|* +\************************************************************************/ + +void B3dGeometry::EndDescription() +{ + if(pComplexPolygon) + delete pComplexPolygon; + pComplexPolygon = NULL; +} + +/************************************************************************* +|* +|* Neues Primitiv beginnen +|* +\************************************************************************/ + +void B3dGeometry::StartObject(BOOL bHintComplex, BOOL bOutl) +{ + // Hint uebernehmen + bHintIsComplex = bHintComplex; + bOutline = bOutl; + + // ComplexPolygon anlegen falls nicht vorhanden + if(bHintIsComplex) + { + if(!pComplexPolygon) + pComplexPolygon = new B3dComplexPolygon; + pComplexPolygon->StartPrimitive(); + } + else + { + // Direkt neues Polygon beginnen + StartPolygon(); + } +} + +/************************************************************************* +|* +|* Primitiv abschliessen +|* +\************************************************************************/ + +void B3dGeometry::EndObject() +{ + // Unteren Index holen + UINT32 nLow = 0L; + if(aIndexBucket.Count()) + nLow = aIndexBucket[aIndexBucket.Count()-1].GetIndex(); + + if(bHintIsComplex) + { + pComplexPolygon->EndPrimitive(this); + } + else + { + // Polygon abschliessen + EndPolygon(); + } + + // EbenenNormale berechnen und setzen; bei Linien und + // Punkten wird PlaneNormal auf (0,0,0) gesetzt + UINT32 nHigh = aIndexBucket[aIndexBucket.Count()-1].GetIndex(); + Vector3D aPlaneNormal = -CalcNormal(nLow, nHigh); + while(nLow < nHigh) + aEntityBucket[nLow++].PlaneNormal() = aPlaneNormal; +} + +/************************************************************************* +|* +|* Geometrieuebergabe +|* +\************************************************************************/ + +void B3dGeometry::AddEdge(const Vector3D& rPoint) +{ + if(bHintIsComplex) + { + B3dEntity& rNew = pComplexPolygon->GetFreeEntity(); + + rNew.Reset(); + rNew.Point() = rPoint; + rNew.SetValid(); + rNew.SetEdgeVisible(TRUE); + + pComplexPolygon->PostAddVertex(rNew); + } + else + { + B3dEntity& rNew = GetFreeEntity(); + + rNew.Reset(); + rNew.Point() = rPoint; + rNew.SetValid(); + rNew.SetEdgeVisible(TRUE); + } +} + +void B3dGeometry::AddEdge( + const Vector3D& rPoint, + const Vector3D& rNormal) +{ + if(bHintIsComplex) + { + B3dEntity& rNew = pComplexPolygon->GetFreeEntity(); + + rNew.Reset(); + rNew.Point() = rPoint; + rNew.SetValid(); + rNew.Normal() = rNormal; + rNew.SetNormalUsed(); + rNew.SetEdgeVisible(TRUE); + + pComplexPolygon->PostAddVertex(rNew); + } + else + { + B3dEntity& rNew = GetFreeEntity(); + + rNew.Reset(); + rNew.Point() = rPoint; + rNew.SetValid(); + rNew.Normal() = rNormal; + rNew.SetNormalUsed(); + rNew.SetEdgeVisible(TRUE); + } +} + +void B3dGeometry::AddEdge( + const Vector3D& rPoint, + const Vector3D& rNormal, + const Vector3D& rTexture) +{ + if(bHintIsComplex) + { + B3dEntity& rNew = pComplexPolygon->GetFreeEntity(); + + rNew.Reset(); + rNew.Point() = rPoint; + rNew.SetValid(); + rNew.Normal() = rNormal; + rNew.SetNormalUsed(); + rNew.TexCoor() = rTexture; + rNew.SetTexCoorUsed(); + rNew.SetEdgeVisible(TRUE); + + pComplexPolygon->PostAddVertex(rNew); + } + else + { + B3dEntity& rNew = GetFreeEntity(); + + rNew.Reset(); + rNew.Point() = rPoint; + rNew.SetValid(); + rNew.Normal() = rNormal; + rNew.SetNormalUsed(); + rNew.TexCoor() = rTexture; + rNew.SetTexCoorUsed(); + rNew.SetEdgeVisible(TRUE); + } +} + +/************************************************************************* +|* +|* Copy-Operator +|* +\************************************************************************/ + +void B3dGeometry::operator=(const B3dGeometry& rObj) +{ + // Bucket kopieren + aEntityBucket = rObj.aEntityBucket; + aIndexBucket = rObj.aIndexBucket; + + // ComplexPolygon nicht kopieren + pComplexPolygon = NULL; + + // Hint auch nicht + bHintIsComplex = FALSE; +} + +/************************************************************************* +|* +|* Callbacks bei komplexen Primitiven +|* +\************************************************************************/ + +void B3dGeometry::StartComplexPrimitive() +{ + StartPolygon(); +} + +void B3dGeometry::EndComplexPrimitive() +{ + EndPolygon(); +} + +void B3dGeometry::AddComplexVertex(B3dEntity& rNew, BOOL bIsVisible) +{ + // Kopieren + B3dEntity& rLocal = GetFreeEntity(); + rLocal = rNew; + + // EdgeFlag anpassen + rLocal.SetEdgeVisible(bIsVisible); +} + +/************************************************************************* +|* +|* PolygonStart und -Ende aufzeichnen +|* +\************************************************************************/ + +void B3dGeometry::StartPolygon() +{ +} + +void B3dGeometry::EndPolygon() +{ + GeometryIndexValue aNewIndex(aEntityBucket.Count()); + if(bOutline) + aNewIndex.SetMode(B3D_INDEX_MODE_LINE); + aIndexBucket.Append(aNewIndex); +} + +/************************************************************************* +|* +|* Eine beliebige Transformation auf die Geometrie anwenden +|* +\************************************************************************/ + +void B3dGeometry::Transform(const Matrix4D& rMat) +{ + for(UINT32 a=0;a<aEntityBucket.Count();a++) + aEntityBucket[a].Transform(rMat); +} + +/************************************************************************* +|* +|* Hittest auf Geometrie +|* Liegt der angegebene Schnittpunkt innerhalb eines der Polygone? +|* +\************************************************************************/ + +INT32 B3dGeometry::CheckHit(const Vector3D& rFront, const Vector3D& rBack, USHORT nTol) +{ + UINT32 nPolyCounter = 0; + UINT32 nEntityCounter = 0; + UINT32 nUpperBound; + INT32 nRetval; + + while(nPolyCounter < aIndexBucket.Count()) + { + // Obergrenze neues Polygon holen + nUpperBound = aIndexBucket[nPolyCounter++].GetIndex(); + + // Hittest fuer momentanes Polygon + nRetval = CheckSinglePolygonHit(nEntityCounter, nUpperBound, rFront, rBack); + if(nRetval != -1L) + return nRetval; + + // Auf naechstes Polygon + nEntityCounter = nUpperBound; + } + return nRetval; +} + +INT32 B3dGeometry::CheckSinglePolygonHit(UINT32 nLow, UINT32 nHigh, const Vector3D& rFront, const Vector3D& rBack) +{ + if(nLow + 2 < nHigh) + { + // Schnittpunkt berechnen + Vector3D aCut; + if(GetCutPoint(nLow, aCut, rFront, rBack)) + { + // Schnittpunkt existiert, liegt dieser im angegebenen + // konvexen Polygon? + if(IsInside(nLow, nHigh, aCut)) + { + return ((INT32)(aCut.Z() + 0.5)); + } + } + } + return -1L; +} + +BOOL B3dGeometry::GetCutPoint(UINT32 nLow, Vector3D& rCut, const Vector3D& rFront, const Vector3D& rBack) +{ + BOOL bCutValid = FALSE; + + // Normale und Skalar der Ebenengleichung ermitteln + Vector3D aNormal = aEntityBucket[nLow].PlaneNormal(); + double fScalar = -(aEntityBucket[nLow + 1].Point().GetVector3D().Scalar(aNormal)); + Vector3D aLineVec = rFront - rBack; + double fZwi = aNormal.Scalar(aLineVec); + + if(fabs(fZwi) > SMALL_DVALUE) + { + fZwi = (-fScalar - (rBack.Scalar(aNormal))) / fZwi; +// if(fZwi > SMALL_DVALUE && fZwi < 1.0 - SMALL_DVALUE) +// { + rCut.X() = rBack.X() + (aLineVec.X() * fZwi); + rCut.Y() = rBack.Y() + (aLineVec.Y() * fZwi); + rCut.Z() = rBack.Z() + (aLineVec.Z() * fZwi); + + bCutValid = TRUE; +// } + } + return bCutValid; +} + +BOOL B3dGeometry::IsInside(UINT32 nLow, UINT32 nHigh, const Vector3D& rPnt) +{ + BOOL bInside(FALSE); + B3dVolume aVolume; + + // Volume von genau dieser Flaeche feststellen + for(UINT32 a=nLow;a<nHigh;a++) + aVolume.Union(aEntityBucket[a].Point().GetVector3D()); + + // Hier eigentlich ein aVolume.IsInside(rPnt), doch da hier ein + // Vergleich mit Epsilon-Umgebung gebraucht wird, vergleiche selbst + BOOL bIsInside = + (rPnt.X() + SMALL_DVALUE >= aVolume.MinVec().X() && rPnt.X() - SMALL_DVALUE <= aVolume.MaxVec().X() + && rPnt.Y() + SMALL_DVALUE >= aVolume.MinVec().Y() && rPnt.Y() - SMALL_DVALUE <= aVolume.MaxVec().Y() + && rPnt.Z() + SMALL_DVALUE >= aVolume.MinVec().Z() && rPnt.Z() - SMALL_DVALUE <= aVolume.MaxVec().Z()); + + if(bIsInside) + { + BOOL bInsideXY(FALSE); + BOOL bInsideXZ(FALSE); + BOOL bInsideYZ(FALSE); + const Vector3D* pPrev = &(aEntityBucket[nHigh - 1].Point().GetVector3D()); + const Vector3D* pActual; + Vector3D aDiffPrev, aDiffActual; + + while(nLow < nHigh) + { + // Neuen Punkt holen + pActual = &(aEntityBucket[nLow++].Point().GetVector3D()); + + // Diffs bilden + aDiffPrev = *pPrev - rPnt; + aDiffActual = *pActual - rPnt; + + // Ueberschneidung in Y moeglich? + if((aDiffPrev.Y() > 0.0 && aDiffActual.Y() <= 0.0) || (aDiffActual.Y() > 0.0 && aDiffPrev.Y() <= 0.0)) + { + // in welchem Bereich liegt X? + if(aDiffPrev.X() >= 0.0 && aDiffActual.X() >= 0.0) + { + // Ueberschneidung + bInsideXY = !bInsideXY; + } + else if((aDiffPrev.X() > 0.0 && aDiffActual.X() <= 0.0) || (aDiffActual.X() > 0.0 && aDiffPrev.X() <= 0.0)) + { + // eventuell Ueberschneidung + // wo liegt die X-Koordinate des Schnitts mit der X-Achse? + if(aDiffActual.Y() != aDiffPrev.Y()) + if(aDiffPrev.X() - ((aDiffPrev.Y() * (aDiffActual.X() - aDiffPrev.X())) / (aDiffActual.Y() - aDiffPrev.Y())) >= 0.0) + // Ueberschneidung + bInsideXY = !bInsideXY; + } + + // in welchem Bereich liegt Z? + if(aDiffPrev.Z() >= 0.0 && aDiffActual.Z() >= 0.0) + { + // Ueberschneidung + bInsideYZ = !bInsideYZ; + } + else if((aDiffPrev.Z() > 0.0 && aDiffActual.Z() <= 0.0) || (aDiffActual.Z() > 0.0 && aDiffPrev.Z() <= 0.0)) + { + // eventuell Ueberschneidung + // wo liegt die X-Koordinate des Schnitts mit der X-Achse? + if(aDiffActual.Y() != aDiffPrev.Y()) + if(aDiffPrev.Z() - ((aDiffPrev.Y() * (aDiffActual.Z() - aDiffPrev.Z())) / (aDiffActual.Y() - aDiffPrev.Y())) >= 0.0) + // Ueberschneidung + bInsideYZ = !bInsideYZ; + } + } + + // Ueberschneidung in X moeglich? + if((aDiffPrev.X() > 0.0 && aDiffActual.X() <= 0.0) || (aDiffActual.X() > 0.0 && aDiffPrev.X() <= 0.0)) + { + // in welchem Bereich liegt Z? + if(aDiffPrev.Z() >= 0.0 && aDiffActual.Z() >= 0.0) + { + // Ueberschneidung + bInsideXZ = !bInsideXZ; + } + else if((aDiffPrev.Z() > 0.0 && aDiffActual.Z() <= 0.0) || (aDiffActual.Z() > 0.0 && aDiffPrev.Z() <= 0.0)) + { + // eventuell Ueberschneidung + // wo liegt die X-Koordinate des Schnitts mit der X-Achse? + if(aDiffActual.X() != aDiffPrev.X()) + if(aDiffPrev.Z() - ((aDiffPrev.X() * (aDiffActual.Z() - aDiffPrev.Z())) / (aDiffActual.X() - aDiffPrev.X())) >= 0.0) + // Ueberschneidung + bInsideXZ = !bInsideXZ; + } + } + + // Punkt als Vorgaenger merken + pPrev = pActual; + } + // Wahrheitswert bilden + bInside = bInsideXY || bInsideXZ || bInsideYZ; + } + return bInside; +} + +/************************************************************************* +|* +|* BoundVolume liefern +|* +\************************************************************************/ + +B3dVolume B3dGeometry::GetBoundVolume() +{ + B3dVolume aRetval; + + for(UINT32 a=0;a<aEntityBucket.Count();a++) + aRetval.Union(aEntityBucket[a].Point().GetVector3D()); + + return aRetval; +} + +/************************************************************************* +|* +|* Mittelpunkt liefern +|* +\************************************************************************/ + +Vector3D B3dGeometry::GetCenter() +{ + B3dVolume aVolume = GetBoundVolume(); + return (aVolume.MaxVec() + aVolume.MinVec()) / 2.0; +} + +/************************************************************************* +|* +|* Standard - Normalen generieren +|* +\************************************************************************/ + +void B3dGeometry::CreateDefaultNormalsSphere() +{ + // Alle Normalen ausgehend vom Zentrum der Geometrie bilden + Vector3D aCenter = GetCenter(); + + for(UINT32 a=0;a<aEntityBucket.Count();a++) + { + const Vector3D& aPoint = aEntityBucket[a].Point().GetVector3D(); + Vector3D aNewNormal = aPoint - aCenter; + aNewNormal.Normalize(); + aEntityBucket[a].Normal() = aNewNormal; + aEntityBucket[a].SetNormalUsed(TRUE); + } +} + +/************************************************************************* +|* +|* Normale ermitteln fuer einzelnes Polygon +|* +\************************************************************************/ + +Vector3D B3dGeometry::CalcNormal(UINT32 nLow, UINT32 nHigh) +{ + const Vector3D* pVec1 = NULL; + const Vector3D* pVec2 = NULL; + const Vector3D* pVec3 = NULL; + Vector3D aNormal; + + while(nLow < nHigh && !(pVec1 && pVec2 && pVec3)) + { + if(!pVec1) + { + pVec1 = &(aEntityBucket[nLow++].Point().GetVector3D()); + } + else if(!pVec2) + { + pVec2 = &(aEntityBucket[nLow++].Point().GetVector3D()); + if(*pVec2 == *pVec1) + pVec2 = NULL; + } + else if(!pVec3) + { + pVec3 = &(aEntityBucket[nLow++].Point().GetVector3D()); + if(*pVec3 == *pVec2 || pVec3 == pVec1) + pVec3 = NULL; + } + } + if(pVec1 && pVec2 && pVec3) + { + aNormal = (*pVec2 - *pVec1)|(*pVec2 - *pVec3); + aNormal.Normalize(); + } + return aNormal; +} + +/************************************************************************* +|* +|* Normaleninformationen ungueltig machen +|* +\************************************************************************/ + +void B3dGeometry::RemoveNormals() +{ + for(UINT32 a=0;a<aEntityBucket.Count();a++) + aEntityBucket[a].SetNormalUsed(FALSE); +} + +/************************************************************************* +|* +|* Standard - Texturkoordinaten generieren +|* +\************************************************************************/ + +void B3dGeometry::CreateDefaultTexture(UINT16 nCreateWhat, BOOL bUseSphere) +{ + if(nCreateWhat) + { + if(bUseSphere) + { + // Texturkoordinaten mittels Kugelprojektion ermitteln, + // dazu das Zentrum der Geometrie benutzen + // Alle Normalen ausgehend vom Zentrum der Geometrie bilden + Vector3D aCenter = GetCenter(); + UINT32 nPointCounter = 0; + + for(UINT32 a=0;a<aIndexBucket.Count();a++) + { + // Lokales Zentrum der zu behandelnden Flaeche bilden, + // um zu wissen von welcher Seite sich diese Flaeche + // dem Winkel F_PI bzw. -F_PI naehert + Vector3D aLocalCenter; + for(UINT32 b=nPointCounter;b<aIndexBucket[a].GetIndex();b++) + aLocalCenter += aEntityBucket[b].Point().GetVector3D(); + aLocalCenter /= aIndexBucket[a].GetIndex() - nPointCounter; + + // Vektor vom Mittelpunkt zum lokalen Zentrum bilden + aLocalCenter = aLocalCenter - aCenter; + if(fabs(aLocalCenter.X()) < SMALL_DVALUE) + aLocalCenter.X() = 0.0; + if(fabs(aLocalCenter.Y()) < SMALL_DVALUE) + aLocalCenter.Y() = 0.0; + if(fabs(aLocalCenter.Z()) < SMALL_DVALUE) + aLocalCenter.Z() = 0.0; + + // X,Y fuer das lokale Zentrum bilden + double fXCenter = atan2(aLocalCenter.Z(), aLocalCenter.X()); + double fYCenter = atan2(aLocalCenter.Y(), aLocalCenter.GetXZLength()); + fXCenter = 1.0 - ((fXCenter + F_PI) / F_2PI); + fYCenter = 1.0 - ((fYCenter + F_PI2) / F_PI); + + // Einzelne Punkte behandeln + UINT32 nRememberPointCounter = nPointCounter; + while(nPointCounter < aIndexBucket[a].GetIndex()) + { + // Vektor vom Mittelpunkt zum Punkt bilden + const Vector3D& aPoint = aEntityBucket[nPointCounter].Point().GetVector3D(); + Vector3D aDirection = aPoint - aCenter; + if(fabs(aDirection.X()) < SMALL_DVALUE) + aDirection.X() = 0.0; + if(fabs(aDirection.Y()) < SMALL_DVALUE) + aDirection.Y() = 0.0; + if(fabs(aDirection.Z()) < SMALL_DVALUE) + aDirection.Z() = 0.0; + + // X,Y fuer Punkt bilden + double fXPoint = atan2(aDirection.Z(), aDirection.X()); + double fYPoint = atan2(aDirection.Y(), aDirection.GetXZLength()); + fXPoint = 1.0 - ((fXPoint + F_PI) / F_2PI); + fYPoint = 1.0 - ((fYPoint + F_PI2) / F_PI); + + // X,Y des Punktes korrigieren + if(fXPoint > fXCenter + 0.5) + fXPoint -= 1.0; + if(fXPoint < fXCenter - 0.5) + fXPoint += 1.0; + + // Polarkoordinaten als Texturkoordinaten zuweisen + if(nCreateWhat & B3D_CREATE_DEFAULT_X) + aEntityBucket[nPointCounter].TexCoor().X() = fXPoint; + if(nCreateWhat & B3D_CREATE_DEFAULT_Y) + aEntityBucket[nPointCounter].TexCoor().Y() = fYPoint; + if(nCreateWhat & B3D_CREATE_DEFAULT_Z) + aEntityBucket[nPointCounter].TexCoor().Z() = 0.0; + + aEntityBucket[nPointCounter++].SetTexCoorUsed(TRUE); + } + + // Punkte korrigieren, die direkt in den Polarregionen liegen. Deren + // X-Koordinate kann nicht korrekt sein. Die korrekte X-Koordinate + // ist diejenige des Punktes, der in den Pol hinein oder aus diesem heraus + // fuehrt, auf der Kugel also direkt darauf zu. + if(nCreateWhat & B3D_CREATE_DEFAULT_X) + { + nPointCounter = nRememberPointCounter; + while(nPointCounter < aIndexBucket[a].GetIndex()) + { + Vector3D& aCoor = aEntityBucket[nPointCounter].TexCoor(); + if(fabs(aCoor.Y()) < SMALL_DVALUE || fabs(aCoor.Y() - 1.0) < SMALL_DVALUE) + { + // Nachfolger finden + UINT32 nNextIndex = (nPointCounter + 1 < aIndexBucket[a].GetIndex()) + ? nPointCounter + 1 : nRememberPointCounter; + Vector3D& aNextCoor = aEntityBucket[nNextIndex].TexCoor(); + + // Vorgaenger finden + UINT32 nPrevIndex = (nPointCounter && nPointCounter - 1 >= nRememberPointCounter) + ? nPointCounter - 1 : aIndexBucket[a].GetIndex() - 1; + Vector3D& aPrevCoor = aEntityBucket[nPrevIndex].TexCoor(); + + // Nachfolger testen: Liegt dieser ausserhalb des Pols? + if(fabs(aNextCoor.Y()) > SMALL_DVALUE && fabs(aNextCoor.Y() - 1.0) > SMALL_DVALUE) + { + // falls ja: X-Koordinate uebernehmen + aCoor.X() = aNextCoor.X(); + } + // Vorgaenger testen: Liegt dieser ausserhalb des Pols? + else if(fabs(aPrevCoor.Y()) > SMALL_DVALUE && fabs(aPrevCoor.Y() - 1.0) > SMALL_DVALUE) + { + // falls ja, X-Koordinate uebernehmen + aCoor.X() = aPrevCoor.X(); + } + else + { + // Weder Vorgaenger noch Nachfolger liegen ausserhalb des Pols. + // Uebernimm daher wenigstens den bereits korrigierten X-Wert + // des Vorgaengers + aCoor.X() = aPrevCoor.X(); + } + } + // naechster Punkt + nPointCounter++; + } + } + } + } + else + { + // Texturkoordinaten als Parallelprojektion auf X,Y,Z - Koordinaten + // im Bereich 1.0 bis 0.0 der Geometrie abstellen + // Gesamtabmessungen holen + B3dVolume aVolume = GetBoundVolume(); + + for(UINT32 a=0;a<aEntityBucket.Count();a++) + { + const Vector3D& aPoint = aEntityBucket[a].Point().GetVector3D(); + + if(nCreateWhat & B3D_CREATE_DEFAULT_X) + { + if(aVolume.GetWidth()) + aEntityBucket[a].TexCoor().X() = (aPoint.X() - aVolume.MinVec().X()) / aVolume.GetWidth(); + else + aEntityBucket[a].TexCoor().X() = 0.0; + } + + if(nCreateWhat & B3D_CREATE_DEFAULT_Y) + { + if(aVolume.GetHeight()) + aEntityBucket[a].TexCoor().Y() = 1.0 - ((aPoint.Y() - aVolume.MinVec().Y()) / aVolume.GetHeight()); + else + aEntityBucket[a].TexCoor().Y() = 1.0; + } + + if(nCreateWhat & B3D_CREATE_DEFAULT_Z) + aEntityBucket[a].TexCoor().Z() = 0.0; + + aEntityBucket[a].SetTexCoorUsed(TRUE); + } + } + } +} + +/************************************************************************* +|* +|* Texturinformationen ungueltig machen +|* +\************************************************************************/ + +void B3dGeometry::RemoveTexture() +{ + for(UINT32 a=0;a<aEntityBucket.Count();a++) + aEntityBucket[a].SetTexCoorUsed(FALSE); +} + +/************************************************************************* +|* +|* Default-Geometrien erstellen +|* +\************************************************************************/ + +void B3dGeometry::CreateCube(const B3dVolume& rVolume) +{ + Erase(); + StartDescription(); + Vector3D A(rVolume.MinVec().X(), rVolume.MaxVec().Y(), rVolume.MinVec().Z()); + Vector3D B(rVolume.MaxVec().X(), rVolume.MaxVec().Y(), rVolume.MinVec().Z()); + Vector3D C(rVolume.MaxVec().X(), rVolume.MinVec().Y(), rVolume.MinVec().Z()); + Vector3D D(rVolume.MinVec().X(), rVolume.MinVec().Y(), rVolume.MinVec().Z()); + Vector3D E(rVolume.MinVec().X(), rVolume.MaxVec().Y(), rVolume.MaxVec().Z()); + Vector3D F(rVolume.MaxVec().X(), rVolume.MaxVec().Y(), rVolume.MaxVec().Z()); + Vector3D G(rVolume.MaxVec().X(), rVolume.MinVec().Y(), rVolume.MaxVec().Z()); + Vector3D H(rVolume.MinVec().X(), rVolume.MinVec().Y(), rVolume.MaxVec().Z()); + StartObject(FALSE); + AddEdge(A); + AddEdge(B); + AddEdge(C); + AddEdge(D); + EndObject(); + StartObject(FALSE); + AddEdge(A); + AddEdge(E); + AddEdge(F); + AddEdge(B); + EndObject(); + StartObject(FALSE); + AddEdge(B); + AddEdge(F); + AddEdge(G); + AddEdge(C); + EndObject(); + StartObject(FALSE); + AddEdge(C); + AddEdge(G); + AddEdge(H); + AddEdge(D); + EndObject(); + StartObject(FALSE); + AddEdge(D); + AddEdge(H); + AddEdge(E); + AddEdge(A); + EndObject(); + StartObject(FALSE); + AddEdge(E); + AddEdge(H); + AddEdge(G); + AddEdge(F); + EndObject(); + EndDescription(); + CreateDefaultNormalsSphere(); + CreateDefaultTexture(B3D_CREATE_DEFAULT_ALL, FALSE); +} + +void B3dGeometry::CreateSphere(const B3dVolume& rVolume, double fX, double fY) +{ + Erase(); + StartDescription(); + Vector3D A,B,C,D; + double fXInc, fYInc; + if(fX == 0.0) + fX = 4.0; + fXInc = F_2PI / fX; + if(fY == 0.0) + fY = 4.0; + fYInc = F_PI / fY; + UINT16 nX = (UINT16)fX; + UINT16 nY = (UINT16)fY; + fX = 0.0; + for(UINT16 a=0;a<nX;a++,fX+=fXInc) + { + fY = -F_PI2; + for(UINT16 b=0;b<nY;b++,fY+=fYInc) + { + A.Y() = B.Y() = sin(fY+fYInc); + D.Y() = C.Y() = sin(fY); + A.X() = cos(fX) * cos(fY+fYInc); + D.X() = cos(fX) * cos(fY); + B.X() = cos(fX+fXInc) * cos(fY+fYInc); + C.X() = cos(fX+fXInc) * cos(fY); + A.Z() = sin(fX) * cos(fY+fYInc); + D.Z() = sin(fX) * cos(fY); + B.Z() = sin(fX+fXInc) * cos(fY+fYInc); + C.Z() = sin(fX+fXInc) * cos(fY); + StartObject(FALSE); + AddEdge(A); + AddEdge(B); + AddEdge(C); + AddEdge(D); + EndObject(); + } + } + EndDescription(); + CreateDefaultNormalsSphere(); + CreateDefaultTexture(B3D_CREATE_DEFAULT_ALL, TRUE); + Matrix4D aTransform; + aTransform.Translate(Vector3D(1.0, 1.0, 1.0)); + aTransform.Scale( + (rVolume.MaxVec().X() - rVolume.MinVec().X())/2.0, + (rVolume.MaxVec().Y() - rVolume.MinVec().Y())/2.0, + (rVolume.MaxVec().Z() - rVolume.MinVec().Z())/2.0); + aTransform.Translate(rVolume.MinVec()); + Transform(aTransform); +} + +/************************************************************************* +|* +|* Normalen invertieren +|* +\************************************************************************/ + +void B3dGeometry::InvertNormals() +{ + for(UINT32 a=0;a<aEntityBucket.Count();a++) + aEntityBucket[a].Normal() = -aEntityBucket[a].Normal(); +} + diff --git a/goodies/source/base3d/b3dlight.cxx b/goodies/source/base3d/b3dlight.cxx new file mode 100644 index 000000000000..fdb5bc37192f --- /dev/null +++ b/goodies/source/base3d/b3dlight.cxx @@ -0,0 +1,870 @@ +/************************************************************************* + * + * $RCSfile: b3dlight.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DLIGHT_HXX +#include "b3dlight.hxx" +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +/************************************************************************* +|* +|* Konstruktor B3dLight +|* +\************************************************************************/ + +B3dLight::B3dLight() +{ +} + +/************************************************************************* +|* +|* Intensitaet einer bestimmten Lichtkomponente setzen +|* +\************************************************************************/ + +void B3dLight::SetIntensity(const Color rNew, Base3DMaterialValue eVal) +{ + switch(eVal) + { + case Base3DMaterialAmbient: + { + aAmbient = rNew; + if(rNew.GetRed() || rNew.GetGreen() || rNew.GetBlue()) + bIsAmbient = TRUE; + else + bIsAmbient = FALSE; + break; + } + case Base3DMaterialDiffuse: + { + aDiffuse = rNew; + if(rNew.GetRed() || rNew.GetGreen() || rNew.GetBlue()) + bIsDiffuse = TRUE; + else + bIsDiffuse = FALSE; + break; + } + default: + { + aSpecular = rNew; + if(rNew.GetRed() || rNew.GetGreen() || rNew.GetBlue()) + bIsSpecular = TRUE; + else + bIsSpecular = FALSE; + break; + } + } +} + +/************************************************************************* +|* +|* Intensitaet einer bestimmten Lichtkomponente lesen +|* +\************************************************************************/ + +const Color B3dLight::GetIntensity(Base3DMaterialValue eVal) +{ + switch(eVal) + { + case Base3DMaterialAmbient: + { + return aAmbient; + break; + } + case Base3DMaterialDiffuse: + { + return aDiffuse; + break; + } + default: + { + return aSpecular; + break; + } + } +} + +/************************************************************************* +|* +|* Lichtquelle initialisieren (selbe defaults wie OpenGL) +|* +\************************************************************************/ + +void B3dLight::Init() +{ + aAmbient = Color(255, 0, 0, 0); + if(IsFirst()) + { + aDiffuse = Color(255, 204, 204, 204); + aSpecular = Color(255, 255, 255, 255); + aPosition = Vector3D(1.0, 1.0, 1.0); + aPosition.Normalize(); + bIsDiffuse = TRUE; + bIsSpecular = TRUE; + bIsEnabled = TRUE; + } + else + { + aDiffuse = Color(0, 0, 0, 0); + aSpecular = Color(0, 0, 0, 0); + aPosition = Vector3D(0.0, 0.0, 1.0); + bIsDiffuse = FALSE; + bIsSpecular = FALSE; + bIsEnabled = FALSE; + } + aPositionEye = Vector3D(0.0, 0.0, 0.0); + aSpotDirection = Vector3D(0.0, 0.0, -1.0); + aSpotDirectionEye = Vector3D(0.0, 0.0, 0.0); + nSpotExponent = 0; + fSpotCutoff = 180.0; + fConstantAttenuation = 1.0; + fLinearAttenuation = 0.0; + fQuadraticAttenuation = 0.0; + bLinearOrQuadratic = FALSE; + bIsDirectionalSource = TRUE; + bIsSpot = FALSE; + bIsAmbient = FALSE; +} + +/************************************************************************* +|* +|* Richtung der Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLight::SetSpotDirection(const Vector3D& rNew) +{ + aSpotDirection=rNew; + aSpotDirection.Normalize(); +} + +/************************************************************************* +|* +|* Richtung der Lichtquelle in Augkoordinaten setzen +|* +\************************************************************************/ + +void B3dLight::SetSpotDirectionEye(const Vector3D& rNew) +{ + aSpotDirectionEye=rNew; + aSpotDirectionEye.Normalize(); +} + +/************************************************************************* +|* +|* Kegel der Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLight::SetSpotCutoff(double fNew) +{ + fSpotCutoff = fNew; + bIsSpot = (fNew == 180.0) ? FALSE : TRUE; + fCosSpotCutoff = cos(fNew * F_PI180); +} + +/************************************************************************* +|* +|* Lineare Attenuation setzen +|* +\************************************************************************/ + +void B3dLight::SetLinearAttenuation(double fNew) +{ + fLinearAttenuation = fNew; + bLinearOrQuadratic = + (fNew + fQuadraticAttenuation == 0.0) ? FALSE : TRUE; +} + +/************************************************************************* +|* +|* Quadratische Attenuation setzen +|* +\************************************************************************/ + +void B3dLight::SetQuadraticAttenuation(double fNew) +{ + fQuadraticAttenuation = fNew; + bLinearOrQuadratic = + (fNew + fLinearAttenuation == 0.0) ? FALSE : TRUE; +} + +void B3dLight::WriteData(SvStream& rOut) const +{ + rOut << aAmbient; + rOut << aDiffuse; + rOut << aSpecular; + + rOut << aPosition; + rOut << aPositionEye; + rOut << aSpotDirection; + rOut << aSpotDirectionEye; + rOut << nSpotExponent; + + rOut << fSpotCutoff; + rOut << fCosSpotCutoff; + rOut << fConstantAttenuation; + rOut << fLinearAttenuation; + rOut << fQuadraticAttenuation; + + rOut << (BOOL)bIsFirstLight; + rOut << (BOOL)bIsEnabled; + rOut << (BOOL)bIsDirectionalSource; + rOut << (BOOL)bIsSpot; + rOut << (BOOL)bIsAmbient; + rOut << (BOOL)bIsDiffuse; + rOut << (BOOL)bIsSpecular; + rOut << (BOOL)bLinearOrQuadratic; +} + +void B3dLight::ReadData(SvStream& rIn) +{ + BOOL bTmp; + + rIn >> aAmbient; + rIn >> aDiffuse; + rIn >> aSpecular; + + rIn >> aPosition; + rIn >> aPositionEye; + rIn >> aSpotDirection; + rIn >> aSpotDirectionEye; + rIn >> nSpotExponent; + + rIn >> fSpotCutoff; + rIn >> fCosSpotCutoff; + rIn >> fConstantAttenuation; + rIn >> fLinearAttenuation; + rIn >> fQuadraticAttenuation; + + rIn >> bTmp; bIsFirstLight = bTmp; + rIn >> bTmp; bIsEnabled = bTmp; + rIn >> bTmp; bIsDirectionalSource = bTmp; + rIn >> bTmp; bIsSpot = bTmp; + rIn >> bTmp; bIsAmbient = bTmp; + rIn >> bTmp; bIsDiffuse = bTmp; + rIn >> bTmp; bIsSpecular = bTmp; + rIn >> bTmp; bLinearOrQuadratic = bTmp; +} + +/************************************************************************* +|* +|* Gruppe von Lichtquellen, Konstruktor +|* +\************************************************************************/ + +B3dLightGroup::B3dLightGroup() +: aGlobalAmbientLight(255, 102, 102, 102), + bLocalViewer(TRUE), + bModelTwoSide(FALSE), + bLightingEnabled(TRUE) +{ + // Lichtquellen initialisieren + for(UINT16 i=0; i < BASE3D_MAX_NUMBER_LIGHTS;i++) + { + aLight[i].SetFirst(i==0); + aLight[i].Init(); + } +} + +/************************************************************************* +|* +|* globales Umgebungslicht setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetGlobalAmbientLight(const Color rNew) +{ + if(aGlobalAmbientLight != rNew) + { + aGlobalAmbientLight = rNew; + } +} + +/************************************************************************* +|* +|* globales Umgebungslicht lesen +|* +\************************************************************************/ + +const Color B3dLightGroup::GetGlobalAmbientLight() +{ + return aGlobalAmbientLight; +} + +/************************************************************************* +|* +|* Modus globaler Viewer bei Berechnung specular reflection setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetLocalViewer(BOOL bNew) +{ + if(bLocalViewer != bNew) + { + bLocalViewer = bNew; + } +} + +/************************************************************************* +|* +|* Modus globaler Viewer bei Berechnung specular reflection lesen +|* +\************************************************************************/ + +BOOL B3dLightGroup::GetLocalViewer() +{ + return bLocalViewer; +} + +/************************************************************************* +|* +|* Modus Beleuchtungsmodell beidseitig anwenden setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetModelTwoSide(BOOL bNew) +{ + if(bModelTwoSide != bNew) + { + bModelTwoSide = bNew; + } +} + +/************************************************************************* +|* +|* Modus Beleuchtungsmodell beidseitig anwenden lesen +|* +\************************************************************************/ + +BOOL B3dLightGroup::GetModelTwoSide() +{ + return bModelTwoSide; +} + +/************************************************************************* +|* +|* Beleuchtungsmodell aktivieren/deaktivieren +|* +\************************************************************************/ + +void B3dLightGroup::EnableLighting(BOOL bNew) +{ + if(bLightingEnabled != bNew) + { + bLightingEnabled = bNew; + } +} + +/************************************************************************* +|* +|* Abfrage, ob das Beleuchtungsmodell aktiviert/deaktiviert ist +|* +\************************************************************************/ + +BOOL B3dLightGroup::IsLightingEnabled() +{ + return bLightingEnabled; +} + +/************************************************************************* +|* +|* Die Intensitaet eines bestimmten Aspekts einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetIntensity(const Color rNew, + Base3DMaterialValue eMat, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetIntensity(rNew, eMat); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Die Intensitaet eines bestimmten Aspekts einer Lichtquelle lesen +|* +\************************************************************************/ + +const Color B3dLightGroup::GetIntensity(Base3DMaterialValue eMat, + Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].GetIntensity(eMat); +} + +/************************************************************************* +|* +|* Die Position einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetPosition(const Vector3D& rNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetPosition(rNew); + aLight[eNum].SetDirectionalSource(FALSE); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Die Position einer Lichtquelle lesen +|* +\************************************************************************/ + +const Vector3D& B3dLightGroup::GetPosition(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } +#ifdef DBG_UTIL + if(IsDirectionalSource()) + DBG_ERROR("Zugriff auf die Position einer gerichteten Lichtquelle!"); +#endif + return aLight[eNum].GetPosition(); +} + +/************************************************************************* +|* +|* Die Richtung einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetDirection(const Vector3D& rNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetPosition(rNew); + aLight[eNum].SetDirectionalSource(TRUE); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Die Richtung einer Lichtquelle lesen +|* +\************************************************************************/ + +const Vector3D& B3dLightGroup::GetDirection(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } +#ifdef DBG_UTIL + if(!IsDirectionalSource()) + DBG_ERROR("Zugriff auf die Richtung einer ungerichteten Lichtquelle!"); +#endif + return aLight[eNum].GetPosition(); +} + +/************************************************************************* +|* +|* Die Richtung einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetSpotDirection(const Vector3D& rNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetSpotDirection(rNew); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Die Richtung einer Lichtquelle lesen +|* +\************************************************************************/ + +const Vector3D& B3dLightGroup::GetSpotDirection(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].GetSpotDirection(); +} + +/************************************************************************* +|* +|* Den SpotExponent einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetSpotExponent(UINT16 nNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetSpotExponent(nNew); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Den SpotExponent einer Lichtquelle lesen +|* +\************************************************************************/ + +UINT16 B3dLightGroup::GetSpotExponent(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].GetSpotExponent(); +} + +/************************************************************************* +|* +|* Die Einengung des Lichtkegels einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetSpotCutoff(double fNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetSpotCutoff(fNew); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Die Einengung des Lichtkegels einer Lichtquelle lesen +|* +\************************************************************************/ + +double B3dLightGroup::GetSpotCutoff(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].GetSpotCutoff(); +} + +/************************************************************************* +|* +|* Den konstanten AttenuationFactor einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetConstantAttenuation(double fNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetConstantAttenuation(fNew); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Den konstanten AttenuationFactor einer Lichtquelle lesen +|* +\************************************************************************/ + +double B3dLightGroup::GetConstantAttenuation(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].GetConstantAttenuation(); +} + +/************************************************************************* +|* +|* Den linearen AttenuationFactor einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetLinearAttenuation(double fNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetLinearAttenuation(fNew); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Den linearen AttenuationFactor einer Lichtquelle lesen +|* +\************************************************************************/ + +double B3dLightGroup::GetLinearAttenuation(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].GetLinearAttenuation(); +} + +/************************************************************************* +|* +|* Den quadratischen AttenuationFactor einer Lichtquelle setzen +|* +\************************************************************************/ + +void B3dLightGroup::SetQuadraticAttenuation(double fNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].SetQuadraticAttenuation(fNew); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Den quadratischen AttenuationFactor einer Lichtquelle lesen +|* +\************************************************************************/ + +double B3dLightGroup::GetQuadraticAttenuation(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].GetQuadraticAttenuation(); +} + +/************************************************************************* +|* +|* Eine Lichtquelle aktivieren/deaktivieren +|* +\************************************************************************/ + +void B3dLightGroup::Enable(BOOL bNew, Base3DLightNumber eNum) +{ + if(eNum >= Base3DLight0 && eNum <= Base3DLight7) + { + aLight[eNum].Enable(bNew); + } +#ifdef DBG_UTIL + else + DBG_ERROR("Access to Light out of range"); +#endif +} + +/************************************************************************* +|* +|* Abfrage, ob eine Lichtquelle aktiviert/deaktiviert ist +|* +\************************************************************************/ + +BOOL B3dLightGroup::IsEnabled(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].IsEnabled(); +} + +/************************************************************************* +|* +|* Abfrage, ob eine Lichtquelle als directional source eingerichtet ist +|* +\************************************************************************/ + +BOOL B3dLightGroup::IsDirectionalSource(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum].IsDirectionalSource(); +} + +/************************************************************************* +|* +|* Direkter Zugriff auf B3dLight fuer abgeleitete Klassen +|* +\************************************************************************/ + +B3dLight& B3dLightGroup::GetLightObject(Base3DLightNumber eNum) +{ + if(eNum < Base3DLight0 || eNum > Base3DLight7) + { + eNum = Base3DLight0; +#ifdef DBG_UTIL + DBG_ERROR("Access to Light out of range"); +#endif + } + return aLight[eNum]; +} + +void B3dLightGroup::WriteData(SvStream& rOut) const +{ + for(UINT16 a=0;a<BASE3D_MAX_NUMBER_LIGHTS;a++) + { + B3dLight& rLight = ((B3dLightGroup*)(this))->GetLightObject((Base3DLightNumber)(Base3DLight0 + a)); + rLight.WriteData(rOut); + } + + rOut << aGlobalAmbientLight; + + rOut << (BOOL)bLightingEnabled; + rOut << (BOOL)bLocalViewer; + rOut << (BOOL)bModelTwoSide; +} + +void B3dLightGroup::ReadData(SvStream& rIn) +{ + BOOL bTmp; + + for(UINT16 a=0;a<BASE3D_MAX_NUMBER_LIGHTS;a++) + { + B3dLight& rLight = GetLightObject((Base3DLightNumber)(Base3DLight0 + a)); + rLight.ReadData(rIn); + } + + rIn >> aGlobalAmbientLight; + + rIn >> bTmp; bLightingEnabled = bTmp; + rIn >> bTmp; bLocalViewer = bTmp; + rIn >> bTmp; bModelTwoSide = bTmp; +} + diff --git a/goodies/source/base3d/b3dopngl.cxx b/goodies/source/base3d/b3dopngl.cxx new file mode 100644 index 000000000000..e5feb7f41a60 --- /dev/null +++ b/goodies/source/base3d/b3dopngl.cxx @@ -0,0 +1,1502 @@ +/************************************************************************* + * + * $RCSfile: b3dopngl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SV_OUTDEV_HXX +#include <vcl/outdev.hxx> +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _B3D_B3DOPNGL_HXX +#include "b3dopngl.hxx" +#endif + +#ifndef _B3D_HMATRIX_HXX +#include "hmatrix.hxx" +#endif + +#ifndef _B3D_B3DTEX_HXX +#include "b3dtex.hxx" +#endif + +#ifndef _B3D_B3DTRANS_HXX +#include "b3dtrans.hxx" +#endif + +#ifndef _B3D_B3DGEOM_HXX +#include "b3dgeom.hxx" +#endif + +#ifndef _SFXINIMGR_HXX +#include <svtools/iniman.hxx> +#endif + +/************************************************************************* +|* +|* Konstruktor Base3DOpenGL +|* +\************************************************************************/ + +Base3DOpenGL::Base3DOpenGL(OutputDevice* pOutDev) +: Base3D(pOutDev), + aOpenGL(pOutDev), + aEmptyVector(0.0, 0.0, 0.0), + aLastNormal(DBL_MAX, DBL_MAX, DBL_MAX), + aLastTexCoor(DBL_MAX, DBL_MAX, DBL_MAX), + fOffFacMul100((float)(-0.2 * 100.0)), + fOffUniMul100((float)(-1.0 * 100.0)), + aPhongBuffer(12), // 4K + nPhongDivideSize(20), + bForceToSinglePrimitiveOutput(TRUE) // (#70626#) +{ + // create OpenGL context for pOutDev; pOutDev is NOT a printer, + // so don't care about printers in this place + if(aOpenGL.IsValid()) + { + // setup default parameters + aOpenGL.ClearDepth( 1.0 ); + aOpenGL.DepthFunc( GL_LEQUAL ); + aOpenGL.Enable( GL_DEPTH_TEST ); + aOpenGL.Enable( GL_DITHER ); + aOpenGL.Enable( GL_NORMALIZE ); + aOpenGL.Disable( GL_CULL_FACE ); + aOpenGL.Disable( GL_LIGHTING ); + aOpenGL.Disable( GL_LINE_SMOOTH ); + aOpenGL.Disable( GL_POINT_SMOOTH ); + aOpenGL.Disable( GL_POLYGON_SMOOTH ); + aOpenGL.Disable( GL_POLYGON_STIPPLE ); + aOpenGL.Disable( GL_LINE_STIPPLE ); + aOpenGL.Disable( GL_TEXTURE_1D ); + aOpenGL.Disable( GL_TEXTURE_2D ); + aOpenGL.Disable( GL_BLEND ); + aOpenGL.DepthMask( GL_TRUE ); + aOpenGL.ShadeModel( GL_SMOOTH ); + aOpenGL.EdgeFlag( GL_TRUE ); + aOpenGL.Disable( GL_SCISSOR_TEST ); + } + SetContextIsValid(aOpenGL.IsValid()); + CalcInternPhongDivideSize(); + + // read bForceToSinglePrimitiveOutput-flag from .ini + String aTmp = SfxIniManager::Get()->Get(SFX_KEY_3D_OPENGL_FASTER); + bForceToSinglePrimitiveOutput = + (aTmp.Len() && aTmp.GetChar(0) == sal_Unicode('0')); +} + +/************************************************************************* +|* +|* Typbestimmung +|* +\************************************************************************/ + +UINT16 Base3DOpenGL::GetBase3DType() +{ + return BASE3D_TYPE_OPENGL; +} + +/************************************************************************* +|* +|* Start der Szenenbeschreibung: Evtl. neuer HDC, Loesche Tiefenbuffer +|* +\************************************************************************/ + +void Base3DOpenGL::StartScene() +{ + // Falls Transparenz an war, diese zuruecknehmen + aOpenGL.Disable( GL_BLEND ); + aOpenGL.DepthMask( TRUE ); + + // OutputDevice setzen und ZBuffer loeschen + aOpenGL.SetConnectOutputDevice(GetOutputDevice()); + aOpenGL.Clear( GL_DEPTH_BUFFER_BIT ); +} + +/************************************************************************* +|* +|* Scissoring Region setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetScissorRegionPixel(const Rectangle& rRect, BOOL bActivate) +{ + // OpenGL specifics + aOpenGL.Scissor( rRect.Left(), rRect.Top(), + rRect.GetWidth(), rRect.GetHeight()); + + // call parent + Base3D::SetScissorRegionPixel(rRect, bActivate); +} + +/************************************************************************* +|* +|* Dithering +|* +\************************************************************************/ + +void Base3DOpenGL::SetDither(BOOL bNew) +{ + // call parent + Base3D::SetDither(bNew); + + // OpenGL specifics + if(GetDither()) + aOpenGL.Enable( GL_DITHER ); + else + aOpenGL.Disable( GL_DITHER ); +} + +/************************************************************************* +|* +|* Scissoring aktivieren/deaktivieren +|* +\************************************************************************/ + +void Base3DOpenGL::ActivateScissorRegion(BOOL bNew) +{ + // OpenGL specifics + if(bNew) + { + aOpenGL.Enable(GL_SCISSOR_TEST); + } + else + { + aOpenGL.Disable(GL_SCISSOR_TEST); + } + + // call parent + Base3D::ActivateScissorRegion(bNew); +} + +/************************************************************************* +|* +|* Ende der Szenenbeschreibung: Erzwinge bisher nicht erzeugte Ausgaben +|* +\************************************************************************/ + +void Base3DOpenGL::EndScene() +{ + aOpenGL.Flush(); + aOpenGL.Finish(); +} + +/************************************************************************* +|* +|* Neuen freien Eintrag fuer naechste geometrische Daten liefern +|* +\************************************************************************/ + +B3dEntity& Base3DOpenGL::ImplGetFreeEntity() +{ + return aEntity; +} + +/************************************************************************* +|* +|* starte primitiv auch in OpenGL +|* +\************************************************************************/ + +void Base3DOpenGL::ImplStartPrimitive() +{ + bPhongBufferedMode = (GetShadeModel() == Base3DPhong + && GetRenderMode() == Base3DRenderFill + && (GetObjectMode() == Base3DTriangles + || GetObjectMode() == Base3DTriangleStrip + || GetObjectMode() == Base3DTriangleFan + || GetObjectMode() == Base3DQuads + || GetObjectMode() == Base3DQuadStrip + || GetObjectMode() == Base3DPolygon )); + + // Transparenz beachten + if(GetMaterial(Base3DMaterialDiffuse).GetTransparency()) + { + aOpenGL.Enable( GL_BLEND ); + aOpenGL.DepthMask( FALSE ); + aOpenGL.BlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + else + { + aOpenGL.Disable( GL_BLEND ); + aOpenGL.DepthMask( TRUE ); + } + + if(bPhongBufferedMode) + { + // Phong-Modus: Ausgabe sammeln und in kleinere + // Dreiecke zerlegt bei ImplEndPrimitive() rendern + aPhongBuffer.Erase(); + } + else + { + // OpenGL direkt benutzen + aOpenGL.Begin(GetObjectMode()); + } +} + +/************************************************************************* +|* +|* beende primitiv auch in OpenGL +|* +\************************************************************************/ + +void Base3DOpenGL::ImplEndPrimitive() +{ + if(bPhongBufferedMode) + { + DrawPhongPrimitives(); + } + else + { + aOpenGL.End(); + } +} + +/************************************************************************* +|* +|* Darstellungsqualitaet setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetDisplayQuality(UINT8 nNew) +{ + // call parent + Base3D::SetDisplayQuality(nNew); + + // endgueltige Splittinggroesse neuberechnen + CalcInternPhongDivideSize(); +} + +/************************************************************************* +|* +|* PhongMode Splitting-Groesse neu setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetPhongDivideSize(long nNew) +{ + nPhongDivideSize = nNew; + + // endgueltige Splittinggroesse neuberechnen + CalcInternPhongDivideSize(); +} + +/************************************************************************* +|* +|* PhongMode interne Splitting-Groesse neu setzen +|* +\************************************************************************/ + +void Base3DOpenGL::CalcInternPhongDivideSize() +{ + if(GetDisplayQuality() != 255) + { + long nNew = GetPhongDivideSize() + + ((255L - (INT32)GetDisplayQuality())>>2); + nInternPhongDivideSize = nNew * nNew; + } + else + nInternPhongDivideSize = GetPhongDivideSize() * GetPhongDivideSize(); +} + +/************************************************************************* +|* +|* Zeichne fuer Phong gebufferte primitive als Dreiecke +|* +\************************************************************************/ + +void Base3DOpenGL::DrawPhongPrimitives() +{ + UINT32 aCount = aPhongBuffer.Count(); + UINT32 aPos(0L); + bPhongBufferedMode = FALSE; + aOpenGL.Begin(Base3DTriangles); + + switch(GetObjectMode()) + { + case Base3DTriangles : + { + while(aPos < aCount) + { + DrawPhongTriangle(aPos, aPos+1, aPos+2); + aPos += 3; + } + break; + } + case Base3DTriangleStrip: + { + aPos = 1; + while(aPos < aCount) + { + if(aPos%2) + DrawPhongTriangle(aPos-1, aPos, aPos+1); + else + DrawPhongTriangle(aPos-1, aPos+1, aPos); + aPos++; + } + break; + } + case Base3DTriangleFan: + { + aPos = 1; + while(aPos < aCount) + { + DrawPhongTriangle(0, aPos, aPos+1); + aPos++; + } + break; + } + case Base3DQuads: + { + while(aPos < aCount) + { + DrawPhongTriangle(aPos, aPos+1, aPos+2); + DrawPhongTriangle(aPos+2, aPos+3, aPos); + aPos += 4; + } + break; + } + case Base3DQuadStrip: + { + aPos = 1; + while(aPos < aCount) + { + DrawPhongTriangle(aPos, aPos+1, aPos+3); + DrawPhongTriangle(aPos, aPos+3, aPos+2); + aPos+=2; + } + break; + } + case Base3DPolygon: + { + aPos = 2; + while(aPos < aCount) + { + DrawPhongTriangle(0, aPos-1, aPos); + aPos++; + } + break; + } + } + aOpenGL.End(); +} + +/************************************************************************* +|* +|* Zeichne fuer Phong gebufferte Dreiecke +|* +\************************************************************************/ + +void Base3DOpenGL::DrawPhongTriangle(UINT32 nInd1, UINT32 nInd2, UINT32 nInd3) +{ + Vector3D aPos1 = GetTransformationSet()->ObjectToViewCoor(aPhongBuffer[nInd1].Point().GetVector3D()); + double fXMin = aPos1.X(); + double fXMax = aPos1.X(); + double fYMin = aPos1.Y(); + double fYMax = aPos1.Y(); + Vector3D aPos2 = GetTransformationSet()->ObjectToViewCoor(aPhongBuffer[nInd2].Point().GetVector3D()); + if(aPos2.X() < fXMin) + fXMin = aPos2.X(); + if(aPos2.X() > fXMax) + fXMax = aPos2.X(); + if(aPos2.Y() < fYMin) + fYMin = aPos2.Y(); + if(aPos2.Y() > fYMax) + fYMax = aPos2.Y(); + aPos2 = GetTransformationSet()->ObjectToViewCoor(aPhongBuffer[nInd3].Point().GetVector3D()); + if(aPos2.X() < fXMin) + fXMin = aPos2.X(); + if(aPos2.X() > fXMax) + fXMax = aPos2.X(); + if(aPos2.Y() < fYMin) + fYMin = aPos2.Y(); + if(aPos2.Y() > fYMax) + fYMax = aPos2.Y(); + + Size aPixelSize = GetOutputDevice()->LogicToPixel( + Size((long)(fXMax - fXMin),(long)(fYMax - fYMin))); + if(aPixelSize.Width() * aPixelSize.Height() > nInternPhongDivideSize) + { + UINT32 aCount = aPhongBuffer.Count(); + aPhongBuffer.Append(); + aPhongBuffer.Append(); + aPhongBuffer.Append(); + + aPhongBuffer[aCount ].CalcMiddle(aPhongBuffer[nInd1], aPhongBuffer[nInd2]); + aPhongBuffer[aCount+1].CalcMiddle(aPhongBuffer[nInd2], aPhongBuffer[nInd3]); + aPhongBuffer[aCount+2].CalcMiddle(aPhongBuffer[nInd3], aPhongBuffer[nInd1]); + + DrawPhongTriangle(nInd1, aCount, aCount+2); + DrawPhongTriangle(aCount, nInd2, aCount+1); + DrawPhongTriangle(aCount+1, nInd3, aCount+2); + DrawPhongTriangle(aCount, aCount+1, aCount+2); + + aPhongBuffer.Remove(); + aPhongBuffer.Remove(); + aPhongBuffer.Remove(); + } + else + { + ImplPostAddVertex(aPhongBuffer[nInd1]); + ImplPostAddVertex(aPhongBuffer[nInd2]); + ImplPostAddVertex(aPhongBuffer[nInd3]); + } +} + +/************************************************************************* +|* +|* Geometrische Daten direkt an OpenGL weitergeben +|* ACHTUNG! Es wird die aktuelle Farbe benutzt, NICHT die in Enttity3D +|* enthaltene! +|* +\************************************************************************/ + +void Base3DOpenGL::ImplPostAddVertex(B3dEntity& rEntity) +{ + if(bPhongBufferedMode) + { + aPhongBuffer.Append(rEntity); + } + else + { + // Normale setzen + if(rEntity.IsNormalUsed()) + { + if(GetForceFlat() || GetShadeModel() == Base3DFlat) + { + if(rEntity.PlaneNormal() != aLastNormal) + { + aLastNormal = rEntity.PlaneNormal(); + aOpenGL.Normal3dv(&aLastNormal.X()); + } + } + else + { + if(rEntity.Normal() != aLastNormal) + { + aLastNormal = rEntity.Normal(); + aOpenGL.Normal3dv(&aLastNormal.X()); + } + } + } + else + { + if(aLastNormal != aEmptyVector) + { + aLastNormal = aEmptyVector; + aOpenGL.Normal3dv(&aLastNormal.X()); + } + } + + // Texturkoordinate setzen + if(rEntity.IsTexCoorUsed()) + { + if(rEntity.TexCoor() != aLastTexCoor) + { + aLastTexCoor = rEntity.TexCoor(); + aOpenGL.TexCoord3dv(&aLastTexCoor.X()); + } + } + else + { + if(aLastTexCoor != aEmptyVector) + { + aLastTexCoor = aEmptyVector; + aOpenGL.TexCoord3dv(&aLastTexCoor.X()); + } + } + + // Punkt erzeugen + aOpenGL.Vertex3dv(&rEntity.Point().X()); + } +} + +/************************************************************************* +|* +|* beim setzen von color und alpha reagieren +|* +\************************************************************************/ + +void Base3DOpenGL::SetColor(Color aNew) +{ + // call parent + Base3D::SetColor(aNew); + + // Normale Farbausgabe + aOpenGL.Color4ub(GetColor().GetRed(), GetColor().GetGreen(), + GetColor().GetBlue(), 0xff - GetColor().GetTransparency()); +} + +/************************************************************************* +|* +|* Materialeigenschaften setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetMaterial(Color rNew, Base3DMaterialValue eVal, + Base3DMaterialMode eMode) +{ + // call parent + Base3D::SetMaterial(rNew, eVal, eMode); + + // OpenGL Specifics + GLenum eFace = GL_FRONT_AND_BACK; + if(eMode == Base3DMaterialFront) + eFace = GL_FRONT; + if(eMode == Base3DMaterialBack) + eFace = GL_BACK; + GLenum eName = GL_SPECULAR; + if(eVal == Base3DMaterialAmbient) + eName = GL_AMBIENT; + if(eVal == Base3DMaterialDiffuse) + eName = GL_DIFFUSE; + if(eVal == Base3DMaterialEmission) + eName = GL_EMISSION; + + // Array fuellen + float fArray[4] = { + ((float)GetMaterial(eVal, eMode).GetRed()) / (float)255.0, + ((float)GetMaterial(eVal, eMode).GetGreen()) / (float)255.0, + ((float)GetMaterial(eVal, eMode).GetBlue()) / (float)255.0, + ((float)(255 - GetMaterial(eVal, eMode).GetTransparency())) / (float)255.0 + }; + + aOpenGL.Materialfv(eFace, eName, fArray); +} + +/************************************************************************* +|* +|* Materialeigenschaften setzen, exponent der specular-Eigenschaft +|* +\************************************************************************/ + +void Base3DOpenGL::SetShininess(UINT16 nExponent, + Base3DMaterialMode eMode) +{ + // call parent + Base3D::SetShininess(nExponent, eMode); + + // OpenGL Specifics + GLenum eFace = GL_FRONT_AND_BACK; + if(eMode == Base3DMaterialFront) + eFace = GL_FRONT; + if(eMode == Base3DMaterialBack) + eFace = GL_BACK; + aOpenGL.Materialf(eFace, GL_SHININESS, (float)nExponent); +} + +/************************************************************************* +|* +|* Aktuell zu benutzende Textur setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetActiveTexture(B3dTexture* pTex) +{ + // call parent + Base3D::SetActiveTexture(pTex); + + // make current texture, cast ist unkritisch, da innerhalb von + // Base3DOpenGL nur Texturen von diesem Typ angelegt worden + // sein koennen + if(GetActiveTexture()) + { + aOpenGL.Enable(GL_TEXTURE_2D); + ((B3dTextureOpenGL*)GetActiveTexture())->MakeCurrentTexture(aOpenGL); + } + else + { + aOpenGL.BindTexture(GL_TEXTURE_2D, 0); + aOpenGL.Disable(GL_TEXTURE_2D); + } +} + +/************************************************************************* +|* +|* Ein Textur-Objekt inkarnieren +|* +\************************************************************************/ + +B3dTexture* Base3DOpenGL::CreateTexture(TextureAttributes& rAtt, Bitmap& rBitmap) +{ + // Hier Parent NICHT rufen! Sonst wird auch noch eine normale Textur erzeugt + B3dTextureOpenGL* pRetval = new B3dTextureOpenGL(rAtt, rBitmap, aOpenGL); + DBG_ASSERT(pRetval,"AW: Kein Speicher fuer OpenGL-Textur bekommen!"); + return pRetval; +} + +/************************************************************************* +|* +|* OpenGL - Textur loeschen +|* +\************************************************************************/ + +void Base3DOpenGL::DestroyTexture(B3dTexture* pTex) +{ + // Spezielle Loeschaufgaben im Zusammenhang mit OpenGL + ((B3dTextureOpenGL*)pTex)->DestroyOpenGLTexture(aOpenGL); + + // call parent, endgueltig loeschen + Base3D::DestroyTexture(pTex); +} + +/************************************************************************* +|* +|* PolygonOffset setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetPolygonOffset(Base3DPolygonOffset eNew, BOOL bNew) +{ + // call parent + Base3D::SetPolygonOffset(eNew, bNew); + + if(GetPolygonOffset()) + aOpenGL.PolygonOffset((float)(fOffFacMul100 / 100.0), (float)(fOffUniMul100 / 100.0)); + else + aOpenGL.PolygonOffset((float)0.0, (float)0.0); + + // OpenGL Specifics + switch(eNew) + { + case Base3DPolygonOffsetFill : + if(bNew) + aOpenGL.Enable( GL_POLYGON_OFFSET_FILL ); + else + aOpenGL.Disable( GL_POLYGON_OFFSET_FILL ); + break; + + case Base3DPolygonOffsetLine : + if(bNew) + aOpenGL.Enable( GL_POLYGON_OFFSET_LINE ); + else + aOpenGL.Disable( GL_POLYGON_OFFSET_LINE ); + break; + + case Base3DPolygonOffsetPoint : + if(bNew) + aOpenGL.Enable( GL_POLYGON_OFFSET_POINT ); + else + aOpenGL.Disable( GL_POLYGON_OFFSET_POINT ); + break; + } +} + +/************************************************************************* +|* +|* Beleuchtung setzen/lesen +|* +\************************************************************************/ + +void Base3DOpenGL::SetLightGroup(B3dLightGroup* pSet, BOOL bSetGlobal) +{ + // call parent + Base3D::SetLightGroup(pSet, bSetGlobal); + + if(GetLightGroup()) + { + // Allgemeine Parameter setzen + SetGlobalAmbientLight(GetLightGroup()->GetGlobalAmbientLight()); + SetLocalViewer(GetLightGroup()->GetLocalViewer()); + SetModelTwoSide(GetLightGroup()->GetModelTwoSide()); + EnableLighting(GetLightGroup()->IsLightingEnabled()); + + // Einzelne Lampen setzen + if(GetTransformationSet() && bSetGlobal) + { + aOpenGL.MatrixMode(GL_MODELVIEW); + aOpenGL.LoadIdentity(); + } + + // Set and enable lights from the beginning of array in + // OpenGL + UINT16 nNumAlloc = 0; + + UINT16 a; + for(a=0;a<BASE3D_MAX_NUMBER_LIGHTS;a++) + { + Base3DLightNumber eNum = (Base3DLightNumber)(Base3DLight0 + a); + B3dLight& rLight = GetLightGroup()->GetLightObject(eNum); + + if(rLight.IsEnabled()) + { + Base3DLightNumber eNumAlloc = (Base3DLightNumber)(Base3DLight0 + nNumAlloc); + nNumAlloc++; + + Enable(TRUE, eNumAlloc); + + SetIntensity(rLight.GetIntensity(Base3DMaterialAmbient), + Base3DMaterialAmbient, eNumAlloc); + SetIntensity(rLight.GetIntensity(Base3DMaterialDiffuse), + Base3DMaterialDiffuse, eNumAlloc); + SetIntensity(rLight.GetIntensity(Base3DMaterialSpecular), + Base3DMaterialSpecular, eNumAlloc); + + if(rLight.IsDirectionalSource()) + { + SetDirection(rLight.GetPosition(), eNumAlloc); + } + else + { + SetPosition(rLight.GetPosition(), eNumAlloc); + SetSpotDirection(rLight.GetSpotDirection(), eNumAlloc); + SetSpotExponent(rLight.GetSpotExponent(), eNumAlloc); + SetSpotCutoff(rLight.GetSpotCutoff(), eNumAlloc); + } + + SetConstantAttenuation(rLight.GetConstantAttenuation(), eNumAlloc); + SetLinearAttenuation(rLight.GetLinearAttenuation(), eNumAlloc); + SetQuadraticAttenuation(rLight.GetQuadraticAttenuation(), eNumAlloc); + } + } + + for(a=nNumAlloc;a<BASE3D_MAX_NUMBER_LIGHTS;a++) + { + Base3DLightNumber eNum = (Base3DLightNumber)(Base3DLight0 + a); + Enable(FALSE, eNum); + } + + if(GetTransformationSet() && bSetGlobal) + PostSetObjectOrientation(GetTransformationSet()); + } +} + +/************************************************************************* +|* +|* globales Umgebungslicht setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetGlobalAmbientLight(const Color rNew) +{ + // OpenGL Specifics + Color aSource; + if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL) + { + // Graustufen + UINT8 nLuminance = rNew.GetLuminance(); + aSource.SetRed(nLuminance); + aSource.SetGreen(nLuminance); + aSource.SetBlue(nLuminance); + aSource.SetTransparency(rNew.GetTransparency()); + } + else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL) + { + // Keine Ausgabe, hier Weiss als Farbe setzen + aSource = Color(COL_WHITE); + } + else + { + // Normale Farbausgabe + aSource = rNew; + } + + // Array fuellen + float fArray[4] = { + ((float)aSource.GetRed()) / (float)255.0, + ((float)aSource.GetGreen()) / (float)255.0, + ((float)aSource.GetBlue()) / (float)255.0, + ((float)aSource.GetTransparency()) / (float)255.0 + }; + aOpenGL.LightModelfv(GL_LIGHT_MODEL_AMBIENT, fArray); +} + +/************************************************************************* +|* +|* Modus globaler Viewer bei Berechnung specular reflection setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetLocalViewer(BOOL bNew) +{ + // OpenGL Specifics + aOpenGL.LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, + bNew ? (float)0.0 : (float)1.0); +} + +/************************************************************************* +|* +|* Modus Beleuchtungsmodell beidseitig anwenden setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetModelTwoSide(BOOL bNew) +{ + // OpenGL Specifics + aOpenGL.LightModelf(GL_LIGHT_MODEL_TWO_SIDE, + bNew ? (float)1.0 : (float)0.0); +} + +/************************************************************************* +|* +|* Beleuchtungsmodell aktivieren/deaktivieren +|* +\************************************************************************/ + +void Base3DOpenGL::EnableLighting(BOOL bNew) +{ + // OpenGL Specifics + if(bNew) + aOpenGL.Enable( GL_LIGHTING ); + else + aOpenGL.Disable( GL_LIGHTING ); +} + +/************************************************************************* +|* +|* Die Intensitaet eines bestimmten Aspekts einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetIntensity(const Color rNew, + Base3DMaterialValue eVal, Base3DLightNumber eNum) +{ + // OpenGL Specifics + Color aSource; + if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL) + { + // Graustufen + UINT8 nLuminance = rNew.GetLuminance(); + aSource.SetRed(nLuminance); + aSource.SetGreen(nLuminance); + aSource.SetBlue(nLuminance); + aSource.SetTransparency(rNew.GetTransparency()); + } + else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL) + { + // Keine Ausgabe, hier Weiss als Farbe setzen + aSource = Color(COL_WHITE); + } + else + { + // Normale Farbausgabe + aSource = rNew; + } + + // Array fuellen + float fArray[4] = { + ((float)aSource.GetRed()) / (float)255.0, + ((float)aSource.GetGreen()) / (float)255.0, + ((float)aSource.GetBlue()) / (float)255.0, + ((float)aSource.GetTransparency()) / (float)255.0 + }; + + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + GLenum eName = GL_SPECULAR; + if(eVal == Base3DMaterialAmbient) + eName = GL_AMBIENT; + if(eVal == Base3DMaterialDiffuse) + eName = GL_DIFFUSE; + aOpenGL.Lightfv(eLight, eName, fArray); +} + +/************************************************************************* +|* +|* Die Position einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetPosition(const Vector3D& rNew, Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + float fArray[4] = { + (float)rNew[0], (float)rNew[1], (float)rNew[2], (float)1.0 + }; + aOpenGL.Lightfv(eLight, GL_POSITION, fArray); +} + +/************************************************************************* +|* +|* Die Richtung einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetDirection(const Vector3D& rNew, Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + float fArray[4] = { + (float)rNew[0], (float)rNew[1], (float)rNew[2], (float)0.0 + }; + aOpenGL.Lightfv(eLight, GL_POSITION, fArray); +} + +/************************************************************************* +|* +|* Die Richtung einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetSpotDirection(const Vector3D& rNew, + Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + float fArray[4] = { + (float)rNew[0], (float)rNew[1], (float)rNew[2], (float)0.0 + }; + aOpenGL.Lightfv(eLight, GL_SPOT_DIRECTION, fArray); +} + +/************************************************************************* +|* +|* Den SpotExponent einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetSpotExponent(UINT16 nNew, Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + aOpenGL.Lightf(eLight, GL_SPOT_EXPONENT, (float)nNew); +} + +/************************************************************************* +|* +|* Die Einengung des Lichtkegels einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetSpotCutoff(double fNew, Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + aOpenGL.Lightf(eLight, GL_SPOT_CUTOFF, (float)fNew); +} + +/************************************************************************* +|* +|* Den konstanten AttenuationFactor einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetConstantAttenuation(double fNew, + Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + aOpenGL.Lightf(eLight, GL_CONSTANT_ATTENUATION, (float)fNew); +} + +/************************************************************************* +|* +|* Den linearen AttenuationFactor einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetLinearAttenuation(double fNew, + Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + aOpenGL.Lightf(eLight, GL_LINEAR_ATTENUATION, (float)fNew); +} + +/************************************************************************* +|* +|* Den quadratischen AttenuationFactor einer Lichtquelle setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetQuadraticAttenuation(double fNew, + Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + aOpenGL.Lightf(eLight, GL_QUADRATIC_ATTENUATION, (float)fNew); +} + +/************************************************************************* +|* +|* Eine Lichtquelle aktivieren/deaktivieren +|* +\************************************************************************/ + +void Base3DOpenGL::Enable(BOOL bNew, Base3DLightNumber eNum) +{ + // OpenGL Specifics + GLenum eLight = GL_LIGHT0 + (eNum - Base3DLight0); + if(bNew) + aOpenGL.Enable(eLight); + else + aOpenGL.Disable(eLight); +} + +/************************************************************************* +|* +|* RenderMode setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetRenderMode(Base3DRenderMode eNew, + Base3DMaterialMode eMode) +{ + // call parent + Base3D::SetRenderMode(eNew, eMode); + + // OpenGL Specifics + GLenum eFace = GL_FRONT_AND_BACK; + if(eMode == Base3DMaterialFront) + eFace = GL_FRONT; + if(eMode == Base3DMaterialBack) + eFace = GL_BACK; + + switch(eNew) + { + case Base3DRenderNone : + { + break; + } + case Base3DRenderPoint : + { + aOpenGL.PolygonMode(eFace, GL_POINT); + break; + } + case Base3DRenderLine : + { + aOpenGL.PolygonMode(eFace, GL_LINE); + break; + } + case Base3DRenderFill : + { + aOpenGL.PolygonMode(eFace, GL_FILL); + break; + } + } +} + +/************************************************************************* +|* +|* ShadeModel setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetShadeModel(Base3DShadeModel eNew) +{ + // call parent + Base3D::SetShadeModel(eNew); + + switch(eNew) + { + case Base3DSmooth : + case Base3DPhong : + { + aOpenGL.ShadeModel(GL_SMOOTH); + break; + } + case Base3DFlat : + { + aOpenGL.ShadeModel(GL_FLAT); + break; + } + } +} + +/************************************************************************* +|* +|* CullingMode setzen +|* +\************************************************************************/ + +void Base3DOpenGL::SetCullMode(Base3DCullMode eNew) +{ + // call parent + Base3D::SetCullMode(eNew); + + switch(eNew) + { + case Base3DCullFront : + { + aOpenGL.CullFace(GL_FRONT); + aOpenGL.Enable(GL_CULL_FACE); + break; + } + case Base3DCullBack : + { + aOpenGL.CullFace(GL_BACK); + aOpenGL.Enable(GL_CULL_FACE); + break; + } + case Base3DCullNone : + { + aOpenGL.Disable(GL_CULL_FACE); + break; + } + } +} + +/************************************************************************* +|* +|* EdgeFlag schreiben +|* +\************************************************************************/ + +void Base3DOpenGL::SetEdgeFlag(BOOL bNew) +{ + // EdgeFlag fuer OpenGL setzen + if(bNew) + aOpenGL.EdgeFlag(GL_TRUE); + else + aOpenGL.EdgeFlag(GL_FALSE); + + // call parent + Base3D::SetEdgeFlag(bNew); +} + +/************************************************************************* +|* +|* PointSize schreiben +|* +\************************************************************************/ + +void Base3DOpenGL::SetPointSize(double fNew) +{ + // PointSize fuer OpenGL setzen + aOpenGL.PointSize((GLfloat)fNew); + + // call parent + Base3D::SetPointSize(fNew); +} + +/************************************************************************* +|* +|* LineWidth schreiben +|* +\************************************************************************/ + +void Base3DOpenGL::SetLineWidth(double fNew) +{ + // LineWidth fuer OpenGL setzen + aOpenGL.LineWidth((GLfloat)fNew); + + // call parent + Base3D::SetLineWidth(fNew); +} + +/************************************************************************* +|* +|* Callbacks bei Matrixaenderungen, Default-Implementierungen +|* +\************************************************************************/ + +void Base3DOpenGL::SetTransformationSet(B3dTransformationSet* pSet) +{ + // call parent + Base3D::SetTransformationSet(pSet); + + if(GetTransformationSet()) + { + PostSetObjectOrientation(GetTransformationSet()); + PostSetProjection(GetTransformationSet()); + PostSetTexture(GetTransformationSet()); + PostSetViewport(GetTransformationSet()); + } +} + +void Base3DOpenGL::PostSetObjectOrientation(B3dTransformationSet* pCaller) +{ + // OpenGL specifics + Matrix4D aMat = pCaller->GetObjectTrans(); + aMat *= pCaller->GetOrientation(); + double fBuffer[16] = { + aMat[0][0], aMat[1][0], aMat[2][0], aMat[3][0], + aMat[0][1], aMat[1][1], aMat[2][1], aMat[3][1], + aMat[0][2], aMat[1][2], aMat[2][2], aMat[3][2], + aMat[0][3], aMat[1][3], aMat[2][3], aMat[3][3] + }; + aOpenGL.MatrixMode(GL_MODELVIEW); + aOpenGL.LoadMatrixd(fBuffer); +} + +void Base3DOpenGL::PostSetProjection(B3dTransformationSet* pCaller) +{ + // OpenGL specifics + const Matrix4D& rMat = pCaller->GetProjection(); + double fBuffer[16] = { + rMat[0][0], rMat[1][0], rMat[2][0], rMat[3][0], + rMat[0][1], rMat[1][1], rMat[2][1], rMat[3][1], + rMat[0][2], rMat[1][2], rMat[2][2], rMat[3][2], + rMat[0][3], rMat[1][3], rMat[2][3], rMat[3][3] + }; + aOpenGL.MatrixMode(GL_PROJECTION); + aOpenGL.LoadMatrixd(fBuffer); +} + +void Base3DOpenGL::PostSetTexture(B3dTransformationSet* pCaller) +{ + // OpenGL specifics + const Matrix4D& rMat = pCaller->GetTexture(); + double fBuffer[16] = { + rMat[0][0], rMat[1][0], rMat[2][0], rMat[3][0], + rMat[0][1], rMat[1][1], rMat[2][1], rMat[3][1], + rMat[0][2], rMat[1][2], rMat[2][2], rMat[3][2], + rMat[0][3], rMat[1][3], rMat[2][3], rMat[3][3] + }; + aOpenGL.MatrixMode(GL_TEXTURE); + aOpenGL.LoadMatrixd(fBuffer); +} + +void Base3DOpenGL::PostSetViewport(B3dTransformationSet* pCaller) +{ + // OpenGL specifics + Rectangle aBoundPixel(GetOutputDevice()-> + LogicToPixel(pCaller->GetLogicalViewportBounds())); + aOpenGL.Viewport( aBoundPixel.Left(), aBoundPixel.Top(), + aBoundPixel.GetWidth() - 1, aBoundPixel.GetHeight() - 1); +} + +/************************************************************************* +|* +|* Ein Objekt in Form einer B3dGeometry direkt ausgeben +|* +\************************************************************************/ + +void Base3DOpenGL::DrawPolygonGeometry(B3dGeometry& rGeometry, BOOL bOutline) +{ + // bForceToSinglePrimitiveOutput: (#70626#) + if(bForceToSinglePrimitiveOutput || (GetShadeModel() == Base3DPhong && GetRenderMode() == Base3DRenderFill)) + { + // call parent, render with many primitives + Base3D::DrawPolygonGeometry(rGeometry, bOutline); + } + else + { + // Buckets der Geometrie holen + B3dEntityBucket& rEntityBucket = rGeometry.GetEntityBucket(); + GeometryIndexValueBucket& rIndexBucket = rGeometry.GetIndexBucket(); + + if(rEntityBucket.Count() && rIndexBucket.Count()) + { + // Arrays aktivieren + aOpenGL.EnableClientState(GL_VERTEX_ARRAY); + + UINT32 nPolyCounter = 0; + UINT32 nEntityCounter = 0; + UINT32 nArrayStartIndex = 0; + UINT32 nUpperBound; + + // Pointer setzen + UINT16 nArray = 0; + aOpenGL.VertexPointer(3, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].Point()); + + if(bOutline) + { + // Transparenz Linien beachten + if(GetColor().GetTransparency()) + { + aOpenGL.Enable( GL_BLEND ); + aOpenGL.DepthMask( FALSE ); + aOpenGL.BlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + else + { + aOpenGL.Disable( GL_BLEND ); + aOpenGL.DepthMask( TRUE ); + } + + // ALLE Linien Zeichnen + aOpenGL.Disable(GL_CULL_FACE); + + // Polygone als Outline ausgeben + aOpenGL.PolygonMode(GL_FRONT_AND_BACK, GL_LINE); + aOpenGL.PolygonOffset((float)(fOffFacMul100 / 100.0), (float)(fOffUniMul100 / 100.0)); + aOpenGL.Enable( GL_POLYGON_OFFSET_LINE ); + aOpenGL.EnableClientState(GL_EDGE_FLAG_ARRAY); + aOpenGL.EdgeFlagPointer(rEntityBucket.GetSlotSize(), &rEntityBucket[0].EdgeFlag()); + + while(nPolyCounter < rIndexBucket.Count()) + { + // Naechstes Primitiv + nUpperBound = rIndexBucket[nPolyCounter].GetIndex(); + BOOL bLineMode = (rIndexBucket[nPolyCounter++].GetMode() == B3D_INDEX_MODE_LINE); + + if(nUpperBound >> rEntityBucket.GetBlockShift() != nArray) + { + // Einzelschritt, Bereichsueberschreitung im Buffer + // Als Polygon ausgeben + aOpenGL.Begin(bLineMode ? Base3DLineStrip : Base3DPolygon); + + // Polygon ausgeben + while(nEntityCounter < nUpperBound) + { + B3dEntity& rEntity = rEntityBucket[nEntityCounter++]; + aOpenGL.EdgeFlag(rEntity.IsEdgeVisible() ? GL_TRUE : GL_FALSE); + aOpenGL.Vertex3dv((const double *)(&rEntity.Point())); + } + + // Primitiv abschliessen + aOpenGL.End(); + + // NUR auf neues Array setzen, wenn noch was da ist (#59941#) + if(nEntityCounter < rEntityBucket.Count()) + { + // Pointer auf neues Array setzen + nArray = (UINT16)(nEntityCounter >> rEntityBucket.GetBlockShift()); + nArrayStartIndex = nEntityCounter; + B3dEntity& rStart = rEntityBucket[nEntityCounter]; + + aOpenGL.VertexPointer(3, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rStart); + aOpenGL.EdgeFlagPointer(rEntityBucket.GetSlotSize(), &(rStart.EdgeFlag())); + } + } + else + { + // Primitiv komplett raushauen, liegt in einem Buffer + aOpenGL.DrawArrays(bLineMode ? Base3DLineStrip : Base3DPolygon, + nEntityCounter - nArrayStartIndex, + nUpperBound - nEntityCounter); + nEntityCounter = nUpperBound; + } + } + + // Arrays deaktivieren + aOpenGL.DisableClientState(GL_VERTEX_ARRAY); + aOpenGL.DisableClientState(GL_EDGE_FLAG_ARRAY); + } + else + { + // Transparenz Flaechen beachten + if(GetMaterial(Base3DMaterialDiffuse).GetTransparency()) + { + aOpenGL.Enable( GL_BLEND ); + aOpenGL.DepthMask( FALSE ); + aOpenGL.BlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + else + { + aOpenGL.Disable( GL_BLEND ); + aOpenGL.DepthMask( TRUE ); + } + + // Polygone gefuellt ausgeben + aOpenGL.PolygonMode(GL_FRONT_AND_BACK, GL_FILL); + aOpenGL.EnableClientState(GL_NORMAL_ARRAY); + aOpenGL.EnableClientState(GL_TEXTURE_COORD_ARRAY); + if(GetForceFlat() || GetShadeModel() == Base3DFlat) + aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].PlaneNormal()); + else + aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].Normal()); + aOpenGL.TexCoordPointer(2, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rEntityBucket[0].TexCoor()); + + while(nPolyCounter < rIndexBucket.Count()) + { + // Naechstes Primitiv + nUpperBound = rIndexBucket[nPolyCounter].GetIndex(); + BOOL bLineMode = (rIndexBucket[nPolyCounter++].GetMode() == B3D_INDEX_MODE_LINE); + + if(nUpperBound >> rEntityBucket.GetBlockShift() != nArray) + { + // Einzelschritt, Bereichsueberschreitung im Buffer + // Als Polygon ausgeben + aOpenGL.Begin(bLineMode ? Base3DLineStrip : Base3DPolygon); + + // Polygon ausgeben + while(nEntityCounter < nUpperBound) + { + B3dEntity& rEntity = rEntityBucket[nEntityCounter++]; + if(GetForceFlat() || GetShadeModel() == Base3DFlat) + aOpenGL.Normal3dv((const double *)(&rEntity.PlaneNormal())); + else + aOpenGL.Normal3dv((const double *)(&rEntity.Normal())); + aOpenGL.TexCoord3dv((const double *)(&rEntity.TexCoor())); + aOpenGL.Vertex3dv((const double *)(&rEntity.Point())); + } + + // Primitiv abschliessen + aOpenGL.End(); + + // NUR auf neues Array setzen, wenn noch was da ist (#58702#) + if(nEntityCounter < rEntityBucket.Count()) + { + // Pointer auf neues Array setzen + nArray = (UINT16)(nEntityCounter >> rEntityBucket.GetBlockShift()); + nArrayStartIndex = nEntityCounter; + B3dEntity& rStart = rEntityBucket[nEntityCounter]; + + aOpenGL.VertexPointer(3, GL_DOUBLE, rEntityBucket.GetSlotSize(), &rStart); + if(GetForceFlat() || GetShadeModel() == Base3DFlat) + aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &(rStart.PlaneNormal())); + else + aOpenGL.NormalPointer(GL_DOUBLE, rEntityBucket.GetSlotSize(), &(rStart.Normal())); + aOpenGL.TexCoordPointer(2, GL_DOUBLE, rEntityBucket.GetSlotSize(), &(rStart.TexCoor())); + } + } + else + { + // Primitiv komplett raushauen, liegt in einem Buffer + aOpenGL.DrawArrays(bLineMode ? Base3DLineStrip : Base3DPolygon, + nEntityCounter - nArrayStartIndex, + nUpperBound - nEntityCounter); + nEntityCounter = nUpperBound; + } + } + + // Arrays deaktivieren + aOpenGL.DisableClientState(GL_VERTEX_ARRAY); + aOpenGL.DisableClientState(GL_NORMAL_ARRAY); + aOpenGL.DisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + } +} + diff --git a/goodies/source/base3d/b3dopngl.hxx b/goodies/source/base3d/b3dopngl.hxx new file mode 100644 index 000000000000..910cb49caa0a --- /dev/null +++ b/goodies/source/base3d/b3dopngl.hxx @@ -0,0 +1,223 @@ +/************************************************************************* + * + * $RCSfile: b3dopngl.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DOPNGL_HXX +#define _B3D_B3DOPNGL_HXX + +#ifndef _B3D_BASE3D_HXX +#include "base3d.hxx" +#endif + +#ifndef _SV_OPENGL_HXX +#include <vcl/opengl.hxx> +#endif + +/************************************************************************* +|* +|* Die Basisklasse fuer Standard 3D Ausgaben mittels OpenGL unter +|* Windows (Win95 und Windows NT) +|* +\************************************************************************/ + +class Base3DOpenGL : public Base3D +{ +private: + // Datenuebergabe + B3dEntity aEntity; + + // OpenGL Objekt + OpenGL aOpenGL; + + // Letzte Normale und letzte Texturkoordinate + Vector3D aLastNormal; + Vector3D aLastTexCoor; + Vector3D aEmptyVector; + + float fOffFacMul100; + float fOffUniMul100; + + // Simulation Phong-Mode + BOOL bPhongBufferedMode; + B3dEntityBucket aPhongBuffer; + long nPhongDivideSize; + long nInternPhongDivideSize; + + // flags (#70626#) + BOOL bForceToSinglePrimitiveOutput; + + void DrawPhongPrimitives(); + void DrawPhongTriangle(UINT32 nInd1, UINT32 nInd2, UINT32 nInd3); + void CalcInternPhongDivideSize(); + +public: + Base3DOpenGL(OutputDevice* pOutDev); + + // DivideSize bei Phong-Simulation + long GetPhongDivideSize() { return nPhongDivideSize; } + void SetPhongDivideSize(long nNew); + + // Get/Set force to single primitive output (#70626#) + BOOL IsForceToSinglePrimitiveOutput() const { return bForceToSinglePrimitiveOutput; } + void SetForceToSinglePrimitiveOutput(BOOL bNew) { bForceToSinglePrimitiveOutput = bNew; } + + // Typbestimmung + virtual UINT16 GetBase3DType(); + + virtual void StartScene(); + virtual void EndScene(); + + // Scissoring + virtual void SetScissorRegionPixel(const Rectangle& rRect, BOOL bActivate=TRUE); + virtual void ActivateScissorRegion(BOOL bNew); + + // Dithering + virtual void SetDither(BOOL bNew); + + // Farbe + virtual void SetColor(Color aNew); + + // Material + virtual void SetMaterial(Color rNew, + Base3DMaterialValue=Base3DMaterialAmbient, + Base3DMaterialMode=Base3DMaterialFrontAndBack); + virtual void SetShininess(UINT16 nExponent, + Base3DMaterialMode=Base3DMaterialFrontAndBack); + + // Texturen +private: + virtual B3dTexture* CreateTexture(TextureAttributes& rAtt, Bitmap& rBitmap); + virtual void DestroyTexture(B3dTexture*); +public: + virtual void SetActiveTexture(B3dTexture* pTex=NULL); + + // Darstellungsqualitaet + virtual void SetDisplayQuality(UINT8 nNew); + + // PolygonOffset + virtual void SetPolygonOffset( + Base3DPolygonOffset eNew=Base3DPolygonOffsetLine, BOOL bNew=FALSE); + + // Beleuchtung setzen/lesen + virtual void SetLightGroup(B3dLightGroup* pSet, BOOL bSetGlobal=TRUE); + + virtual void SetRenderMode(Base3DRenderMode eNew, + Base3DMaterialMode=Base3DMaterialFrontAndBack); + virtual void SetShadeModel(Base3DShadeModel eNew); + virtual void SetCullMode(Base3DCullMode eNew); + + virtual void SetEdgeFlag(BOOL bNew=TRUE); + virtual void SetPointSize(double fNew=1.0); + virtual void SetLineWidth(double fNew=1.0); + + // Ein Objekt in Form einer B3dGeometry direkt ausgeben + virtual void DrawPolygonGeometry(B3dGeometry& rGeometry, BOOL bOutline=FALSE); + + // Callbacks bei Matrixaenderungen + virtual void SetTransformationSet(B3dTransformationSet* pSet); + +protected: + // Geometrische Daten uebergeben + virtual B3dEntity& ImplGetFreeEntity(); + virtual void ImplPostAddVertex(B3dEntity& rEnt); + + virtual void ImplStartPrimitive(); + virtual void ImplEndPrimitive(); + + // Callbacks bei Matrixaenderungen + void PostSetObjectOrientation(B3dTransformationSet* pCaller); + void PostSetProjection(B3dTransformationSet* pCaller); + void PostSetTexture(B3dTransformationSet* pCaller); + void PostSetViewport(B3dTransformationSet* pCaller); + + // lokale Parameter des LightModels + void SetGlobalAmbientLight(const Color rNew); + void SetLocalViewer(BOOL bNew=TRUE); + void SetModelTwoSide(BOOL bNew=FALSE); + + // Hauptschalter fuer die Beleuchtung + void EnableLighting(BOOL bNew=TRUE); + + // Lichtquellen Interface + void SetIntensity(const Color rNew, + Base3DMaterialValue=Base3DMaterialAmbient, + Base3DLightNumber=Base3DLight0); + void SetPosition(const Vector3D& rNew, + Base3DLightNumber=Base3DLight0); + void SetDirection(const Vector3D& rNew, + Base3DLightNumber=Base3DLight0); + void SetSpotDirection(const Vector3D& rNew, + Base3DLightNumber=Base3DLight0); + void SetSpotExponent(UINT16 nNew, + Base3DLightNumber=Base3DLight0); + void SetSpotCutoff(double fNew, + Base3DLightNumber=Base3DLight0); + void SetConstantAttenuation(double fNew, + Base3DLightNumber=Base3DLight0); + void SetLinearAttenuation(double fNew, + Base3DLightNumber=Base3DLight0); + void SetQuadraticAttenuation(double fNew, + Base3DLightNumber=Base3DLight0); + void Enable(BOOL bNew=TRUE, + Base3DLightNumber=Base3DLight0); +}; + + +#endif // _B3D_B3DOPNGL_HXX diff --git a/goodies/source/base3d/b3dtex.cxx b/goodies/source/base3d/b3dtex.cxx new file mode 100644 index 000000000000..39c67644b30f --- /dev/null +++ b/goodies/source/base3d/b3dtex.cxx @@ -0,0 +1,1176 @@ +/************************************************************************* + * + * $RCSfile: b3dtex.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DTEX_HXX +#include "b3dtex.hxx" +#endif + +#ifndef _B3D_B3DOPNGL_HXX +#include "b3dopngl.hxx" +#endif + +#ifndef _SV_BMPACC_HXX +#include <vcl/bmpacc.hxx> +#endif + +#ifndef _NEW_HXX +#include <tools/new.hxx> +#endif + +/************************************************************************* +|* +|* Klassen fuer TexturAttribute beim Anfordern von Texturen +|* +\************************************************************************/ + +TextureAttributes::TextureAttributes() +{ +} + +// Fuer Bitmaps + +TextureAttributesBitmap::TextureAttributesBitmap(Bitmap aBmp) +: TextureAttributes(), + aBitmapAttribute(aBmp) +{ +} + +BOOL TextureAttributesBitmap::operator==(const TextureAttributes& rAtt) const +{ + if(GetTextureAttributeType() == rAtt.GetTextureAttributeType()) + { + const TextureAttributesBitmap& rAttBmp = (const TextureAttributesBitmap&)rAtt; + + if(rAttBmp.aBitmapAttribute == aBitmapAttribute) + return TRUE; + } + return FALSE; +} + +UINT16 TextureAttributesBitmap::GetTextureAttributeType() const +{ + return TEXTURE_ATTRIBUTE_TYPE_BITMAP; +} + +// Fuer Gradientfills + +TextureAttributesGradient::TextureAttributesGradient(void* pF, void *pSC) +: TextureAttributes(), + pFill(pF), + pStepCount(pSC) +{ +} + +BOOL TextureAttributesGradient::operator==(const TextureAttributes& rAtt) const +{ + if(GetTextureAttributeType() == rAtt.GetTextureAttributeType()) + { + const TextureAttributesGradient& rAttGra = (const TextureAttributesGradient&)rAtt; + + if(rAttGra.pFill == pFill + && rAttGra.pStepCount == pStepCount) + return TRUE; + } + return FALSE; +} + +UINT16 TextureAttributesGradient::GetTextureAttributeType() const +{ + return TEXTURE_ATTRIBUTE_TYPE_GRADIENT; +} + +// Fuer Hatchfills + +TextureAttributesHatch::TextureAttributesHatch(void* pF) +: TextureAttributes(), + pFill(pF) +{ +} + +BOOL TextureAttributesHatch::operator==(const TextureAttributes& rAtt) const +{ + if(GetTextureAttributeType() == rAtt.GetTextureAttributeType()) + { + const TextureAttributesHatch& rAttHat = (const TextureAttributesHatch&)rAtt; + + if(rAttHat.pFill == pFill) + return TRUE; + } + return FALSE; +} + +UINT16 TextureAttributesHatch::GetTextureAttributeType() const +{ + return TEXTURE_ATTRIBUTE_TYPE_HATCH; +} + + +/************************************************************************* +|* +|* Konstruktor Textur +|* +\************************************************************************/ + +B3dTexture::B3dTexture( + TextureAttributes& rAtt, + Bitmap& rBmp, + Base3DTextureKind eKnd, + Base3DTextureMode eMod, + Base3DTextureFilter eFlt, + Base3DTextureWrap eS, + Base3DTextureWrap eT) +: aBitmap(rBmp), + pReadAccess(NULL), + nUsageCount(B3D_TEXTURE_LIFETIME), + eKind(eKnd), + eMode(eMod), + eFilter(eFlt), + eWrapS(eS), + eWrapT(eT), + nSwitchVal(0), + bTextureKindChanged(FALSE) +{ + // ReadAccess auf Textur anfordern + pReadAccess = aBitmap.AcquireReadAccess(); + DBG_ASSERT(pReadAccess, "AW: Keinen Lesezugriff auf Textur-Bitmap bekommen"); + + // Attribute kopieren + switch(rAtt.GetTextureAttributeType()) + { + case TEXTURE_ATTRIBUTE_TYPE_BITMAP : + pAttributes = new TextureAttributesBitmap( + ((TextureAttributesBitmap&)rAtt).GetBitmapAttribute()); + break; + + case TEXTURE_ATTRIBUTE_TYPE_GRADIENT : + pAttributes = new TextureAttributesGradient( + ((TextureAttributesGradient&)rAtt).GetFillAttribute(), + ((TextureAttributesGradient&)rAtt).GetStepCountAttribute()); + break; + + case TEXTURE_ATTRIBUTE_TYPE_HATCH : + pAttributes = new TextureAttributesHatch( + ((TextureAttributesHatch&)rAtt).GetHatchFillAttribute()); + break; + } + + // SwitchVal setzen + SetSwitchVal(); +} + +/************************************************************************* +|* +|* Destruktor Textur +|* +\************************************************************************/ + +B3dTexture::~B3dTexture() +{ + // ReadAccess auf Textur freigeben + if(pReadAccess) + { + aBitmap.ReleaseAccess(pReadAccess); + pReadAccess = NULL; + } + + // Attribute wegschmeissen + if(pAttributes) + delete pAttributes; + pAttributes = NULL; +} + +// Zugriff auf die Attribute der Textur +TextureAttributes& B3dTexture::GetAttributes() +{ + return *pAttributes; +} + +/************************************************************************* +|* +|* Art des Wrappings in X setzen +|* +\************************************************************************/ + +void B3dTexture::SetTextureWrapS(Base3DTextureWrap eNew) +{ + if(eNew != eWrapS) + { + eWrapS = eNew; + bTextureKindChanged = TRUE; + } +} + +/************************************************************************* +|* +|* Art des Wrappings in Y setzen +|* +\************************************************************************/ + +void B3dTexture::SetTextureWrapT(Base3DTextureWrap eNew) +{ + if(eNew != eWrapT) + { + eWrapT = eNew; + bTextureKindChanged = TRUE; + } +} + +/************************************************************************* +|* +|* Blend-Color lesen/bestimmen +|* +\************************************************************************/ + +void B3dTexture::SetBlendColor(Color rNew) +{ + if(rNew.GetRed() != aColBlend.GetRed() + || rNew.GetGreen() != aColBlend.GetGreen() + || rNew.GetBlue() != aColBlend.GetBlue()) + { + aColBlend.SetRed(rNew.GetRed()); + aColBlend.SetGreen(rNew.GetGreen()); + aColBlend.SetBlue(rNew.GetBlue()); + if(eWrapS == Base3DTextureSingle || eWrapT == Base3DTextureSingle) + bTextureKindChanged = TRUE; + } +} + +Color B3dTexture::GetBlendColor() +{ + Color aRetval(aColBlend.GetRed(), + aColBlend.GetGreen(), + aColBlend.GetBlue()); + return aRetval; +} + +/************************************************************************* +|* +|* Textur-Ersatz-Color lesen/bestimmen +|* +\************************************************************************/ + +void B3dTexture::SetTextureColor(Color rNew) +{ + if(rNew.GetRed() != aColTexture.GetRed() + || rNew.GetGreen() != aColTexture.GetGreen() + || rNew.GetBlue() != aColTexture.GetBlue()) + { + aColTexture.SetRed(rNew.GetRed()); + aColTexture.SetGreen(rNew.GetGreen()); + aColTexture.SetBlue(rNew.GetBlue()); + if(eWrapS == Base3DTextureSingle || eWrapT == Base3DTextureSingle) + bTextureKindChanged = TRUE; + } +} + +Color B3dTexture::GetTextureColor() +{ + Color aRetval(aColTexture.GetRed(), + aColTexture.GetGreen(), + aColTexture.GetBlue()); + return aRetval; +} + +/************************************************************************* +|* +|* Internen Verteilungswert setzen +|* +\************************************************************************/ + +void B3dTexture::SetSwitchVal() +{ + nSwitchVal = 0; + + // Kind + if(GetTextureKind() == Base3DTextureLuminance) + nSwitchVal |= B3D_TXT_KIND_LUM; + else if(GetTextureKind() == Base3DTextureIntensity) + nSwitchVal |= B3D_TXT_KIND_INT; + else if(GetTextureKind() == Base3DTextureColor) + nSwitchVal |= B3D_TXT_KIND_COL; + + // Mode + if(GetTextureMode() == Base3DTextureReplace) + nSwitchVal |= B3D_TXT_MODE_REP; + else if(GetTextureMode() == Base3DTextureModulate) + nSwitchVal |= B3D_TXT_MODE_MOD; + else if(GetTextureMode() == Base3DTextureBlend) + nSwitchVal |= B3D_TXT_MODE_BND; + + // Filter + if(GetTextureFilter() == Base3DTextureNearest) + nSwitchVal |= B3D_TXT_FLTR_NEA; +} + +/************************************************************************* +|* +|* Zugriffsfunktion auf die Farben der Bitmap +|* +\************************************************************************/ + +const BitmapColor B3dTexture::GetBitmapColor(long nX, long nY) +{ + return pReadAccess->GetColor(nY, nX); +} + +/************************************************************************* +|* +|* Art der Pixeldaten lesen/bestimmen +|* +\************************************************************************/ + +void B3dTexture::SetTextureKind(Base3DTextureKind eNew) +{ + if(eKind != eNew) + { + eKind = eNew; + bTextureKindChanged = TRUE; + } + SetSwitchVal(); +} + +/************************************************************************* +|* +|* Texturmodus lesen/bestimmen +|* +\************************************************************************/ + +void B3dTexture::SetTextureMode(Base3DTextureMode eNew) +{ + eMode = eNew; + SetSwitchVal(); +} + +/************************************************************************* +|* +|* Filtermodus lesen/bestimmen +|* +\************************************************************************/ + +void B3dTexture::SetTextureFilter(Base3DTextureFilter eNew) +{ + eFilter = eNew; + SetSwitchVal(); +} + +/************************************************************************* +|* +|* Die Texturfunktion selbst. Die ursruengliche Farbe des Punktes +|* innerhalb der Grenzen des Parameterbereiches S,T (in Bitmapkoordinaten) +|* wird modifiziert. +|* +\************************************************************************/ + +void B3dTexture::ModifyColor(Color& rCol, double fS, double fT) +{ + // Integer-Koordinaten der Texturposition bilden + long nX((long)fS); + long nY((long)fT); + BitmapColor aBmCol = aColTexture; + BOOL bOnTexture(TRUE); + + // Wrapping in S-Richtung + if(eWrapS == Base3DTextureClamp) + { + // Clamping + if(nX < 0) + nX = 0; + else if(nX >= GetBitmapSize().Width()) + nX = GetBitmapSize().Width() - 1; + } + else if(eWrapS == Base3DTextureRepeat) + { + // Repeating + nX %= GetBitmapSize().Width(); + if(nX < 0) + nX += GetBitmapSize().Width(); + } + else + { + // Single + if(nX < 0 || nX >= GetBitmapSize().Width()) + bOnTexture = FALSE; + } + + // Wrapping in T-Richtung + if(bOnTexture) + { + if(eWrapT == Base3DTextureClamp) + { + // Clamping + if(nY < 0) + nY = 0; + else if(nY >= GetBitmapSize().Height()) + nY = GetBitmapSize().Height() - 1; + } + else if(eWrapT == Base3DTextureRepeat) + { + // Repeating + nY %= GetBitmapSize().Height(); + if(nY < 0) + nY += GetBitmapSize().Height(); + } + else + { + // Single + if(nY < 0 || nY >= GetBitmapSize().Height()) + bOnTexture = FALSE; + } + + if(bOnTexture) + aBmCol = pReadAccess->GetColor(nY, nX); + } + + // Falls die Position nicht innerhalb der Textur ist, auch das Filtern + // unterdruecken um keine falschen BitmapAcesses zu bekommen + UINT8 nLocalSwitchVal(nSwitchVal); + if(!bOnTexture) + nLocalSwitchVal |= B3D_TXT_FLTR_NEA; + + switch(nLocalSwitchVal) + { + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_REP|B3D_TXT_KIND_COL) : + { + rCol.SetRed(aBmCol.GetRed()); + rCol.SetGreen(aBmCol.GetGreen()); + rCol.SetBlue(aBmCol.GetBlue()); + break; + } + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_MOD|B3D_TXT_KIND_COL) : + { + rCol.SetRed((UINT8)( ((UINT16)rCol.GetRed() * (UINT16)aBmCol.GetRed())>>8 )); + rCol.SetGreen((UINT8)( ((UINT16)rCol.GetGreen() * (UINT16)aBmCol.GetGreen())>>8 )); + rCol.SetBlue((UINT8)( ((UINT16)rCol.GetBlue() * (UINT16)aBmCol.GetBlue())>>8 )); + break; + } + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_BND|B3D_TXT_KIND_COL) : + { + rCol.SetRed((UINT8)( ((UINT16)rCol.GetRed() * (0x00ff - (UINT16)aBmCol.GetRed())) + + ((UINT16)aColBlend.GetRed() * (UINT16)aBmCol.GetRed()) )); + rCol.SetGreen((UINT8)( ((UINT16)rCol.GetGreen() * (0x00ff - (UINT16)aBmCol.GetGreen())) + + ((UINT16)aColBlend.GetGreen() * (UINT16)aBmCol.GetGreen()) )); + rCol.SetBlue((UINT8)( ((UINT16)rCol.GetBlue() * (0x00ff - (UINT16)aBmCol.GetBlue())) + + ((UINT16)aColBlend.GetBlue() * (UINT16)aBmCol.GetBlue()) )); + break; + } + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_REP|B3D_TXT_KIND_INT) : + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_REP|B3D_TXT_KIND_LUM) : + { + rCol.SetRed((aBmCol.GetRed() + aBmCol.GetGreen() + aBmCol.GetBlue()) / 3); + rCol.SetGreen(rCol.GetRed()); + rCol.SetBlue(rCol.GetRed()); + break; + } + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_MOD|B3D_TXT_KIND_INT) : + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_MOD|B3D_TXT_KIND_LUM) : + { + UINT16 nMidCol = (aBmCol.GetRed() + aBmCol.GetGreen() + aBmCol.GetBlue()) / 3; + rCol.SetRed((UINT8)( ((UINT16)rCol.GetRed() * nMidCol)>>8 )); + rCol.SetGreen((UINT8)( ((UINT16)rCol.GetGreen() * nMidCol)>>8 )); + rCol.SetBlue((UINT8)( ((UINT16)rCol.GetBlue() * nMidCol)>>8 )); + break; + } + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_BND|B3D_TXT_KIND_INT) : + case (B3D_TXT_FLTR_NEA|B3D_TXT_MODE_BND|B3D_TXT_KIND_LUM) : + { + UINT16 nMidCol = (aBmCol.GetRed() + aBmCol.GetGreen() + aBmCol.GetBlue()) / 3; + UINT16 nInvMidCol = 0x00ff - nMidCol; + rCol.SetRed((UINT8)( ((UINT16)rCol.GetRed() * nInvMidCol) + + ((UINT16)aColBlend.GetRed() * nMidCol) )); + rCol.SetGreen((UINT8)( ((UINT16)rCol.GetGreen() * nInvMidCol) + + ((UINT16)aColBlend.GetGreen() * nMidCol) )); + rCol.SetBlue((UINT8)( ((UINT16)rCol.GetBlue() * nInvMidCol) + + ((UINT16)aColBlend.GetBlue() * nMidCol) )); + break; + } + case (B3D_TXT_MODE_REP|B3D_TXT_KIND_COL) : + { + fS = fS - floor(fS); + fT = fT - floor(fT); + long nX2, nY2; + + if(fS > 0.5) { + nX2 = (nX + 1) % GetBitmapSize().Width(); + fS = 1.0 - fS; + } else + nX2 = nX ? nX - 1 : GetBitmapSize().Width() - 1; + + if(fT > 0.5) { + nY2 = (nY + 1) % GetBitmapSize().Height(); + fT = 1.0 - fT; + } else + nY2 = nY ? nY - 1 : GetBitmapSize().Height() - 1; + + fS += 0.5; + fT += 0.5; + double fRight = 1.0 - fS; + double fBottom = 1.0 - fT; + + BitmapColor aColTL = pReadAccess->GetColor(nY, nX); + BitmapColor aColTR = pReadAccess->GetColor(nY, nX2); + BitmapColor aColBL = pReadAccess->GetColor(nY2, nX); + BitmapColor aColBR = pReadAccess->GetColor(nY2, nX2); + + rCol.SetRed((UINT8)(((double)aColTL.GetRed() * fS + (double)aColTR.GetRed() * fRight) * fT + + ((double)aColBL.GetRed() * fS + (double)aColBR.GetRed() * fRight) * fBottom)); + rCol.SetGreen((UINT8)(((double)aColTL.GetGreen() * fS + (double)aColTR.GetGreen() * fRight) * fT + + ((double)aColBL.GetGreen() * fS + (double)aColBR.GetGreen() * fRight) * fBottom)); + rCol.SetBlue((UINT8)(((double)aColTL.GetBlue() * fS + (double)aColTR.GetBlue() * fRight) * fT + + ((double)aColBL.GetBlue() * fS + (double)aColBR.GetBlue() * fRight) * fBottom)); + break; + } + case (B3D_TXT_MODE_MOD|B3D_TXT_KIND_COL) : + { + fS = fS - floor(fS); + fT = fT - floor(fT); + long nX2, nY2; + + if(fS > 0.5) { + nX2 = (nX + 1) % GetBitmapSize().Width(); + fS = 1.0 - fS; + } else + nX2 = nX ? nX - 1 : GetBitmapSize().Width() - 1; + + if(fT > 0.5) { + nY2 = (nY + 1) % GetBitmapSize().Height(); + fT = 1.0 - fT; + } else + nY2 = nY ? nY - 1 : GetBitmapSize().Height() - 1; + + fS += 0.5; + fT += 0.5; + double fRight = 1.0 - fS; + double fBottom = 1.0 - fT; + + BitmapColor aColTL = pReadAccess->GetColor(nY, nX); + BitmapColor aColTR = pReadAccess->GetColor(nY, nX2); + BitmapColor aColBL = pReadAccess->GetColor(nY2, nX); + BitmapColor aColBR = pReadAccess->GetColor(nY2, nX2); + + double fRed = ((double)aColTL.GetRed() * fS + (double)aColTR.GetRed() * fRight) * fT + + ((double)aColBL.GetRed() * fS + (double)aColBR.GetRed() * fRight) * fBottom; + double fGreen = ((double)aColTL.GetGreen() * fS + (double)aColTR.GetGreen() * fRight) * fT + + ((double)aColBL.GetGreen() * fS + (double)aColBR.GetGreen() * fRight) * fBottom; + double fBlue = ((double)aColTL.GetBlue() * fS + (double)aColTR.GetBlue() * fRight) * fT + + ((double)aColBL.GetBlue() * fS + (double)aColBR.GetBlue() * fRight) * fBottom; + + rCol.SetRed((UINT8)(((double)rCol.GetRed() * fRed) / 255.0)); + rCol.SetGreen((UINT8)(((double)rCol.GetGreen() * fGreen) / 255.0)); + rCol.SetBlue((UINT8)(((double)rCol.GetBlue() * fBlue) / 255.0)); + break; + } + case (B3D_TXT_MODE_BND|B3D_TXT_KIND_COL) : + { + fS = fS - floor(fS); + fT = fT - floor(fT); + long nX2, nY2; + + if(fS > 0.5) { + nX2 = (nX + 1) % GetBitmapSize().Width(); + fS = 1.0 - fS; + } else + nX2 = nX ? nX - 1 : GetBitmapSize().Width() - 1; + + if(fT > 0.5) { + nY2 = (nY + 1) % GetBitmapSize().Height(); + fT = 1.0 - fT; + } else + nY2 = nY ? nY - 1 : GetBitmapSize().Height() - 1; + + fS += 0.5; + fT += 0.5; + double fRight = 1.0 - fS; + double fBottom = 1.0 - fT; + + BitmapColor aColTL = pReadAccess->GetColor(nY, nX); + BitmapColor aColTR = pReadAccess->GetColor(nY, nX2); + BitmapColor aColBL = pReadAccess->GetColor(nY2, nX); + BitmapColor aColBR = pReadAccess->GetColor(nY2, nX2); + + double fRed = ((double)aColTL.GetRed() * fS + (double)aColTR.GetRed() * fRight) * fT + + ((double)aColBL.GetRed() * fS + (double)aColBR.GetRed() * fRight) * fBottom; + double fGreen = ((double)aColTL.GetGreen() * fS + (double)aColTR.GetGreen() * fRight) * fT + + ((double)aColBL.GetGreen() * fS + (double)aColBR.GetGreen() * fRight) * fBottom; + double fBlue = ((double)aColTL.GetBlue() * fS + (double)aColTR.GetBlue() * fRight) * fT + + ((double)aColBL.GetBlue() * fS + (double)aColBR.GetBlue() * fRight) * fBottom; + + rCol.SetRed((UINT8)((((double)rCol.GetRed() * (255.0 - fRed)) + ((double)aColBlend.GetRed() * fRed)) / 255.0)); + rCol.SetGreen((UINT8)((((double)rCol.GetGreen() * (255.0 - fGreen)) + ((double)aColBlend.GetGreen() * fGreen)) / 255.0)); + rCol.SetBlue((UINT8)((((double)rCol.GetBlue() * (255.0 - fBlue)) + ((double)aColBlend.GetBlue() * fBlue)) / 255.0)); + break; + } + case (B3D_TXT_MODE_REP|B3D_TXT_KIND_INT) : + case (B3D_TXT_MODE_REP|B3D_TXT_KIND_LUM) : + { + fS = fS - floor(fS); + fT = fT - floor(fT); + long nX2, nY2; + + if(fS > 0.5) { + nX2 = (nX + 1) % GetBitmapSize().Width(); + fS = 1.0 - fS; + } else + nX2 = nX ? nX - 1 : GetBitmapSize().Width() - 1; + + if(fT > 0.5) { + nY2 = (nY + 1) % GetBitmapSize().Height(); + fT = 1.0 - fT; + } else + nY2 = nY ? nY - 1 : GetBitmapSize().Height() - 1; + + fS += 0.5; + fT += 0.5; + double fRight = 1.0 - fS; + double fBottom = 1.0 - fT; + + UINT8 nMidVal = (UINT8)(( + (double)pReadAccess->GetLuminance(nY, nX) * fS + + (double)pReadAccess->GetLuminance(nY, nX2) * fRight) * fT + ( + (double)pReadAccess->GetLuminance(nY2, nX) * fS + + (double)pReadAccess->GetLuminance(nY2, nX2) * fRight) * fBottom); + + rCol.SetRed(nMidVal); + rCol.SetGreen(nMidVal); + rCol.SetBlue(nMidVal); + break; + } + case (B3D_TXT_MODE_MOD|B3D_TXT_KIND_INT) : + case (B3D_TXT_MODE_MOD|B3D_TXT_KIND_LUM) : + { + fS = fS - floor(fS); + fT = fT - floor(fT); + long nX2, nY2; + + if(fS > 0.5) { + nX2 = (nX + 1) % GetBitmapSize().Width(); + fS = 1.0 - fS; + } else + nX2 = nX ? nX - 1 : GetBitmapSize().Width() - 1; + + if(fT > 0.5) { + nY2 = (nY + 1) % GetBitmapSize().Height(); + fT = 1.0 - fT; + } else + nY2 = nY ? nY - 1 : GetBitmapSize().Height() - 1; + + fS += 0.5; + fT += 0.5; + double fRight = 1.0 - fS; + double fBottom = 1.0 - fT; + + double fMidVal = ( + (double)pReadAccess->GetLuminance(nY, nX) * fS + + (double)pReadAccess->GetLuminance(nY, nX2) * fRight) * fT + ( + (double)pReadAccess->GetLuminance(nY2, nX) * fS + + (double)pReadAccess->GetLuminance(nY2, nX2) * fRight) * fBottom; + + rCol.SetRed((UINT8)(((double)rCol.GetRed() * fMidVal) / 255.0)); + rCol.SetGreen((UINT8)(((double)rCol.GetGreen() * fMidVal) / 255.0)); + rCol.SetBlue((UINT8)(((double)rCol.GetBlue() * fMidVal) / 255.0)); + break; + } + case (B3D_TXT_MODE_BND|B3D_TXT_KIND_INT) : + case (B3D_TXT_MODE_BND|B3D_TXT_KIND_LUM) : + { + fS = fS - floor(fS); + fT = fT - floor(fT); + long nX2, nY2; + + if(fS > 0.5) { + nX2 = (nX + 1) % GetBitmapSize().Width(); + fS = 1.0 - fS; + } else + nX2 = nX ? nX - 1 : GetBitmapSize().Width() - 1; + + if(fT > 0.5) { + nY2 = (nY + 1) % GetBitmapSize().Height(); + fT = 1.0 - fT; + } else + nY2 = nY ? nY - 1 : GetBitmapSize().Height() - 1; + + fS += 0.5; + fT += 0.5; + double fRight = 1.0 - fS; + double fBottom = 1.0 - fT; + + double fMidVal = ( + (double)pReadAccess->GetLuminance(nY, nX) * fS + + (double)pReadAccess->GetLuminance(nY, nX2) * fRight) * fT + ( + (double)pReadAccess->GetLuminance(nY2, nX) * fS + + (double)pReadAccess->GetLuminance(nY2, nX2) * fRight) * fBottom; + double fInvMidVal(255.0 - fMidVal); + + rCol.SetRed((UINT8)((((double)rCol.GetRed() * fInvMidVal) + ((double)aColBlend.GetRed() * fMidVal)) / 255.0)); + rCol.SetGreen((UINT8)((((double)rCol.GetGreen() * fInvMidVal) + ((double)aColBlend.GetGreen() * fMidVal)) / 255.0)); + rCol.SetBlue((UINT8)((((double)rCol.GetBlue() * fInvMidVal) + ((double)aColBlend.GetBlue() * fMidVal)) / 255.0)); + break; + } + } + +// Funktionsfaehige Version komplett auf double precision und +// kuerzesten Pfaden +// +// // Parameter fuer Farbe der Texturstelle bereitstellen +// double fRed, fGreen, fBlue; +// +// // Eventuell glaetten? +// if(GetTextureFilter() == Base3DTextureLinear) +// { +// // Filtern +// double fLeft = fS - floor(fS); +// double fTop = fT - floor(fT); +// double fRight, fBottom; +// long nX2, nY2; +// +// if(fLeft > 0.5) +// { +// nX2 = (nX + 1) % GetBitmapSize().Width(); +// fLeft = (1.0 - fLeft) + 0.5; +// fRight = 1.0 - fLeft; +// } +// else +// { +// nX2 = nX ? nX - 1 : GetBitmapSize().Width() - 1; +// fLeft = fLeft + 0.5; +// fRight = 1.0 - fLeft; +// } +// +// +// if(fTop > 0.5) +// { +// nY2 = (nY + 1) % GetBitmapSize().Height(); +// fTop = (1.0 - fTop) + 0.5; +// fBottom = 1.0 - fTop; +// } +// else +// { +// nY2 = nY ? nY - 1 : GetBitmapSize().Height() - 1; +// fTop = fTop + 0.5; +// fBottom = 1.0 - fTop; +// } +// +// const BitmapColor& rColTL = GetBitmapColor(nX, nY); +// const BitmapColor& rColTR = GetBitmapColor(nX2, nY); +// const BitmapColor& rColBL = GetBitmapColor(nX, nY2); +// const BitmapColor& rColBR = GetBitmapColor(nX2, nY2); +// +// fRed = ((double)rColTL.GetRed() * fLeft + (double)rColTR.GetRed() * fRight) * fTop +// + ((double)rColBL.GetRed() * fLeft + (double)rColBR.GetRed() * fRight) * fBottom; +// +// fGreen = ((double)rColTL.GetGreen() * fLeft + (double)rColTR.GetGreen() * fRight) * fTop +// + ((double)rColBL.GetGreen() * fLeft + (double)rColBR.GetGreen() * fRight) * fBottom; +// +// fBlue = ((double)rColTL.GetBlue() * fLeft + (double)rColTR.GetBlue() * fRight) * fTop +// + ((double)rColBL.GetBlue() * fLeft + (double)rColBR.GetBlue() * fRight) * fBottom; +// } +// else +// { +// // Nearest Pixel +// const BitmapColor& rBmCol = GetBitmapColor(nX, nY); +// fRed = (double)rBmCol.GetRed(); +// fGreen = (double)rBmCol.GetGreen(); +// fBlue = (double)rBmCol.GetBlue(); +// } +// +// // Jetzt anhand der TextureKind entscheiden +// if(eKind == Base3DTextureColor) +// { +// if(eMode == Base3DTextureReplace) +// { +// rCol.SetRed((UINT8)fRed); +// rCol.SetGreen((UINT8)fGreen); +// rCol.SetBlue((UINT8)fBlue); +// } +// else if(eMode == Base3DTextureModulate) +// { +// rCol.SetRed((UINT8)(((double)rCol.GetRed() * fRed) / 255.0)); +// rCol.SetGreen((UINT8)(((double)rCol.GetGreen() * fGreen) / 255.0)); +// rCol.SetBlue((UINT8)(((double)rCol.GetBlue() * fBlue) / 255.0)); +// } +// else // Base3DTextureBlend +// { +// rCol.SetRed((UINT8)((((double)rCol.GetRed() * (255.0 - fRed)) + ((double)aColBlend.GetRed() * fRed)) / 255.0)); +// rCol.SetGreen((UINT8)((((double)rCol.GetGreen() * (255.0 - fGreen)) + ((double)aColBlend.GetGreen() * fGreen)) / 255.0)); +// rCol.SetBlue((UINT8)((((double)rCol.GetBlue() * (255.0 - fBlue)) + ((double)aColBlend.GetBlue() * fBlue)) / 255.0)); +// } +// } +// else +// { +// double fMidVal((fRed + fGreen + fBlue) / 3.0); +// if(eMode == Base3DTextureReplace) +// { +// rCol.SetRed((UINT8)fMidVal); +// rCol.SetGreen((UINT8)fMidVal); +// rCol.SetBlue((UINT8)fMidVal); +// } +// else if(eMode == Base3DTextureModulate) +// { +// rCol.SetRed((UINT8)(((double)rCol.GetRed() * fMidVal) / 255.0)); +// rCol.SetGreen((UINT8)(((double)rCol.GetGreen() * fMidVal) / 255.0)); +// rCol.SetBlue((UINT8)(((double)rCol.GetBlue() * fMidVal) / 255.0)); +// } +// else // Base3DTextureBlend +// { +// double fInvMidVal(255.0 - fMidVal); +// rCol.SetRed((UINT8)((((double)rCol.GetRed() * fInvMidVal) + ((double)aColBlend.GetRed() * fRed)) / 255.0)); +// rCol.SetGreen((UINT8)((((double)rCol.GetGreen() * fInvMidVal) + ((double)aColBlend.GetGreen() * fGreen)) / 255.0)); +// rCol.SetBlue((UINT8)((((double)rCol.GetBlue() * fInvMidVal) + ((double)aColBlend.GetBlue() * fBlue)) / 255.0)); +// } +// } +} + +/************************************************************************* +|* +|* Konstruktor TexturOpenGL +|* +\************************************************************************/ + +B3dTextureOpenGL::B3dTextureOpenGL( + TextureAttributes& rAtt, + Bitmap& rBmp, + OpenGL& rOGL, + Base3DTextureKind eKnd, + Base3DTextureMode eMod, + Base3DTextureFilter eFlt, + Base3DTextureWrap eS, + Base3DTextureWrap eT) +: B3dTexture(rAtt, rBmp, eKnd, eMod, eFlt, eS, eT), + nTextureName(0) +{ + // TextureName anfordern + rOGL.GenTextures(1, &nTextureName); +} + +/************************************************************************* +|* +|* Destruktor TexturOpenGL +|* +\************************************************************************/ + +B3dTextureOpenGL::~B3dTextureOpenGL() +{ +} + +/************************************************************************* +|* +|* In OpenGL die Textur zerstoeren +|* +\************************************************************************/ + +void B3dTextureOpenGL::DestroyOpenGLTexture(OpenGL& rOpenGL) +{ + // OpenGL Textur wieder freigeben + rOpenGL.DeleteTextures(1, &nTextureName); +} + +/************************************************************************* +|* +|* Setze diese Textur in OpenGL als aktuelle Textur +|* +\************************************************************************/ + +void B3dTextureOpenGL::MakeCurrentTexture(OpenGL& rOpenGL) +{ + // Eventuell Textur erst erzeugen? + if(!rOpenGL.IsTexture(nTextureName) || bTextureKindChanged) + { + // Textur erzeugen und binden + CreateOpenGLTexture(rOpenGL); + } + else + { + // Jetzt Textur binden + rOpenGL.BindTexture(GL_TEXTURE_2D, nTextureName); + } + + // Nun die Parameter an der Textur setzen + switch(GetTextureWrapS()) + { + case Base3DTextureSingle : + case Base3DTextureClamp : + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + break; + case Base3DTextureRepeat : + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + break; + } + switch(GetTextureWrapT()) + { + case Base3DTextureSingle : + case Base3DTextureClamp : + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + break; + case Base3DTextureRepeat : + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + break; + } + switch(GetTextureFilter()) + { + case Base3DTextureNearest : + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case Base3DTextureLinear : + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + rOpenGL.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + } + switch(GetTextureMode()) + { + case Base3DTextureReplace : + rOpenGL.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + break; + case Base3DTextureModulate : + rOpenGL.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + break; + case Base3DTextureBlend : + { + rOpenGL.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); + float fArray[4] = { + ((float)GetBlendColor().GetRed()) / (float)255.0, + ((float)GetBlendColor().GetGreen()) / (float)255.0, + ((float)GetBlendColor().GetBlue()) / (float)255.0, + ((float)GetBlendColor().GetTransparency()) / (float)255.0 + }; + rOpenGL.TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, fArray); + break; + } + } +} + +/************************************************************************* +|* +|* Erzeuge diese Textur als OpenGL-Textur +|* +\************************************************************************/ + +void B3dTextureOpenGL::CreateOpenGLTexture(OpenGL& rOpenGL) +{ + Size aSize(0,0); + + // Groesse entscheiden (auf 1024 begrenzen) + for(UINT16 a=1;a<0x0400 && (!aSize.Width() || !aSize.Height());a<<=1) + { + if(!aSize.Width() && (a>=GetBitmapSize().Width())) + aSize.Width() = a; + if(!aSize.Height() && (a>=GetBitmapSize().Height())) + aSize.Height() = a; + } + + // begrenzen falls groesser als 1024 + if(!aSize.Width()) + aSize.Width() = 0x0400; + if(!aSize.Height()) + aSize.Height() = 0x0400; + + // Minimalgroesse garantieren, auch an 4Byte-Alignment denken + // falls hier mal geaendert wird... (siehe OpenGL Bitmap Befehle) + if(aSize.Width() < 8) + aSize.Width() = 8; + if(aSize.Height() < 8) + aSize.Height() = 8; + + // Skalierte Bitmap anlegen + Bitmap aBitmap(GetBitmap()); + if(aSize != GetBitmapSize()) + aBitmap.Scale((double)aSize.Width() / (double)GetBitmapSize().Width(), + (double)aSize.Height() / (double)GetBitmapSize().Height()); + + // Falls es sich um eine nur einmal zu wiederholende Bitmap + // handelt, lege nun eine mit einem definierten Rand an + if(GetTextureWrapS() == Base3DTextureSingle + || GetTextureWrapT() == Base3DTextureSingle) + { + Bitmap aHelpBitmap(aBitmap); + Size aNewSize(aSize); + Point aNewPos(0, 0); + + if(GetTextureWrapS() == Base3DTextureSingle) + { + aNewSize.Width() -= 4; + aNewPos.X() = 2; + } + if(GetTextureWrapT() == Base3DTextureSingle) + { + aNewSize.Height() -= 4; + aNewPos.Y() = 2; + } + + aHelpBitmap.Scale((double)aNewSize.Width() / (double)aSize.Width(), + (double)aNewSize.Height() / (double)aSize.Height()); + Color aEraseCol = GetTextureColor(); + aBitmap.Erase(aEraseCol); + Point aPoint; + Rectangle aCopySrc(aPoint, aNewSize); + Rectangle aCopyDest(aNewPos, aNewSize); + aBitmap.CopyPixel(aCopyDest, aCopySrc, &aHelpBitmap); + } + + // Lesezugriff auf neue Bitmap holen + BitmapReadAccess* pReadAccess = aBitmap.AcquireReadAccess(); + if(pReadAccess) + { + // Buffer holen + long nSize = aSize.Width() * aSize.Height(); + if(GetTextureKind() == Base3DTextureColor) + nSize *= 3; + GL_UINT8 pBuffer = (GL_UINT8)SvMemAlloc(nSize); + + if(pBuffer) + { + // Daten kopieren + GL_UINT8 pRunner = pBuffer; + if(GetTextureKind() == Base3DTextureColor) + { + if(pReadAccess->HasPalette()) + { + for(long a=0;a<aSize.Height();a++) + { + for(long b=0;b<aSize.Width();b++) + { + const BitmapColor& rCol = pReadAccess->GetPaletteColor( + pReadAccess->GetPixel(a, b)); + *pRunner++ = rCol.GetRed(); + *pRunner++ = rCol.GetGreen(); + *pRunner++ = rCol.GetBlue(); + } + } + } + else + { + for(long a=0;a<aSize.Height();a++) + { + for(long b=0;b<aSize.Width();b++) + { + const BitmapColor& rCol = pReadAccess->GetPixel(a, b); + *pRunner++ = rCol.GetRed(); + *pRunner++ = rCol.GetGreen(); + *pRunner++ = rCol.GetBlue(); + } + } + } + } + else + { + if(pReadAccess->HasPalette()) + { + for(long a=0;a<aSize.Height();a++) + { + for(long b=0;b<aSize.Width();b++) + { + const BitmapColor& rCol = pReadAccess->GetPaletteColor( + pReadAccess->GetPixel(a, b)); + *pRunner++ = (rCol.GetRed() + rCol.GetGreen() + rCol.GetBlue()) / 3; + } + } + } + else + { + for(long a=0;a<aSize.Height();a++) + { + for(long b=0;b<aSize.Width();b++) + { + const BitmapColor& rCol = pReadAccess->GetPixel(a, b); + *pRunner++ = (rCol.GetRed() + rCol.GetGreen() + rCol.GetBlue()) / 3; + } + } + } + } + + // Textur das erste mal binden und damit initialisieren + rOpenGL.BindTexture(GL_TEXTURE_2D, nTextureName); + + // Jetzt ein glTexImage2D() ausfuehren + GLint nInternalFormat; + GLint nFormat; + + switch(GetTextureKind()) + { + case Base3DTextureLuminance: + nInternalFormat = GL_LUMINANCE; + nFormat = GL_LUMINANCE; + break; + case Base3DTextureIntensity: + nInternalFormat = GL_INTENSITY; + nFormat = GL_LUMINANCE; + break; + case Base3DTextureColor: + nInternalFormat = GL_RGB; + nFormat = GL_RGB; + break; + } + + rOpenGL.TexImage2D(GL_TEXTURE_2D, 0, nInternalFormat, + (GLsizei)aSize.Width(), + (GLsizei)aSize.Height(), + 0, nFormat, GL_UNSIGNED_BYTE, pBuffer); + + SvMemFree(pBuffer); + } + + // Lesezugriff freigeben + aBitmap.ReleaseAccess(pReadAccess); + } + + // Hinweis auf Veraenderung der Texturart auf jeden Fall elliminieren + bTextureKindChanged = FALSE; +} + diff --git a/goodies/source/base3d/b3dtrans.cxx b/goodies/source/base3d/b3dtrans.cxx new file mode 100644 index 000000000000..0765e2adc001 --- /dev/null +++ b/goodies/source/base3d/b3dtrans.cxx @@ -0,0 +1,936 @@ +/************************************************************************* + * + * $RCSfile: b3dtrans.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_B3DTRANS_HXX +#include "b3dtrans.hxx" +#endif + +#ifndef _B3D_BASE3D_HXX +#include "base3d.hxx" +#endif + +#ifndef _B3D_VOLUM_HXX +#include "b3dvolum.hxx" +#endif + +/************************************************************************* +|* +|* Transformationen fuer alle 3D Ausgaben +|* +\************************************************************************/ + +B3dTransformationSet::B3dTransformationSet() +{ + Reset(); +} + +/************************************************************************* +|* +|* Reset der Werte +|* +\************************************************************************/ + +void B3dTransformationSet::Reset() +{ + // Matritzen auf Einheitsmatritzen + aObjectTrans.Identity(); + PostSetObjectTrans(); + + aOrientation.Orientation(); + PostSetOrientation(); + + aTexture.Identity(); + + fLeftBound = fBottomBound = -1.0; + fRightBound = fTopBound = 1.0; + fNearBound = 0.001; + fFarBound = 1.001; + + eRatio = Base3DRatioGrow; + fRatio = 0.0; + + aViewportRectangle = Rectangle(-1, -1, 2, 2); + aVisibleRectangle = aViewportRectangle; + + bPerspective = TRUE; + + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + + CalcViewport(); +} + +/************************************************************************* +|* +|* Objekttransformation +|* +\************************************************************************/ + +void B3dTransformationSet::SetObjectTrans(Matrix4D& rObj) +{ + aObjectTrans = rObj; + + bObjectToDeviceValid = FALSE; + bInvTransObjectToEyeValid = FALSE; + + PostSetObjectTrans(); +} + +void B3dTransformationSet::PostSetObjectTrans() +{ + // Zuweisen und Inverse bestimmen + aInvObjectTrans = aObjectTrans; + aInvObjectTrans.Invert(); +} + +/************************************************************************* +|* +|* Orientierungstransformation +|* +\************************************************************************/ + +#ifndef ICC +void B3dTransformationSet::SetOrientation( Vector3D& aVRP, Vector3D& aVPN, Vector3D& aVUP) +#else +void B3dTransformationSet::SetOrientation( Vector3D aVRP, Vector3D aVPN, Vector3D aVUP) +#endif +{ + aOrientation.Identity(); + aOrientation.Orientation(Point4D(aVRP), aVPN, aVUP); + + bInvTransObjectToEyeValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + + PostSetOrientation(); +} + +void B3dTransformationSet::SetOrientation(Matrix4D& mOrient) +{ + aOrientation = mOrient; + + bInvTransObjectToEyeValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + + PostSetOrientation(); +} + +void B3dTransformationSet::PostSetOrientation() +{ + // Zuweisen und Inverse bestimmen + aInvOrientation = aOrientation; + aInvOrientation.Invert(); +} + +/************************************************************************* +|* +|* Projektionstransformation +|* +\************************************************************************/ + +void B3dTransformationSet::SetProjection(Matrix4D& mProject) +{ + aProjection = mProject; + PostSetProjection(); +} + +const Matrix4D& B3dTransformationSet::GetProjection() +{ + if(!bProjectionValid) + CalcViewport(); + return aProjection; +} + +const Matrix4D& B3dTransformationSet::GetInvProjection() +{ + if(!bProjectionValid) + CalcViewport(); + return aInvProjection; +} + +void B3dTransformationSet::PostSetProjection() +{ + // Zuweisen und Inverse bestimmen + aInvProjection = GetProjection(); + aInvProjection.Invert(); + + // Abhaengige Matritzen invalidieren + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; +} + +/************************************************************************* +|* +|* Texturtransformation +|* +\************************************************************************/ + +void B3dTransformationSet::SetTexture(Matrix4D& rTxt) +{ + aTexture = rTxt; + PostSetTexture(); +} + +void B3dTransformationSet::PostSetTexture() +{ +} + +/************************************************************************* +|* +|* Viewport-Transformation +|* +\************************************************************************/ + +void B3dTransformationSet::CalcViewport() +{ + // Faktoren fuer die Projektion + double fLeft = fLeftBound; + double fRight = fRightBound; + double fBottom = fBottomBound; + double fTop = fTopBound; + + // Soll das Seitenverhaeltnis Beachtung finden? + // Falls ja, Bereich der Projektion an Seitenverhaeltnis anpassen + if(GetRatio() != 0.0) + { + // Berechne aktuelles Seitenverhaeltnis der Bounds + double fBoundWidth = (double)(aViewportRectangle.GetWidth() + 1); + double fBoundHeight = (double)(aViewportRectangle.GetHeight() + 1); + double fActRatio; + double fFactor; + + if(fBoundWidth != 0.0) + fActRatio = fBoundHeight / fBoundWidth; + + switch(eRatio) + { + case Base3DRatioShrink : + { + // Kleineren Teil vergroessern + if(fActRatio > fRatio) + { + // X vergroessern + fFactor = 1.0 / fActRatio; + fRight *= fFactor; + fLeft *= fFactor; + } + else + { + // Y vergroessern + fFactor = fActRatio; + fTop *= fFactor; + fBottom *= fFactor; + } + break; + } + case Base3DRatioGrow : + { + // GroesserenTeil verkleinern + if(fActRatio > fRatio) + { + // Y verkleinern + fFactor = fActRatio; + fTop *= fFactor; + fBottom *= fFactor; + } + else + { + // X verkleinern + fFactor = 1.0 / fActRatio; + fRight *= fFactor; + fLeft *= fFactor; + } + break; + } + case Base3DRatioMiddle : + { + // Mitteln + fFactor = ((1.0 / fActRatio) + 1.0) / 2.0; + fRight *= fFactor; + fLeft *= fFactor; + fFactor = (fActRatio + 1.0) / 2.0; + fTop *= fFactor; + fBottom *= fFactor; + break; + } + } + } + + // Ueberschneiden sich Darstellungsflaeche und Objektflaeche? + aSetBound = aViewportRectangle; + + // Mit den neuen Werten Projektion und ViewPort setzen + Matrix4D aNewProjection; + double fDistPart = (fFarBound - fNearBound) * SMALL_DVALUE; + + // Near, Far etwas grosszuegiger setzen, um falsches, + // zu kritisches clippen zu verhindern + if(bPerspective) + aNewProjection.Frustum(fLeft, fRight, fBottom, fTop, + fNearBound - fDistPart, fFarBound + fDistPart); + else + aNewProjection.Ortho(fLeft, fRight, fBottom, fTop, + fNearBound - fDistPart, fFarBound + fDistPart); + + // jetzt schon auf gueltig setzen um Endlosschleife zu vermeiden + bProjectionValid = TRUE; + + // Neue Projektion setzen + SetProjection(aNewProjection); + + // fill parameters for ViewportTransformation + // Translation + aTranslate[0] = (double)aSetBound.Left() + ((aSetBound.GetWidth() - 1L) / 2.0); + aTranslate[1] = (double)aSetBound.Top() + ((aSetBound.GetHeight() - 1L) / 2.0); + aTranslate[2] = ZBUFFER_DEPTH_RANGE / 2.0; + + // Skalierung + aScale[0] = (aSetBound.GetWidth() - 1L) / 2.0; + aScale[1] = (aSetBound.GetHeight() - 1L) / -2.0; + aScale[2] = ZBUFFER_DEPTH_RANGE / 2.0; + + // Auf Veraenderung des ViewPorts reagieren + PostSetViewport(); +} + +void B3dTransformationSet::SetRatio(double fNew) +{ + if(fRatio != fNew) + { + fRatio = fNew; + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + } +} + +void B3dTransformationSet::SetRatioMode(Base3DRatio eNew) +{ + if(eRatio != eNew) + { + eRatio = eNew; + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + } +} + +void B3dTransformationSet::SetDeviceRectangle(double fL, double fR, double fB, double fT, + BOOL bBroadCastChange) +{ + if(fL != fLeftBound || fR != fRightBound || fB != fBottomBound || fT != fTopBound) + { + fLeftBound = fL; + fRightBound = fR; + fBottomBound = fB; + fTopBound = fT; + + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + + // Aenderung bekanntmachen + if(bBroadCastChange) + DeviceRectangleChange(); + } +} + +void B3dTransformationSet::SetDeviceVolume(const B3dVolume& rVol, BOOL bBroadCastChange) +{ + SetDeviceRectangle(rVol.MinVec().X(), rVol.MaxVec().X(), + rVol.MinVec().Y(), rVol.MaxVec().Y(), bBroadCastChange); + SetFrontClippingPlane(rVol.MinVec().Z()); + SetBackClippingPlane(rVol.MaxVec().Z()); +} + +void B3dTransformationSet::DeviceRectangleChange() +{ +} + +void B3dTransformationSet::GetDeviceRectangle(double &fL, double &fR, double& fB, double& fT) +{ + fL = fLeftBound; + fR = fRightBound; + fB = fBottomBound; + fT = fTopBound; + + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; +} + +B3dVolume B3dTransformationSet::GetDeviceVolume() +{ + B3dVolume aRet; + aRet.MinVec() = Vector3D(fLeftBound, fBottomBound, fNearBound); + aRet.MaxVec() = Vector3D(fRightBound, fTopBound, fFarBound); + return aRet; +} + +void B3dTransformationSet::SetFrontClippingPlane(double fF) +{ + if(fNearBound != fF) + { + fNearBound = fF; + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + } +} + +void B3dTransformationSet::SetBackClippingPlane(double fB) +{ + if(fFarBound != fB) + { + fFarBound = fB; + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + } +} + +void B3dTransformationSet::SetPerspective(BOOL bNew) +{ + if(bPerspective != bNew) + { + bPerspective = bNew; + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + } +} + +void B3dTransformationSet::SetViewportRectangle(Rectangle& rRect, Rectangle& rVisible) +{ + if(rRect != aViewportRectangle || rVisible != aVisibleRectangle) + { + aViewportRectangle = rRect; + aVisibleRectangle = rVisible; + + bProjectionValid = FALSE; + bObjectToDeviceValid = FALSE; + bWorldToViewValid = FALSE; + } +} + +void B3dTransformationSet::PostSetViewport() +{ +} + +const Rectangle& B3dTransformationSet::GetLogicalViewportBounds() +{ + if(!bProjectionValid) + CalcViewport(); + return aSetBound; +} + +const Vector3D& B3dTransformationSet::GetScale() +{ + if(!bProjectionValid) + CalcViewport(); + return aScale; +} + +const Vector3D& B3dTransformationSet::GetTranslate() +{ + if(!bProjectionValid) + CalcViewport(); + return aTranslate; +} + +/************************************************************************* +|* +|* Hilfsmatrixberechnungsroutinen +|* +\************************************************************************/ + +void B3dTransformationSet::CalcMatObjectToDevice() +{ + // ObjectToDevice berechnen (Orientation * Projection * Object) + aObjectToDevice = aObjectTrans; + aObjectToDevice *= aOrientation; + aObjectToDevice *= GetProjection(); + + // auf gueltig setzen + bObjectToDeviceValid = TRUE; +} + +const Matrix4D& B3dTransformationSet::GetObjectToDevice() +{ + if(!bObjectToDeviceValid) + CalcMatObjectToDevice(); + return aObjectToDevice; +} + +void B3dTransformationSet::CalcMatInvTransObjectToEye() +{ + aInvTransObjectToEye = aObjectTrans; + aInvTransObjectToEye *= aOrientation; + aInvTransObjectToEye.Invert(); + aInvTransObjectToEye.Transpose(); + + // eventuelle Translationen rausschmeissen, da diese + // Matrix nur zur Transformation von Vektoren gedacht ist + aInvTransObjectToEye[3] = Point4D(0.0, 0.0, 0.0, 1.0); + + // auf gueltig setzen + bInvTransObjectToEyeValid = TRUE; +} + +const Matrix4D& B3dTransformationSet::GetInvTransObjectToEye() +{ + if(!bInvTransObjectToEyeValid) + CalcMatInvTransObjectToEye(); + return aInvTransObjectToEye; +} + +Matrix4D B3dTransformationSet::GetMatFromObjectToView() +{ + Matrix4D aFromObjectToView = GetObjectToDevice(); + + aFromObjectToView.Scale(GetScale()); + aFromObjectToView.Translate(GetTranslate()); + + return aFromObjectToView; +} + +void B3dTransformationSet::CalcMatFromWorldToView() +{ + aMatFromWorldToView = aOrientation; + aMatFromWorldToView *= GetProjection(); + aMatFromWorldToView.Scale(GetScale()); + aMatFromWorldToView.Translate(GetTranslate()); + aInvMatFromWorldToView = aMatFromWorldToView; + aInvMatFromWorldToView.Invert(); + + // gueltig setzen + bWorldToViewValid = TRUE; +} + +const Matrix4D& B3dTransformationSet::GetMatFromWorldToView() +{ + if(!bWorldToViewValid) + CalcMatFromWorldToView(); + return aMatFromWorldToView; +} + +const Matrix4D& B3dTransformationSet::GetInvMatFromWorldToView() +{ + if(!bWorldToViewValid) + CalcMatFromWorldToView(); + return aInvMatFromWorldToView; +} + +/************************************************************************* +|* +|* Direkter Zugriff auf verschiedene Transformationen +|* +\************************************************************************/ + +const Vector3D B3dTransformationSet::WorldToEyeCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetOrientation(); + return aVec; +} + +const Vector3D B3dTransformationSet::EyeToWorldCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetInvOrientation(); + return aVec; +} + +const Vector3D B3dTransformationSet::EyeToViewCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetProjection(); + aVec *= GetScale(); + aVec += GetTranslate(); + return aVec; +} + +const Vector3D B3dTransformationSet::ViewToEyeCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec -= GetTranslate(); + aVec = aVec / GetScale(); + aVec *= GetInvProjection(); + return aVec; +} + +const Vector3D B3dTransformationSet::WorldToViewCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetMatFromWorldToView(); + return aVec; +} + +const Vector3D B3dTransformationSet::ViewToWorldCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetInvMatFromWorldToView(); + return aVec; +} + +const Vector3D B3dTransformationSet::DeviceToViewCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetScale(); + aVec += GetTranslate(); + return aVec; +} + +const Vector3D B3dTransformationSet::ViewToDeviceCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec -= GetTranslate(); + aVec = aVec / GetScale(); + return aVec; +} + +const Vector3D B3dTransformationSet::ObjectToWorldCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetObjectTrans(); + return aVec; +} + +const Vector3D B3dTransformationSet::WorldToObjectCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetInvObjectTrans(); + return aVec; +} + +const Vector3D B3dTransformationSet::ObjectToViewCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetObjectTrans(); + aVec *= GetMatFromWorldToView(); + return aVec; +} + +const Vector3D B3dTransformationSet::ViewToObjectCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetInvMatFromWorldToView(); + aVec *= GetInvObjectTrans(); + return aVec; +} + +const Vector3D B3dTransformationSet::ObjectToEyeCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetObjectTrans(); + aVec *= GetOrientation(); + return aVec; +} + +const Vector3D B3dTransformationSet::EyeToObjectCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetInvOrientation(); + aVec *= GetInvObjectTrans(); + return aVec; +} + +const Vector3D B3dTransformationSet::DeviceToEyeCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetInvProjection(); + return aVec; +} + +const Vector3D B3dTransformationSet::EyeToDeviceCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetProjection(); + return aVec; +} + +const Vector3D B3dTransformationSet::InvTransObjectToEye(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetInvTransObjectToEye(); + return aVec; +} + +const Vector3D B3dTransformationSet::TransTextureCoor(const Vector3D& rVec) +{ + Vector3D aVec(rVec); + aVec *= GetTexture(); + return aVec; +} + +/************************************************************************* +|* +|* Konstruktor B3dViewport +|* +\************************************************************************/ + +B3dViewport::B3dViewport() +: B3dTransformationSet(), + aVRP(0, 0, 0), + aVPN(0, 0, 1), + aVUV(0, 1, 0) +{ + CalcOrientation(); +} + +void B3dViewport::SetVRP(const Vector3D& rNewVRP) +{ + aVRP = rNewVRP; + CalcOrientation(); +} + +void B3dViewport::SetVPN(const Vector3D& rNewVPN) +{ + aVPN = rNewVPN; + CalcOrientation(); +} + +void B3dViewport::SetVUV(const Vector3D& rNewVUV) +{ + aVUV = rNewVUV; + CalcOrientation(); +} + +void B3dViewport::SetViewportValues( + const Vector3D& rNewVRP, + const Vector3D& rNewVPN, + const Vector3D& rNewVUV) +{ + aVRP = rNewVRP; + aVPN = rNewVPN; + aVUV = rNewVUV; + CalcOrientation(); +} + +void B3dViewport::CalcOrientation() +{ + SetOrientation(aVRP, aVPN, aVUV); +} + +/************************************************************************* +|* +|* Konstruktor B3dViewport +|* +\************************************************************************/ + +B3dCamera::B3dCamera(const Vector3D& rPos, const Vector3D& rLkAt, + double fFocLen, double fBnkAng, BOOL bUseFocLen) +: B3dViewport(), + aPosition(rPos), + aCorrectedPosition(rPos), + aLookAt(rLkAt), + fFocalLength(fFocLen), + fBankAngle(fBnkAng), + bUseFocalLength(bUseFocLen) +{ + CalcNewViewportValues(); +} + +void B3dCamera::SetPosition(const Vector3D& rNewPos) +{ + if(rNewPos != aPosition) + { + // Zuweisen + aCorrectedPosition = aPosition = rNewPos; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetLookAt(const Vector3D& rNewLookAt) +{ + if(rNewLookAt != aLookAt) + { + // Zuweisen + aLookAt = rNewLookAt; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetPositionAndLookAt(const Vector3D& rNewPos, const Vector3D& rNewLookAt) +{ + if(rNewPos != aPosition || rNewLookAt != aLookAt) + { + // Zuweisen + aPosition = rNewPos; + aLookAt = rNewLookAt; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetFocalLength(double fLen) +{ + if(fLen != fFocalLength) + { + // Zuweisen + if(fLen < 5.0) + fLen = 5.0; + fFocalLength = fLen; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetBankAngle(double fAngle) +{ + if(fAngle != fBankAngle) + { + // Zuweisen + fBankAngle = fAngle; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::SetUseFocalLength(BOOL bNew) +{ + if(bNew != (BOOL)bUseFocalLength) + { + // Zuweisen + bUseFocalLength = bNew; + + // Neuberechnung + CalcNewViewportValues(); + } +} + +void B3dCamera::DeviceRectangleChange() +{ + // call parent + B3dViewport::DeviceRectangleChange(); + + // Auf Aenderung reagieren + CalcNewViewportValues(); +} + +void B3dCamera::CalcNewViewportValues() +{ + Vector3D aViewVector = aPosition - aLookAt; + Vector3D aNewVPN = aViewVector; + + Vector3D aNewVUV(0.0, 1.0, 0.0); + if(aNewVPN.GetLength() < aNewVPN.Y()) + aNewVUV.X() = 0.5; + + aNewVUV.Normalize(); + aNewVPN.Normalize(); + + Vector3D aNewToTheRight = aNewVPN; + aNewToTheRight |= aNewVUV; + aNewToTheRight.Normalize(); + aNewVUV = aNewToTheRight | aNewVPN; + aNewVUV.Normalize(); + + SetViewportValues(aPosition, aNewVPN, aNewVUV); + if(CalcFocalLength()) + SetViewportValues(aCorrectedPosition, aNewVPN, aNewVUV); + + if(fBankAngle != 0.0) + { + Matrix4D aRotMat; + aRotMat.RotateZ(fBankAngle); + Vector3D aUp(0.0, 1.0, 0.0); + aUp *= aRotMat; + aUp = EyeToWorldCoor(aUp); + aUp.Normalize(); + SetVUV(aUp); + } +} + +BOOL B3dCamera::CalcFocalLength() +{ + double fWidth = GetDeviceRectangleWidth(); + BOOL bRetval = FALSE; + + if(bUseFocalLength) + { + // Position aufgrund der FocalLength korrigieren + aCorrectedPosition = Vector3D(0.0, 0.0, fFocalLength * fWidth / 35.0); + aCorrectedPosition = EyeToWorldCoor(aCorrectedPosition); + bRetval = TRUE; + } + else + { + // FocalLength anhand der Position anpassen + Vector3D aOldPosition; + aOldPosition = WorldToEyeCoor(aOldPosition); + if(fWidth != 0.0) + fFocalLength = aOldPosition.Z() / fWidth * 35.0; + if(fFocalLength < 5.0) + fFocalLength = 5.0; + } + return bRetval; +} + diff --git a/goodies/source/base3d/base3d.cxx b/goodies/source/base3d/base3d.cxx new file mode 100644 index 000000000000..6a45cb2fb01d --- /dev/null +++ b/goodies/source/base3d/base3d.cxx @@ -0,0 +1,1268 @@ +/************************************************************************* + * + * $RCSfile: base3d.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_BASE3D_HXX +#include "base3d.hxx" +#endif + +#ifndef _B3D_B3DENTITY_HXX +#include "b3dentty.hxx" +#endif + +#ifndef _B3D_B3DTEX_HXX +#include "b3dtex.hxx" +#endif + +#ifndef _B3D_B3DOPNGL_HXX +#include "b3dopngl.hxx" +#endif + +#ifndef _B3D_B3DDEFLT_HXX +#include "b3ddeflt.hxx" +#endif + +#ifndef _B3D_B3DPRINT_HXX +#include "b3dprint.hxx" +#endif + +#ifndef _B3D_B3DGEOM_HXX +#include "b3dgeom.hxx" +#endif + +#ifndef _B3D_B3DTRANS_HXX +#include "b3dtrans.hxx" +#endif + +#ifndef _SHL_HXX +#include <tools/shl.hxx> +#endif + +#ifndef _SV_POLY_HXX +#include <vcl/poly.hxx> +#endif + +#ifndef _SFXINIPROP_HXX +#include <svtools/iniprop.hxx> +#endif + +#ifndef _SFXINIMGR_HXX +#include <svtools/iniman.hxx> +#endif + +/************************************************************************* +|* +|* Konstruktor B3dGlobalData +|* +\************************************************************************/ + +B3dGlobalData::B3dGlobalData() +{ +} + +/************************************************************************* +|* +|* Destruktor B3dGlobalData +|* +\************************************************************************/ + +B3dGlobalData::~B3dGlobalData() +{ +} + +/************************************************************************* +|* +|* Konstruktor Base3D +|* +\************************************************************************/ + +Base3D::Base3D(OutputDevice* pOutDev) +: OutDev3D(), + pDevice(pOutDev), + eObjectMode(Base3DPoints), + aCurrentColor(Color(0xff, 0xff, 0xff)), + aComplexPolygon(), + eRenderModeFront(Base3DRenderFill), + eRenderModeBack(Base3DRenderFill), + eShadeModel(Base3DSmooth), + eCullMode(Base3DCullNone), + fPointSize(1.0), + fLineWidth(1.0), + pActiveTexture(NULL), + pTransformationSet(NULL), + pLightGroup(NULL), + aMaterialFront(), + aMaterialBack(), + nDisplayQuality(127), + bEdgeFlag(TRUE), + bContextIsValid(TRUE), + bPolyOffsetFill(FALSE), + bPolyOffsetLine(FALSE), + bPolyOffsetPoint(FALSE), + bScissorRegionActive(FALSE), + bDitherActive(TRUE) +{ + // Grundsaetzliche Materialeigenschaften setzen + ResetMaterial(Base3DMaterialFrontAndBack); + + // Fuer OS/2 die FP-Exceptions abschalten +#if defined(OS2) +#define SC_FPEXCEPTIONS_ON() _control87( MCW_EM, 0 ) +#define SC_FPEXCEPTIONS_OFF() _control87( MCW_EM, MCW_EM ) + SC_FPEXCEPTIONS_OFF(); +#endif + + // Fuer WIN95/NT die FP-Exceptions abschalten +#if defined(WNT) || defined(WIN) +#define SC_FPEXCEPTIONS_ON() _control87( _MCW_EM, 0 ) +#define SC_FPEXCEPTIONS_OFF() _control87( _MCW_EM, _MCW_EM ) + SC_FPEXCEPTIONS_OFF(); +#endif +} + +/************************************************************************* +|* +|* Destruktor Base3D +|* +\************************************************************************/ + +Base3D::~Base3D() +{ +} + +/************************************************************************* +|* +|* Erzeuge einen Base3D Kontext in Anhaengigkeit vom uebergebenen +|* OutputDevice und trage Ihn dort ein +|* +\************************************************************************/ + +Base3D* Base3D::Create(OutputDevice* pOutDev, BOOL bForcePrinter) +{ + Base3D* pRetval = NULL; + if(pOutDev) + { + // Anforderungen feststellen + BOOL bOwnDevice = FALSE; + if(pOutDev->GetOutDevType() == OUTDEV_VIRDEV + || pOutDev->GetOutDevType() == OUTDEV_PRINTER + || pOutDev->GetConnectMetaFile() != NULL) + bOwnDevice = TRUE; + + // Existiert schon ein 3D-Kontext, der auch an dieses + // OutputDevice gebunden ist? + if(pOutDev->Get3DContext() + && ((Base3D*)(pOutDev->Get3DContext()))->GetOutputDevice() == pOutDev) + { + pRetval = (Base3D*)pOutDev->Get3DContext(); + } + + // Falls Ja, ist er den Anforderungen gewachsen? + if(pRetval) + { + BOOL bForceNew(FALSE); + + if((!bForceNew) && (bOwnDevice)&&(pRetval->GetBase3DType() == BASE3D_TYPE_OPENGL)) + { + bForceNew = TRUE; + } + + if((!bForceNew) && (bForcePrinter)&&(pRetval->GetBase3DType() != BASE3D_TYPE_PRINTER)) + { + bForceNew = TRUE; + } + + if((!bForceNew) && (!bForcePrinter)&&(pRetval->GetBase3DType() == BASE3D_TYPE_PRINTER)) + { + bForceNew = TRUE; + } + + if(!bForceNew && !bOwnDevice) + { + // Versuchen, einen OpenGL Kontext zu bekommen? Teste das + // globale Flag aus der .INI + BOOL bUseOpenGL = FALSE; + String aTmp = SfxIniManager::Get()->Get( SFX_KEY_3D_OPENGL ); + + if(aTmp.Len() && aTmp.GetChar(0) != sal_Unicode('0')) + bUseOpenGL = TRUE; + + if((bUseOpenGL && pRetval->GetBase3DType() != BASE3D_TYPE_OPENGL) + || (!bUseOpenGL && pRetval->GetBase3DType() == BASE3D_TYPE_OPENGL)) + { + bForceNew = TRUE; + bOwnDevice = !bUseOpenGL; + } + } + + if(bForceNew) + { + pRetval->Destroy(pOutDev); + pRetval = NULL; + } + } + + if(!pRetval) + { + // zerstoere altes Base3D, war nicht mehr an das + // OutputDevice gebunden + if(pOutDev->Get3DContext()) + pOutDev->Get3DContext()->Destroy(pOutDev); + + // erzeuge neues Base3D, je nach Anforderungen + if(bForcePrinter) + { + pRetval = new Base3DPrinter(pOutDev); + } + else if(bOwnDevice) + { + pRetval = new Base3DDefault(pOutDev); + } + else + { + // Versuche OpenGL, fallback auf default + // falls OpenGL nicht verfuegbar + pRetval = CreateScreenRenderer(pOutDev); + } + + // 3D-Kontext eintragen als Renderer im angegebenen OutputDevice + if(pRetval) + pOutDev->Set3DContext((Base3D*)pRetval); + } + } + return pRetval; +} + +/************************************************************************* +|* +|* Versuche, einen 3D Kontext zur Bildschirmdarstellung zu generieren. +|* Diese Funktion wird nur bei WNT realisiert. Sie muss entscheiden, +|* ob OpenGL-DLL's verfuegbar sind und entsprechend den OpenGL +|* Renderer oder einen Default Renderer erzeugen. +|* +\************************************************************************/ + +Base3D* Base3D::CreateScreenRenderer(OutputDevice* pOutDev) +{ + // OpenGL Kontext erzeugen + Base3D* pRetval = NULL; + + // Versuchen, einen OpenGL Kontext zu bekommen? Teste das + // globale Flag aus der .INI + BOOL bUseOpenGL = FALSE; + String aTmp = SfxIniManager::Get()->Get( SFX_KEY_3D_OPENGL ); + + if(aTmp.Len() && aTmp.GetChar(0) != sal_Unicode('0')) + bUseOpenGL = TRUE; + + // Versuchen, einen OpenGL Kontext zu bekommen + if(bUseOpenGL) + pRetval = new Base3DOpenGL(pOutDev); + + if(!pRetval || !pRetval->IsContextValid()) + { + if(pRetval) + { + delete pRetval; + pRetval = NULL; + } + } + + // versuche alternativ, einen Default Renderer zu inkarnieren + if(!pRetval) + pRetval = new Base3DDefault(pOutDev); + + return pRetval; +} + +/************************************************************************* +|* +|* Entferne den Kontext aus dem assoziierten OutputDevice und zerstoere +|* sich selbst +|* +|* Als Platzhalter fuer den Zeiger auf einen Kontext im OutputDevice +|* wird momentan pTheCurrentBase3DIncarnation benutzt +|* +\************************************************************************/ + +void Base3D::Destroy(OutputDevice *pOutDev) +{ + Base3D* pTmp; + if((pTmp = (Base3D*)GetOutputDevice()->Get3DContext()) == this) + { + GetOutputDevice()->Set3DContext(NULL); + delete pTmp; + } +} + +/************************************************************************* +|* +|* TransformationSet setzen +|* +\************************************************************************/ + +void Base3D::SetTransformationSet(B3dTransformationSet* pSet) +{ + // Aktuelles TransformationSet eintragen + pTransformationSet = pSet; +} + +/************************************************************************* +|* +|* Beleuchtung setzen +|* +\************************************************************************/ + +void Base3D::SetLightGroup(B3dLightGroup* pSet, BOOL bSetGlobal) +{ + // Aktuelle Beleuchtung eintragen + pLightGroup = pSet; +} + +/************************************************************************* +|* +|* Scissoring Region setzen +|* +\************************************************************************/ + +void Base3D::SetScissorRegionPixel(const Rectangle& rRect, BOOL bActivate) +{ + aScissorRectangle = rRect; + ActivateScissorRegion(bActivate); +} + +void Base3D::SetScissorRegion(const Rectangle& rRect, BOOL bActivate) +{ + SetScissorRegionPixel(pDevice->LogicToPixel(rRect), bActivate); +} + +/************************************************************************* +|* +|* Scissoring aktivieren/deaktivieren +|* +\************************************************************************/ + +void Base3D::ActivateScissorRegion(BOOL bNew) +{ + if(bNew != bScissorRegionActive) + bScissorRegionActive = bNew; +} + +/************************************************************************* +|* +|* Dithering setzen +|* +\************************************************************************/ + +void Base3D::SetDither(BOOL bNew) +{ + bDitherActive = bNew; +} + +/************************************************************************* +|* +|* Objektmodus holen +|* +\************************************************************************/ + +Base3DObjectMode Base3D::GetObjectMode() +{ + return eObjectMode; +} + +/************************************************************************* +|* +|* Ein neues Primitiv vom Typ nMode starten +|* +\************************************************************************/ + +void Base3D::StartPrimitive(Base3DObjectMode eMode) +{ + eObjectMode = eMode; + if(eObjectMode > Base3DPolygon) + { + switch(eObjectMode) + { + case Base3DComplexPolygonCut : + { + // Neues Polygon beginnen + aComplexPolygon.SetTestForCut(TRUE); + aComplexPolygon.StartPrimitive(); + break; + } + case Base3DComplexPolygon : + { + // Neues Polygon beginnen + aComplexPolygon.SetTestForCut(FALSE); + aComplexPolygon.StartPrimitive(); + break; + } + } + } + else + { + ImplStartPrimitive(); + } +} + +/************************************************************************* +|* +|* Primitiv beenden +|* +\************************************************************************/ + +void Base3D::EndPrimitive() +{ + if(eObjectMode > Base3DPolygon) + { + switch(eObjectMode) + { + case Base3DComplexPolygon : + case Base3DComplexPolygonCut : + { + // Selbst fuer Darstellung sorgen + aComplexPolygon.EndPrimitive(this); + break; + } + } + } + else + { + ImplEndPrimitive(); + } +} + +/************************************************************************* +|* +|* Ein Objekt in Form einer B3dGeometry direkt ausgeben +|* +\************************************************************************/ + +void Base3D::DrawPolygonGeometry(B3dGeometry& rGeometry, BOOL bOutline) +{ + // Buckets der Geometrie holen + B3dEntityBucket& rEntityBucket = rGeometry.GetEntityBucket(); + GeometryIndexValueBucket& rIndexBucket = rGeometry.GetIndexBucket(); + + UINT32 nPolyCounter = 0; + UINT32 nEntityCounter = 0; + UINT32 nUpperBound; + + while(nPolyCounter < rIndexBucket.Count()) + { + // Naechstes Primitiv + nUpperBound = rIndexBucket[nPolyCounter].GetIndex(); + + if(bOutline) + { + // Polygon als Outline ausgeben + SetRenderMode(Base3DRenderLine); + SetPolygonOffset(Base3DPolygonOffsetLine, TRUE); + + // ALLE Linien Zeichnen + SetCullMode(Base3DCullNone); + } + else + { + // Polygone gefuellt ausgeben + SetRenderMode(Base3DRenderFill); + SetPolygonOffset(Base3DPolygonOffsetLine, FALSE); + } + + if(rIndexBucket[nPolyCounter++].GetMode() == B3D_INDEX_MODE_LINE) + { + eObjectMode = Base3DLineStrip; + } + else + { + eObjectMode = Base3DPolygon; + } + + // Neues Polygon beginnen + ImplStartPrimitive(); + + // Polygon ausgeben + while(nEntityCounter < nUpperBound) + { + B3dEntity& rEntity = ImplGetFreeEntity(); + rEntity = rEntityBucket[nEntityCounter++]; + if(bOutline) + { + rEntity.SetNormalUsed(FALSE); + rEntity.SetTexCoorUsed(FALSE); + SetEdgeFlag(rEntity.IsEdgeVisible()); + } + ImplPostAddVertex(rEntity); + } + + // Primitiv abschliessen + ImplEndPrimitive(); + } +} + +/************************************************************************* +|* +|* Direkter Zugriff auf B3dMaterial fuer abgeleitete Klassen +|* +\************************************************************************/ + +B3dMaterial& Base3D::GetMaterialObject(Base3DMaterialMode eMode) +{ + if(eMode == Base3DMaterialFront) + return aMaterialFront; + return aMaterialBack; +} + +/************************************************************************* +|* +|* geometrische Daten uebernehmen +|* +\************************************************************************/ + +void Base3D::AddVertex(Vector3D& rVertex) +{ + // Platz fuer neue Daten holen + B3dEntity& rEntity = GetFreeEntity(); + rEntity.Reset(); + + // geometrische Daten + rEntity.Point() = Point4D(rVertex); + rEntity.SetValid(); + + // Nachbehandlung + PostAddVertex(rEntity); +} + +void Base3D::AddVertex(Vector3D& rVertex, Vector3D& rNormal) +{ + // Platz fuer neue Daten holen + B3dEntity& rEntity = GetFreeEntity(); + rEntity.Reset(); + + // geometrische Daten + rEntity.Point() = Point4D(rVertex); + rEntity.SetValid(); + + // Normale + if(GetLightGroup() && GetLightGroup()->IsLightingEnabled()) + { + rEntity.Normal() = rNormal; + rEntity.SetNormalUsed(); + } + + // Nachbehandlung + PostAddVertex(rEntity); +} + +void Base3D::AddVertex(Vector3D& rVertex, Vector3D& rNormal, + Vector3D& rTexPos) +{ + // Platz fuer neue Daten holen + B3dEntity& rEntity = GetFreeEntity(); + rEntity.Reset(); + + // geometrische Daten + rEntity.Point() = Point4D(rVertex); + rEntity.SetValid(); + + // Normale + if(GetLightGroup() && GetLightGroup()->IsLightingEnabled()) + { + rEntity.Normal() = rNormal; + rEntity.SetNormalUsed(); + } + + // Texturdaten + rEntity.TexCoor() = rTexPos; + rEntity.SetTexCoorUsed(); + + // Nachbehandlung + PostAddVertex(rEntity); +} + +void Base3D::AddVertex(B3dEntity& rEnt) +{ + // Platz fuer neue Daten holen + B3dEntity& rEntity = GetFreeEntity(); + + // Kopieren + rEntity = rEnt; + + // Nachbehandlung + PostAddVertex(rEntity); +} + +void Base3D::PostAddVertex(B3dEntity& rEntity) +{ + // Flag fuer die Sichtbarkeit von Kanten kopieren + rEntity.SetEdgeVisible(GetEdgeFlag()); + + // aktuelle Farbe eintragen + rEntity.Color().SetColor(GetColor().GetColor()); + + if(eObjectMode > Base3DPolygon) + { + switch(eObjectMode) + { + case Base3DComplexPolygon : + case Base3DComplexPolygonCut : + { + // Punkt ist nun ausgefuellt + aComplexPolygon.PostAddVertex(rEntity); + break; + } + } + } + else + { + ImplPostAddVertex(rEntity); + } +} + +/************************************************************************* +|* +|* Platz fuer neuen Punkt anfordern +|* +\************************************************************************/ + +B3dEntity& Base3D::GetFreeEntity() +{ + if(eObjectMode > Base3DPolygon) + { + switch(eObjectMode) + { + case Base3DComplexPolygon : + case Base3DComplexPolygonCut : + { + // Im eigenen Buffer anlegen + return aComplexPolygon.GetFreeEntity(); + break; + } + } + } + return ImplGetFreeEntity(); +} + +/************************************************************************* +|* +|* Farbe setzen +|* +\************************************************************************/ + +void Base3D::SetColor(Color aNew) +{ + // Farbe setzen + if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL) + { + // Graustufen + UINT8 nLuminance = aNew.GetLuminance(); + aCurrentColor = Color(nLuminance, nLuminance, nLuminance); + } + else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL) + { + // Keine Ausgabe, hier Schwarz als Farbe setzen, wird + // als Linienfarbe benutzt + aCurrentColor = Color(COL_BLACK); + } + else + { + // Normale Farbausgabe + aCurrentColor = aNew; + } +} + +/************************************************************************* +|* +|* Farbe liefern +|* +\************************************************************************/ + +Color Base3D::GetColor() +{ + return aCurrentColor; +} + +/************************************************************************* +|* +|* Materialeigenschaften setzen +|* +\************************************************************************/ + +void Base3D::SetMaterial(Color aNew, + Base3DMaterialValue eVal, + Base3DMaterialMode eMode) +{ + Color aSource; + if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL) + { + // Graustufen + UINT8 nLuminance = aNew.GetLuminance(); + aSource.SetRed(nLuminance); + aSource.SetGreen(nLuminance); + aSource.SetBlue(nLuminance); + aSource.SetTransparency(aNew.GetTransparency()); + } + else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL) + { + // Keine Ausgabe, hier Weiss als Farbe setzen + aSource = Color(COL_WHITE); + } + else + { + // Normale Farbausgabe + aSource = aNew; + } + + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialFront) + { + aMaterialFront.SetMaterial(aSource, eVal); + } + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialBack) + { + aMaterialBack.SetMaterial(aSource, eVal); + } +} + +/************************************************************************* +|* +|* Materialeigenschaften abfragen +|* +\************************************************************************/ + +Color Base3D::GetMaterial(Base3DMaterialValue eVal, + Base3DMaterialMode eMode) +{ + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialFront) + { + return aMaterialFront.GetMaterial(eVal); + } + return aMaterialBack.GetMaterial(eVal); +} + +/************************************************************************* +|* +|* Materialeigenschaften setzen, exponent der specular-Eigenschaft +|* +\************************************************************************/ + +void Base3D::SetShininess(UINT16 nExponent, + Base3DMaterialMode eMode) +{ + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialFront) + { + aMaterialFront.SetShininess(nExponent); + } + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialBack) + { + aMaterialBack.SetShininess(nExponent); + } +} + +/************************************************************************* +|* +|* Materialeigenschaften abfragen, exponent der specular-Eigenschaft +|* +\************************************************************************/ + +UINT16 Base3D::GetShininess(Base3DMaterialMode eMode) +{ + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialFront) + { + return aMaterialFront.GetShininess(); + } + return aMaterialBack.GetShininess(); +} + +/************************************************************************* +|* +|* Materialeigenschaften auf Ausgangszustand +|* +\************************************************************************/ + +void Base3D::ResetMaterial(Base3DMaterialMode eMode) +{ + Color aColor(255, 51, 51, 51); + SetMaterial(aColor, Base3DMaterialAmbient, eMode); + aColor.SetColor(TRGB_COLORDATA(255, 204, 204, 204)); + SetMaterial(aColor, Base3DMaterialDiffuse, eMode); + aColor.SetColor(TRGB_COLORDATA(255, 0, 0, 0)); + SetMaterial(aColor, Base3DMaterialSpecular, eMode); + aColor.SetColor(TRGB_COLORDATA(255, 0, 0, 0)); + SetMaterial(aColor, Base3DMaterialEmission, eMode); + SetShininess(0, eMode); +} + +/************************************************************************* +|* +|* GlobalData holen +|* +\************************************************************************/ + +B3dGlobalData& Base3D::GetGlobalData() +{ + B3dGlobalData** ppGlobalData = (B3dGlobalData**)GetAppData(SHL_BASE3D); + if(*ppGlobalData) + return **ppGlobalData; + + // GlobalData anlegen + *ppGlobalData = new B3dGlobalData; + return **ppGlobalData; +} + +/************************************************************************* +|* +|* TextureStore aus GlobalData holen +|* +\************************************************************************/ + +B3dTextureStore& Base3D::GetTextureStore() +{ + return GetGlobalData().GetTextureStore(); +} + +/************************************************************************* +|* +|* Textur mit den angegebenen Attributen als Grundlage anfordern. +|* +\************************************************************************/ + +B3dTexture* Base3D::ObtainTexture(TextureAttributes& rAtt) +{ + B3dTexture* pRetval = NULL; + + // Textur suchen und bei Treffer zurueckgeben + B3dTextureStore& rTextureStore = GetTextureStore(); + for(UINT16 a=0;a<rTextureStore.Count();a++) + { + if(rTextureStore[a]->GetAttributes() == rAtt) + { + pRetval = rTextureStore[a]; + pRetval->Touch(); + } + else + { + rTextureStore[a]->DecrementUsageCount(); + + // Auf zu loeschende Texturen testen + if(!rTextureStore[a]->GetUsageCount()) + { + B3dTexture *pTex = rTextureStore[a]; + rTextureStore.Remove(a); + DestroyTexture(pTex); + a--; + } + } + } + + // Textur zurueckgeben + return pRetval; +} + +/************************************************************************* +|* +|* Textur mit den angegebenen Attributen als Grundlage anfordern. Falls +|* eine solche Textur nicht existiert, erzeuge eine und gib diese zurueck +|* +\************************************************************************/ + +B3dTexture* Base3D::ObtainTexture(TextureAttributes& rAtt, Bitmap& rBitmap) +{ + B3dTexture* pRetval = ObtainTexture(rAtt); + + if(!pRetval) + { + // Existiert tatsaechlich nicht, generiere eine neue Textur + B3dTextureStore& rTextureStore = GetTextureStore(); + + pRetval = CreateTexture(rAtt, rBitmap); + rTextureStore.Insert((const B3dTexture*&)pRetval, rTextureStore.Count()); + } + + // Textur zurueckgeben + return pRetval; +} + +/************************************************************************* +|* +|* Gezielt eine Textur freigeben +|* +\************************************************************************/ + +void Base3D::DeleteTexture(TextureAttributes& rAtt) +{ + B3dTexture* pTexture = NULL; + + // Textur suchen + B3dTextureStore& rTextureStore = GetTextureStore(); + UINT16 a; + for(a=0;a<rTextureStore.Count();a++) + { + if(rTextureStore[a]->GetAttributes() == rAtt) + { + pTexture = rTextureStore[a]; + } + } + + if(pTexture) + { + if(pTexture == pActiveTexture) + pActiveTexture = NULL; + + rTextureStore.Remove(a); + DestroyTexture(pTexture); + } +} + +/************************************************************************* +|* +|* Alle Texturen freigeben +|* +\************************************************************************/ + +void Base3D::DeleteAllTextures() +{ + pActiveTexture = NULL; + + B3dTextureStore& rTextureStore = GetTextureStore(); + while(rTextureStore.Count()) + { + B3dTexture *pTex = rTextureStore[0]; + rTextureStore.Remove(0); + DestroyTexture(pTex); + } +} + +/************************************************************************* +|* +|* Ein Textur-Objekt inkarnieren +|* +\************************************************************************/ + +B3dTexture* Base3D::CreateTexture(TextureAttributes& rAtt, Bitmap& rBitmap) +{ + B3dTexture* pRetval = new B3dTexture(rAtt, rBitmap); + DBG_ASSERT(pRetval,"AW: Kein Speicher fuer Textur bekommen!"); + return pRetval; +} + +/************************************************************************* +|* +|* Normale Textur loeschen +|* +\************************************************************************/ + +void Base3D::DestroyTexture(B3dTexture* pTex) +{ + delete pTex; +} + +/************************************************************************* +|* +|* Aktuell zu benutzende Textur setzen +|* +\************************************************************************/ + +void Base3D::SetActiveTexture(B3dTexture* pTex) +{ + if(pTex) + { + if(GetOutputDevice()->GetDrawMode() & DRAWMODE_GRAYFILL) + { + // Graustufen + pTex->SetTextureKind(Base3DTextureIntensity); + } + else if(GetOutputDevice()->GetDrawMode() & DRAWMODE_WHITEFILL) + { + // Keine Ausgabe, keine Textur setzen + pTex = NULL; + } + } + + // ... und setzen + pActiveTexture = pTex; +} + +/************************************************************************* +|* +|* Darstellungsqualitaet setzen +|* +\************************************************************************/ + +void Base3D::SetDisplayQuality(UINT8 nNew) +{ + nDisplayQuality = nNew; +} + +/************************************************************************* +|* +|* Darstellungsqualitaet lesen +|* +\************************************************************************/ + +UINT8 Base3D::GetDisplayQuality() +{ + return nDisplayQuality; +} + +/************************************************************************* +|* +|* PolygonOffset setzen +|* +\************************************************************************/ + +void Base3D::SetPolygonOffset(Base3DPolygonOffset eNew, BOOL bNew) +{ + switch(eNew) + { + case Base3DPolygonOffsetFill : + bPolyOffsetFill = bNew; + break; + + case Base3DPolygonOffsetLine : + bPolyOffsetLine = bNew; + break; + + case Base3DPolygonOffsetPoint : + bPolyOffsetPoint = bNew; + break; + } +} + +/************************************************************************* +|* +|* PolygonOffset lesen +|* +\************************************************************************/ + +BOOL Base3D::GetPolygonOffset(Base3DPolygonOffset eNew) +{ + if(eNew == Base3DPolygonOffsetLine) + return bPolyOffsetLine; + if(eNew == Base3DPolygonOffsetFill) + return bPolyOffsetFill; + return bPolyOffsetPoint; +} + +/************************************************************************* +|* +|* EdgeFlag lesen +|* +\************************************************************************/ + +BOOL Base3D::GetEdgeFlag() +{ + return bEdgeFlag; +} + +/************************************************************************* +|* +|* EdgeFlag schreiben +|* +\************************************************************************/ + +void Base3D::SetEdgeFlag(BOOL bNew) +{ + bEdgeFlag = bNew; +} + +/************************************************************************* +|* +|* PointSize lesen +|* +\************************************************************************/ + +double Base3D::GetPointSize() +{ + return fPointSize; +} + +/************************************************************************* +|* +|* PointSize schreiben +|* +\************************************************************************/ + +void Base3D::SetPointSize(double fNew) +{ + fPointSize = fNew; +} + +/************************************************************************* +|* +|* LineWidth lesen +|* +\************************************************************************/ + +double Base3D::GetLineWidth() +{ + return fLineWidth; +} + +/************************************************************************* +|* +|* LineWidth schreiben +|* +\************************************************************************/ + +void Base3D::SetLineWidth(double fNew) +{ + fLineWidth = fNew; +} + +/************************************************************************* +|* +|* RenderMode setzen +|* +\************************************************************************/ + +void Base3D::SetRenderMode(Base3DRenderMode eNew, + Base3DMaterialMode eMode) +{ + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialFront) + { + eRenderModeFront = eNew; + } + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialBack) + { + eRenderModeBack = eNew; + } +} + +/************************************************************************* +|* +|* RenderMode lieferen +|* +\************************************************************************/ + +Base3DRenderMode Base3D::GetRenderMode(Base3DMaterialMode eMode) +{ + if(eMode == Base3DMaterialFrontAndBack + || eMode == Base3DMaterialFront) + { + return eRenderModeFront; + } + return eRenderModeBack; +} + +/************************************************************************* +|* +|* ShadeModel setzen +|* +\************************************************************************/ + +void Base3D::SetShadeModel(Base3DShadeModel eNew) +{ + eShadeModel = eNew; +} + +/************************************************************************* +|* +|* ShadeModel lieferen +|* +\************************************************************************/ + +Base3DShadeModel Base3D::GetShadeModel() +{ + return eShadeModel; +} + +/************************************************************************* +|* +|* CullingMode setzen +|* +\************************************************************************/ + +void Base3D::SetCullMode(Base3DCullMode eNew) +{ + eCullMode = eNew; +} + +/************************************************************************* +|* +|* CullingMode liefern +|* +\************************************************************************/ + +Base3DCullMode Base3D::GetCullMode() +{ + return eCullMode; +} + +/************************************************************************* +|* +|* Texturenverwaltung +|* +\************************************************************************/ + +SV_IMPL_PTRARR(B3dTextureStore, B3dTexture*); + + +#ifdef DBG_UTIL +#include "b3dtest.cxx" +#endif + diff --git a/goodies/source/base3d/makefile.mk b/goodies/source/base3d/makefile.mk new file mode 100644 index 000000000000..925276be0378 --- /dev/null +++ b/goodies/source/base3d/makefile.mk @@ -0,0 +1,124 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=goodies +TARGET=base3d +AUTOSEG=true + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +.IF "$(header)" == "" + +CXXFILES= \ + base3d.cxx \ + b3dtrans.cxx \ + b3ddeflt.cxx \ + b3dopngl.cxx \ + b3dprint.cxx \ + b3dcommn.cxx \ + vector3d.cxx \ + point4d.cxx \ + matril3d.cxx \ + b3dlight.cxx \ + b3dcolor.cxx \ + b3dentty.cxx \ + b3dcompo.cxx \ + hmatrix.cxx \ + b3dtex.cxx \ + b3dgeom.cxx \ + b3dvolum.cxx + +#SRS1NAME= +#SRC1FILES= + +SLOFILES= \ + $(SLO)$/base3d.obj \ + $(SLO)$/b3dtrans.obj \ + $(SLO)$/b3ddeflt.obj \ + $(SLO)$/b3dopngl.obj \ + $(SLO)$/b3dprint.obj \ + $(SLO)$/b3dcommn.obj \ + $(SLO)$/vector3d.obj \ + $(SLO)$/point4d.obj \ + $(SLO)$/matril3d.obj \ + $(SLO)$/b3dcolor.obj \ + $(SLO)$/b3dlight.obj \ + $(SLO)$/b3dentty.obj \ + $(SLO)$/b3dcompo.obj \ + $(SLO)$/hmatrix.obj \ + $(SLO)$/b3dtex.obj \ + $(SLO)$/b3dgeom.obj \ + $(SLO)$/b3dvolum.obj + + +.ENDIF # "$(header)" == "" + +.INCLUDE : target.mk + diff --git a/goodies/source/base3d/matril3d.cxx b/goodies/source/base3d/matril3d.cxx new file mode 100644 index 000000000000..f0af32ac38e4 --- /dev/null +++ b/goodies/source/base3d/matril3d.cxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * $RCSfile: matril3d.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _B3D_MATRIL3D_HXX +#include "matril3d.hxx" +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +/************************************************************************* +|* +|* Konstruktor B3dMaterial +|* +\************************************************************************/ + +B3dMaterial::B3dMaterial() +: aAmbient(COL_BLACK), // kein lokales Umgebungslicht + aDiffuse(0x00, 0xb8, 0xff), // Blau7 + aSpecular(COL_WHITE), // Weisser Glanzpunkt + aEmission(COL_BLACK), // Keine Selbstleuchtfarbe + nExponent(15) // Glanzpunktbuendelung +{ +} + +/************************************************************************* +|* +|* Materialeigenschaft setzen +|* +\************************************************************************/ + +void B3dMaterial::SetMaterial(Color rNew, Base3DMaterialValue eVal) +{ + switch(eVal) + { + case Base3DMaterialAmbient: + aAmbient = rNew; + break; + case Base3DMaterialDiffuse: + aDiffuse = rNew; + break; + case Base3DMaterialSpecular: + aSpecular = rNew; + break; + case Base3DMaterialEmission: + aEmission = rNew; + break; + } +} + +/************************************************************************* +|* +|* Materialeigenschaft abfragen +|* +\************************************************************************/ + +Color B3dMaterial::GetMaterial(Base3DMaterialValue eVal) const +{ + if(eVal == Base3DMaterialAmbient) + return aAmbient; + if(eVal == Base3DMaterialDiffuse) + return aDiffuse; + if(eVal == Base3DMaterialEmission) + return aEmission; + return aSpecular; +} + +/************************************************************************* +|* +|* Materialeigenschaften setzen, exponent der specular-Eigenschaft +|* +\************************************************************************/ + +void B3dMaterial::SetShininess(UINT16 nNew) +{ + nExponent = nNew; +} + +/************************************************************************* +|* +|* Materialeigenschaften abfragen, exponent der specular-Eigenschaft +|* +\************************************************************************/ + +UINT16 B3dMaterial::GetShininess() const +{ + return nExponent; +} + +void B3dMaterial::WriteData(SvStream& rOut) const +{ + rOut << aAmbient; + rOut << aDiffuse; + rOut << aSpecular; + rOut << aEmission; + rOut << nExponent; +} + +void B3dMaterial::ReadData(SvStream& rIn) +{ + rIn >> aAmbient; + rIn >> aDiffuse; + rIn >> aSpecular; + rIn >> aEmission; + rIn >> nExponent; +} + +/************************************************************************* +|* +|* Vergleichsoperator +|* +\************************************************************************/ + +BOOL B3dMaterial::operator==(const B3dMaterial& rMat) +{ + if(aAmbient == rMat.aAmbient + && aDiffuse == rMat.aDiffuse + && aSpecular == rMat.aSpecular + && aEmission == rMat.aEmission + && nExponent == rMat.nExponent) + return TRUE; + return FALSE; +} + +/************************************************************************* +|* +|* Bucket fuer geometrische Daten +|* +\************************************************************************/ + +BASE3D_IMPL_BUCKET(B3dMaterial, Bucket) + diff --git a/goodies/source/filter.vcl/egif/dlgegif.cxx b/goodies/source/filter.vcl/egif/dlgegif.cxx new file mode 100644 index 000000000000..db3ea2d61fd6 --- /dev/null +++ b/goodies/source/filter.vcl/egif/dlgegif.cxx @@ -0,0 +1,137 @@ +/************************************************************************* + * + * $RCSfile: dlgegif.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:11 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#pragma hdrstop +#include <tools/ref.hxx> +#include <vcl/config.hxx> +#include <vcl/msgbox.hxx> +#include "dlgegif.hxx" +#include "dlgegif.hrc" +#include "strings.hrc" + +/************************************************************************* +|* +|* Ctor +|* +\************************************************************************/ + +DlgExportEGIF::DlgExportEGIF( FltCallDialogParameter& rPara ) : + ModalDialog ( rPara.pWindow, ResId( DLG_EXPORT_GIF, rPara.pResMgr ) ), + aCbxInterlaced ( this, ResId( CBX_INTERLACED ) ), + aCbxTranslucent ( this, ResId( CBX_TRANSLUCENT ) ), + aGrpMode ( this, ResId( GRP_MODE ) ), + aGrpDraw ( this, ResId( GRP_DRAW ) ), + aBtnOK ( this, ResId( BTN_OK ) ), + aBtnCancel ( this, ResId( BTN_CANCEL ) ), + aBtnHelp ( this, ResId( BTN_HELP ) ), + pConfig ( rPara.pCfg ), + pMgr ( rPara.pResMgr ) +{ + FreeResource(); + + String aInterlaceStr( ResId( KEY_INTER, pMgr ) ); + String aTranslucentStr( ResId( KEY_TRANS, pMgr ) ); + // Config-Parameter lesen + BOOL bInterlaced = ( pConfig->ReadKey( ByteString( aInterlaceStr, RTL_TEXTENCODING_UTF8 ) ).ToInt32() != 0 ); + BOOL bTranslucent = ( (char) pConfig->ReadKey( ByteString( aTranslucentStr, RTL_TEXTENCODING_UTF8 ) ).ToInt32() != 0 ); + + aCbxInterlaced.Check( bInterlaced ); + aCbxTranslucent.Check( bTranslucent ); + + aBtnOK.SetClickHdl( LINK( this, DlgExportEGIF, OK ) ); +} + +/************************************************************************* +|* +|* Speichert eingestellte Werte in ini-Datei +|* +\************************************************************************/ + +IMPL_LINK( DlgExportEGIF, OK, void *, EMPTYARG ) +{ + + // Config-Parameter schreiben + String aInterlaceStr( ResId( KEY_INTER, pMgr ) ); + String aTranslucentStr( ResId( KEY_TRANS, pMgr ) ); + + ByteString aStr; + + if ( aCbxInterlaced.IsChecked() ) + aStr = '1'; + else + aStr = '0'; + + pConfig->WriteKey( ByteString( aInterlaceStr, RTL_TEXTENCODING_UTF8 ), aStr ); + + if ( aCbxTranslucent.IsChecked() ) + aStr = '1'; + else + aStr = '0'; + + pConfig->WriteKey( ByteString( aTranslucentStr, RTL_TEXTENCODING_UTF8 ), aStr ); + + EndDialog( RET_OK ); + + return 0; +} + + + diff --git a/goodies/source/filter.vcl/egif/dlgegif.hrc b/goodies/source/filter.vcl/egif/dlgegif.hrc new file mode 100644 index 000000000000..8ae49d512f5b --- /dev/null +++ b/goodies/source/filter.vcl/egif/dlgegif.hrc @@ -0,0 +1,70 @@ +/************************************************************************* + * + * $RCSfile: dlgegif.hrc,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:11 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include "goodies.hrc" + +#define BTN_OK 1 +#define BTN_CANCEL 1 +#define BTN_HELP 1 +#define FI_DESCR 1 +#define GRP_MODE 1 +#define GRP_DRAW 2 +#define CBX_INTERLACED 1 +#define CBX_TRANSLUCENT 2 diff --git a/goodies/source/filter.vcl/egif/dlgegif.hxx b/goodies/source/filter.vcl/egif/dlgegif.hxx new file mode 100644 index 000000000000..41a16506f48a --- /dev/null +++ b/goodies/source/filter.vcl/egif/dlgegif.hxx @@ -0,0 +1,101 @@ +/************************************************************************* + * + * $RCSfile: dlgegif.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 16:30:11 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General P |