diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.h b/Engine/source/T3D/assets/ShapeAnimationAsset.h index 7a0ab10d9..2a1afd248 100644 --- a/Engine/source/T3D/assets/ShapeAnimationAsset.h +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.h @@ -79,7 +79,7 @@ public: static void initPersistFields(); virtual void copyTo(SimObject* object); - void setAnimationFile(const char* pScriptFile); + void setAnimationFile(const char* pAnimationFile); inline StringTableEntry getAnimationFile(void) const { return mFileName; }; inline StringTableEntry getAnimationPath(void) const { return mFilePath; }; diff --git a/Engine/source/T3D/assets/SoundAsset.cpp b/Engine/source/T3D/assets/SoundAsset.cpp index 9a6d5e0f9..7a7b1d6b4 100644 --- a/Engine/source/T3D/assets/SoundAsset.cpp +++ b/Engine/source/T3D/assets/SoundAsset.cpp @@ -95,8 +95,8 @@ SoundAsset::SoundAsset() mSoundFile = StringTable->EmptyString(); mSoundPath = StringTable->EmptyString(); - mPitchAdjust = 0; - mVolumeAdjust = 0; + mPitchAdjust = 1; + mVolumeAdjust = 1; //mSound = nullptr; } @@ -157,3 +157,8 @@ void SoundAsset::setSoundFile(const char* pSoundFile) // Refresh the asset. refreshAsset(); } + +DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "") +{ + return object->getSoundPath(); +} diff --git a/Engine/source/T3D/assets/SoundAsset.h b/Engine/source/T3D/assets/SoundAsset.h index 723c9a2b8..013780cae 100644 --- a/Engine/source/T3D/assets/SoundAsset.h +++ b/Engine/source/T3D/assets/SoundAsset.h @@ -63,7 +63,7 @@ public: /// Declare Console Object. DECLARE_CONOBJECT(SoundAsset); - void setSoundFile(const char* pScriptFile); + void setSoundFile(const char* pSoundFile); inline StringTableEntry getSoundFile(void) const { return mSoundFile; }; inline StringTableEntry getSoundPath(void) const { return mSoundPath; }; diff --git a/Engine/source/T3D/assets/assetImporter.cpp b/Engine/source/T3D/assets/assetImporter.cpp index bee6e318f..497a7215b 100644 --- a/Engine/source/T3D/assets/assetImporter.cpp +++ b/Engine/source/T3D/assets/assetImporter.cpp @@ -1797,7 +1797,7 @@ void AssetImporter::processShapeAsset(AssetImportObject* assetItem) //If we have animations but no meshes, then this is a pure animation file so we can swap the asset type here if (meshCount == 0) { - //assetItem->assetType = "ShapeAnimation"; + assetItem->assetType = "ShapeAnimationAsset"; } } @@ -1913,6 +1913,95 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m matAssetItem->assetName = matAssetName; } +void AssetImporter::processSoundAsset(AssetImportObject* assetItem) +{ + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Image for Import: %s", assetItem->assetName.c_str()); + activityLog.push_back(importLogBuffer); + + if ((activeImportConfig->GenerateMaterialOnImport && assetItem->parentAssetItem == nullptr)/* || assetItem->parentAssetItem != nullptr*/) + { + //find our suffix match, if any + String noSuffixName = assetItem->assetName; + String suffixType; + String suffix = parseImageSuffixes(assetItem->assetName, &suffixType); + if (suffix.isNotEmpty()) + { + assetItem->imageSuffixType = suffixType; + S32 suffixPos = assetItem->assetName.find(suffix, 0, String::NoCase | String::Left); + noSuffixName = assetItem->assetName.substr(0, suffixPos); + } + + //We try to automatically populate materials under the naming convention: materialName: Rock, image maps: Rock_Albedo, Rock_Normal, etc + + AssetImportObject* materialAsset = findImportingAssetByName(noSuffixName); + if (materialAsset != nullptr && materialAsset->assetType != String("MaterialAsset")) + { + //We may have a situation where an asset matches the no-suffix name, but it's not a material asset. Ignore this + //asset item for now + + materialAsset = nullptr; + } + + //If we didn't find a matching material asset in our current items, we'll make one now + if (materialAsset == nullptr) + { + if (!assetItem->filePath.isEmpty()) + { + materialAsset = addImportingAsset("MaterialAsset", assetItem->filePath, nullptr, noSuffixName); + } + } + + //Not that, one way or another, we have the generated material asset, lets move on to associating our image with it + if (materialAsset != nullptr && materialAsset != assetItem->parentAssetItem) + { + if (assetItem->parentAssetItem != nullptr) + { + //If the image had an existing parent, it gets removed from that parent's child item list + assetItem->parentAssetItem->childAssetItems.remove(assetItem); + } + else + { + //If it didn't have one, we're going to pull it from the importingAssets list + importingAssets.remove(assetItem); + } + + //Now we can add it to the correct material asset + materialAsset->childAssetItems.push_back(assetItem); + assetItem->parentAssetItem = materialAsset; + + assetHeirarchyChanged = true; + } + + //Now to do some cleverness. If we're generating a material, we can parse like assets being imported(similar filenames) but different suffixes + //If we find these, we'll just populate into the original's material + + //if we need to append the diffuse suffix and indeed didn't find a suffix on the name, do that here + if (suffixType.isEmpty()) + { + if (activeImportConfig->UseDiffuseSuffixOnOriginImage) + { + String diffuseToken = StringUnit::getUnit(activeImportConfig->DiffuseTypeSuffixes, 0, ",;"); + assetItem->assetName = assetItem->assetName + diffuseToken; + assetItem->cleanAssetName = assetItem->assetName; + } + else + { + //We need to ensure that our image asset doesn't match the same name as the material asset, so if we're not trying to force the diffuse suffix + //we'll give it a generic one + if (materialAsset && materialAsset->assetName.compare(assetItem->assetName) == 0) + { + assetItem->assetName = assetItem->assetName + "_image"; + assetItem->cleanAssetName = assetItem->assetName; + } + } + + //Assume for abledo if it has no suffix matches + assetItem->imageSuffixType = "Albedo"; + } + } + + assetItem->processed = true; +} // // Validation // @@ -2293,8 +2382,10 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) { assetPath = importShapeAsset(importingAssets[i]); } - /*else if (importingAssets[i]->assetType == String("SoundAsset")) - assetPath = SoundAsset::importAsset(importingAssets[i]);*/ + else if (importingAssets[i]->assetType == String("SoundAsset")) + { + assetPath = importSoundAsset(importingAssets[i]); + } else if (importingAssets[i]->assetType == String("MaterialAsset")) { assetPath = importMaterialAsset(importingAssets[i]); @@ -2371,8 +2462,10 @@ void AssetImporter::importAssets(AssetImportObject* assetItem) { assetPath = importShapeAsset(childItem); } - /*else if (childItem->assetType == String("SoundAsset")) - assetPath = SoundAsset::importAsset(childItem);*/ + else if (childItem->assetType == String("SoundAsset")) + { + assetPath = importSoundAsset(childItem); + } else if (childItem->assetType == String("MaterialAsset")) { assetPath = importMaterialAsset(childItem); @@ -2985,3 +3078,115 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem) return tamlPath; } + +Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem) +{ + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Sound Asset: %s", assetItem->assetName.c_str()); + activityLog.push_back(importLogBuffer); + + SoundAsset* newAsset = new SoundAsset(); + newAsset->registerObject(); + + StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str()); + + String imageFileName = assetItem->filePath.getFileName() + "." + assetItem->filePath.getExtension(); + String assetPath = targetPath + "/" + imageFileName; + String tamlPath = targetPath + "/" + assetName + ".asset.taml"; + String originalPath = assetItem->filePath.getFullPath().c_str(); + + char qualifiedFromFile[2048]; + char qualifiedToFile[2048]; + + Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); + Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); + + newAsset->setAssetName(assetName); + newAsset->setSoundFile(imageFileName.c_str()); + + //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original + //file path for reimporting support later + if (!isReimport && dStrcmp(qualifiedFromFile, qualifiedToFile)) + { + newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); + } + + Taml tamlWriter; + bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str()); + + if (!importSuccessful) + { + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str()); + activityLog.push_back(importLogBuffer); + return ""; + } + + if (!isReimport) + { + bool isInPlace = !dStrcmp(qualifiedFromFile, qualifiedToFile); + + if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport)) + { + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str()); + activityLog.push_back(importLogBuffer); + return ""; + } + } + + return tamlPath; +} + +Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetItem) +{ + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Beginning importing of Shape Animation Asset: %s", assetItem->assetName.c_str()); + activityLog.push_back(importLogBuffer); + + ShapeAnimationAsset* newAsset = new ShapeAnimationAsset(); + newAsset->registerObject(); + + StringTableEntry assetName = StringTable->insert(assetItem->assetName.c_str()); + + String imageFileName = assetItem->filePath.getFileName() + "." + assetItem->filePath.getExtension(); + String assetPath = targetPath + "/" + imageFileName; + String tamlPath = targetPath + "/" + assetName + ".asset.taml"; + String originalPath = assetItem->filePath.getFullPath().c_str(); + + char qualifiedFromFile[2048]; + char qualifiedToFile[2048]; + + Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile)); + Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile)); + + newAsset->setAssetName(assetName); + newAsset->setAnimationFile(imageFileName.c_str()); + + //If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original + //file path for reimporting support later + if (!isReimport && dStrcmp(qualifiedFromFile, qualifiedToFile)) + { + newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile); + } + + Taml tamlWriter; + bool importSuccessful = tamlWriter.write(newAsset, tamlPath.c_str()); + + if (!importSuccessful) + { + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to write asset taml file %s", tamlPath.c_str()); + activityLog.push_back(importLogBuffer); + return ""; + } + + if (!isReimport) + { + bool isInPlace = !dStrcmp(qualifiedFromFile, qualifiedToFile); + + if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport)) + { + dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str()); + activityLog.push_back(importLogBuffer); + return ""; + } + } + + return tamlPath; +} diff --git a/Engine/source/T3D/assets/assetImporter.h b/Engine/source/T3D/assets/assetImporter.h index 2a0403958..3920ceb4f 100644 --- a/Engine/source/T3D/assets/assetImporter.h +++ b/Engine/source/T3D/assets/assetImporter.h @@ -750,6 +750,12 @@ public: /// void processShapeMaterialInfo(AssetImportObject* assetItem, S32 materialItemId); + /// + /// Process a specific AssetImportObject that is an SoundAsset type to prepare it for importing + /// @param assetItem, The AssetImportObject to process + /// + void processSoundAsset(AssetImportObject* assetItem); + /// /// Run through and validate assets for issues, such as name collisions /// @@ -797,23 +803,37 @@ public: /// /// Runs the import processing on a specific ImageAsset item /// @param assetItem, The asset item to import - /// @return AssetId of the asset that was imported. If import failed, it will be empty. + /// @return TAML File path of the new asset that was imported. If import failed, it will be empty. /// Torque::Path importImageAsset(AssetImportObject* assetItem); /// /// Runs the import processing on a specific MaterialAsset item /// @param assetItem, The asset item to import - /// @return AssetId of the asset that was imported. If import failed, it will be empty. + /// @return TAML File path of the new asset that was imported. If import failed, it will be empty. /// Torque::Path importMaterialAsset(AssetImportObject* assetItem); /// /// Runs the import processing on a specific ShapeAsset item /// @param assetItem, The asset item to import - /// @return AssetId of the asset that was imported. If import failed, it will be empty. + /// @return TAML File path of the new asset that was imported. If import failed, it will be empty. /// - Torque::Path importShapeAsset(AssetImportObject* assetItem); + Torque::Path importShapeAsset(AssetImportObject* assetItem); + + /// + /// Runs the import processing on a specific SoundAsset item + /// @param assetItem, The asset item to import + /// @return TAML File path of the new asset that was imported. If import failed, it will be empty. + /// + Torque::Path importSoundAsset(AssetImportObject* assetItem); + + /// + /// Runs the import processing on a specific ShapeAnimationAsset item + /// @param assetItem, The asset item to import + /// @return TAML File path of the new asset that was imported. If import failed, it will be empty. + /// + Torque::Path importShapeAnimationAsset(AssetImportObject* assetItem); // /// diff --git a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.cs b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.cs index 7d3739cd5..a432bd980 100644 --- a/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.cs +++ b/Templates/BaseGame/game/tools/assetBrowser/scripts/assetTypes/sound.cs @@ -9,4 +9,40 @@ function AssetBrowser::buildSoundAssetPreview(%this, %assetDef, %previewData) %previewData.assetFriendlyName = %assetDef.assetName; %previewData.assetDesc = %assetDef.description; %previewData.tooltip = %assetDef.assetName; +} + +function AssetBrowser::onSoundAssetEditorDropped(%this, %assetDef, %position) +{ + %targetPosition = EWorldEditor.unproject(%position SPC 1000); + %camPos = LocalClientConnection.camera.getPosition(); + %rayResult = containerRayCast(%camPos, %targetPosition, -1); + + %pos = EWCreatorWindow.getCreateObjectPosition(); + + if(%rayResult != 0) + { + %pos = getWords(%rayResult, 1, 3); + } + else + { + %pos = "0 0 0"; + } + + %assetId = %assetDef.getAssetId(); + + %newSFXEmitter = new SFXEmitter() + { + position = %pos; + fileName = %assetDef.getSoundPath(); + pitch = %assetDef.pitchAdjust; + volume = %assetDef.volumeAdjust; + }; + + getScene(0).add(%newSFXEmitter); + + EWorldEditor.clearSelection(); + EWorldEditor.selectObject(%newSFXEmitter); + + EWorldEditor.isDirty = true; + } \ No newline at end of file