mirror of
https://github.com/Facepunch/sbox-public.git
synced 2026-08-01 08:18:20 -04:00
// SkinnedModelRenderer - the only new entry point for speaking
SoundHandle SpeakSound( SoundEvent sound, GameObject mouth = null )
SoundHandle SpeakSound( SoundFile sound, float volume = 1, float pitch = 1, GameObject mouth = null )
// SoundFile - the authored lipsync track, read from the compiled vsnd
VisemeTrack Visemes { get; } // null = no track (or not loaded yet, see IsValidForPlayback)
// VisemeTrack - visemes over time, authored in the sound editor
IReadOnlyList<VisemeFrame> Frames { get; }
float Duration { get; }
bool Sample( float time, Span<float> weights )
// VisemeFrame - one viseme span (struct: Viseme, StartTime, EndTime)
// Visemes - the standard 15-viseme table, OVR order
static IReadOnlyList<string> MorphNames { get; }
static int Count { get; }
// MorphCollection - the one shared viseme blend (sounds, voice chat, editor preview)
void ApplyVisemes( ReadOnlySpan<float> visemeWeights, float scale = 1, float smoothTime = 0 )
// ModelMorphs - per-model viseme weight table, cached managed-side (no interop on lookups)
float GetVisemeMorph( int viseme, int morph )
float GetVisemeMorph( string viseme, int morph )
// ResourceCompileContext - inject managed data into natively-compiled resources
void WriteBlock( string blockName, ReadOnlySpan<byte> data ) // four-char block names, eg "LIPS"
void WriteBlockJson( string blockName, object obj )
JsonObject ReadMeta() // the asset's .meta, registers a compile dependency
T ReadMeta<T>( string key, T defaultValue = default )
// ResourceLoadContext - read blocks back when the resource loads (Resource.OnLoaded, engine-internal for now)
// public ref struct, only valid during the load callback
bool Exists( string blockName )
ReadOnlySpan<byte> ReadData( string blockName )
string ReadString( string blockName )
T ReadJson<T>( string blockName, T defaultValue = default )
80 lines
2.2 KiB
C#
80 lines
2.2 KiB
C#
using System.Text.Json;
|
|
|
|
namespace Sandbox;
|
|
|
|
/// <summary>
|
|
/// Lets a <see cref="Resource"/> read from its compiled file while the file data
|
|
/// is in memory, during <see cref="Resource.OnLoaded"/>. Blocks are written at
|
|
/// compile time, eg with <see cref="Resources.ResourceCompileContext.WriteBlockJson"/>.
|
|
/// Only valid during the call - copy out anything you want to keep.
|
|
/// </summary>
|
|
public readonly ref struct ResourceLoadContext
|
|
{
|
|
readonly string _resourceName;
|
|
readonly IntPtr _header;
|
|
|
|
internal ResourceLoadContext( string resourceName, IntPtr header )
|
|
{
|
|
_resourceName = resourceName;
|
|
_header = header;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Does the compiled file contain this block? Block names are four character
|
|
/// codes, eg "LIPS".
|
|
/// </summary>
|
|
public bool Exists( string blockName )
|
|
{
|
|
return !ReadData( blockName ).IsEmpty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read a named block's data. The span points directly into the loaded file,
|
|
/// so it's only valid during <see cref="Resource.OnLoaded"/> - copy anything
|
|
/// you want to keep.
|
|
/// </summary>
|
|
public unsafe ReadOnlySpan<byte> ReadData( string blockName )
|
|
{
|
|
if ( _header == IntPtr.Zero || blockName is null || blockName.Length != 4 )
|
|
return default;
|
|
|
|
var pBlock = NativeEngine.EngineGlue.ReadCompiledResourceFileBlock( blockName, _header, out var size );
|
|
if ( pBlock == IntPtr.Zero || size <= 0 )
|
|
return default;
|
|
|
|
return new ReadOnlySpan<byte>( (void*)pBlock, size );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read a named block as a utf-8 string, or null if the block doesn't exist.
|
|
/// </summary>
|
|
public string ReadString( string blockName )
|
|
{
|
|
var data = ReadData( blockName );
|
|
if ( data.IsEmpty )
|
|
return null;
|
|
|
|
return System.Text.Encoding.UTF8.GetString( data );
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read a named block as json, eg <c>context.ReadJson<List<VisemeFrame>>( "LIPS" )</c>.
|
|
/// </summary>
|
|
public T ReadJson<T>( string blockName, T defaultValue = default )
|
|
{
|
|
var data = ReadData( blockName );
|
|
if ( data.IsEmpty )
|
|
return defaultValue;
|
|
|
|
try
|
|
{
|
|
return JsonSerializer.Deserialize<T>( data, Json.options );
|
|
}
|
|
catch ( Exception e )
|
|
{
|
|
Log.Warning( e, $"Couldn't read block '{blockName}' from {_resourceName}" );
|
|
return defaultValue;
|
|
}
|
|
}
|
|
}
|