/* ** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** 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 . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// // FILE: W3DRopeDraw.cpp //////////////////////////////////////////////////////////////////////// // Author: Steven Johnson, Aug 2002 // Desc: Rope drawing /////////////////////////////////////////////////////////////////////////////////////////////////// // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include #include #include "Common/Thing.h" #include "Common/ThingTemplate.h" #include "Common/Xfer.h" #include "GameClient/ClientRandomValue.h" #include "GameClient/Color.h" #include "GameClient/Drawable.h" #include "GameClient/GameClient.h" #include "GameLogic/GameLogic.h" #include "W3DDevice/GameClient/W3DDisplay.h" #include "W3DDevice/GameClient/Module/W3DRopeDraw.h" #include "WW3D2/Line3D.h" #include "W3DDevice/GameClient/W3DScene.h" #include "Common/GameState.h" #ifdef _INTERNAL // for occasional debugging... //#pragma optimize("", off) //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") #endif /////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- W3DRopeDraw::W3DRopeDraw( Thing *thing, const ModuleData* moduleData ) : DrawModule( thing, moduleData ) { m_curLen = 0.0f; m_maxLen = 1.0f; m_width = 0.5f; m_color.red = 0.0f; m_color.green = 0.0f; m_color.blue = 0.0f; m_curSpeed = 0.0f; m_maxSpeed = 0.0f; m_accel = 0.0f; m_wobbleLen = m_maxLen; // huge m_wobbleAmp = 0.0f; m_segments.clear(); m_curWobblePhase = 0.0f; m_curZOffset = 0.0f; } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void W3DRopeDraw::buildSegments() { DEBUG_ASSERTCRASH(m_segments.empty(), ("Hmmn, not empty")); m_segments.clear(); Int numSegs = ceil(m_maxLen / m_wobbleLen); Real eachLen = m_maxLen / (Real)numSegs; Coord3D pos = *getDrawable()->getPosition(); for (int i = 0; i < numSegs; ++i, pos.z += eachLen) { SegInfo info; Real axis = GameClientRandomValueReal(0, 2*PI); info.wobbleAxisX = Cos(axis); info.wobbleAxisY = Sin(axis); info.line = NEW Line3DClass( Vector3(pos.x,pos.y,pos.z), Vector3(pos.x,pos.y,pos.z+eachLen), m_width * 0.5f, // width m_color.red, // red m_color.green, // green m_color.blue, // blue 1.0f ); // transparency info.softLine = NEW Line3DClass( Vector3(pos.x,pos.y,pos.z), Vector3(pos.x,pos.y,pos.z+eachLen), m_width, // width m_color.red, // red m_color.green, // green m_color.blue, // blue 0.5f ); // transparency W3DDisplay::m_3DScene->Add_Render_Object( info.line ); W3DDisplay::m_3DScene->Add_Render_Object( info.softLine ); m_segments.push_back(info); } } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void W3DRopeDraw::tossSegments() { // remove tracer from the scene and delete for (std::vector::iterator it = m_segments.begin(); it != m_segments.end(); ++it) { if (it->line) { W3DDisplay::m_3DScene->Remove_Render_Object(it->line); REF_PTR_RELEASE((it->line)); } if (it->softLine) { W3DDisplay::m_3DScene->Remove_Render_Object(it->softLine); REF_PTR_RELEASE((it->softLine)); } } m_segments.clear(); } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void W3DRopeDraw::initRopeParms(Real length, Real width, const RGBColor& color, Real wobbleLen, Real wobbleAmp, Real wobbleRate) { m_maxLen = max(1.0f, length); m_curLen = 0.0f; m_width = width; m_color = color; m_wobbleLen = min(m_maxLen, wobbleLen); m_wobbleAmp = wobbleAmp; m_wobbleRate = wobbleRate; m_curZOffset = 0.0f; tossSegments(); buildSegments(); } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void W3DRopeDraw::setRopeCurLen(Real length) { m_curLen = length; } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void W3DRopeDraw::setRopeSpeed(Real curSpeed, Real maxSpeed, Real accel) { m_curSpeed = curSpeed; m_maxSpeed = maxSpeed; m_accel = accel; } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- W3DRopeDraw::~W3DRopeDraw() { tossSegments(); } //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void W3DRopeDraw::doDrawModule(const Matrix3D* transformMtx) { if (m_segments.empty()) { buildSegments(); } if (!m_segments.empty()) { Real deflection = Sin(m_curWobblePhase) * m_wobbleAmp; const Coord3D* pos = getDrawable()->getPosition(); Vector3 start(pos->x, pos->y, pos->z + m_curZOffset); Real eachLen = m_curLen / m_segments.size(); for (std::vector::iterator it = m_segments.begin(); it != m_segments.end(); ++it) { Vector3 end(pos->x + deflection*it->wobbleAxisX, pos->y + deflection*it->wobbleAxisY, start.Z - eachLen); if (it->line) (it->line)->Reset(start, end); if (it->softLine) (it->softLine)->Reset(start, end); start = end; } } m_curWobblePhase += m_wobbleRate; if (m_curWobblePhase > 2*PI) m_curWobblePhase -= 2*PI; m_curZOffset += m_curSpeed; m_curSpeed += m_accel; if (m_curSpeed > m_maxSpeed) m_curSpeed = m_maxSpeed; else if (m_curSpeed < -m_maxSpeed) m_curSpeed = -m_maxSpeed; } // ------------------------------------------------------------------------------------------------ /** CRC */ // ------------------------------------------------------------------------------------------------ void W3DRopeDraw::crc( Xfer *xfer ) { // extend base class DrawModule::crc( xfer ); } // end crc // ------------------------------------------------------------------------------------------------ /** Xfer method * Version Info: * 1: Initial version */ // ------------------------------------------------------------------------------------------------ void W3DRopeDraw::xfer( Xfer *xfer ) { // version const XferVersion currentVersion = 1; XferVersion version = currentVersion; xfer->xferVersion( &version, currentVersion ); // extend base class DrawModule::xfer( xfer ); // m_segments is not saved // cur len xfer->xferReal( &m_curLen ); // max len xfer->xferReal( &m_maxLen ); // width xfer->xferReal( &m_width ); // color xfer->xferRGBColor( &m_color ); // cur speed xfer->xferReal( &m_curSpeed ); // max speed xfer->xferReal( &m_maxSpeed ); // acceleration xfer->xferReal( &m_accel ); // wobble len xfer->xferReal( &m_wobbleLen ); // wobble amp xfer->xferReal( &m_wobbleAmp ); // wobble rate xfer->xferReal( &m_wobbleRate ); // current wobble phase xfer->xferReal( &m_curWobblePhase ); // cur Z offset xfer->xferReal( &m_curZOffset ); if (xfer->getXferMode() == XFER_LOAD) tossSegments(); } // end xfer // ------------------------------------------------------------------------------------------------ /** Load post process */ // ------------------------------------------------------------------------------------------------ void W3DRopeDraw::loadPostProcess( void ) { // extend base class DrawModule::loadPostProcess(); } // end loadPostProcess