#include <valfunc.h>
Inheritance diagram for ValueFunctionPressure:
Public Member Functions | |
ValueFunctionPressure () | |
Constructor Pressure functions store a table of recorded pressure values and return curve-interpolated pressure values on demand. | |
~ValueFunctionPressure () | |
Destructor. | |
virtual double | GetValue (double Position) |
To read the value of this function at a given position. | |
virtual ValueFunction * | Clone (void) |
Clone operator. Creates an exact copy of this object. | |
virtual BOOL | IsDifferent (ValueFunction *pOther) |
Comparator. Determines if 2 different ValueFunction objects are considered different. | |
BOOL | AddPressure (float Position, float PressureValue) |
Adds a pressure record to the ValueFunction table. | |
void | NormalisePositions (void) |
Normalises all positions in the table to lie within a 0.0 to 1.0 range, by dividing them by the last element position value. (i.e. it assumes that the last element in the array will have the largest Position value). | |
virtual CamelotFileRecord * | WriteFileRecord (INT32 RecordTag, INT32 ExtraBytes, BaseCamelotFilter *pFilter) |
Saves a ValueFunction object to a Xara file. This function will create a new variable-sized record with the given record tag, and will write out whatever data is needed to save this ValueFunction's state to the file. | |
virtual ValueFunctionID | GetUniqueID (void) |
Protected Member Functions | |
virtual ValueFunction * | CreateAndReadFileRecord (CXaraFileRecord *pInputRecord) |
Loads a ValueFunction object from a record which was saved into a file using the WriteFileRecord call. This is called by the base class loader routine ReadFileRecord, which finds an appropriate instance of a derived class to call to load the data in question. | |
BOOL | ExpandArray (INT32 NewSize) |
Ensures that the pressure storage array has no fewer than NewSize entries. | |
virtual ValueFunctionPressure * | CreateInstance (void) |
Creates a new blank object of the same type as this one. Internal function used in ValueFunctionPressure & ValueFunctionPressureS. | |
Protected Attributes | |
VFPressureRecord * | pArray |
INT32 | ArraySize |
INT32 | NextFree |
Private Member Functions | |
CC_DECLARE_DYNAMIC (ValueFunctionPressure) |
Definition at line 854 of file valfunc.h.
|
Constructor Pressure functions store a table of recorded pressure values and return curve-interpolated pressure values on demand.
Definition at line 2820 of file valfunc.cpp.
|
|
Destructor.
Definition at line 2840 of file valfunc.cpp.
|
|
Adds a pressure record to the ValueFunction table.
PressureValue - The pressure value to record for this position
Definition at line 3027 of file valfunc.cpp. 03028 { 03029 ERROR3IF(PressureValue < 0.0 || PressureValue > 1.0, "Illegal pressure value"); 03030 ERROR3IF(Position < 0.0, "Illegal (negative) position value"); 03031 03032 // Make sure there's plenty of room for new entries 03033 if (NextFree >= ArraySize && !ExpandArray(ArraySize + 32)) 03034 return(FALSE); 03035 03036 // Only record the value if the position has advanced. Error if the position has 03037 // gone retrograde, but quietly dismiss equal positions. 03038 ERROR3IF(NextFree > 0 && Position < pArray[NextFree-1].Position, 03039 "AddPressure - pressure values must be ascending"); 03040 if (NextFree > 0 && Position <= pArray[NextFree-1].Position) 03041 return(TRUE); 03042 03043 // And write this entry 03044 pArray[NextFree].Position = Position; 03045 pArray[NextFree].Pressure = PressureValue; 03046 NextFree++; 03047 03048 return(TRUE); 03049 }
|
|
|
|
Clone operator. Creates an exact copy of this object.
Implements ValueFunction. Definition at line 2932 of file valfunc.cpp. 02933 { 02934 // Create another object of this type 02935 ValueFunctionPressure *pClone = CreateInstance(); 02936 02937 if (pClone != NULL) 02938 { 02939 // If that worked, make it allocate an array large enough to hold a copy of 02940 // our data, and memcpy the array across. 02941 if (pClone->ExpandArray(NextFree)) 02942 { 02943 // We only copy the used array entries so the clone will have no wasted space in it 02944 memcpy(pClone->pArray, pArray, NextFree * sizeof(VFPressureRecord)); 02945 pClone->NextFree = NextFree; 02946 pClone->ArraySize = NextFree; 02947 } 02948 } 02949 02950 return(pClone); 02951 }
|
|
Loads a ValueFunction object from a record which was saved into a file using the WriteFileRecord call. This is called by the base class loader routine ReadFileRecord, which finds an appropriate instance of a derived class to call to load the data in question.
Implements ValueFunction. Definition at line 3242 of file valfunc.cpp. 03243 { 03244 ERROR3IF(pInputRecord == NULL, "Illegal NULL param"); 03245 03246 UINT32 NumEntries = 0; 03247 pInputRecord->ReadUINT32(&NumEntries); 03248 03249 ValueFunctionPressure *pValFunc = CreateInstance(); 03250 03251 if (pValFunc != NULL && NumEntries > 0) 03252 { 03253 // Make the array big enough to hold all the entries, to save reallocing it as we go, 03254 // and also to save us having to check for failure on each pressure item we add. 03255 if (!pValFunc->ExpandArray(NumEntries)) 03256 { 03257 delete pValFunc; 03258 return(NULL); 03259 } 03260 03261 UINT16 Position; 03262 UINT16 Pressure; 03263 03264 for (UINT32 i = 0; i < NumEntries; i++) 03265 { 03266 pInputRecord->ReadUINT16(&Position); 03267 pInputRecord->ReadUINT16(&Pressure); 03268 pValFunc->AddPressure( ((float)Position) / (float) 65535.0, 03269 ((float)Pressure) / (float) 65535.0); 03270 } 03271 } 03272 03273 return(pValFunc); 03274 }
|
|
Creates a new blank object of the same type as this one. Internal function used in ValueFunctionPressure & ValueFunctionPressureS.
Reimplemented in ValueFunctionPressureS. Definition at line 3298 of file valfunc.cpp. 03299 { 03300 return(new ValueFunctionPressure); 03301 }
|
|
Ensures that the pressure storage array has no fewer than NewSize entries.
Definition at line 3103 of file valfunc.cpp. 03104 { 03105 if (NewSize <= ArraySize) 03106 return(TRUE); // That was easy! 03107 03108 VFPressureRecord *pNewArray = NULL; 03109 03110 if (pArray == NULL) 03111 pNewArray = (VFPressureRecord *) CCMalloc(NewSize * sizeof(VFPressureRecord)); 03112 else 03113 pNewArray = (VFPressureRecord *) CCRealloc(pArray, NewSize * sizeof(VFPressureRecord)); 03114 03115 if (pNewArray == NULL) 03116 return(FALSE); 03117 03118 // We succeeded, so remember the new address & size 03119 pArray = pNewArray; 03120 ArraySize = NewSize; 03121 03122 return(TRUE); 03123 }
|
|
Implements ValueFunction. Reimplemented in ValueFunctionPressureS. Definition at line 879 of file valfunc.h. 00879 { return(ValueFunctionID_Pressure); };
|
|
To read the value of this function at a given position.
The "curve" may be improved in future, but is currently a simple linear interpolation. !!!!TODO: This should cache the last array index it was asked for, and start the search from that index, as we usually ask for values for sequential, close, position values, and this will vastly reduce the searching overhead in most cases. Note that we may step through positions in both positive & negative directions, so it will have to handle this carefully. Implements ValueFunction. Reimplemented in ValueFunctionPressureS. Definition at line 2876 of file valfunc.cpp. 02877 { 02878 // No entries have been recorded! 02879 if (NextFree < 1) 02880 return(0.0); 02881 02882 // If the position is outside the range in our table, return the closest entry 02883 if (Position <= pArray[0].Position) 02884 return(pArray[0].Pressure); 02885 02886 if (Position >= pArray[NextFree-1].Position) 02887 return(pArray[NextFree-1].Pressure); 02888 02889 // Search to find the closest 2 array entries to the position 02890 // We assume the array fills the 0.0 to 1.0 range, so we search from the closest 02891 // "end" of the array to halve the average search time. 02892 INT32 i; 02893 if (Position >= 0.5) 02894 { 02895 i = NextFree; 02896 while (i > 1 && Position < pArray[i-1].Position) 02897 i--; 02898 } 02899 else 02900 { 02901 i = 1; 02902 while (i < NextFree && Position > pArray[i].Position) 02903 i++; 02904 } 02905 02906 ERROR3IF(i < 1 || i >= NextFree, "I've screwed up the scanning loop code"); 02907 02908 // Otherwise, the position lies between array elements [i-1] and [i], so we 02909 // interpolate between these positions 02910 ERROR3IF((pArray[i].Position - pArray[i-1].Position) <= 0.0, "Pressure array is non-ascending!"); 02911 const double MixValue = (Position - pArray[i-1].Position) / 02912 (pArray[i].Position - pArray[i-1].Position); 02913 02914 return((MixValue * pArray[i].Pressure) + ((1.0 - MixValue) * pArray[i-1].Pressure)); 02915 }
|
|
Comparator. Determines if 2 different ValueFunction objects are considered different.
Reimplemented from ValueFunction. Definition at line 2976 of file valfunc.cpp. 02977 { 02978 if (ValueFunction::IsDifferent(pOther)) 02979 return(TRUE); 02980 02981 // Both objects are instances of this class, so compare them more carefully 02982 ValueFunctionPressure *pPressure = (ValueFunctionPressure *)pOther; 02983 if (NextFree != pPressure->NextFree) 02984 return(TRUE); // Don't have same number of entries 02985 02986 // Now compare the entire array 02987 for (INT32 i = 0; i < NextFree; i++) 02988 { 02989 if (pArray[i].Position != pPressure->pArray[i].Position || 02990 pArray[i].Pressure != pPressure->pArray[i].Pressure) 02991 { 02992 return(TRUE); 02993 } 02994 } 02995 02996 // Cor. They must be the same! 02997 return(FALSE); 02998 }
|
|
Normalises all positions in the table to lie within a 0.0 to 1.0 range, by dividing them by the last element position value. (i.e. it assumes that the last element in the array will have the largest Position value).
Definition at line 3066 of file valfunc.cpp. 03067 { 03068 // If fewer than 1 entries, or no array, then there's nothing to do 03069 if (pArray == NULL || NextFree < 1) 03070 return; 03071 03072 // Find the maximum value, and baulk if it would cause a divide by zero. 03073 if (pArray[NextFree-1].Position <= 0.0) 03074 { 03075 ERROR3("Max position in table is zero or negative - normalisation failed"); 03076 return; 03077 } 03078 03079 float RMaxPosition = 1.0/pArray[NextFree-1].Position; 03080 for (INT32 i = 0; i < NextFree; i++) 03081 pArray[i].Position *= RMaxPosition; 03082 }
|
|
Saves a ValueFunction object to a Xara file. This function will create a new variable-sized record with the given record tag, and will write out whatever data is needed to save this ValueFunction's state to the file.
All ValueFunction record data has 3 sections, whiich are recorded as follows: 1. ValueFunction header, identifying which type of VF is being saved INT32 ValueFunctionUniqueID (4 bytes) 2. Derived-class-data (0 or more bytes). This particular class adds: UINT32 NumTableEntries + n entries of the form: UNIT16 Position UINT16 Pressure (4 + (NumTableEntries*4) bytes) 3. Caller data. This is written by the caller to the returned record object. This data must be ExtraBytes (0 or more) bytes in length. The Position & Pressure values are 16-bit unsigned values between 0 & 65535. These represent floating point values between 0.0 & 1.0, i.e. are simply a (UINT16) (Value * 65535.0). I don't bother avoiding rounding errors, as 1/128000th is an insignificant error.
Implements ValueFunction. Definition at line 3178 of file valfunc.cpp. 03180 { 03181 ERROR3IF(pFilter == NULL, "Illegal NULL param"); 03182 ERROR3IF(ExtraBytes < 0, "Stupid ExtraBytes request in ValueFunction::WriteFileRecord"); 03183 03184 // Calculate how many bytes of information this VF will write. We do not include 03185 // the header info written by the base class or the ExtraInfo desired by the caller - 03186 // the base class adds all that in for us. 03187 const INT32 MyRecordSize = 4 + (4 * NextFree); 03188 03189 // Create an appropriate record, and write our data to it 03190 CamelotFileRecord *pRec = CreateAndWriteFileRecord(RecordTag, MyRecordSize, ExtraBytes, pFilter); 03191 03192 if (pRec != NULL) 03193 { 03194 BOOL ok = TRUE; 03195 if (ok) ok = pRec->WriteUINT32((UINT32) NextFree); 03196 03197 for (INT32 i = 0; (i < NextFree) && ok; i++) 03198 { 03199 if (ok) ok = pRec->WriteUINT16((UINT16) (pArray[i].Position * 65535.0)); 03200 if (ok) ok = pRec->WriteUINT16((UINT16) (pArray[i].Pressure * 65535.0)); 03201 } 03202 03203 if (!ok) // If we failed, clean up & return NULL 03204 { 03205 delete pRec; 03206 pRec = NULL; 03207 } 03208 } 03209 03210 return(pRec); 03211 }
|
|
|
|
|
|
|