#include "DataGraph.h" #include "..\..\icommon\memfile.h" #include "..\..\icommon\types.h" #include "..\..\icommon\graphtime.h" #include "..\..\icommon\names.h" #include "..\..\..\common_h\core.h" #include "..\..\TextFile.h" #include "..\..\service\particleservice.h" extern ParticleService* PService; #ifndef _XBOX #include "..\..\..\common_h\tinyxml\tinyxml.h" #endif #include "fieldlist.h" #include "..\..\..\Common_h\data_swizzle.h" #pragma warning (disable : 4800) //Взять случайное число из диапазона __forceinline float RandomRange (float Min, float Max) { return RRnd(Min, Max); /* float Temp; if (Min>Max) { Temp = Max; Max = Min; Min = Temp; } float Rand = (float)(rand()%1000) / 1000.0f; Rand *= (Max - Min); return Rand + Min;*/ } DataGraph::DataGraph () /*: _MinGraph(_FL_), _MaxGraph(_FL_)*/ { GraphData = NULL; MinGraphDataStart = -1; MaxGraphDataStart = -1; MinGraphDataSize = 0; MaxGraphDataSize = 0; bConstGraph = false; szName = NULL; szEditorName = NULL; Master = NULL; bRelative = false; bNegative = false; ResetCachedTime (); } void DataGraph::SetMasterField (FieldList* pMaster) { Master = pMaster; } //конструктор/деструктор DataGraph::DataGraph (FieldList* pMaster) /*: _MinGraph(_FL_), _MaxGraph(_FL_)*/ { GraphData = NULL; MinGraphDataStart = -1; MaxGraphDataStart = -1; MinGraphDataSize = 0; MaxGraphDataSize = 0; bConstGraph = false; szName = NULL; szEditorName = NULL; Master = pMaster; bRelative = false; bNegative = false; ResetCachedTime (); } DataGraph::~DataGraph () { } void DataGraph::CalculateConstData () { if (MinGraphDataSize == 2 && MaxGraphDataSize == 2) { if (GraphData->GetElement(MinGraphDataStart+1).Time >= 7000.0f && GraphData->GetElement(MaxGraphDataStart+1).Time >= 7000.0f) { bConstGraph = true; } } else { if (MinGraphDataSize == 1 && MaxGraphDataSize == 1) { bConstGraph = true; } } if (bConstGraph) { if (MinGraphDataSize > 0 && MaxGraphDataSize > 0) { fConstMin = GraphData->GetElement(MinGraphDataStart).Val; fConstMax = GraphData->GetElement(MaxGraphDataStart).Val; } else { fConstMin = 0.0f; fConstMax = 0.0f; } } } //Установить значения... void DataGraph::SetValues (const GraphVertex* MinValues, DWORD MinValuesSize, const GraphVertex* MaxValues, DWORD MaxValuesSize) { GraphData = PService->AllocateDataForGraphs(MinValuesSize, MaxValuesSize, MinGraphDataStart, MinGraphDataSize, MaxGraphDataStart, MaxGraphDataSize); DWORD n = 0; for (n = 0; n < MinValuesSize; n++) { GraphData->GetElement(MinGraphDataStart+n) = MinValues[n]; //MinGraph[n] = MinValues[n]; } for (n = 0; n < MaxValuesSize; n++) { GraphData->GetElement(MaxGraphDataStart+n) = MaxValues[n]; //MaxGraph[n] = MaxValues[n]; } ResetCachedTime (); if (Master) Master->UpdateCache(); CalculateConstData(); } //Устанавливает "значение по умолчанию" void DataGraph::SetDefaultValue (float MaxValue, float MinValue) { //AllocateDataForGraphs(2, 2); GraphData = PService->AllocateDataForGraphs(2, 2, MinGraphDataStart, MinGraphDataSize, MaxGraphDataStart, MaxGraphDataSize); GraphVertex Min; Min.Val = MinValue; Min.Time = MIN_GRAPH_TIME; //MinGraph.Add(Min); GraphData->GetElement(MinGraphDataStart) = Min; Min.Time = MAX_GRAPH_TIME; //MinGraph.Add(Min); GraphData->GetElement(MinGraphDataStart+1) = Min; GraphVertex Max; Max.Val = MinValue; Max.Time = MIN_GRAPH_TIME; //MaxGraph.Add(Max); GraphData->GetElement(MaxGraphDataStart) = Max; Max.Time = MAX_GRAPH_TIME; //MaxGraph.Add(Max); GraphData->GetElement(MaxGraphDataStart) = Max; ResetCachedTime (); CalculateConstData(); } //Получить кол-во в графике минимума DWORD DataGraph::GetMinCount () { return MinGraphDataSize; } //Получить кол-во в графике максимума DWORD DataGraph::GetMaxCount () { return MaxGraphDataSize; } //Получить значение по индексу из графика минимума const GraphVertex& DataGraph::GetMinVertex (DWORD Index) { return GraphData->GetElement(MinGraphDataStart+Index); //return MinGraph[Index]; } //Получить значение по индексу из графика максимума const GraphVertex& DataGraph::GetMaxVertex (DWORD Index) { return GraphData->GetElement(MaxGraphDataStart+Index); //return MaxGraph[Index]; } void DataGraph::ResetCachedTime () { MaxCachedTime = NOT_INITED_CACHE_VALUE; MinCachedTime = NOT_INITED_CACHE_VALUE; } void DataGraph::Load (MemFile* File) { //MinGraph.DelAll(); //MaxGraph.DelAll(); dword dwNegative = 0; File->ReadType(dwNegative); XSwizzleDWord(dwNegative); SetNegative(dwNegative); dword dwRelative = 0; File->ReadType(dwRelative); XSwizzleDWord(dwRelative); SetRelative(dwRelative); dword MaxGraphItemsCount = 0; File->ReadType(MaxGraphItemsCount); XSwizzleDWord(MaxGraphItemsCount); DWORD i = 0; //MaxGraph.Reserve(MaxGraphItemsCount); //AllocateDataForGraphs(-1, MaxGraphItemsCount); GraphData = PService->AllocateDataForGraphs(-1, MaxGraphItemsCount, MinGraphDataStart, MinGraphDataSize, MaxGraphDataStart, MaxGraphDataSize); for (i = 0; i < MaxGraphItemsCount; i++) { float fTime = 0.0f; File->ReadType(fTime); XSwizzleFloat(fTime); float fValue = 0.0f; File->ReadType(fValue); XSwizzleFloat(fValue); if (!bNegative && fValue < 0.0f) fValue = 0.0f; GraphVertex MaxVertex; MaxVertex.Time = fTime; MaxVertex.Val = fValue; //MaxGraph.Add(MaxVertex); GraphData->GetElement(MaxGraphDataStart+i) = MaxVertex; //api->Trace("Max value %d = %3.2f, %3.2f", i, fTime, fValue); } dword MinGraphItemsCount = 0; File->ReadType(MinGraphItemsCount); XSwizzleDWord(MinGraphItemsCount); //MinGraph.Reserve(MinGraphItemsCount); //AllocateDataForGraphs(MinGraphItemsCount, -1); GraphData = PService->AllocateDataForGraphs(MinGraphItemsCount, -1, MinGraphDataStart, MinGraphDataSize, MaxGraphDataStart, MaxGraphDataSize); for (i = 0; i < MinGraphItemsCount; i++) { float fTime = 0.0f; File->ReadType(fTime); XSwizzleFloat(fTime); float fValue = 0.0f; File->ReadType(fValue); XSwizzleFloat(fValue); if (!bNegative && fValue < 0.0f) fValue = 0.0f; GraphVertex MinVertex; MinVertex.Time = fTime; MinVertex.Val = fValue; //MinGraph.Add(MinVertex); GraphData->GetElement(MinGraphDataStart+i) = MinVertex; //api->Trace("Min value %d = %3.2f, %3.2f", i, fTime, fValue); } //static char AttribueName[128]; dword NameLength = 0; File->ReadType(NameLength); XSwizzleDWord(NameLength); Assert (NameLength < 128); //File->Read(AttribueName, NameLength); const char* AttribueName = File->GetPointerToString(NameLength); //api->Trace("Name %s", AttribueName); SetName (AttribueName, "a"); //HACK ! Для совместимости со старой версией... //Конвертим после загрузки графики в нужный формат... //if (crt_stricmp (AttribueName, EMISSION_DIR_X) == 0) ConvertDegToRad (); //if (crt_stricmp (AttribueName, EMISSION_DIR_Y) == 0) ConvertDegToRad (); //if (crt_stricmp (AttribueName, EMISSION_DIR_Z) == 0) ConvertDegToRad (); //if (crt_stricmp (AttribueName, PARTICLE_DRAG) == 0) NormalToPercent(); //if (crt_stricmp (AttribueName, PARTICLE_TRANSPARENCY) == 0) NormalToAlpha(); if (Master) Master->UpdateCache(); CalculateConstData(); } //Установить/получить могут быть отрицательные значения в графике или нет... void DataGraph::SetNegative (bool _bNegative) { bNegative = _bNegative; } bool DataGraph::GetNegative () { return bNegative; } //Установить/получить относительный график или нет... void DataGraph::SetRelative (bool _bRelative) { bRelative = _bRelative; } bool DataGraph::GetRelative () { return bRelative; } void DataGraph::SetName (const char* szName, const char* szEditorName) { //api->Trace("DataGraph::SetName - '%s'", szName); this->szName = szName; this->szEditorName = szEditorName; } const char* DataGraph::GetName () { return szName; } void DataGraph::ConvertRadToDeg () { MultiplyBy (MUL_RADTODEG); } void DataGraph::ConvertDegToRad () { MultiplyBy (MUL_DEGTORAD); } void DataGraph::MultiplyBy (float Val) { long n; for (n = 0; n < MaxGraphDataSize; n++) { float & v = GraphData->GetElement(MaxGraphDataStart+n).Val; v *= Val; //MaxGraph[n].Val *= Val; } for (n = 0; n < MinGraphDataSize; n++) { float & v = GraphData->GetElement(MinGraphDataStart+n).Val; v *= Val; //MinGraph[n].Val *= Val; } } void DataGraph::Clamp (float MinValue, float MaxValue) { long n; for (n = 0; n < MaxGraphDataSize; n++) { float & v = GraphData->GetElement(MaxGraphDataStart+n).Val; if (v > MaxValue) v = MaxValue; if (v < MinValue) v = MinValue; } for (n = 0; n < MinGraphDataSize; n++) { float & v = GraphData->GetElement(MinGraphDataStart+n).Val; if (v > MaxValue) v = MaxValue; if (v < MinValue) v = MinValue; } CalculateConstData (); } void DataGraph::Reverse () { long n; for (n = 0; n < MaxGraphDataSize; n++) { float & v = GraphData->GetElement(MaxGraphDataStart+n).Val; v = 1.0f - v; //MaxGraph[n].Val = 1.0f - MaxGraph[n].Val; } for (n = 0; n < MinGraphDataSize; n++) { float & v = GraphData->GetElement(MinGraphDataStart+n).Val; v = 1.0f - v; //MinGraph[n].Val = 1.0f - MinGraph[n].Val; } CalculateConstData (); } void DataGraph::NormalToPercent () { MultiplyBy (0.01f); Reverse (); Clamp (0.0f, 1.0f); CalculateConstData (); } void DataGraph::PercentToNormal () { Reverse (); MultiplyBy (100.0f); CalculateConstData (); } void DataGraph::NormalToAlpha () { NormalToPercent (); MultiplyBy (255.0f); CalculateConstData(); } void DataGraph::AlphaToNormal () { MultiplyBy (0.00392156862745098f); PercentToNormal (); CalculateConstData(); } float DataGraph::GetMaxTime () { float MaxVal = 10.0f; float MinVal = 10.0f; DWORD MaxCount = MaxGraphDataSize; DWORD MinCount = MinGraphDataSize; if (MaxCount > 2) MaxVal = GraphData->GetElement(MaxGraphDataStart+MaxCount-2).Time; if (MinCount > 2) MinVal = GraphData->GetElement(MinGraphDataStart+MaxCount-2).Time; if (MaxVal > MinVal) return MaxVal; return MinVal; } void DataGraph::Write (MemFile* File) { DWORD dwNegative = GetNegative(); File->WriteType(dwNegative); DWORD dwRelative = GetRelative(); File->WriteType(dwRelative); DWORD MaxGraphItemsCount = MaxGraphDataSize; File->WriteType(MaxGraphItemsCount); DWORD i = 0; for (i = 0; i < MaxGraphItemsCount; i++) { float fTime = GraphData->GetElement(MaxGraphDataStart+i).Time; File->WriteType(fTime); float fValue = GraphData->GetElement(MaxGraphDataStart+i).Val; File->WriteType(fValue); } DWORD MinGraphItemsCount = MinGraphDataSize; File->WriteType(MinGraphItemsCount); for (i = 0; i < MinGraphItemsCount; i++) { float fTime = GraphData->GetElement(MinGraphDataStart+i).Time; File->WriteType(fTime); float fValue = GraphData->GetElement(MinGraphDataStart+i).Val; File->WriteType(fValue); } //save name DWORD NameLength = crt_strlen (szName); DWORD NameLengthPlusZero = NameLength+1; File->WriteType(NameLengthPlusZero); Assert (NameLength < 128); File->Write(szName, NameLength); File->WriteZeroByte(); } const char* DataGraph::GetEditorName () { return szEditorName; } #ifndef _XBOX void DataGraph::WriteXML (TextFile* xmlFile, dword level) { xmlFile->Write((level+1), "\n", szName); xmlFile->Write((level+1), "\n", GetNegative()); xmlFile->Write((level+1), "\n", GetRelative()); xmlFile->Write((level+1), "\n"); for (long n = 0; n < MaxGraphDataSize; n++) { xmlFile->Write((level+1), "\n"); xmlFile->Write((level+2), "\n"); } xmlFile->Write((level+1), "\n"); xmlFile->Write((level+1), "\n"); for (long n = 0; n < MinGraphDataSize; n++) { xmlFile->Write((level+1), "\n"); xmlFile->Write((level+2), "\n"); } xmlFile->Write((level+1), "\n"); } void DataGraph::LoadXML (TiXmlElement* root) { /* FIXME: to using GraphData MinGraph.DelAll(); MaxGraph.DelAll(); TiXmlElement* name = root->FirstChildElement("Name"); if (name) { SetName (name->Attribute("val"), "a"); } TiXmlElement* neg = root->FirstChildElement("Negative"); if (neg) { SetNegative (atoi (neg->Attribute("val")) == 1); } TiXmlElement* rel = root->FirstChildElement("Relative"); if (rel) { SetRelative (atoi (rel->Attribute("val")) == 1); } TiXmlElement* maxGraphNode = NULL; maxGraphNode = root->FirstChildElement("MaxGraph"); if (maxGraphNode) { for(TiXmlElement* child = maxGraphNode->FirstChildElement(); child; child = child->NextSiblingElement()) { string NodeName = child->Value(); if (NodeName == "Key") { GraphVertex MaxVertex; TiXmlElement* time = child->FirstChildElement("Time"); TiXmlElement* val = child->FirstChildElement("Value"); if (time) { MaxVertex.Time = (float)atof (time->Attribute("val")); } if (val) { MaxVertex.Val = (float)atof (val->Attribute("val")); } MaxGraph.Add(MaxVertex); } } } TiXmlElement* minGraphNode = NULL; minGraphNode = root->FirstChildElement("MinGraph"); if (minGraphNode) { for(TiXmlElement* child = minGraphNode->FirstChildElement(); child; child = child->NextSiblingElement()) { string NodeName = child->Value(); if (NodeName == "Key") { GraphVertex MinVertex; TiXmlElement* time = child->FirstChildElement("Time"); TiXmlElement* val = child->FirstChildElement("Value"); if (time) { MinVertex.Time = (float)atof (time->Attribute("val")); } if (val) { MinVertex.Val = (float)atof (val->Attribute("val")); } MinGraph.Add(MinVertex); } } } CalculateConstData(); */ } #endif