123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 |
- /////////////////////////////////////////////////////////////////////////////
- // AGCVector.cpp : Implementation of CAGCVector
- //
- #include "pch.h"
- #include "AGCVector.h"
- /////////////////////////////////////////////////////////////////////////////
- // CVector
- TC_OBJECT_EXTERN_IMPL(CAGCVector)
- /////////////////////////////////////////////////////////////////////////////
- // Implementation
- HRESULT CAGCVector::GetRawVector(IAGCVector* pVector, Vector* pVectorRaw)
- {
- __try
- {
- if (!pVector)
- return E_POINTER;
- IAGCVectorPrivate* pPrivate = NULL;
- RETURN_FAILED(pVector->QueryInterface(__uuidof(pPrivate), (void**)&pPrivate));
- assert(pPrivate);
- if (!pPrivate)
- return E_INVALIDARG;
- HRESULT hr = pPrivate->CopyVectorTo(pVectorRaw);
- pPrivate->Release();
- return hr;
- }
- __except(1)
- {
- return E_POINTER;
- }
- }
- HRESULT CAGCVector::CreateResultVector(const Vector* pVectorRaw,
- IAGCVector** ppResult)
- {
- CComObject<CAGCVector>* pVector = NULL;
- RETURN_FAILED(pVector->CreateInstance(&pVector));
- IAGCVectorPtr spVector(pVector);
- RETURN_FAILED(pVector->InitFromVector(pVectorRaw));
- CLEAROUT(ppResult, (IAGCVector*)spVector);
- spVector.Detach();
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // ISupportErrorInfo Interface Methods
- STDMETHODIMP CAGCVector::InterfaceSupportsErrorInfo(REFIID riid)
- {
- static const IID* arr[] =
- {
- &IID_IAGCVector
- };
- for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
- {
- if (InlineIsEqualGUID(*arr[i],riid))
- return S_OK;
- }
- return S_FALSE;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IPersist Interface Methods
- STDMETHODIMP CAGCVector::GetClassID(CLSID* pClassID)
- {
- __try
- {
- *pClassID = GetObjectCLSID();
- }
- __except(1)
- {
- return E_POINTER;
- }
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IPersistStreamInit Interface Methods
- STDMETHODIMP CAGCVector::IsDirty()
- {
- // Return dirty flag
- XLock lock(this);
- return m_bDirty ? S_OK : S_FALSE;
- }
- STDMETHODIMP CAGCVector::Load(LPSTREAM pStm)
- {
- // Read the number of floats being read
- long cDims;
- RETURN_FAILED(pStm->Read(&cDims, sizeof(cDims), NULL));
- if (DIMENSIONS != cDims)
- {
- assert(DIMENSIONS == cDims);
- return ERROR_INVALID_DATA;
- }
- // Read each float from the stream
- float xArg, yArg, zArg;
- RETURN_FAILED(pStm->Read(&xArg, sizeof(xArg), NULL));
- RETURN_FAILED(pStm->Read(&yArg, sizeof(yArg), NULL));
- RETURN_FAILED(pStm->Read(&zArg, sizeof(zArg), NULL));
- // Save the values
- return InitXYZ(xArg, yArg, zArg);
- }
- STDMETHODIMP CAGCVector::Save(LPSTREAM pStm, BOOL fClearDirty)
- {
- // Write out the number of floats being written
- long cDims = DIMENSIONS;
- RETURN_FAILED(pStm->Write(&cDims, sizeof(cDims), NULL));
- // Write each float to the stream
- XLock lock(this);
- float xArg = m_vector.X(), yArg = m_vector.Y(), zArg = m_vector.Z();
- RETURN_FAILED(pStm->Write(&xArg, sizeof(xArg), NULL));
- RETURN_FAILED(pStm->Write(&yArg, sizeof(yArg), NULL));
- RETURN_FAILED(pStm->Write(&zArg, sizeof(zArg), NULL));
- // Clear the dirty flag, if specified
- if (fClearDirty)
- m_bDirty = false;
- // Indicate success
- return S_OK;
- }
- STDMETHODIMP CAGCVector::GetSizeMax(ULARGE_INTEGER* pCbSize)
- {
- __try
- {
- // NOTE: This needs to exactly match what's written in Save
- pCbSize->LowPart = sizeof(long) + sizeof(float) * DIMENSIONS;
- pCbSize->HighPart = 0;
- }
- __except(1)
- {
- return E_POINTER;
- }
- // Indicate success
- return S_OK;
- }
- STDMETHODIMP CAGCVector::InitNew( void)
- {
- // Initialize the vector object
- XLock lock(this);
- m_vector = Vector::GetZero();
- // Indicate success
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IPersistPropertyBag Interface Methods
- STDMETHODIMP CAGCVector::Load(IPropertyBag* pPropBag, IErrorLog* pErrorLog)
- {
- // Load each dimension (column) of the vector object
- CComVariant varX(0.f), varY(0.f), varZ(0.f);
- RETURN_FAILED(pPropBag->Read(L"X", &varX, pErrorLog));
- RETURN_FAILED(pPropBag->Read(L"Y", &varY, pErrorLog));
- RETURN_FAILED(pPropBag->Read(L"Z", &varZ, pErrorLog));
- // Save the values
- return InitXYZ(V_R4(&varX), V_R4(&varY), V_R4(&varZ));
- }
- STDMETHODIMP CAGCVector::Save(IPropertyBag* pPropBag, BOOL fClearDirty, BOOL)
- {
- // Save each dimension (column) of the vector object
- XLock lock(this);
- RETURN_FAILED(pPropBag->Write(L"X", &CComVariant(m_vector.X())));
- RETURN_FAILED(pPropBag->Write(L"Y", &CComVariant(m_vector.Y())));
- RETURN_FAILED(pPropBag->Write(L"Z", &CComVariant(m_vector.Z())));
- // Clear the dirty flag, if specified
- if (fClearDirty)
- m_bDirty = false;
- // Indicate success
- return S_OK;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IAGCVector Interface Methods
- STDMETHODIMP CAGCVector::put_X(float Val)
- {
- XLock lock(this);
- if (m_vector.X() != Val)
- {
- m_vector.SetX(Val);
- m_bDirty = true;
- }
- return S_OK;
- }
- STDMETHODIMP CAGCVector::get_X(float* pVal)
- {
- XLock lock(this);
- CLEAROUT(pVal, m_vector.X());
- return S_OK;
- }
- STDMETHODIMP CAGCVector::put_Y(float Val)
- {
- XLock lock(this);
- if (m_vector.Y() != Val)
- {
- m_vector.SetY(Val);
- m_bDirty = true;
- }
- return S_OK;
- }
- STDMETHODIMP CAGCVector::get_Y(float* pVal)
- {
- XLock lock(this);
- CLEAROUT(pVal, m_vector.Y());
- return S_OK;
- }
- STDMETHODIMP CAGCVector::put_Z(float Val)
- {
- XLock lock(this);
- if (m_vector.Z() != Val)
- {
- m_vector.SetZ(Val);
- m_bDirty = true;
- }
- return S_OK;
- }
- STDMETHODIMP CAGCVector::get_Z(float* pVal)
- {
- XLock lock(this);
- CLEAROUT(pVal, m_vector.Z());
- return S_OK;
- }
- STDMETHODIMP CAGCVector::put_DisplayString(BSTR bstrDisplayString)
- {
- // Invalid if string is empty
- if (!BSTRLen(bstrDisplayString))
- return E_INVALIDARG;
- // Load the format string
- CComBSTR bstrFmt;
- if (!bstrFmt.LoadString(IDS_FMT_VECTOR))
- return HRESULT_FROM_WIN32(::GetLastError());
- // Extract the values from the string
- float xArg, yArg, zArg;
- if (3 != swscanf(bstrDisplayString, bstrFmt, &xArg, &yArg, &zArg))
- return E_INVALIDARG;
- // Save the values
- return InitXYZ(xArg, yArg, zArg);
- }
- STDMETHODIMP CAGCVector::get_DisplayString(BSTR* pbstrDisplayString)
- {
- // Load the format string
- CComBSTR bstrFmt;
- if (!bstrFmt.LoadString(IDS_FMT_VECTOR))
- return HRESULT_FROM_WIN32(::GetLastError());
- // Format the string
- XLock lock(this);
- OLECHAR szText[_MAX_PATH];
- swprintf(szText, bstrFmt, m_vector.X(), m_vector.Y(), m_vector.Z());
- // Detach the string to the [out] parameter
- CComBSTR bstr(szText);
- CLEAROUT(pbstrDisplayString, (BSTR)bstr);
- bstr.Detach();
- // Indicate success
- return S_OK;
- }
- STDMETHODIMP CAGCVector::InitXYZ(float xArg, float yArg, float zArg)
- {
- XLock lock(this);
- if (m_vector.X() != xArg || m_vector.Y() != yArg || m_vector.Z() != zArg)
- {
- m_vector.SetX(xArg);
- m_vector.SetY(yArg);
- m_vector.SetZ(zArg);
- m_bDirty = true;
- }
- return S_OK;
- }
- STDMETHODIMP CAGCVector::InitCopy(IAGCVector* pVector)
- {
- // Get the values of the specified vector
- float xArg, yArg, zArg;
- RETURN_FAILED(pVector->get_X(&xArg));
- RETURN_FAILED(pVector->get_Y(&yArg));
- RETURN_FAILED(pVector->get_Z(&zArg));
- // Save the values
- return InitXYZ(xArg, yArg, zArg);
- }
- STDMETHODIMP CAGCVector::InitRandomDirection()
- {
- // Create a random direction
- return InitFromVector(&Vector::RandomDirection());
- }
- STDMETHODIMP CAGCVector::InitRandomPosition(float fRadius)
- {
- // Create a random position
- return InitFromVector(&Vector::RandomPosition(fRadius));
- }
- STDMETHODIMP CAGCVector::get_IsZero(VARIANT_BOOL* pbIsZero)
- {
- XLock lock(this);
- CLEAROUT(pbIsZero, VARBOOL(m_vector.IsZero()));
- return S_OK;
- }
- STDMETHODIMP CAGCVector::get_IsEqual(IAGCVector* pVector,
- VARIANT_BOOL* pbIsEqual)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- CLEAROUT(pbIsEqual, VARBOOL(vector == m_vector));
- return S_OK;
- }
- STDMETHODIMP CAGCVector::get_Length(float* pfLength)
- {
- XLock lock(this);
- CLEAROUT(pfLength, m_vector.Length());
- return S_OK;
- }
- STDMETHODIMP CAGCVector::get_LengthSquared(float* pfLengthSquared)
- {
- XLock lock(this);
- CLEAROUT(pfLengthSquared, m_vector.LengthSquared());
- return S_OK;
- }
- STDMETHODIMP CAGCVector::get_OrthogonalVector(IAGCVector** ppResult)
- {
- XLock lock(this);
- return CreateResultVector(&m_vector.GetOrthogonalVector(), ppResult);
- }
- STDMETHODIMP CAGCVector::Add(IAGCVector* pVector, IAGCVector** ppResult)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return CreateResultVector(&(m_vector + vector), ppResult);
- }
- STDMETHODIMP CAGCVector::Subtract(IAGCVector* pVector, IAGCVector** ppResult)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return CreateResultVector(&(m_vector - vector), ppResult);
- }
- STDMETHODIMP CAGCVector::Multiply(float f, IAGCVector** ppResult)
- {
- XLock lock(this);
- return CreateResultVector(&(m_vector * f), ppResult);
- }
- STDMETHODIMP CAGCVector::Divide(float f, IAGCVector** ppResult)
- {
- XLock lock(this);
- return CreateResultVector(&(m_vector / f), ppResult);
- }
- STDMETHODIMP CAGCVector::Normalize(IAGCVector** ppResult)
- {
- XLock lock(this);
- return CreateResultVector(&m_vector.Normalize(), ppResult);
- }
- STDMETHODIMP CAGCVector::CrossProduct(IAGCVector* pVector,
- IAGCVector** ppResult)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return CreateResultVector(&::CrossProduct(m_vector, vector), ppResult);
- }
- STDMETHODIMP CAGCVector::Interpolate(IAGCVector* pVector, float fValue,
- IAGCVector** ppResult)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return CreateResultVector(&::Interpolate(m_vector, vector, fValue), ppResult);
- }
- STDMETHODIMP CAGCVector::AddInPlace(IAGCVector* pVector)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return InitFromVector(&(m_vector + vector));
- }
- STDMETHODIMP CAGCVector::SubtractInPlace(IAGCVector* pVector)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return InitFromVector(&(m_vector - vector));
- }
- STDMETHODIMP CAGCVector::MultiplyInPlace(float f)
- {
- XLock lock(this);
- return InitFromVector(&(m_vector * f));
- }
- STDMETHODIMP CAGCVector::DivideInPlace(float f)
- {
- XLock lock(this);
- return InitFromVector(&(m_vector / f));
- }
- STDMETHODIMP CAGCVector::NormalizeInPlace()
- {
- XLock lock(this);
- m_vector.SetNormalize();
- return S_OK;
- }
- STDMETHODIMP CAGCVector::CrossProductInPlace(IAGCVector* pVector)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return InitFromVector(&::CrossProduct(m_vector, vector));
- }
- STDMETHODIMP CAGCVector::InterpolateInPlace(IAGCVector* pVector, float fValue)
- {
- Vector vector;
- RETURN_FAILED(GetRawVector(pVector, &vector));
- XLock lock(this);
- return InitFromVector(&::Interpolate(m_vector, vector, fValue));
- }
- /////////////////////////////////////////////////////////////////////////////
- // IAGCVectorPrivate Interface Methods
- STDMETHODIMP CAGCVector::InitFromVector(const void* pvVector)
- {
- Vector vectorTemp;
- const Vector* pVector = reinterpret_cast<const Vector*>(pvVector);
- if (!pVector)
- {
- vectorTemp = Vector::GetZero();
- pVector = &vectorTemp;
- }
- return InitXYZ(pVector->X(), pVector->Y(), pVector->Z());
- }
- STDMETHODIMP CAGCVector::CopyVectorTo(void* pvVector)
- {
- XLock lock(this);
- Vector* pVector = reinterpret_cast<Vector*>(pvVector);
- pVector->SetX(m_vector.X());
- pVector->SetY(m_vector.Y());
- pVector->SetZ(m_vector.Z());
- return S_OK;
- }
|