Whole load of stuff. Renders, admin management bar, CDN, you name it!
This commit is contained in:
parent
e4ef85a1ce
commit
70f2f88394
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,5 @@
|
|||
REM : XlXi 2022
|
||||
REM : Put this in the directory of your PNG export.
|
||||
REM : ImageMagick is required.
|
||||
|
||||
magick convert -delay 333,10000 -loop 0 -alpha set -dispose previous *.png ani.gif
|
||||
|
|
@ -29,6 +29,9 @@
|
|||
RewriteCond %{HTTP_HOST} !^www\. [NC]
|
||||
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
|
||||
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}
|
||||
|
||||
DocumentRoot "D:/wamp320/graphictoria/sitetest3/web/public"
|
||||
</VirtualHost>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
Graphictoria 2022
|
||||
CDN helper.
|
||||
*/
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Models\CdnHash;
|
||||
|
||||
class CdnHelper
|
||||
{
|
||||
public static function GetDisk()
|
||||
{
|
||||
return Storage::build([
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/content'),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function Hash($content)
|
||||
{
|
||||
return hash('sha256', $content);
|
||||
}
|
||||
|
||||
public static function SaveContent($content, $mime)
|
||||
{
|
||||
$disk = self::GetDisk();
|
||||
$hash = self::Hash($content);
|
||||
|
||||
if(!$disk->exists($hash) || !CdnHash::where('hash', $hash)->exists()) {
|
||||
$disk->put($hash, $content);
|
||||
|
||||
$cdnItem = new CdnHash();
|
||||
$cdnItem->hash = $hash;
|
||||
$cdnItem->mime_type = $mime;
|
||||
$cdnItem->save();
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
public static function SaveContentB64($contentB64, $mime)
|
||||
{
|
||||
return self::SaveContent(base64_decode($contentB64), $mime);
|
||||
}
|
||||
}
|
||||
|
|
@ -115,11 +115,13 @@ class QAaMBHelper
|
|||
{
|
||||
$memoryInfo = self::getSystemMemoryInfo();
|
||||
|
||||
// XlXi: the -2 is required so it fits inside of the bar thing
|
||||
// XlXi: change this if theres ever a separate graph
|
||||
return sprintf(
|
||||
'%s of %s (%s%%) <br/> %s Free',
|
||||
self::memoryString($memoryInfo['MemTotal'] - $memoryInfo['MemFree']),
|
||||
self::memoryString($memoryInfo['MemTotal']),
|
||||
round(self::getMemoryPercentage() * 100),
|
||||
round(self::getMemoryPercentage() * (100-2)),
|
||||
self::memoryString($memoryInfo['MemFree'])
|
||||
);
|
||||
}
|
||||
|
|
@ -133,9 +135,11 @@ class QAaMBHelper
|
|||
|
||||
public static function getCpuUsage()
|
||||
{
|
||||
// XlXi: the -2 is required so it fits inside of the bar thing
|
||||
// XlXi: change this if theres ever a separate graph
|
||||
return sprintf(
|
||||
'%s%% CPU Usage',
|
||||
round(self::getSystemCpuInfo() * 100)
|
||||
round(self::getSystemCpuInfo() * (100-2))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
use App\Helpers\ValidationHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Jobs\ArbiterRender;
|
||||
use App\Models\Asset;
|
||||
use App\Models\RenderTracker;
|
||||
|
||||
class ThumbnailController extends Controller
|
||||
{
|
||||
public function renderAsset(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'id' => [
|
||||
'required',
|
||||
Rule::exists('App\Models\Asset', 'id')->where(function($query) {
|
||||
return $query->where('moderated', false);
|
||||
})
|
||||
],
|
||||
'type' => 'regex:/(3D|2D)/i'
|
||||
]);
|
||||
|
||||
if($validator->fails())
|
||||
return ValidationHelper::generateValidatorError($validator);
|
||||
|
||||
$valid = $validator->valid();
|
||||
$asset = Asset::where('id', $valid['id'])->first();
|
||||
|
||||
$valid['type'] = strtolower($valid['type']);
|
||||
|
||||
if($asset->thumbnail2DHash && $valid['type'] == '2d')
|
||||
return response(['status' => 'success', 'data' => route('content', $asset->thumbnail2DHash)]);
|
||||
|
||||
if($asset->thumbnail3DHash && $valid['type'] == '3d')
|
||||
return response(['status' => 'success', 'data' => route('content', $asset->thumbnail3DHash)]);
|
||||
|
||||
$tracker = RenderTracker::where('type', sprintf('asset%s', $valid['type']))
|
||||
->where('target', $valid['id']);
|
||||
|
||||
if(!$tracker->exists()) {
|
||||
$tracker = new RenderTracker;
|
||||
$tracker->type = sprintf('asset%s', $valid['type']);
|
||||
$tracker->target = $valid['id'];
|
||||
$tracker->save();
|
||||
|
||||
ArbiterRender::dispatch($tracker, $valid['type'] == '3d');
|
||||
}
|
||||
|
||||
return response(['status' => 'loading']);
|
||||
}
|
||||
|
||||
public function renderUser()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function tryAsset()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Cdn;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use App\Models\CdnHash;
|
||||
use App\Helpers\CdnHelper;
|
||||
use App\Helpers\ValidationHelper;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class CdnController extends Controller
|
||||
{
|
||||
public function getContent(Request $request, $hash)
|
||||
{
|
||||
$disk = CdnHelper::GetDisk();
|
||||
|
||||
if(preg_match('/^[a-f0-9]{64}$/i', $hash) && $disk->exists($hash)) {
|
||||
$content = CdnHash::where('hash', $hash)->first();
|
||||
|
||||
if(!$content || $content->deleted)
|
||||
return response('This item is currently unavailable.')
|
||||
->header('content-type', 'text/plain');
|
||||
|
||||
return response($disk->get($hash))
|
||||
->header('content-type', $content->mime_type);
|
||||
} else {
|
||||
return response('Invalid hash.')
|
||||
->header('content-type', 'text/plain');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Controllers\Web;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Grid\SoapService;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use App\Grid\SoapService;
|
||||
use App\Helpers\CdnHelper;
|
||||
use App\Models\RenderTracker;
|
||||
|
||||
class ArbiterRender implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of seconds the job can run before timing out.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $timeout = 120;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 3;
|
||||
|
||||
/**
|
||||
* The tracker instance.
|
||||
*
|
||||
* @var \App\Models\RenderTracker
|
||||
*/
|
||||
public $tracker;
|
||||
|
||||
/**
|
||||
* Is the render 3d?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $is3D;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(RenderTracker $tracker, bool $is3D)
|
||||
{
|
||||
$this->tracker = $tracker;
|
||||
$this->is3D = $is3D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$testScript = <<<TestScript
|
||||
settings()["Task Scheduler"].ThreadPoolConfig = Enum.ThreadPoolConfig.PerCore4;
|
||||
game:GetService("ContentProvider"):SetThreadPool(16)
|
||||
game:GetService("Stats"):SetReportUrl("http://api.gtoria.net/reportstat?cock=1")
|
||||
|
||||
local Lighting = game:GetService("Lighting")
|
||||
Lighting.ClockTime = 13
|
||||
Lighting.GeographicLatitude = -5
|
||||
|
||||
game:Load("http://gtoria.net/asset/?id=3529");
|
||||
for _, Object in pairs(game:GetChildren())do
|
||||
if Object:IsA("Tool") then
|
||||
Object.Parent = workspace
|
||||
end
|
||||
end
|
||||
|
||||
-- format, width, height, sky, crop
|
||||
return game:GetService("ThumbnailGenerator"):Click("OBJ", 840, 840, true, true)
|
||||
TestScript;
|
||||
|
||||
$test = new SoapService('http://192.168.0.3:64989');
|
||||
$result = $test->OpenJob(SoapService::MakeJobJSON(Str::uuid()->toString(), 120, 0, 0, sprintf('Render %s %d', $this->tracker->type, $this->tracker->target), $testScript));
|
||||
|
||||
if(is_soap_fault($result))
|
||||
$this->fail(sprintf('SOAP Fault: (faultcode: %s, faultstring: %s)', $result->faultcode, $result->faultstring));
|
||||
|
||||
$result = $result->OpenJobExResult->LuaValue[0]->value;
|
||||
|
||||
if($this->is3D) {
|
||||
$content = json_decode($result);
|
||||
$result = [
|
||||
'camera' => $content->camera,
|
||||
'AABB' => $content->AABB,
|
||||
'obj' => '',
|
||||
'mtl' => '',
|
||||
'textures' => []
|
||||
];
|
||||
|
||||
$mtlTmp;
|
||||
foreach($content->files as $file => $fileB64) {
|
||||
$extension = strtolower(substr(strrchr($file, '.'), 1));
|
||||
if($extension == 'mtl')
|
||||
$mtlTmp = base64_decode($fileB64->content);
|
||||
}
|
||||
|
||||
// RCC adds map_d for whatever reason. (alpha map)
|
||||
$mtlTmp = preg_replace('/^map_d.+\n/im', '', $mtlTmp);
|
||||
// Fix the shine
|
||||
$mtlTmp = preg_replace('/^Ns \d+/im', 'Ns 0', $mtlTmp);
|
||||
$mtlTmp = preg_replace('/^Ks.+/im', 'Ks 0.0627451 0.0627451 0.0627451', $mtlTmp);
|
||||
|
||||
foreach($content->files as $file => $fileB64) {
|
||||
$extension = strtolower(substr(strrchr($file, '.'), 1));
|
||||
|
||||
if($extension != 'obj' && $extension != 'mtl')
|
||||
$extension = 'textures';
|
||||
|
||||
if($extension == 'mtl')
|
||||
continue;
|
||||
|
||||
$cdnHash = CdnHelper::SaveContentB64($fileB64->content, ($extension == 'png' ? 'image/png' : 'text/plain'));
|
||||
$mtlTmp = str_replace($file, $cdnHash, $mtlTmp);
|
||||
|
||||
if(array_key_exists($extension, $result)) {
|
||||
if(gettype($result[$extension]) == 'array')
|
||||
array_push($result[$extension], $cdnHash);
|
||||
else
|
||||
$result[$extension] = $cdnHash;
|
||||
} else {
|
||||
$result[$extension] = $cdnHash;
|
||||
}
|
||||
}
|
||||
|
||||
$result['mtl'] = CdnHelper::SaveContent($mtlTmp, 'text/plain');
|
||||
|
||||
$this->tracker->targetObj->set3DHash(CdnHelper::SaveContent(json_encode($result), 'text/plain'));
|
||||
} else {
|
||||
$this->tracker->targetObj->set2DHash(CdnHelper::SaveContentB64($result, 'image/png'));
|
||||
}
|
||||
|
||||
$this->tracker->delete();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class CdnHash extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class RenderTracker extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public function targetObj()
|
||||
{
|
||||
if($this->type == 'user2d' || $this->type == 'user3d')
|
||||
return $this->belongsTo(User::class, 'target');
|
||||
elseif($this->type == 'asset2d' || $this->type == 'asset3d')
|
||||
return $this->belongsTo(Asset::class, 'target');
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
use Carbon\Carbon;
|
||||
|
||||
use App\Models\AssetVersion;
|
||||
use App\Models\User;
|
||||
|
||||
class Asset extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
|
@ -153,6 +150,18 @@ class Asset extends Model
|
|||
return 'https://gtoria.local/images/testing/hat.png';
|
||||
}
|
||||
|
||||
public function set2DHash($hash)
|
||||
{
|
||||
$this->thumbnail2DHash = $hash;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function set3DHash($hash)
|
||||
{
|
||||
$this->thumbnail3DHash = $hash;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
public function getCreated()
|
||||
{
|
||||
$date = $this['created_at'];
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
|
|
@ -24,6 +25,8 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
URL::forceScheme('https');
|
||||
|
||||
Blade::directive('owner', function() {
|
||||
return '<?php if(Auth::check() && Auth::user()->hasRoleset(\'Owner\')): ?>';
|
||||
});
|
||||
|
|
|
|||
|
|
@ -54,6 +54,14 @@ class RouteServiceProvider extends ServiceProvider
|
|||
->middleware('api')
|
||||
->namespace('App\Http\Controllers\Api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
//
|
||||
// Domain: cdn.gtoria.net
|
||||
//
|
||||
Route::domain('cdn.' . DomainHelper::TopLevelDomain())
|
||||
->middleware('api')
|
||||
->namespace('App\Http\Controllers\Cdn')
|
||||
->group(base_path('routes/cdn.php'));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'default' => env('QUEUE_CONNECTION', 'sync'),
|
||||
'default' => env('QUEUE_CONNECTION', 'database'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -31,10 +31,8 @@ return new class extends Migration
|
|||
$table->unsignedSmallInteger('assetAttributeId')->nullable();
|
||||
$table->unsignedBigInteger('assetVersionId')->comment('The most recent version id for the asset. This is used internally as asset version 0 when using the /asset api.');
|
||||
|
||||
// Calculating the subdomain on runtime is too expensive.
|
||||
// So full URLs are used instead of just the hashes.
|
||||
$table->string('thumbnailURL')->nullable();
|
||||
$table->string('3dThumbnailURL')->nullable();
|
||||
$table->string('thumbnail2DHash')->nullable();
|
||||
$table->string('thumbnail3DHash')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('cdn_hashes', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('hash');
|
||||
$table->string('mime_type');
|
||||
$table->unsignedBigInteger('user_id')->nullable();
|
||||
$table->unsignedBigInteger('asset_version_id')->nullable();
|
||||
$table->boolean('deleted')->default(false); // XlXi: in the case of copyright or whatever
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('cdn_hashes');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('render_trackers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('type');
|
||||
$table->unsignedBigInteger('target');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('render_trackers');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
};
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@react-three/postprocessing": "^2.6.1",
|
||||
"@restart/ui": "^1.3.1",
|
||||
"classnames": "^2.3.1",
|
||||
"install": "^0.13.0",
|
||||
|
|
@ -1613,7 +1614,6 @@
|
|||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.1.2.tgz",
|
||||
"integrity": "sha512-E/XrL0QlzExycPzwhOEZGVOheJ/Clr5uNv3oCds88MiNqEmg3UU1iauZk7DhjsUo3jgEW4lf0I5HRl7/HC5ZkQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@chevrotain/gast": "^10.1.2",
|
||||
"@chevrotain/types": "^10.1.2",
|
||||
|
|
@ -1624,7 +1624,6 @@
|
|||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-10.1.2.tgz",
|
||||
"integrity": "sha512-er+TcxUOMuGOPoiOq8CJsRm92zGE4YPIYtyxJfxoVwVgtj4AMrPNCmrHvYaK/bsbt2DaDuFdcbbAfM9bcBXW6Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@chevrotain/types": "^10.1.2",
|
||||
"lodash": "4.17.21"
|
||||
|
|
@ -1633,14 +1632,12 @@
|
|||
"node_modules/@chevrotain/types": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-10.1.2.tgz",
|
||||
"integrity": "sha512-4qF9SmmWKv8AIG/3d+71VFuqLumNCQTP5GoL0CW6x7Ay2OdXm6FUgWFLTMneGUjYUk2C+MSCf7etQfdq3LEr1A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-4qF9SmmWKv8AIG/3d+71VFuqLumNCQTP5GoL0CW6x7Ay2OdXm6FUgWFLTMneGUjYUk2C+MSCf7etQfdq3LEr1A=="
|
||||
},
|
||||
"node_modules/@chevrotain/utils": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-10.1.2.tgz",
|
||||
"integrity": "sha512-bbZIpW6fdyf7FMaeDmw3cBbkTqsecxEkwlVKgVfqqXWBPLH6azxhPA2V9F7OhoZSVrsnMYw7QuyK6qutXPjEew==",
|
||||
"dev": true
|
||||
"integrity": "sha512-bbZIpW6fdyf7FMaeDmw3cBbkTqsecxEkwlVKgVfqqXWBPLH6azxhPA2V9F7OhoZSVrsnMYw7QuyK6qutXPjEew=="
|
||||
},
|
||||
"node_modules/@colors/colors": {
|
||||
"version": "1.5.0",
|
||||
|
|
@ -1874,7 +1871,6 @@
|
|||
"version": "8.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.0.13.tgz",
|
||||
"integrity": "sha512-hJdVS2F8LJFenR07l80JnkLAMeJ7gf3wiB8OzQ49GjSwjPgPG8bjYumMmchY/eouU+myYtNej0tK6mV6wctmdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.17.8",
|
||||
"@types/react-reconciler": "^0.26.6",
|
||||
|
|
@ -1912,6 +1908,22 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@react-three/postprocessing": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-three/postprocessing/-/postprocessing-2.6.1.tgz",
|
||||
"integrity": "sha512-IX6i8JI5iY9zYSjOh9ZKr3URQ+V8NSnFEOL0xBPDP7BdyLjwXKs5fPR/ClnW4bGt/4T1TMsGmLCXJ97gtZVRZA==",
|
||||
"dependencies": {
|
||||
"postprocessing": "^6.28.5",
|
||||
"react-merge-refs": "^1.1.0",
|
||||
"screen-space-reflections": "2.1.1",
|
||||
"three-stdlib": "^2.8.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-three/fiber": ">=7.0",
|
||||
"react": ">=17.0",
|
||||
"three": ">=0.136.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@restart/hooks": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz",
|
||||
|
|
@ -2209,7 +2221,6 @@
|
|||
"version": "0.26.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.6.tgz",
|
||||
"integrity": "sha512-N8MpyC6PJksD+CbMaZ1GW1t940+L4K+f7soiNKcKfgOgof3xWLvs5nPRQ/Q0P6QwDX0GH1PT1MsiQh2FtUY6aw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
|
@ -2434,8 +2445,7 @@
|
|||
"node_modules/@webgpu/glslang": {
|
||||
"version": "0.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@webgpu/glslang/-/glslang-0.0.15.tgz",
|
||||
"integrity": "sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q=="
|
||||
},
|
||||
"node_modules/@webpack-cli/configtest": {
|
||||
"version": "1.1.1",
|
||||
|
|
@ -3213,7 +3223,6 @@
|
|||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-10.1.2.tgz",
|
||||
"integrity": "sha512-hvRiQuhhTZxkPMGD/dke+s1EGo8AkKDBU05CcufBO278qgAQSwIC4QyLdHz0CFHVtqVYWjlAS5D1KwvBbaHT+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@chevrotain/cst-dts-gen": "^10.1.2",
|
||||
"@chevrotain/gast": "^10.1.2",
|
||||
|
|
@ -3853,8 +3862,7 @@
|
|||
"node_modules/debounce": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
||||
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
|
||||
"dev": true
|
||||
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
|
|
@ -4153,8 +4161,7 @@
|
|||
"node_modules/draco3d": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.2.tgz",
|
||||
"integrity": "sha512-AeRQ25Fb29c14vpjnh167UGW0nGY0ZpEM3ld+zEXoEySlmEXcXfsCHZeTgo5qXH925V1JsdjrzasdaQ22/vXog==",
|
||||
"dev": true
|
||||
"integrity": "sha512-AeRQ25Fb29c14vpjnh167UGW0nGY0ZpEM3ld+zEXoEySlmEXcXfsCHZeTgo5qXH925V1JsdjrzasdaQ22/vXog=="
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
|
|
@ -4500,8 +4507,7 @@
|
|||
"node_modules/fflate": {
|
||||
"version": "0.6.10",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz",
|
||||
"integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg=="
|
||||
},
|
||||
"node_modules/file-loader": {
|
||||
"version": "6.2.0",
|
||||
|
|
@ -5604,8 +5610,7 @@
|
|||
"node_modules/ktx-parse": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.2.2.tgz",
|
||||
"integrity": "sha512-cFBc1jnGG2WlUf52NbDUXK2obJ+Mo9WUkBRvr6tP6CKxRMvZwDDFNV3JAS4cewETp5KyexByfWm9sm+O8AffiQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-cFBc1jnGG2WlUf52NbDUXK2obJ+Mo9WUkBRvr6tP6CKxRMvZwDDFNV3JAS4cewETp5KyexByfWm9sm+O8AffiQ=="
|
||||
},
|
||||
"node_modules/laravel-mix": {
|
||||
"version": "6.0.43",
|
||||
|
|
@ -6119,8 +6124,7 @@
|
|||
"node_modules/mmd-parser": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mmd-parser/-/mmd-parser-1.0.4.tgz",
|
||||
"integrity": "sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg=="
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
|
|
@ -8643,7 +8647,6 @@
|
|||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz",
|
||||
"integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string.prototype.codepointat": "^0.2.1",
|
||||
"tiny-inflate": "^1.0.3"
|
||||
|
|
@ -9475,11 +9478,21 @@
|
|||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"node_modules/postprocessing": {
|
||||
"version": "6.28.5",
|
||||
"resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.28.5.tgz",
|
||||
"integrity": "sha512-e9aH6T720AiQpStdgqrQSsHzpddFQ7Q8v204sZx4iSTnUuYvkq7mFPOyzhVDlx5NrmXXbwz2PEK2XTq+qEYSMg==",
|
||||
"engines": {
|
||||
"node": ">= 0.13.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"three": ">= 0.107.0 < 0.144.0"
|
||||
}
|
||||
},
|
||||
"node_modules/potpack": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
|
||||
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="
|
||||
},
|
||||
"node_modules/pretty-time": {
|
||||
"version": "1.1.0",
|
||||
|
|
@ -9723,7 +9736,6 @@
|
|||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz",
|
||||
"integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/gregberge"
|
||||
|
|
@ -9733,7 +9745,6 @@
|
|||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz",
|
||||
"integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.21.0"
|
||||
|
|
@ -9789,7 +9800,6 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz",
|
||||
"integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debounce": "^1.2.1"
|
||||
},
|
||||
|
|
@ -9889,8 +9899,7 @@
|
|||
"node_modules/regexp-to-ast": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz",
|
||||
"integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw=="
|
||||
},
|
||||
"node_modules/regexpu-core": {
|
||||
"version": "5.0.1",
|
||||
|
|
@ -10159,7 +10168,6 @@
|
|||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
|
||||
"integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
|
|
@ -10181,6 +10189,15 @@
|
|||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/screen-space-reflections": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/screen-space-reflections/-/screen-space-reflections-2.1.1.tgz",
|
||||
"integrity": "sha512-UwBaTb6Ss/8EfhDHEdybPhMbHXmtchOcpHHTa5guFFzjj1f0998twZRr/svOJaA/Nyi44VL2Cqf3xGhdu3hC2w==",
|
||||
"peerDependencies": {
|
||||
"postprocessing": ">=6.28.0",
|
||||
"three": ">=0.141.0"
|
||||
}
|
||||
},
|
||||
"node_modules/select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
|
|
@ -10590,8 +10607,7 @@
|
|||
"node_modules/string.prototype.codepointat": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
|
||||
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
|
|
@ -10689,7 +10705,6 @@
|
|||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.0.8.tgz",
|
||||
"integrity": "sha512-ZC3r8Hu1y0dIThzsGw0RLZplnX9yXwfItcvaIzJc2VQVi8TGyGDlu92syMB5ulybfvGLHAI5Ghzlk23UBPF8xg==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"react": ">=17.0"
|
||||
}
|
||||
|
|
@ -10874,10 +10889,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/three": {
|
||||
"version": "0.140.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.140.0.tgz",
|
||||
"integrity": "sha512-jcHjbnYspPLDdsDQChmzyAoZ5KhJbgFk6pNGlAIc9fQMvsfPGjF5H9glrngqvb2CR/qXcClMyp5PYdF996lldA==",
|
||||
"dev": true,
|
||||
"version": "0.143.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.143.0.tgz",
|
||||
"integrity": "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/three-mesh-bvh": {
|
||||
|
|
@ -10893,7 +10907,6 @@
|
|||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.10.1.tgz",
|
||||
"integrity": "sha512-qKJLFB5KMUhPe4JgtJ6bnY7+nEuNPVbxfKyAeRIRbTTBF1oP/rKogZAio+NI5SXSo4iuIu59e02AzOzh8AR9cQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.16.7",
|
||||
"@webgpu/glslang": "^0.0.15",
|
||||
|
|
@ -10929,8 +10942,7 @@
|
|||
"node_modules/tiny-inflate": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
|
||||
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
|
||||
},
|
||||
"node_modules/to-arraybuffer": {
|
||||
"version": "1.0.1",
|
||||
|
|
@ -11916,14 +11928,12 @@
|
|||
"node_modules/zstddec": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.0.2.tgz",
|
||||
"integrity": "sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA=="
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz",
|
||||
"integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.7.0"
|
||||
},
|
||||
|
|
@ -13000,7 +13010,6 @@
|
|||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-10.1.2.tgz",
|
||||
"integrity": "sha512-E/XrL0QlzExycPzwhOEZGVOheJ/Clr5uNv3oCds88MiNqEmg3UU1iauZk7DhjsUo3jgEW4lf0I5HRl7/HC5ZkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@chevrotain/gast": "^10.1.2",
|
||||
"@chevrotain/types": "^10.1.2",
|
||||
|
|
@ -13011,7 +13020,6 @@
|
|||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-10.1.2.tgz",
|
||||
"integrity": "sha512-er+TcxUOMuGOPoiOq8CJsRm92zGE4YPIYtyxJfxoVwVgtj4AMrPNCmrHvYaK/bsbt2DaDuFdcbbAfM9bcBXW6Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@chevrotain/types": "^10.1.2",
|
||||
"lodash": "4.17.21"
|
||||
|
|
@ -13020,14 +13028,12 @@
|
|||
"@chevrotain/types": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-10.1.2.tgz",
|
||||
"integrity": "sha512-4qF9SmmWKv8AIG/3d+71VFuqLumNCQTP5GoL0CW6x7Ay2OdXm6FUgWFLTMneGUjYUk2C+MSCf7etQfdq3LEr1A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-4qF9SmmWKv8AIG/3d+71VFuqLumNCQTP5GoL0CW6x7Ay2OdXm6FUgWFLTMneGUjYUk2C+MSCf7etQfdq3LEr1A=="
|
||||
},
|
||||
"@chevrotain/utils": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-10.1.2.tgz",
|
||||
"integrity": "sha512-bbZIpW6fdyf7FMaeDmw3cBbkTqsecxEkwlVKgVfqqXWBPLH6azxhPA2V9F7OhoZSVrsnMYw7QuyK6qutXPjEew==",
|
||||
"dev": true
|
||||
"integrity": "sha512-bbZIpW6fdyf7FMaeDmw3cBbkTqsecxEkwlVKgVfqqXWBPLH6azxhPA2V9F7OhoZSVrsnMYw7QuyK6qutXPjEew=="
|
||||
},
|
||||
"@colors/colors": {
|
||||
"version": "1.5.0",
|
||||
|
|
@ -13201,7 +13207,6 @@
|
|||
"version": "8.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.0.13.tgz",
|
||||
"integrity": "sha512-hJdVS2F8LJFenR07l80JnkLAMeJ7gf3wiB8OzQ49GjSwjPgPG8bjYumMmchY/eouU+myYtNej0tK6mV6wctmdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.17.8",
|
||||
"@types/react-reconciler": "^0.26.6",
|
||||
|
|
@ -13213,6 +13218,17 @@
|
|||
"zustand": "^3.7.1"
|
||||
}
|
||||
},
|
||||
"@react-three/postprocessing": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-three/postprocessing/-/postprocessing-2.6.1.tgz",
|
||||
"integrity": "sha512-IX6i8JI5iY9zYSjOh9ZKr3URQ+V8NSnFEOL0xBPDP7BdyLjwXKs5fPR/ClnW4bGt/4T1TMsGmLCXJ97gtZVRZA==",
|
||||
"requires": {
|
||||
"postprocessing": "^6.28.5",
|
||||
"react-merge-refs": "^1.1.0",
|
||||
"screen-space-reflections": "2.1.1",
|
||||
"three-stdlib": "^2.8.11"
|
||||
}
|
||||
},
|
||||
"@restart/hooks": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.7.tgz",
|
||||
|
|
@ -13496,7 +13512,6 @@
|
|||
"version": "0.26.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.6.tgz",
|
||||
"integrity": "sha512-N8MpyC6PJksD+CbMaZ1GW1t940+L4K+f7soiNKcKfgOgof3xWLvs5nPRQ/Q0P6QwDX0GH1PT1MsiQh2FtUY6aw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
|
|
@ -13718,8 +13733,7 @@
|
|||
"@webgpu/glslang": {
|
||||
"version": "0.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@webgpu/glslang/-/glslang-0.0.15.tgz",
|
||||
"integrity": "sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-niT+Prh3Aff8Uf1MVBVUsaNjFj9rJAKDXuoHIKiQbB+6IUP/3J3JIhBNyZ7lDhytvXxw6ppgnwKZdDJ08UMj4Q=="
|
||||
},
|
||||
"@webpack-cli/configtest": {
|
||||
"version": "1.1.1",
|
||||
|
|
@ -14311,7 +14325,6 @@
|
|||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-10.1.2.tgz",
|
||||
"integrity": "sha512-hvRiQuhhTZxkPMGD/dke+s1EGo8AkKDBU05CcufBO278qgAQSwIC4QyLdHz0CFHVtqVYWjlAS5D1KwvBbaHT+w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@chevrotain/cst-dts-gen": "^10.1.2",
|
||||
"@chevrotain/gast": "^10.1.2",
|
||||
|
|
@ -14804,8 +14817,7 @@
|
|||
"debounce": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
||||
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
|
||||
"dev": true
|
||||
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
|
|
@ -15031,8 +15043,7 @@
|
|||
"draco3d": {
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.2.tgz",
|
||||
"integrity": "sha512-AeRQ25Fb29c14vpjnh167UGW0nGY0ZpEM3ld+zEXoEySlmEXcXfsCHZeTgo5qXH925V1JsdjrzasdaQ22/vXog==",
|
||||
"dev": true
|
||||
"integrity": "sha512-AeRQ25Fb29c14vpjnh167UGW0nGY0ZpEM3ld+zEXoEySlmEXcXfsCHZeTgo5qXH925V1JsdjrzasdaQ22/vXog=="
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
|
|
@ -15310,8 +15321,7 @@
|
|||
"fflate": {
|
||||
"version": "0.6.10",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz",
|
||||
"integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg=="
|
||||
},
|
||||
"file-loader": {
|
||||
"version": "6.2.0",
|
||||
|
|
@ -16088,8 +16098,7 @@
|
|||
"ktx-parse": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.2.2.tgz",
|
||||
"integrity": "sha512-cFBc1jnGG2WlUf52NbDUXK2obJ+Mo9WUkBRvr6tP6CKxRMvZwDDFNV3JAS4cewETp5KyexByfWm9sm+O8AffiQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-cFBc1jnGG2WlUf52NbDUXK2obJ+Mo9WUkBRvr6tP6CKxRMvZwDDFNV3JAS4cewETp5KyexByfWm9sm+O8AffiQ=="
|
||||
},
|
||||
"laravel-mix": {
|
||||
"version": "6.0.43",
|
||||
|
|
@ -16481,8 +16490,7 @@
|
|||
"mmd-parser": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mmd-parser/-/mmd-parser-1.0.4.tgz",
|
||||
"integrity": "sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Qi0VCU46t2IwfGv5KF0+D/t9cizcDug7qnNoy9Ggk7aucp0tssV8IwTMkBlDbm+VqAf3cdQHTCARKSsuS2MYFg=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
|
|
@ -18198,7 +18206,6 @@
|
|||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.4.tgz",
|
||||
"integrity": "sha512-d2JE9RP/6uagpQAVtJoF0pJJA/fgai89Cc50Yp0EJHk+eLp6QQ7gBoblsnubRULNY132I0J1QKMJ+JTbMqz4sw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string.prototype.codepointat": "^0.2.1",
|
||||
"tiny-inflate": "^1.0.3"
|
||||
|
|
@ -18711,11 +18718,16 @@
|
|||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
|
||||
},
|
||||
"postprocessing": {
|
||||
"version": "6.28.5",
|
||||
"resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.28.5.tgz",
|
||||
"integrity": "sha512-e9aH6T720AiQpStdgqrQSsHzpddFQ7Q8v204sZx4iSTnUuYvkq7mFPOyzhVDlx5NrmXXbwz2PEK2XTq+qEYSMg==",
|
||||
"requires": {}
|
||||
},
|
||||
"potpack": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
|
||||
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="
|
||||
},
|
||||
"pretty-time": {
|
||||
"version": "1.1.0",
|
||||
|
|
@ -18903,14 +18915,12 @@
|
|||
"react-merge-refs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz",
|
||||
"integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ=="
|
||||
},
|
||||
"react-reconciler": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz",
|
||||
"integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0",
|
||||
"scheduler": "^0.21.0"
|
||||
|
|
@ -18947,7 +18957,6 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.1.tgz",
|
||||
"integrity": "sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debounce": "^1.2.1"
|
||||
}
|
||||
|
|
@ -19036,8 +19045,7 @@
|
|||
"regexp-to-ast": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz",
|
||||
"integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw=="
|
||||
},
|
||||
"regexpu-core": {
|
||||
"version": "5.0.1",
|
||||
|
|
@ -19210,7 +19218,6 @@
|
|||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
|
||||
"integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
|
|
@ -19225,6 +19232,12 @@
|
|||
"ajv-keywords": "^3.5.2"
|
||||
}
|
||||
},
|
||||
"screen-space-reflections": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/screen-space-reflections/-/screen-space-reflections-2.1.1.tgz",
|
||||
"integrity": "sha512-UwBaTb6Ss/8EfhDHEdybPhMbHXmtchOcpHHTa5guFFzjj1f0998twZRr/svOJaA/Nyi44VL2Cqf3xGhdu3hC2w==",
|
||||
"requires": {}
|
||||
},
|
||||
"select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
|
||||
|
|
@ -19570,8 +19583,7 @@
|
|||
"string.prototype.codepointat": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
|
||||
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
|
|
@ -19633,7 +19645,6 @@
|
|||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.0.8.tgz",
|
||||
"integrity": "sha512-ZC3r8Hu1y0dIThzsGw0RLZplnX9yXwfItcvaIzJc2VQVi8TGyGDlu92syMB5ulybfvGLHAI5Ghzlk23UBPF8xg==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"svgo": {
|
||||
|
|
@ -19757,10 +19768,9 @@
|
|||
}
|
||||
},
|
||||
"three": {
|
||||
"version": "0.140.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.140.0.tgz",
|
||||
"integrity": "sha512-jcHjbnYspPLDdsDQChmzyAoZ5KhJbgFk6pNGlAIc9fQMvsfPGjF5H9glrngqvb2CR/qXcClMyp5PYdF996lldA==",
|
||||
"dev": true,
|
||||
"version": "0.143.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.143.0.tgz",
|
||||
"integrity": "sha512-oKcAGYHhJ46TGEuHjodo2n6TY2R6lbvrkp+feKZxqsUL/WkH7GKKaeu6RHeyb2Xjfk2dPLRKLsOP0KM2VgT8Zg==",
|
||||
"peer": true
|
||||
},
|
||||
"three-mesh-bvh": {
|
||||
|
|
@ -19774,7 +19784,6 @@
|
|||
"version": "2.10.1",
|
||||
"resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.10.1.tgz",
|
||||
"integrity": "sha512-qKJLFB5KMUhPe4JgtJ6bnY7+nEuNPVbxfKyAeRIRbTTBF1oP/rKogZAio+NI5SXSo4iuIu59e02AzOzh8AR9cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.16.7",
|
||||
"@webgpu/glslang": "^0.0.15",
|
||||
|
|
@ -19804,8 +19813,7 @@
|
|||
"tiny-inflate": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
|
||||
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
|
||||
},
|
||||
"to-arraybuffer": {
|
||||
"version": "1.0.1",
|
||||
|
|
@ -20540,14 +20548,12 @@
|
|||
"zstddec": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/zstddec/-/zstddec-0.0.2.tgz",
|
||||
"integrity": "sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA=="
|
||||
},
|
||||
"zustand": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz",
|
||||
"integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
"tailwindcss": "^3.0.24"
|
||||
},
|
||||
"dependencies": {
|
||||
"@react-three/postprocessing": "^2.6.1",
|
||||
"@restart/ui": "^1.3.1",
|
||||
"classnames": "^2.3.1",
|
||||
"install": "^0.13.0",
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 891 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
|
|
@ -42,7 +42,7 @@ class Comments extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
let commentsElement = document.getElementById(commentsId);
|
||||
let commentsElement = this.props.element;
|
||||
if (commentsElement) {
|
||||
this.assetId = commentsElement.getAttribute('data-asset-id')
|
||||
this.setState({
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
// https://levelup.gitconnected.com/react-lazy-load-image-e6a5ca944f32
|
||||
// XlXi: i was too lazy to write this myself
|
||||
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
export default ({ src, placeholderImg, ...props }) => {
|
||||
const [imgSrc, setSrc] = useState(placeholderImg || src);
|
||||
const onLoad = useCallback(() => {
|
||||
setSrc(src);
|
||||
}, [src]);
|
||||
|
||||
useEffect(() => {
|
||||
const img = new Image();
|
||||
img.src = src;
|
||||
img.addEventListener("load", onLoad);
|
||||
|
||||
return () => {
|
||||
img.removeEventListener("load", onLoad);
|
||||
};
|
||||
}, [src, onLoad]);
|
||||
|
||||
return <img {...props} src={imgSrc} />;
|
||||
};
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
*/
|
||||
|
||||
import { createRef, Component } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import classNames from 'classnames/bind';
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
Graphictoria 5 (https://gtoria.net)
|
||||
Copyright © XlXi 2022
|
||||
*/
|
||||
|
||||
import { Component, Suspense, useEffect, useRef } from 'react';
|
||||
|
||||
import * as THREE from 'three';
|
||||
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
|
||||
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
|
||||
import { OrbitControls, PerspectiveCamera } from "@react-three/drei";
|
||||
import { Canvas, useLoader, useThree } from '@react-three/fiber';
|
||||
import { EffectComposer, SSAO } from '@react-three/postprocessing';
|
||||
import { BlendFunction } from 'postprocessing';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
import { buildGenericApiUrl } from '../util/HTTP.js';
|
||||
import ProgressiveImage from './ProgressiveImage';
|
||||
import Loader from './Loader';
|
||||
|
||||
axios.defaults.withCredentials = true;
|
||||
|
||||
const Scene = ({json}) => {
|
||||
const mtl = useLoader(MTLLoader, json.mtl);
|
||||
const obj = useLoader(OBJLoader, json.obj, (loader) => {
|
||||
mtl.preload();
|
||||
loader.setMaterials(mtl);
|
||||
});
|
||||
let controls = useRef();
|
||||
let midPoint;
|
||||
|
||||
useThree(({camera, scene}) => {
|
||||
let aabbMax = json.AABB.max;
|
||||
let aabbMin = json.AABB.min;
|
||||
aabbMax = new THREE.Vector3(aabbMax.x, aabbMax.y, aabbMax.z);
|
||||
aabbMin = new THREE.Vector3(aabbMin.x, aabbMin.y, aabbMin.z);
|
||||
|
||||
midPoint = new THREE.Vector3();
|
||||
midPoint.copy(aabbMax).add(aabbMin).multiplyScalar(0.5);
|
||||
|
||||
let initialPosition = json.camera.position;
|
||||
let initialDirection = json.camera.direction;
|
||||
|
||||
let thumbnailCameraPosition = new THREE.Vector3(initialPosition.x, initialPosition.y, initialPosition.z);
|
||||
let thumbnailCameraDirection = new THREE.Vector3(initialDirection.x, initialDirection.y, initialDirection.z);
|
||||
|
||||
let pointToLookat = new THREE.Vector3();
|
||||
pointToLookat.copy(thumbnailCameraPosition);
|
||||
pointToLookat.sub(thumbnailCameraDirection);
|
||||
|
||||
camera.position.set(thumbnailCameraPosition.x, thumbnailCameraPosition.y, thumbnailCameraPosition.z);
|
||||
camera.lookAt(pointToLookat);
|
||||
|
||||
// lighting
|
||||
// FIXME: XlXi: if you toggle 3d on and off it'll create these twice
|
||||
let ambient = new THREE.AmbientLight(0x878780);
|
||||
scene.add(ambient);
|
||||
|
||||
let sunLight = new THREE.DirectionalLight(0xacacac);
|
||||
sunLight.position.set(0.671597898, 0.671597898, -0.312909544).normalize();
|
||||
scene.add(sunLight);
|
||||
|
||||
let backLight = new THREE.DirectionalLight(0x444444);
|
||||
let backLightPos = new THREE.Vector3()
|
||||
.copy(sunLight.position)
|
||||
.negate()
|
||||
.normalize(); // inverse of sun direction
|
||||
backLight.position.set(backLightPos);
|
||||
scene.add(backLight);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
controls.current.target = midPoint;
|
||||
controls.current.update();
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<primitive object={obj} />
|
||||
{/*
|
||||
<EffectComposer>
|
||||
<SSAO
|
||||
blendFunction={BlendFunction.MULTIPLY}
|
||||
samples={128}
|
||||
radius={2}
|
||||
intensity={60}
|
||||
/>
|
||||
</EffectComposer>
|
||||
*/}
|
||||
<OrbitControls makeDefault ref={controls} enableDamping={false} enablePan={false} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
class ThumbnailTool extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
initialLoading: true,
|
||||
loading: false,
|
||||
is3d: false,
|
||||
seed3d: 0
|
||||
};
|
||||
|
||||
this.tryAsset = this.tryAsset.bind(this);
|
||||
this.loadThumbnail = this.loadThumbnail.bind(this);
|
||||
this.toggle3D = this.toggle3D.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let thumbnailElement = this.props.element;
|
||||
if (thumbnailElement) {
|
||||
this.thumbnail2d = thumbnailElement.getAttribute('data-asset-thumbnail-2d');
|
||||
this.assetId = thumbnailElement.getAttribute('data-asset-id');
|
||||
this.assetName = thumbnailElement.getAttribute('data-asset-name');
|
||||
|
||||
this.setState({ initialLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
loadThumbnail(url, is3d) {
|
||||
axios.get(buildGenericApiUrl('api', url))
|
||||
.then(res => {
|
||||
let data = res.data;
|
||||
|
||||
if(data.status === 'success') {
|
||||
if(is3d) {
|
||||
axios.get(data.data)
|
||||
.then(res => {
|
||||
let newJson = res.data;
|
||||
newJson.mtl = buildGenericApiUrl('cdn', newJson.mtl);
|
||||
newJson.obj = buildGenericApiUrl('cdn', newJson.obj);
|
||||
if(Array.isArray(newJson.textures)) {
|
||||
let newTextures = [];
|
||||
newJson.textures.map((hash) => {
|
||||
newTextures.push(buildGenericApiUrl('cdn', hash));
|
||||
});
|
||||
newJson.textures = newTextures;
|
||||
} else {
|
||||
newJson.textures = buildGenericApiUrl('cdn', newJson.textures);
|
||||
}
|
||||
|
||||
this.setState({ loading: false, json3d: res.data });
|
||||
});
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
} else {
|
||||
let lt = this.loadThumbnail;
|
||||
setTimeout(function(){lt(url,is3d)}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tryAsset() {
|
||||
let is3d = !this.state.is3d;
|
||||
|
||||
this.setState({ loading: true, is3d: is3d });
|
||||
this.loadThumbnail(`thumbnails/v1/try-asset?id=${this.assetId}&type=${this.state.is3d ? '3D' : '2D'}`, is3d);
|
||||
}
|
||||
|
||||
toggle3D() {
|
||||
let is3d = !this.state.is3d;
|
||||
|
||||
this.setState({ loading: true, is3d: is3d, seed3d: Math.random() });
|
||||
|
||||
if(is3d) {
|
||||
this.loadThumbnail(`thumbnails/v1/asset?id=${this.assetId}&type=3D`, true);
|
||||
} else {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
{
|
||||
this.state.initialLoading
|
||||
?
|
||||
<div className='position-absolute top-50 start-50 translate-middle'>
|
||||
<Loader />
|
||||
</div>
|
||||
:
|
||||
<>
|
||||
{
|
||||
this.state.loading
|
||||
?
|
||||
<div className='position-absolute top-50 start-50 translate-middle'>
|
||||
<Loader />
|
||||
</div>
|
||||
:
|
||||
(
|
||||
this.state.is3d
|
||||
?
|
||||
<Canvas key={ this.state.seed3d }>
|
||||
<Suspense fallback={null}>
|
||||
<Scene json={ this.state.json3d } />
|
||||
</Suspense>
|
||||
</Canvas>
|
||||
:
|
||||
<ProgressiveImage
|
||||
src={ this.thumbnail2d }
|
||||
placeholderImg={ buildGenericApiUrl('www', 'images/busy/asset.png') }
|
||||
alt={ this.assetName }
|
||||
className='img-fluid'
|
||||
/>
|
||||
)
|
||||
}
|
||||
<div className='d-flex position-absolute bottom-0 end-0 pb-2 pe-2'>
|
||||
<button className='btn btn-secondary me-2' onClick={ this.tryAsset } disabled={ this.state.loading }>Try On</button>
|
||||
<button className='btn btn-secondary' onClick={ this.toggle3D } disabled={ this.state.loading }>{ this.state.is3d ? '2D' : '3D' }</button>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ThumbnailTool;
|
||||
|
|
@ -10,15 +10,22 @@ import { render } from 'react-dom';
|
|||
|
||||
import Comments from '../components/Comments';
|
||||
import PurchaseButton from '../components/PurchaseButton';
|
||||
import ThumbnailTool from '../components/ThumbnailTool';
|
||||
|
||||
const purchaseId = 'gt-purchase-button';
|
||||
const commentsId = 'gt-comments'; // XlXi: Keep this in sync with the Comments component.
|
||||
const commentsId = 'gt-comments';
|
||||
const thumbnailId = 'gt-thumbnail';
|
||||
|
||||
$(document).ready(function() {
|
||||
if (document.getElementById(commentsId)) {
|
||||
render(<Comments />, document.getElementById(commentsId));
|
||||
let cElem = document.getElementById(commentsId);
|
||||
render(<Comments element={ cElem } />, cElem);
|
||||
}
|
||||
if (document.getElementById(purchaseId)) {
|
||||
render(<PurchaseButton />, document.getElementById(purchaseId));
|
||||
}
|
||||
if (document.getElementById(thumbnailId)) {
|
||||
let tElem = document.getElementById(thumbnailId);
|
||||
render(<ThumbnailTool element={ tElem } />, tElem);
|
||||
}
|
||||
});
|
||||
|
|
@ -36,6 +36,11 @@ img.twemoji {
|
|||
|
||||
// Shop
|
||||
|
||||
.graphictoria-asset-thumbnail {
|
||||
width: 420px;
|
||||
height: 420px;
|
||||
}
|
||||
|
||||
.graphictoria-item-page {
|
||||
max-width: 1096px;
|
||||
margin: 0 auto 0 auto;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,12 @@
|
|||
<div class="collapse navbar-collapse" id="graphictoria-admin-nav">
|
||||
<ul class="navbar-nav graphictoria-admin-nav ms-auto">
|
||||
@yield('quick-admin')
|
||||
@admin
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: Make this use route() --}}
|
||||
<a href="{{ url('/admin/arbiter-diag') }}" class="nav-link py-0">Arbiter Diag</a>
|
||||
</li>
|
||||
@endadmin
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: Make this use route() --}}
|
||||
<a href="{{ url('/admin') }}" class="nav-link py-0"><i class="fa-solid fa-gavel"></i></a>
|
||||
|
|
@ -83,7 +89,7 @@
|
|||
@endphp
|
||||
<div
|
||||
class="{{ $admin_memorybar_color }} rounded-1 position-absolute graphictoria-admin-memorybar"
|
||||
style="width:{{ $admin_memorybar_usage }}px!important;height:8px!important;"
|
||||
style="width:{{ $admin_memorybar_usage }}%!important;height:8px!important;"
|
||||
></div>
|
||||
</div>
|
||||
<i class="my-auto fa-solid fa-gear"></i>
|
||||
|
|
@ -105,7 +111,7 @@
|
|||
@endphp
|
||||
<div
|
||||
class="{{ $admin_cpubar_color }} rounded-1 position-absolute graphictoria-admin-memorybar"
|
||||
style="width:{{ $admin_cpubar_usage }}px!important;height:8px!important;"
|
||||
style="width:{{ $admin_cpubar_usage }}%!important;height:8px!important;"
|
||||
></div>
|
||||
</div>
|
||||
<i class="my-auto fa-solid fa-microchip"></i>
|
||||
|
|
@ -173,7 +179,6 @@
|
|||
<div id="graphictoria-nav-searchbar" class="graphictoria-search"></div>
|
||||
<ul class="navbar-nav ms-auto me-2">
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: messages and notifications --}}
|
||||
<a @class(['nav-link', 'active'=>str_starts_with(Request::path(), 'my/friends')]) href="{{ url('/my/friends') }}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Friends">
|
||||
@php
|
||||
$friendRequestCount = Auth::user()->getFriendRequests()->count();
|
||||
|
|
@ -188,6 +193,16 @@
|
|||
<i class="fa-solid fa-user-group"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a @class(['nav-link', 'active'=>str_starts_with(Request::path(), 'my/messages')]) href="{{ url('/my/messages') }}" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Messages">
|
||||
<i class="fa-solid fa-inbox"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Notifications">
|
||||
<i class="fa-solid fa-bell"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="d-md-flex">
|
||||
<p class="my-auto me-2 text-muted" style="color:#e59800!important;font-weight:bold">
|
||||
|
|
|
|||
|
|
@ -7,6 +7,26 @@
|
|||
@endsection
|
||||
|
||||
@section('quick-admin')
|
||||
@owner
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: Make this use route() --}}
|
||||
<a href="{{ url('/admin/grant-asset?id=' . $asset->id) }}" class="nav-link py-0">Grant Asset</a>
|
||||
</li>
|
||||
@endowner
|
||||
@admin
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: Make this use route() --}}
|
||||
<a href="{{ url('/admin/rerender-asset?id=' . $asset->id) }}" class="nav-link py-0">Rerender Asset</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: Make this use route() --}}
|
||||
<a href="{{ url('/admin/asset-dependencies?id=' . $asset->id) }}" class="nav-link py-0">Asset Dependencies</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: Make this use route() --}}
|
||||
<a href="{{ url('/admin/endorse-asset?id=' . $asset->id) }}" class="nav-link py-0">Endorse Asset</a>
|
||||
</li>
|
||||
@endadmin
|
||||
<li class="nav-item">
|
||||
{{-- TODO: XlXi: Make this use route() --}}
|
||||
<a href="{{ url('/admin/moderate?id=' . $asset->id . '&type=asset') }}" class="nav-link py-0">Moderate Asset</a>
|
||||
|
|
@ -36,13 +56,14 @@
|
|||
<div class="card-body">
|
||||
<div class="d-flex">
|
||||
<div class="pe-4">
|
||||
<div class="border-1 position-relative">
|
||||
<img src={{ asset('images/testing/hat.png') }} alt="{{ $asset->name }}" class="border img-fluid" />
|
||||
<div id="gt-thumbnail-toolbar"></div>
|
||||
<div class="d-flex position-absolute bottom-0 end-0 pb-2 pe-2">
|
||||
<button class="btn btn-secondary me-2">Try On</button>
|
||||
<button class="btn btn-secondary">3D</button>
|
||||
</div>
|
||||
<div id="gt-thumbnail"
|
||||
class="border position-relative graphictoria-asset-thumbnail"
|
||||
data-asset-thumbnail-2d="{{ asset('images/testing/hat.png') }}"
|
||||
data-asset-thumbnail-3d="{{ route('thumbnails.v1.asset', ['id' => $asset->id]) }}"
|
||||
data-asset-name="{{ $asset->name }}"
|
||||
data-asset-id="{{ $asset->id }}"
|
||||
>
|
||||
<img src="{{ asset('images/testing/hat.png') }}" alt="{{ $asset->name }}" class="img-fluid" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-fill">
|
||||
|
|
|
|||
|
|
@ -12,17 +12,25 @@ Route::middleware('auth')->group(function () {
|
|||
});
|
||||
|
||||
Route::group(['as' => 'comments.', 'prefix' => 'comments'], function() {
|
||||
Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() {
|
||||
Route::get('/list-json', 'CommentsController@listJson')->name('list');
|
||||
Route::post('/share', 'CommentsController@share')->name('share')->middleware(['auth', 'throttle:3,2']);
|
||||
});
|
||||
Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() {
|
||||
Route::get('/list-json', 'CommentsController@listJson')->name('list');
|
||||
Route::post('/share', 'CommentsController@share')->name('share')->middleware(['auth', 'throttle:3,2']);
|
||||
});
|
||||
});
|
||||
|
||||
Route::group(['as' => 'shop.', 'prefix' => 'shop'], function() {
|
||||
Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() {
|
||||
Route::get('/list-json', 'ShopController@listJson')->name('list');
|
||||
});
|
||||
Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() {
|
||||
Route::get('/list-json', 'ShopController@listJson')->name('list');
|
||||
});
|
||||
});
|
||||
|
||||
Route::group(['as' => 'thumbnails.', 'prefix' => 'thumbnails'], function() {
|
||||
Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() {
|
||||
Route::get('/try-asset', 'ThumbnailController@tryAsset')->name('try')->middleware('auth');
|
||||
Route::get('/asset', 'ThumbnailController@renderAsset')->name('asset');
|
||||
Route::get('/user', 'ThumbnailController@renderUser')->name('user');
|
||||
});
|
||||
});
|
||||
|
||||
Route::fallback(function () {
|
||||
return response('404 not found.', 404)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
Route::get('/{hash}', 'CdnController@getContent')->name('content');
|
||||
|
||||
Route::fallback(function () {
|
||||
return response('404 not found.', 404)
|
||||
->header('Content-Type', 'text/plain');
|
||||
});
|
||||
Loading…
Reference in New Issue