// Number of cameras not used. Multiple cameras never used in 7.1.5 bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, CinematicCameraEntry const* dbcentry) { char const* buffer = reinterpret_cast<char const*>(header); FlyByCameraCollection cameras; FlyByCameraCollection targetcam; G3D::Vector4 dbcData; dbcData.x = dbcentry->Origin.X; dbcData.y = dbcentry->Origin.Y; dbcData.z = dbcentry->Origin.Z; dbcData.w = dbcentry->OriginFacing; // Read target locations, only so that we can calculate orientation for (uint32 k = 0; k < cam->target_positions.timestamps.number; ++k) { // Extract Target positions if (cam->target_positions.timestamps.offset_elements + sizeof(M2Array) > buffSize) return false; M2Array const* targTsArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.timestamps.offset_elements); if (targTsArray->offset_elements + sizeof(uint32) > buffSize || cam->target_positions.values.offset_elements + sizeof(M2Array) > buffSize) return false; uint32 const* targTimestamps = reinterpret_cast<uint32 const*>(buffer + targTsArray->offset_elements); M2Array const* targArray = reinterpret_cast<M2Array const*>(buffer + cam->target_positions.values.offset_elements); if (targArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize) return false; M2SplineKey<G3D::Vector3> const* targPositions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + targArray->offset_elements); // Read the data for this set uint32 currPos = targArray->offset_elements; for (uint32 i = 0; i < targTsArray->number; ++i) { if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize) return false; // Translate co-ordinates G3D::Vector3 newPos = translateLocation(&dbcData, &cam->target_position_base, &targPositions->p0); // Add to vector FlyByCamera thisCam; thisCam.timeStamp = targTimestamps[i]; thisCam.locations.Relocate(newPos.x, newPos.y, newPos.z, 0.0f); targetcam.push_back(thisCam); targPositions++; currPos += sizeof(M2SplineKey<G3D::Vector3>); } } // Read camera positions and timestamps (translating first position of 3 only, we don't need to translate the whole spline) for (uint32 k = 0; k < cam->positions.timestamps.number; ++k) { // Extract Camera positions for this set if (cam->positions.timestamps.offset_elements + sizeof(M2Array) > buffSize) return false; M2Array const* posTsArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.timestamps.offset_elements); if (posTsArray->offset_elements + sizeof(uint32) > buffSize || cam->positions.values.offset_elements + sizeof(M2Array) > buffSize) return false; uint32 const* posTimestamps = reinterpret_cast<uint32 const*>(buffer + posTsArray->offset_elements); M2Array const* posArray = reinterpret_cast<M2Array const*>(buffer + cam->positions.values.offset_elements); if (posArray->offset_elements + sizeof(M2SplineKey<G3D::Vector3>) > buffSize) return false; M2SplineKey<G3D::Vector3> const* positions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + posArray->offset_elements); // Read the data for this set uint32 currPos = posArray->offset_elements; for (uint32 i = 0; i < posTsArray->number; ++i) { if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize) return false; // Translate co-ordinates G3D::Vector3 newPos = translateLocation(&dbcData, &cam->position_base, &positions->p0); // Add to vector FlyByCamera thisCam; thisCam.timeStamp = posTimestamps[i]; thisCam.locations.Relocate(newPos.x, newPos.y, newPos.z); if (targetcam.size() > 0) { // Find the target camera before and after this camera FlyByCamera lastTarget; FlyByCamera nextTarget; // Pre-load first item lastTarget = targetcam[0]; nextTarget = targetcam[0]; for (uint32 j = 0; j < targetcam.size(); ++j) { nextTarget = targetcam[j]; if (targetcam[j].timeStamp > posTimestamps[i]) break; lastTarget = targetcam[j]; } float x = lastTarget.locations.GetPositionX(); float y = lastTarget.locations.GetPositionY(); float z = lastTarget.locations.GetPositionZ(); // Now, the timestamps for target cam and position can be different. So, if they differ we interpolate if (lastTarget.timeStamp != posTimestamps[i]) { uint32 timeDiffTarget = nextTarget.timeStamp - lastTarget.timeStamp; uint32 timeDiffThis = posTimestamps[i] - lastTarget.timeStamp; float xDiff = nextTarget.locations.GetPositionX() - lastTarget.locations.GetPositionX(); float yDiff = nextTarget.locations.GetPositionY() - lastTarget.locations.GetPositionY(); float zDiff = nextTarget.locations.GetPositionZ() - lastTarget.locations.GetPositionZ(); x = lastTarget.locations.GetPositionX() + (xDiff * (float(timeDiffThis) / float(timeDiffTarget))); y = lastTarget.locations.GetPositionY() + (yDiff * (float(timeDiffThis) / float(timeDiffTarget))); z = lastTarget.locations.GetPositionZ() + (zDiff * (float(timeDiffThis) / float(timeDiffTarget))); } float xDiff = x - thisCam.locations.GetPositionX(); float yDiff = y - thisCam.locations.GetPositionY(); thisCam.locations.SetOrientation(std::atan2(yDiff, xDiff)); } cameras.push_back(thisCam); positions++; currPos += sizeof(M2SplineKey<G3D::Vector3>); } } sFlyByCameraStore[dbcentry->ID] = cameras; return true; }
// Number of cameras not used. Multiple cameras never used bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, CinematicCameraEntry const* dbcentry) { char const* buffer = reinterpret_cast<char const*>(header); FlyByCameraCollection cameras; FlyByCameraCollection targetcam; G3D::Vector4 DBCData; DBCData.x = dbcentry->Origin.X; DBCData.y = dbcentry->Origin.Y; DBCData.z = dbcentry->Origin.Z; DBCData.w = dbcentry->OriginFacing; // Extract Target positions if (cam->target_positions.timestamps.offset_elements + sizeof(M2Array) > buffSize) return false; uint32 const* targTimestamps = reinterpret_cast<uint32 const*>(buffer + cam->target_positions.timestamps.offset_elements); M2SplineKey<G3D::Vector3> const* targPositions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + cam->target_positions.values.offset_elements); // Read the data for this set uint32 currPos = cam->target_positions.values.offset_elements; for (uint32 i = 0; i < cam->target_positions.timestamps.number; ++i) { if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize) return false; // Translate co-ordinates G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->target_position_base, &targPositions->p0); // Add to vector FlyByCamera thisCam; thisCam.timeStamp = targTimestamps[i]; thisCam.locations.x = newPos.x; thisCam.locations.y = newPos.y; thisCam.locations.z = newPos.z; thisCam.locations.w = 0.0f; targetcam.push_back(thisCam); targPositions++; currPos += sizeof(M2SplineKey<G3D::Vector3>); } // Extract Camera positions for this set if (cam->positions.timestamps.offset_elements + sizeof(M2Array) > buffSize) return false; uint32 const* posTimestamps = reinterpret_cast<uint32 const*>(buffer + cam->positions.timestamps.offset_elements); M2SplineKey<G3D::Vector3> const* positions = reinterpret_cast<M2SplineKey<G3D::Vector3> const*>(buffer + cam->positions.values.offset_elements); // Read the data for this set currPos = cam->positions.values.offset_elements; for (uint32 i = 0; i < cam->positions.timestamps.number; ++i) { if (currPos + sizeof(M2SplineKey<G3D::Vector3>) > buffSize) return false; // Translate co-ordinates G3D::Vector3 newPos = TranslateLocation(&DBCData, &cam->position_base, &positions->p0); // Add to vector FlyByCamera thisCam; thisCam.timeStamp = posTimestamps[i]; thisCam.locations.x = newPos.x; thisCam.locations.y = newPos.y; thisCam.locations.z = newPos.z; if (targetcam.size() > 0) { // Find the target camera before and after this camera FlyByCamera lastTarget; FlyByCamera nextTarget; // Pre-load first item lastTarget = targetcam[0]; nextTarget = targetcam[0]; for (uint32 j = 0; j < targetcam.size(); ++j) { nextTarget = targetcam[j]; if (targetcam[j].timeStamp > posTimestamps[i]) break; lastTarget = targetcam[j]; } float x = lastTarget.locations.x; float y = lastTarget.locations.y; float z = lastTarget.locations.z; // Now, the timestamps for target cam and position can be different. So, if they differ we interpolate if (lastTarget.timeStamp != posTimestamps[i]) { uint32 timeDiffTarget = nextTarget.timeStamp - lastTarget.timeStamp; uint32 timeDiffThis = posTimestamps[i] - lastTarget.timeStamp; float xDiff = nextTarget.locations.x - lastTarget.locations.x; float yDiff = nextTarget.locations.y - lastTarget.locations.y; float zDiff = nextTarget.locations.z - lastTarget.locations.z; x = lastTarget.locations.x + (xDiff * (float(timeDiffThis) / float(timeDiffTarget))); y = lastTarget.locations.y + (yDiff * (float(timeDiffThis) / float(timeDiffTarget))); z = lastTarget.locations.z + (zDiff * (float(timeDiffThis) / float(timeDiffTarget))); } float xDiff = x - thisCam.locations.x; float yDiff = y - thisCam.locations.y; thisCam.locations.w = std::atan2(yDiff, xDiff); if (thisCam.locations.w < 0) thisCam.locations.w += 2 * float(M_PI); } cameras.push_back(thisCam); positions++; currPos += sizeof(M2SplineKey<G3D::Vector3>); } sFlyByCameraStore[dbcentry->ID] = cameras; return true; }