Permalink
Cannot retrieve contributors at this time
360 lines (320 sloc)
15 KB
| /* | |
| * This file is part of the Colobot: Gold Edition source code | |
| * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam | |
| * http://epsitec.ch; http://colobot.info; http://github.com/colobot | |
| * | |
| * This program is free software: you can redistribute it and/or modify | |
| * it under the terms of the GNU General Public License as published by | |
| * the Free Software Foundation, either version 3 of the License, or | |
| * (at your option) any later version. | |
| * | |
| * This program 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 General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program. If not, see http://gnu.org/licenses | |
| */ | |
| /** | |
| * \file graphics/engine/particle.h | |
| * \brief Particle rendering - CParticle class (aka particle) | |
| */ | |
| #pragma once | |
| #include "graphics/engine/engine.h" | |
| #include "object/interface/trace_drawing_object.h" | |
| #include "sound/sound_type.h" | |
| class CRobotMain; | |
| class CObject; | |
| class CSoundInterface; | |
| // Graphics module namespace | |
| namespace Gfx | |
| { | |
| const short MAXPARTICULE = 500; | |
| const short MAXPARTITYPE = 6; | |
| const short MAXTRACK = 100; | |
| const short MAXTRACKLEN = 10; | |
| const short MAXPARTIFOG = 100; | |
| const short MAXWHEELTRACE = 1000; | |
| const short SH_WORLD = 0; // particle in the world in the interface | |
| const short SH_FRONT = 1; // particle in the world on the interface | |
| const short SH_INTERFACE = 2; // particle in the interface | |
| const short SH_MAX = 3; | |
| // type == 0 -> triangles | |
| // type == 1 -> effect00 (black background) | |
| // type == 2 -> effect01 (black background) | |
| // type == 3 -> effect02 (black background) | |
| // type == 4 -> text (white background) | |
| enum ParticleType | |
| { | |
| PARTIEXPLOT = 1, //! < technology explosion | |
| PARTIEXPLOO = 2, //! < organic explosion | |
| PARTIMOTOR = 3, //! < the engine exhaust gas | |
| PARTIGLINT = 4, //! < reflection | |
| PARTIBLITZ = 5, //! < lightning recharging battery | |
| PARTICRASH = 6, //! < dust after fall | |
| PARTIGAS = 7, //! < gas from the reactor | |
| PARTIFIRE = 9, //! < fireball shrinks | |
| PARTIFIREZ = 10, //! < fireball grows | |
| PARTIBLUE = 11, //! < blue ball | |
| PARTISELY = 12, //! < yellow robot lights | |
| PARTISELR = 13, //! < red robot lights | |
| PARTIGUN1 = 18, //! < bullet 1 (fireball) | |
| PARTIGUN2 = 19, //! < bullet 2 (ant) | |
| PARTIGUN3 = 20, //! < bullet 3 (spider) | |
| PARTIGUN4 = 21, //! < bullet 4 (orgaball) | |
| PARTIFRAG = 22, //! < triangular fragment | |
| PARTIQUEUE = 23, //! < inflamed tail (TODO: unused?) | |
| PARTIORGANIC1 = 24, //! < organic ball mother | |
| PARTIORGANIC2 = 25, //! < organic ball daughter | |
| PARTISMOKE1 = 26, //! < black smoke | |
| PARTISMOKE2 = 27, //! < black smoke | |
| PARTISMOKE3 = 28, //! < black smoke | |
| PARTIBLOOD = 30, //! < human blood | |
| PARTIBLOODM = 31, //! < AlienQueen blood | |
| PARTIVAPOR = 32, //! < steam | |
| PARTIVIRUS = 33, //! < virus (random letter) | |
| PARTIRAY1 = 43, //! < ray 1 (turn) | |
| PARTIRAY2 = 44, //! < ray 2 (electric arc) | |
| PARTIRAY3 = 45, //! < ray 3 (ExchangePost) | |
| PARTIFLAME = 47, //! < flame | |
| PARTIBUBBLE = 48, //! < bubble | |
| PARTIFLIC = 49, //! < circles in the water | |
| PARTIEJECT = 50, //! < ejection from the reactor | |
| PARTISCRAPS = 51, //! < waste from the reactor | |
| PARTITOTO = 52, //! < Robby's reactor | |
| PARTIERROR = 53, //! < Robby says no | |
| PARTIWARNING = 54, //! < Robby says blah | |
| PARTIINFO = 54, //! < Robby says yes | |
| PARTIQUARTZ = 55, //! < reflection crystal | |
| PARTISPHERE0 = 56, //! < explosion sphere | |
| PARTISPHERE1 = 57, //! < energy sphere | |
| PARTISPHERE2 = 58, //! < analysis sphere | |
| PARTISPHERE3 = 59, //! < shield sphere | |
| PARTISPHERE4 = 60, //! < information sphere (emit) | |
| PARTISPHERE5 = 61, //! < botanical sphere (gravity root) | |
| PARTISPHERE6 = 62, //! < information sphere (receive) | |
| PARTIGUNDEL = 66, //! < bullet destroyed by shield | |
| PARTIPART = 67, //! < object part | |
| PARTITRACK1 = 68, //! < drag 1 | |
| PARTITRACK2 = 69, //! < drag 2 | |
| PARTITRACK3 = 70, //! < drag 3 | |
| PARTITRACK4 = 71, //! < drag 4 | |
| PARTITRACK5 = 72, //! < drag 5 | |
| PARTITRACK6 = 73, //! < drag 6 | |
| PARTITRACK7 = 74, //! < drag 7 | |
| PARTITRACK8 = 75, //! < drag 8 | |
| PARTITRACK9 = 76, //! < drag 9 | |
| PARTITRACK10 = 77, //! < drag 10 | |
| PARTITRACK11 = 78, //! < drag 11 | |
| PARTITRACK12 = 79, //! < drag 12 (TODO: unused?) | |
| PARTIGLINTb = 88, //! < blue reflection | |
| PARTIGLINTr = 89, //! < red reflection | |
| PARTILENS1 = 90, //! < brilliance 1 (orange) | |
| PARTILENS2 = 91, //! < brilliance 2 (yellow) | |
| PARTILENS3 = 92, //! < brilliance 3 (red) | |
| PARTILENS4 = 93, //! < brilliance 4 (violet) | |
| PARTICONTROL = 94, //! < reflection on button | |
| PARTISHOW = 95, //! < shows a place | |
| PARTICHOC = 96, //! < shock wave | |
| PARTIGFLAT = 97, //! < shows if the ground is flat | |
| PARTIRECOVER = 98, //! < blue ball recycler | |
| PARTIROOT = 100, //! < gravity root smoke | |
| PARTIPLOUF0 = 101, //! < splash | |
| PARTIDROP = 106, //! < drop | |
| PARTIFOG0 = 107, //! < fog 0 | |
| PARTIFOG1 = 108, //! < fog 1 | |
| PARTIFOG2 = 109, //! < fog 2 | |
| PARTIFOG3 = 110, //! < fog 3 | |
| PARTIFOG4 = 111, //! < fog 4 | |
| PARTIFOG5 = 112, //! < fog 5 | |
| PARTIFOG6 = 113, //! < fog 6 | |
| PARTIFOG7 = 114, //! < fog 7 | |
| PARTILIMIT1 = 117, //! < shows the limits 1 | |
| PARTILIMIT2 = 118, //! < shows the limits 2 | |
| PARTILIMIT3 = 119, //! < shows the limits 3 | |
| PARTIWATER = 121, //! < drop of water | |
| PARTIEXPLOG1 = 122, //! < ball explosion 1 | |
| PARTIEXPLOG2 = 123, //! < ball explosion 2 | |
| PARTIBASE = 124, //! < gases of spaceship | |
| }; | |
| enum ParticlePhase | |
| { | |
| PARPHSTART = 0, | |
| PARPHEND = 1, | |
| }; | |
| struct Particle | |
| { | |
| bool used = false; // TRUE -> particle used | |
| bool ray = false; // TRUE -> ray with goal | |
| unsigned short uniqueStamp = 0; // unique mark | |
| short sheet = 0; // sheet (0..n) | |
| ParticleType type = {}; // type PARTI* | |
| ParticlePhase phase = {}; // phase PARPH* | |
| float mass = 0.0f; // mass of the particle (in rebounding) | |
| float weight = 0.0f; // weight of the particle (for noise) | |
| float duration = 0.0f; // length of life | |
| Math::Vector pos; // absolute position (relative if object links) | |
| Math::Vector goal; // goal position (if ray) | |
| Math::Vector speed; // speed of displacement | |
| float windSensitivity = 0.0f; | |
| short bounce = 0; // number of rebounds | |
| Math::Point dim; // dimensions of the rectangle | |
| float zoom = 0.0f; // zoom (0..1) | |
| float angle = 0.0f; // angle of rotation | |
| float intensity = 0.0f; // intensity | |
| Math::Point texSup; // coordinated upper texture | |
| Math::Point texInf; // coordinated lower texture | |
| float time = 0.0f; // age of the particle (0..n) | |
| float phaseTime = 0.0f; // age at the beginning of phase | |
| float testTime = 0.0f; // time since last test | |
| CObject* objLink = nullptr; // father object (for example reactor) | |
| CObject* objFather = nullptr; // father object (for example reactor) | |
| short objRank = 0; // rank of the object, or -1 | |
| short trackRank = 0; // rank of the drag | |
| char text = 0; | |
| Color color = Color(1.0f, 1.0f, 1.0f, 1.0f); | |
| }; | |
| struct Track | |
| { | |
| char used = 0; // TRUE -> drag used | |
| char drawParticle = 0; | |
| float step = 0.0f; // duration of not | |
| float last = 0.0f; // increase last not memorized | |
| float intensity = 0.0f; // intensity at starting (0..1) | |
| float width = 0.0f; // tail width | |
| int posUsed = 0.0f; // number of positions in "pos" | |
| int head = 0; // head to write index | |
| Math::Vector pos[MAXTRACKLEN]; | |
| float len[MAXTRACKLEN] = {}; | |
| }; | |
| struct WheelTrace | |
| { | |
| TraceColor color = TraceColor::Black; | |
| Math::Vector pos[4]; | |
| }; | |
| /** | |
| * \class CParticle | |
| * \brief Particle engine | |
| * | |
| * TODO: documentation | |
| */ | |
| class CParticle | |
| { | |
| public: | |
| CParticle(CEngine* engine); | |
| ~CParticle(); | |
| //! Sets the device to use | |
| void SetDevice(CDevice* device); | |
| //! Removes all particles | |
| void FlushParticle(); | |
| //! Removes all particles of a sheet | |
| void FlushParticle(int sheet); | |
| //! Creates a new particle | |
| int CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim, | |
| ParticleType type, float duration = 1.0f, float mass = 0.0f, | |
| float windSensitivity = 1.0f, int sheet = 0); | |
| //! Creates a new triangular particle (debris) | |
| int CreateFrag(Math::Vector pos, Math::Vector speed, EngineTriangle* triangle, | |
| ParticleType type, float duration = 1.0f, float mass = 0.0f, | |
| float windSensitivity = 1.0f, int sheet = 0); | |
| //! Creates a new particle being a part of object | |
| int CreatePart(Math::Vector pos, Math::Vector speed, ParticleType type, | |
| float duration = 1.0f, float mass = 0.0f, float weight = 0.0f, | |
| float windSensitivity = 1.0f, int sheet = 0); | |
| //! Creates a new linear particle (radius) | |
| int CreateRay(Math::Vector pos, Math::Vector goal, ParticleType type, Math::Point dim, | |
| float duration = 1.0f, int sheet = 0); | |
| //! Creates a particle with a trail | |
| int CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type, | |
| float duration = 1.0f, float mass = 0.0f, float length = 10.0f, float width = 1.0f); | |
| //! Creates a tire mark | |
| void CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3, | |
| const Math::Vector &p4, TraceColor color); | |
| //! Removes all particles of a given type | |
| void DeleteParticle(ParticleType type); | |
| //! Removes all particles of a given channel | |
| void DeleteParticle(int channel); | |
| //! Specifies the object to which the particle is bound | |
| void SetObjectLink(int channel, CObject *object); | |
| //! Specifies the parent object that created the particle | |
| void SetObjectFather(int channel, CObject *object); | |
| void SetPosition(int channel, Math::Vector pos); | |
| void SetDimension(int channel, Math::Point dim); | |
| void SetZoom(int channel, float zoom); | |
| void SetAngle(int channel, float angle); | |
| void SetIntensity(int channel, float intensity); | |
| void SetParam(int channel, Math::Vector pos, Math::Point dim, float zoom, float angle, float intensity); | |
| void SetPhase(int channel, ParticlePhase phase, float duration); | |
| //! Returns the position of the particle | |
| bool GetPosition(int channel, Math::Vector &pos); | |
| //! Returns the color if you're in the fog or black if you're not | |
| Color GetFogColor(Math::Vector pos); | |
| //! Indicates whether a sheet is updated or not | |
| void SetFrameUpdate(int sheet, bool update); | |
| //! Updates all the particles. | |
| void FrameParticle(float rTime); | |
| //! Draws all the particles | |
| void DrawParticle(int sheet); | |
| //! Indicates that the object binds to the particle no longer exists, without deleting it | |
| void CutObjectLink(CObject* obj); | |
| protected: | |
| //! Removes a particle of given rank | |
| void DeleteRank(int rank); | |
| /** | |
| * \brief Adapts the channel so it can be used as an offset in m_particle | |
| * \param channel Channel number to process, will be modified to be index of particle in m_particle | |
| * \return true if success, false if particle doesn't exist anymore | |
| **/ | |
| bool CheckChannel(int &channel); | |
| //! Draws a triangular particle | |
| void DrawParticleTriangle(int i); | |
| //! Draw a normal particle | |
| void DrawParticleNorm(int i); | |
| //! Draw a particle flat (horizontal) | |
| void DrawParticleFlat(int i); | |
| //! Draw a particle to a flat sheet of fog | |
| void DrawParticleFog(int i); | |
| //! Draw a particle in the form of radius | |
| void DrawParticleRay(int i); | |
| //! Draws a spherical particle | |
| void DrawParticleSphere(int i); | |
| //! Draws a cylindrical particle | |
| void DrawParticleCylinder(int i); | |
| //! Draws a text particle | |
| void DrawParticleText(int i); | |
| //! Draws a tire mark | |
| void DrawParticleWheel(int i); | |
| //! Seeks if an object collided with a bullet | |
| CObject* SearchObjectGun(Math::Vector old, Math::Vector pos, ParticleType type, CObject *father); | |
| //! Seeks if an object collided with a ray | |
| CObject* SearchObjectRay(Math::Vector pos, Math::Vector goal, ParticleType type, CObject *father); | |
| //! Sounded one | |
| void Play(SoundType sound, Math::Vector pos, float amplitude); | |
| //! Moves a drag; returns true if the drag is finished | |
| bool TrackMove(int i, Math::Vector pos, float progress); | |
| //! Draws a drag | |
| void TrackDraw(int i, ParticleType type); | |
| protected: | |
| CEngine* m_engine = nullptr; | |
| CDevice* m_device = nullptr; | |
| CTerrain* m_terrain = nullptr; | |
| CWater* m_water = nullptr; | |
| CRobotMain* m_main = nullptr; | |
| CSoundInterface* m_sound = nullptr; | |
| Particle m_particle[MAXPARTICULE*MAXPARTITYPE]; | |
| EngineTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0 | |
| Track m_track[MAXTRACK]; | |
| int m_wheelTraceTotal = 0; | |
| int m_wheelTraceIndex = 0; | |
| WheelTrace m_wheelTrace[MAXWHEELTRACE]; | |
| int m_totalInterface[MAXPARTITYPE][SH_MAX] = {}; | |
| bool m_frameUpdate[SH_MAX] = {}; | |
| int m_fogTotal = 0; | |
| int m_fog[MAXPARTIFOG] = {}; | |
| int m_uniqueStamp = 0; | |
| int m_exploGunCounter = 0; | |
| float m_lastTimeGunDel = 0.0f; | |
| float m_absTime = 0.0f; | |
| }; | |
| } // namespace Gfx |