Example #1
0
LoaderDFF::GeometryList LoaderDFF::readGeometryList(const RWBStream &stream) {
    auto listStream = stream.getInnerStream();

    auto listStructID = listStream.getNextChunk();
    if (listStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Geometry List missing struct chunk");
    }

    char *headerPtr = listStream.getCursor();

    unsigned int numGeometries = *(std::uint32_t *)headerPtr;
    headerPtr += sizeof(std::uint32_t);

    std::vector<GeometryPtr> geometrylist;
    geometrylist.reserve(numGeometries);

    for (auto chunkID = listStream.getNextChunk(); chunkID != 0;
         chunkID = listStream.getNextChunk()) {
        switch (chunkID) {
            case CHUNK_GEOMETRY: {
                geometrylist.push_back(readGeometry(listStream));
            } break;
            default:
                break;
        }
    }

    return geometrylist;
}
Example #2
0
void LoaderDFF::readTexture(Geometry::Material &material,
                            const RWBStream &stream) {
    auto texStream = stream.getInnerStream();

    auto texStructID = texStream.getNextChunk();
    if (texStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Texture missing struct chunk");
    }

    // There's some data in the Texture's struct, but we don't know what it is.

    /// @todo improve how these strings are read.
    std::string name, alpha;

    texStream.getNextChunk();
    name = texStream.getCursor();
    texStream.getNextChunk();
    alpha = texStream.getCursor();

    std::transform(name.begin(), name.end(), name.begin(), ::tolower);
    std::transform(alpha.begin(), alpha.end(), alpha.begin(), ::tolower);

    TextureData::Handle textureinst =
        texturelookup ? texturelookup(name, alpha) : nullptr;
    material.textures.push_back({name, alpha, textureinst});
}
Example #3
0
AtomicPtr LoaderDFF::readAtomic(FrameList &framelist,
                                GeometryList &geometrylist,
                                const RWBStream &stream) {
    auto atomicStream = stream.getInnerStream();

    auto atomicStructID = atomicStream.getNextChunk();
    if (atomicStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Atomic missing struct chunk");
    }

    auto data = atomicStream.getCursor();
    auto frame = *(std::uint32_t *)data;
    data += sizeof(std::uint32_t);
    auto geometry = *(std::uint32_t *)data;
    data += sizeof(std::uint32_t);
    auto flags = *(std::uint32_t *) data;

    // Verify the atomic's particulars
    RW_CHECK(frame < framelist.size(), "atomic frame " << frame
                                                       << " out of bounds");
    RW_CHECK(geometry < geometrylist.size(),
             "atomic geometry " << geometry << " out of bounds");

    auto atomic = std::make_shared<Atomic>();
    if (geometry < geometrylist.size()) {
        atomic->setGeometry(geometrylist[geometry]);
    }
    if (frame < framelist.size()) {
        atomic->setFrame(framelist[frame]);
    }
    atomic->setFlags(flags);

    return atomic;
}
Example #4
0
void SampleReader::init(const unsigned chunkSize) {

  this->chunkSize = chunkSize;

  timeFile.open("Time_1.dat", std::ios::in | std::ios::binary);

  channel0Buffer = new float[chunkSize];
  channel1Buffer = new float[chunkSize];

  getNextChunk();
  /*
    We don't have a start time of the first chunk. Hence we have to
    skip them to get a proper time. As an implication, we should
    assure to start the experiment at least one chunk after the
    measurement!
  */
  getNextChunk();
  examinedSoFar = bufferBegin;
}
Example #5
0
void PCMMusicPlayer::play() {
	if (_curChunk)
		return;
	if (_scriptNum == -1)
		return;

	_end = false;

	getNextChunk();
}
Example #6
0
void LoaderDFF::readMaterial(GeometryPtr &geom, const RWBStream &stream) {
    auto materialStream = stream.getInnerStream();

    auto matStructID = materialStream.getNextChunk();
    if (matStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Material missing struct chunk");
    }

    char *matData = materialStream.getCursor();

    Geometry::Material material;

    // Unkown
    matData += sizeof(std::uint32_t);
    material.colour = *(glm::u8vec4 *)matData;
    matData += sizeof(std::uint32_t);
    // Unkown
    matData += sizeof(std::uint32_t);
    /*bool usesTexture = *(std::uint32_t*)matData;*/
    matData += sizeof(std::uint32_t);

    material.ambientIntensity = *(float *)matData;
    matData += sizeof(float);
    /*float specular = *(float*)matData;*/
    matData += sizeof(float);
    material.diffuseIntensity = *(float *)matData;
    matData += sizeof(float);
    material.flags = 0;

    RWBStream::ChunkID chunkID;
    while ((chunkID = materialStream.getNextChunk())) {
        switch (chunkID) {
            case CHUNK_TEXTURE:
                readTexture(material, materialStream);
                break;
            default:
                break;
        }
    }

    geom->materials.push_back(material);
}
Example #7
0
//---------------------------------------------------------------------------
void CFunction::Format(CExportContext& ctx, const SFString& fmtIn, void *data) const
{
	if (!isShowing())
		return;

	SFString fmt = (fmtIn.IsEmpty() ? defaultFormat() : fmtIn); //.Substitute("\n","\t");
	if (handleCustomFormat(ctx, fmt, data))
		return;

	CFunctionNotify dn(this);
	while (!fmt.IsEmpty())
		ctx << getNextChunk(fmt, nextFunctionChunk, &dn);
}
Example #8
0
void LoaderDFF::readMaterialList(GeometryPtr &geom, const RWBStream &stream) {
    auto listStream = stream.getInnerStream();

    auto listStructID = listStream.getNextChunk();
    if (listStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("MaterialList missing struct chunk");
    }

    unsigned int numMaterials = *(std::uint32_t *)listStream.getCursor();

    geom->materials.reserve(numMaterials);

    RWBStream::ChunkID chunkID;
    while ((chunkID = listStream.getNextChunk())) {
        switch (chunkID) {
            case CHUNK_MATERIAL:
                readMaterial(geom, listStream);
                break;
            default:
                break;
        }
    }
}
Example #9
0
void LoaderDFF::readGeometryExtension(GeometryPtr &geom,
                                      const RWBStream &stream) {
    auto extStream = stream.getInnerStream();

    RWBStream::ChunkID chunkID;
    while ((chunkID = extStream.getNextChunk())) {
        switch (chunkID) {
            case CHUNK_BINMESHPLG:
                readBinMeshPLG(geom, extStream);
                break;
            default:
                break;
        }
    }
}
Example #10
0
double SampleReader::getEnergy(timespec intervalEnd) {
  // TODO: use interval arithmetic to account for offset of clocks?

  double energy = 0.0;
  timespec begin, end;
  unsigned firstSample, lastSample;
  double lackingFirstSampleFraction, lackingLastSampleFraction;

  if ( !(intervalEnd >= examinedSoFar) ) {
      std::cerr << "Warning: Timestamp detected which is prior to previous one, exiting! Assure to wait for at least 1s before starting your code after the measurement begins!" << std::endl;
      std::cerr << "         intervalEnd   = " << intervalEnd.tv_sec << "." << std::setfill('0') << std::setw(9) << intervalEnd.tv_nsec << std::endl;
      std::cerr << "         examinedSoFar = " << examinedSoFar.tv_sec << "." << std::setfill('0') << std::setw(9) << examinedSoFar.tv_nsec << std::endl;
      std::cerr << std::endl;
      exit(EXIT_FAILURE);
  }

  while (intervalEnd > examinedSoFar) {

    if (examinedSoFar >= bufferEnd) {
      getNextChunk();
      examinedSoFar = bufferBegin;
    }

    begin = examinedSoFar;
    end = ( intervalEnd > bufferEnd ? bufferEnd : intervalEnd );
    firstSample = enclosingSample(begin);
    lastSample = enclosingSample(end);

    // account for missing part of (partial) first sample
    lackingFirstSampleFraction = ( (begin - startTimeOfEnclosingSample(begin)) / sampleWidth );
    energy += getEnergyOfSample(firstSample, -lackingFirstSampleFraction);

    // account for boundary and (full) inner samples
    for (unsigned currentSample = firstSample; currentSample <= lastSample; currentSample++) {
      energy += getEnergyOfSample(currentSample, 1);
    }

    // account for missing part of (partial) last sample
    lackingLastSampleFraction = ( (endTimeOfEnclosingSample(end) - end) / sampleWidth );
    energy += getEnergyOfSample(lastSample, -lackingLastSampleFraction);

    examinedSoFar = end;
  }

  return energy;

}
Example #11
0
int PCMMusicPlayer::readBuffer(int16 *buffer, const int numSamples) {
	Common::StackLock slock(_mutex);

	if (!_curChunk && ((_state == S_IDLE) || (_state == S_STOP)))
		return 0;

	int samplesLeft = numSamples;

	while (samplesLeft > 0) {
		if (_silenceSamples > 0) {
			int n = MIN(_silenceSamples, samplesLeft);

			memset(buffer, 0, n);

			buffer += n;
			_silenceSamples -= n;
			samplesLeft -= n;

		} else if (_curChunk &&
		          ((_state == S_MID) || (_state == S_NEXT) || (_state == S_NEW))) {
			int n = _curChunk->readBuffer(buffer, samplesLeft);

			buffer += n;
			samplesLeft -= n;

			if (_curChunk->endOfData()) {
				_state = S_END1;

				delete _curChunk;
				_curChunk = 0;
			}
		} else {

			if (!getNextChunk())
				break;
		}
	}

	return (numSamples - samplesLeft);
}
//
// Loop for ever, and wait for new jobs.
// The general principle used is repeating (starting with locked mutex):
//   wait(condition)
//   pop a job from the job queue
//   unlock(mutex)
//   Do the job.
//   lock(mutex)
//   put result in outgoing queue.
//
// This means that the actual job is done with no locked semaphores. Because of that, it is important that no data is
// manipulated that can also be accessed from the main process.
void ChunkProcess::Task(void) {
	std::unique_lock<std::mutex> lock(fMutex); // This will lock the mutex

	// The condition variable will not have any effect if not waiting for it. And that may happen
	// as the mutex is unlocked in the loop now and then.
	bool waitForCondition = true;

	// Stay in a loop forever, waiting for new messages to play
	while(1) {
		if (waitForCondition)
			fCondLock.wait(lock);
		waitForCondition = true; // Wait for condition next iteration

		if (fTerminate) {
			// Used to request that the child thread terminates.
			fMutex.unlock();
			break;
		}

		if (!fComputeObjectsInput.empty()) {
			// Take out the chunk from the fifo
			chunk *ch = getNextChunk(fComputeObjectsInput);
			if (ch == 0)
				continue;
			if (ch->fScheduledForLoading) {
				ch->fScheduledForComputation = false;
				continue; // Ignore a recomputation, as the chunk will be loaded by new data anyway, later followed by a new computation
			}
			fMutex.unlock(); // Unlock the mutex while doing some heavy work
			// printf("ChunkProcess phase 1, size %d, chunk %d,%d,%d\n", fComputeObjectsInput.size()+1, ch->cc.x, ch->cc.y, ch->cc.z);
			auto co = ChunkObject::Make(ch, false, 0, 0, 0);
			co->FindSpecialObjects(ch); // This will find light sources, and should be done before FindTriangles().
			fMutex.lock();
			ASSERT(ch->fScheduledForComputation);
			co->fChunk = ch;
			fComputedObjectsOutput.insert(std::move(co)); // Add it to the list of recomputed chunks
			waitForCondition = false; // Try another iteration
		}

		if (!fNewChunksInput.empty()) {
			auto nc = getNextChunkBlock(fNewChunksInput);
			chunk *pc = nc->fChunk;
			// It may be that this chunk was also scheduled for recomputation. If so, the Uncompress() below that calls SetDirty() will not
			// schedule a new recomputation again.
			ASSERT(pc->fScheduledForLoading);
			fMutex.unlock(); // Unlock the mutex while doing some work
			// printf("ChunkProcess phase 2, size %d\n", fNewChunksInput.size()+1);
			nc->Uncompress();

			// Save chunk in cache
			ChunkCache::cachunk chunkdata;
			chunkdata.cc = pc->cc;
			chunkdata.flag = nc->flag;
			chunkdata.fCheckSum = nc->fChecksum;
			chunkdata.fOwner = nc->fOwner;
			chunkdata.compressSize = nc->compressSize;
			chunkdata.compressedChunk = nc->fCompressedChunk.get();
			ChunkCache::fgChunkCache.SaveChunkInCache(&chunkdata); // TODO: Use a ChunkProcess::ChunkBlocks as argument instead
			fMutex.lock();
			ASSERT(nc->fChunk == pc);
			fNewChunksOutput.insert(nc); // Add it to the list of loaded chunks
			waitForCondition = false; // Try another iteration
		}
	}
}
Example #13
0
LoaderDFF::FrameList LoaderDFF::readFrameList(const RWBStream &stream) {
    auto listStream = stream.getInnerStream();

    auto listStructID = listStream.getNextChunk();
    if (listStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Frame List missing struct chunk");
    }

    char *headerPtr = listStream.getCursor();

    unsigned int numFrames = *(std::uint32_t *)headerPtr;
    headerPtr += sizeof(std::uint32_t);

    FrameList framelist;
    framelist.reserve(numFrames);

    for (size_t f = 0; f < numFrames; ++f) {
        auto data = (RWBSFrame *)headerPtr;
        headerPtr += sizeof(RWBSFrame);
        auto frame =
            std::make_shared<ModelFrame>(f, data->rotation, data->position);

        RW_CHECK(data->index < int(framelist.size()),
                 "Frame parent out of bounds");
        if (data->index != -1 && data->index < int(framelist.size())) {
            framelist[data->index]->addChild(frame);
        }

        framelist.push_back(frame);
    }

    size_t namedFrames = 0;

    /// @todo perhaps flatten this out a little
    for (auto chunkID = listStream.getNextChunk(); chunkID != 0;
         chunkID = listStream.getNextChunk()) {
        switch (chunkID) {
            case CHUNK_EXTENSION: {
                auto extStream = listStream.getInnerStream();
                for (auto chunkID = extStream.getNextChunk(); chunkID != 0;
                     chunkID = extStream.getNextChunk()) {
                    switch (chunkID) {
                        case CHUNK_NODENAME: {
                            std::string fname(extStream.getCursor(),
                                              extStream.getCurrentChunkSize());
                            std::transform(fname.begin(), fname.end(),
                                           fname.begin(), ::tolower);

                            if (namedFrames < framelist.size()) {
                                framelist[namedFrames++]->setName(fname);
                            }
                        } break;
                        default:
                            break;
                    }
                }
            } break;
            default:
                break;
        }
    }

    return framelist;
}
Example #14
0
GeometryPtr LoaderDFF::readGeometry(const RWBStream &stream) {
    auto geomStream = stream.getInnerStream();

    auto geomStructID = geomStream.getNextChunk();
    if (geomStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Geometry missing struct chunk");
    }

    auto geom = std::make_shared<Geometry>();

    char *headerPtr = geomStream.getCursor();

    geom->flags = *(std::uint16_t *)headerPtr;
    headerPtr += sizeof(std::uint16_t);

    /*unsigned short numUVs = *(std::uint8_t*)headerPtr;*/
    headerPtr += sizeof(std::uint8_t);
    /*unsigned short moreFlags = *(std::uint8_t*)headerPtr;*/
    headerPtr += sizeof(std::uint8_t);

    unsigned int numTris = *(std::uint32_t *)headerPtr;
    headerPtr += sizeof(std::uint32_t);
    unsigned int numVerts = *(std::uint32_t *)headerPtr;
    headerPtr += sizeof(std::uint32_t);
    /*unsigned int numFrames = *(std::uint32_t*)headerPtr;*/
    headerPtr += sizeof(std::uint32_t);

    std::vector<GeometryVertex> verts;
    verts.resize(numVerts);

    if (geomStream.getChunkVersion() < 0x1003FFFF) {
        headerPtr += sizeof(RW::BSGeometryColor);
    }

    /// @todo extract magic numbers.

    if ((geom->flags & 8) == 8) {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].colour = *(glm::u8vec4 *)headerPtr;
            headerPtr += sizeof(glm::u8vec4);
        }
    } else {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].colour = {255, 255, 255, 255};
        }
    }

    if ((geom->flags & 4) == 4 || (geom->flags & 128) == 128) {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].texcoord = *(glm::vec2 *)headerPtr;
            headerPtr += sizeof(glm::vec2);
        }
    }

    // Grab indicies data to generate normals (if applicable).
    RW::BSGeometryTriangle *triangles = (RW::BSGeometryTriangle *)headerPtr;
    headerPtr += sizeof(RW::BSGeometryTriangle) * numTris;

    geom->geometryBounds = *(RW::BSGeometryBounds *)headerPtr;
    geom->geometryBounds.radius = std::abs(geom->geometryBounds.radius);
    headerPtr += sizeof(RW::BSGeometryBounds);

    for (size_t v = 0; v < numVerts; ++v) {
        verts[v].position = *(glm::vec3 *)headerPtr;
        headerPtr += sizeof(glm::vec3);
    }

    if ((geom->flags & 16) == 16) {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].normal = *(glm::vec3 *)headerPtr;
            headerPtr += sizeof(glm::vec3);
        }
    } else {
        // Use triangle data to calculate normals for each vert.
        for (size_t t = 0; t < numTris; ++t) {
            auto &triangle = triangles[t];
            auto &A = verts[triangle.first];
            auto &B = verts[triangle.second];
            auto &C = verts[triangle.third];
            auto normal = glm::normalize(
                glm::cross(C.position - A.position, B.position - A.position));
            A.normal = normal;
            B.normal = normal;
            C.normal = normal;
        }
    }

    // Process the geometry child sections
    for (auto chunkID = geomStream.getNextChunk(); chunkID != 0;
         chunkID = geomStream.getNextChunk()) {
        switch (chunkID) {
            case CHUNK_MATERIALLIST:
                readMaterialList(geom, geomStream);
                break;
            case CHUNK_EXTENSION:
                readGeometryExtension(geom, geomStream);
                break;
            default:
                break;
        }
    }

    geom->dbuff.setFaceType(geom->facetype == Geometry::Triangles
                                ? GL_TRIANGLES
                                : GL_TRIANGLE_STRIP);
    geom->gbuff.uploadVertices(verts);
    geom->dbuff.addGeometry(&geom->gbuff);

    glGenBuffers(1, &geom->EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geom->EBO);

    size_t icount = std::accumulate(
        geom->subgeom.begin(), geom->subgeom.end(), 0u,
        [](size_t a, const SubGeometry &b) { return a + b.numIndices; });
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * icount, 0,
                 GL_STATIC_DRAW);
    for (auto &sg : geom->subgeom) {
        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sg.start * sizeof(uint32_t),
                        sizeof(uint32_t) * sg.numIndices, sg.indices.data());
    }

    return geom;
}