Пример #1
0
    TextureDesc LoadTextureFormat(StringSection<::Assets::ResChar> filename)
    {
        ucs2 wfilename[MaxPath];
        Conversion::Convert(wfilename, dimof(wfilename), filename.begin(), filename.end());

        auto fmt = GetTexFmt(wfilename);
                
        using namespace DirectX;
        TexMetadata metadata;

        HRESULT hresult = -1;
        if (fmt == TexFmt::DDS) {
            hresult = GetMetadataFromDDSFile((const wchar_t*)wfilename, DDS_FLAGS_NONE, metadata);
        } else if (fmt == TexFmt::TGA) {
            hresult = GetMetadataFromTGAFile((const wchar_t*)wfilename, metadata);
        } else if (fmt == TexFmt::WIC) {
            hresult = GetMetadataFromWICFile((const wchar_t*)wfilename, WIC_FLAGS_NONE, metadata);
        } else {
            LogWarning << "Texture format not apparent from filename (" << filename.AsString().c_str() << ")";
        }

        if (SUCCEEDED(hresult)) {
            return BuildTextureDesc(metadata);
        }

        return TextureDesc::Empty();
    }
Пример #2
0
    std::shared_ptr<DependencyValidation> Store::WriteDependencies(
        const ResChar intermediateFileName[], 
        StringSection<ResChar> baseDir,
        IteratorRange<const DependentFileState*> deps,
        bool makeDepValidation) const
    {
        Data data;

        std::shared_ptr<DependencyValidation> result;
        if (makeDepValidation)
            result = std::make_shared<DependencyValidation>();

            //  we have to write the base directory to the dependencies file as well
            //  to keep it short, most filenames should be expressed as relative files
        char buffer[MaxPath];
        data.SetAttribute("BasePath", baseDir.AsString().c_str());

        SplitPath<ResChar> baseSplitPath(baseDir);

        auto dependenciesBlock = std::make_unique<Data>("Dependencies");
        for (auto& s:deps) {
            auto c = std::make_unique<Data>();

            auto relPath = MakeRelativePath(
                baseSplitPath, 
                SplitPath<ResChar>(s._filename));
            c->SetValue(relPath.c_str());

            if (s._status != DependentFileState::Status::Shadowed) {
                c->SetAttribute("ModTimeH", (int)(s._timeMarker>>32ull));
                c->SetAttribute("ModTimeL", (int)(s._timeMarker));
            }
            dependenciesBlock->Add(c.release());
            if (makeDepValidation) RegisterFileDependency(result, s._filename.c_str());
        }
Пример #3
0
 void PushString(
     std::basic_streambuf<OutChar>& stream,
     StringSection<InChar> input)
 {
         //  String conversion process results in several redundant allocations. It's not perfectly
         //  efficient
     using OutputString = std::basic_string<OutChar>;
     auto converted = Conversion::Convert<OutputString>(input.AsString());
     stream.sputn(AsPointer(converted.begin()), converted.size());    
 }
Пример #4
0
    PreparedSkinFile::PreparedSkinFile(const ColladaScaffold& input, const VisualScene& scene, StringSection<utf8> rootNode)
    {
        using namespace RenderCore::ColladaConversion;

        SkeletonRegistry jointRefs;

        ReferencedGeometries refGeos;
        bool gatherSuccess = refGeos.Gather(scene.GetRootNode(), rootNode, jointRefs);

        if (!gatherSuccess) {
            StringMeld<1024> meld;
            using ::operator<<;
            meld << "Error while looking for root node: " << rootNode.AsString().c_str() << ". Known nodes: ";

            auto nodes = scene.GetRootNode().FindAllBreadthFirst([](const Node& n) { return true;});
            for (unsigned c=0; c<nodes.size(); ++c) {
                if (c!=0) meld << ", ";
                meld << nodes[c].GetName().AsString().c_str();
            }

            Throw(::Assets::Exceptions::FormatError(meld.get()));
        }

            // The skeleton joints won't be included in the skeleton
            // until we call FindSkinJoints. We don't really need the
            // full skeleton embedded in the skin file... When the skeleton
            // is not there, we will just see the model in the bind pose.
            // But it can be handy to be there for previewing models quickly.
        refGeos.FindSkinJoints(scene, input._resolveContext, jointRefs);

            // We can now build the skeleton (because ReferencedGeometries::Gather 
            // has initialised jointRefs.

        unsigned topLevelPops = 0;
        auto coordinateTransform = BuildCoordinateTransform(input._doc->GetAssetDesc());
        if (!Equivalent(coordinateTransform, Identity<Float4x4>(), 1e-5f)) {
                // Push on the coordinate transform (if there is one)
                // This should be optimised into other matrices (or even into
                // the geometry) when we perform the skeleton optimisation steps.
            topLevelPops = _skeleton.GetTransformationMachine().PushTransformation(
                coordinateTransform);
        }

            // When extracting an internal node, we ignore the transform 
            // on that internal node
        BuildSkeleton(_skeleton, scene.GetRootNode(), rootNode, jointRefs, false);
        _skeleton.GetTransformationMachine().Pop(topLevelPops);

            // For each output matrix, we want to know if we can merge a transformation into it.
            // We can only do this if (unskinned) geometry instances are attached -- and those
            // geometry instances must be attached in only one place. If the output transform does
            // not have a geometry instance attached, or if any of the geometry instances are
            // attached to more than one matrix, or if something other than a geometry instance is
            // attached, then we cannot do any merging.
        
        TransMachineOptimizer optimizer(refGeos, _skeleton.GetTransformationMachine().GetOutputMatrixCount(), scene);
        _skeleton.GetTransformationMachine().Optimize(optimizer);

            // We can try to optimise the skeleton here. We should collect the list
            // of meshes that we can optimise transforms into (ie, meshes that aren't
            // used in multiple places, and that aren't skinned).
            // We need to collect that list of transforms before we actually instantiate
            // the geometry -- so that merging in the changes can be done in the instantiate
            // step.

        for (auto c:refGeos._meshes) {
            TRY {
                _cmdStream.Add(
                    RenderCore::ColladaConversion::InstantiateGeometry(
                        scene.GetInstanceGeometry(c._objectIndex),
                        c._outputMatrixIndex, optimizer.GetMergedOutputMatrix(c._outputMatrixIndex),
                        c._levelOfDetail,
                        input._resolveContext, _geoObjects, jointRefs,
                        input._cfg));
            } CATCH(const std::exception& e) {
                LogWarning << "Got exception while instantiating geometry (" << scene.GetInstanceGeometry(c._objectIndex)._reference.AsString().c_str() << "). Exception details:";
                LogWarning << e.what();
            } CATCH(...) {
                LogWarning << "Got unknown exception while instantiating geometry (" << scene.GetInstanceGeometry(c._objectIndex)._reference.AsString().c_str() << ").";
            } CATCH_END