LLSettings/LLMesh fixes, also upload cost fix
This commit is contained in:
@@ -8,6 +8,7 @@ import { Utils } from './Utils';
|
|||||||
export class CoalescedGameObject
|
export class CoalescedGameObject
|
||||||
{
|
{
|
||||||
itemID: UUID;
|
itemID: UUID;
|
||||||
|
assetID: UUID;
|
||||||
size: Vector3;
|
size: Vector3;
|
||||||
objects: {
|
objects: {
|
||||||
offset: Vector3,
|
offset: Vector3,
|
||||||
@@ -40,7 +41,7 @@ export class CoalescedGameObject
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
async exportXMLElement(rootNode?: string): Promise<XMLElement>
|
async exportXMLElement(rootNode?: string, skipResolve?: Set<string>): Promise<XMLElement>
|
||||||
{
|
{
|
||||||
const document = builder.create('CoalescedObject');
|
const document = builder.create('CoalescedObject');
|
||||||
document.att('x', this.size.x);
|
document.att('x', this.size.x);
|
||||||
@@ -53,14 +54,14 @@ export class CoalescedGameObject
|
|||||||
ele.att('offsetx', obj.offset.x);
|
ele.att('offsetx', obj.offset.x);
|
||||||
ele.att('offsety', obj.offset.y);
|
ele.att('offsety', obj.offset.y);
|
||||||
ele.att('offsetz', obj.offset.z);
|
ele.att('offsetz', obj.offset.z);
|
||||||
const child = await obj.object.exportXMLElement(rootNode);
|
const child = await obj.object.exportXMLElement(rootNode, false, skipResolve?.has(obj.object.FullID.toString()));
|
||||||
ele.children.push(child);
|
ele.children.push(child);
|
||||||
}
|
}
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
async exportXML(rootNode?: string): Promise<string>
|
async exportXML(rootNode?: string, skipResolve?: Set<string>): Promise<string>
|
||||||
{
|
{
|
||||||
return (await this.exportXMLElement(rootNode)).end({ pretty: true, allowEmpty: true });
|
return (await this.exportXMLElement(rootNode, skipResolve)).end({ pretty: true, allowEmpty: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -716,74 +716,53 @@ export class InventoryFolder
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadAsset(type: AssetType, inventoryType: InventoryType, data: Buffer, name: string, description: string, flags: InventoryItemFlags = InventoryItemFlags.None): Promise<InventoryItem>
|
public async uploadAsset(type: AssetType, inventoryType: InventoryType, data: Buffer, name: string, description: string, flags: InventoryItemFlags = InventoryItemFlags.None): Promise<InventoryItem>
|
||||||
{
|
|
||||||
return new Promise<InventoryItem>((resolve, reject) =>
|
|
||||||
{
|
{
|
||||||
switch (inventoryType)
|
switch (inventoryType)
|
||||||
{
|
{
|
||||||
case InventoryType.Wearable:
|
case InventoryType.Wearable:
|
||||||
case InventoryType.Bodypart:
|
case InventoryType.Bodypart:
|
||||||
|
{
|
||||||
// Wearables have to be uploaded using the legacy method and then created
|
// Wearables have to be uploaded using the legacy method and then created
|
||||||
this.uploadInventoryAssetLegacy(type, inventoryType, data, name, description, flags).then((invItemID: UUID) =>
|
const invItemID = await this.uploadInventoryAssetLegacy(type, inventoryType, data, name, description, flags);
|
||||||
|
const uploadedItem: InventoryItem | null = await this.agent.inventory.fetchInventoryItem(invItemID)
|
||||||
|
if (uploadedItem === null)
|
||||||
{
|
{
|
||||||
this.agent.inventory.fetchInventoryItem(invItemID).then((item: InventoryItem | null) =>
|
throw new Error('Unable to get inventory item');
|
||||||
{
|
|
||||||
if (item === null)
|
|
||||||
{
|
|
||||||
reject(new Error('Unable to get inventory item'));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.addItem(item, false).then(() =>
|
await this.addItem(uploadedItem, false);
|
||||||
{
|
}
|
||||||
resolve(item);
|
return uploadedItem;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).catch((err) =>
|
|
||||||
{
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
}).catch((err) =>
|
|
||||||
{
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
case InventoryType.Landmark:
|
case InventoryType.Landmark:
|
||||||
case InventoryType.Notecard:
|
case InventoryType.Notecard:
|
||||||
case InventoryType.Gesture:
|
case InventoryType.Gesture:
|
||||||
case InventoryType.Script:
|
case InventoryType.Script:
|
||||||
case InventoryType.LSL:
|
case InventoryType.LSL:
|
||||||
case InventoryType.Settings:
|
case InventoryType.Settings:
|
||||||
|
{
|
||||||
// These types must be created first and then modified
|
// These types must be created first and then modified
|
||||||
this.uploadInventoryItem(type, inventoryType, data, name, description, flags).then((invItemID: UUID) =>
|
const invItemID: UUID = await this.uploadInventoryItem(type, inventoryType, data, name, description, flags);
|
||||||
{
|
const item: InventoryItem | null = await this.agent.inventory.fetchInventoryItem(invItemID)
|
||||||
this.agent.inventory.fetchInventoryItem(invItemID).then((item: InventoryItem | null) =>
|
|
||||||
{
|
|
||||||
if (item === null)
|
if (item === null)
|
||||||
{
|
{
|
||||||
reject(new Error('Unable to get inventory item'));
|
throw new Error('Unable to get inventory item');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.addItem(item, false).then(() =>
|
await this.addItem(item, false);
|
||||||
{
|
|
||||||
resolve(item);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).catch((err) =>
|
return item;
|
||||||
{
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
}).catch((err) =>
|
|
||||||
{
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadCost = await this.agent.currentRegion.getUploadCost();
|
||||||
|
|
||||||
Logger.Info('[' + name + ']');
|
Logger.Info('[' + name + ']');
|
||||||
const httpType = Utils.AssetTypeToHTTPAssetType(type);
|
const httpType = Utils.AssetTypeToHTTPAssetType(type);
|
||||||
this.agent.currentRegion.caps.capsPostXML('NewFileAgentInventory', {
|
const response = await this.agent.currentRegion.caps.capsPostXML('NewFileAgentInventory', {
|
||||||
'folder_id': new LLSD.UUID(this.folderID.toString()),
|
'folder_id': new LLSD.UUID(this.folderID.toString()),
|
||||||
'asset_type': httpType,
|
'asset_type': httpType,
|
||||||
'inventory_type': Utils.HTTPAssetTypeToCapInventoryType(httpType),
|
'inventory_type': Utils.HTTPAssetTypeToCapInventoryType(httpType),
|
||||||
@@ -792,55 +771,40 @@ export class InventoryFolder
|
|||||||
'everyone_mask': PermissionMask.All,
|
'everyone_mask': PermissionMask.All,
|
||||||
'group_mask': PermissionMask.All,
|
'group_mask': PermissionMask.All,
|
||||||
'next_owner_mask': PermissionMask.All,
|
'next_owner_mask': PermissionMask.All,
|
||||||
'expected_upload_cost': 0
|
'expected_upload_cost': uploadCost
|
||||||
}).then((response: any) =>
|
});
|
||||||
{
|
|
||||||
if (response['state'] === 'upload')
|
if (response['state'] === 'upload')
|
||||||
{
|
{
|
||||||
const uploadURL = response['uploader'];
|
const uploadURL = response['uploader'];
|
||||||
this.agent.currentRegion.caps.capsRequestUpload(uploadURL, data).then((responseUpload: any) =>
|
const responseUpload = await this.agent.currentRegion.caps.capsRequestUpload(uploadURL, data);
|
||||||
{
|
|
||||||
if (responseUpload['new_inventory_item'] !== undefined)
|
if (responseUpload['new_inventory_item'] !== undefined)
|
||||||
{
|
{
|
||||||
const invItemID = new UUID(responseUpload['new_inventory_item'].toString());
|
const invItemID = new UUID(responseUpload['new_inventory_item'].toString());
|
||||||
this.agent.inventory.fetchInventoryItem(invItemID).then((item: InventoryItem | null) =>
|
const item: InventoryItem | null = await this.agent.inventory.fetchInventoryItem(invItemID);
|
||||||
{
|
|
||||||
if (item === null)
|
if (item === null)
|
||||||
{
|
{
|
||||||
reject(new Error('Unable to get inventory item'));
|
throw new Error('Unable to get inventory item');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.addItem(item, false).then(() =>
|
await this.addItem(item, false);
|
||||||
{
|
|
||||||
resolve(item);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).catch((err) =>
|
return item;
|
||||||
{
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).catch((err) =>
|
else
|
||||||
{
|
{
|
||||||
reject(err);
|
throw new Error('Unable to upload asset');
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
else if (response['error'])
|
else if (response['error'])
|
||||||
{
|
{
|
||||||
reject(response['error']['message']);
|
throw new Error(response['error']['message']);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
reject('Unable to upload asset');
|
throw new Error('Unable to upload asset');
|
||||||
}
|
}
|
||||||
}).catch((err) =>
|
|
||||||
{
|
|
||||||
console.log('Got err');
|
|
||||||
console.log(err);
|
|
||||||
reject(err);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkCopyright(creatorID: UUID): void
|
checkCopyright(creatorID: UUID): void
|
||||||
|
|||||||
458
lib/classes/LLSettings.ts
Normal file
458
lib/classes/LLSettings.ts
Normal file
@@ -0,0 +1,458 @@
|
|||||||
|
import { LLSDNotationParser } from './llsd/LLSDNotationParser';
|
||||||
|
import { UUID } from './UUID';
|
||||||
|
import { Vector3 } from './Vector3';
|
||||||
|
import { Vector2 } from './Vector2';
|
||||||
|
import { Quaternion } from './Quaternion';
|
||||||
|
import { Vector4 } from './Vector4';
|
||||||
|
import { LLSDMap } from './llsd/LLSDMap';
|
||||||
|
|
||||||
|
interface UUIDObjectLLSD
|
||||||
|
{
|
||||||
|
mUUID: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TermConfigLLSD
|
||||||
|
{
|
||||||
|
anisotropy?: number;
|
||||||
|
constant_term: number;
|
||||||
|
exp_scale: number;
|
||||||
|
exp_term: number;
|
||||||
|
linear_term: number;
|
||||||
|
width: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HazeConfigLLSD
|
||||||
|
{
|
||||||
|
ambient: number[];
|
||||||
|
blue_density: number[];
|
||||||
|
blue_horizon: number[];
|
||||||
|
density_multiplier: number;
|
||||||
|
distance_multiplier: number;
|
||||||
|
haze_density: number;
|
||||||
|
haze_horizon: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SettingsConfigLLSD
|
||||||
|
{
|
||||||
|
absorption_config?: TermConfigLLSD[];
|
||||||
|
bloom_id?: UUIDObjectLLSD;
|
||||||
|
cloud_color?: number[];
|
||||||
|
cloud_id?: UUIDObjectLLSD;
|
||||||
|
cloud_pos_density1?: number[];
|
||||||
|
cloud_pos_density2?: number[];
|
||||||
|
cloud_scale?: number;
|
||||||
|
cloud_scroll_rate?: number[];
|
||||||
|
cloud_shadow?: number;
|
||||||
|
cloud_variance?: number;
|
||||||
|
dome_offset?: number;
|
||||||
|
dome_radius?: number;
|
||||||
|
droplet_radius?: number;
|
||||||
|
gamma?: number;
|
||||||
|
glow?: number[];
|
||||||
|
halo_id?: UUIDObjectLLSD;
|
||||||
|
ice_level?: number;
|
||||||
|
legacy_haze?: HazeConfigLLSD;
|
||||||
|
max_y?: number;
|
||||||
|
mie_config?: TermConfigLLSD[];
|
||||||
|
moisture_level?: number;
|
||||||
|
moon_brightness?: number;
|
||||||
|
moon_id?: UUIDObjectLLSD;
|
||||||
|
moon_rotation?: number[];
|
||||||
|
moon_scale?: number;
|
||||||
|
name?: string;
|
||||||
|
planet_radius?: number;
|
||||||
|
rainbow_id?: UUIDObjectLLSD;
|
||||||
|
rayleigh_config?: TermConfigLLSD[];
|
||||||
|
sky_bottom_radius?: number;
|
||||||
|
sky_top_radius?: number;
|
||||||
|
star_brightness?: number;
|
||||||
|
sun_arc_radians?: number;
|
||||||
|
sun_id?: UUIDObjectLLSD;
|
||||||
|
sun_rotation?: number[];
|
||||||
|
sun_scale?: number;
|
||||||
|
sunlight_color?: number[];
|
||||||
|
type?: string;
|
||||||
|
frames?: Record<string, SettingsConfigLLSD>,
|
||||||
|
tracks?: {
|
||||||
|
key_keyframe: number,
|
||||||
|
key_name: string
|
||||||
|
}[][],
|
||||||
|
blur_multiplier?: number;
|
||||||
|
fresnel_offset?: number;
|
||||||
|
fresnel_scale?: number;
|
||||||
|
normal_map?: UUIDObjectLLSD;
|
||||||
|
normal_scale?: number[];
|
||||||
|
scale_above?: number;
|
||||||
|
scale_below?: number;
|
||||||
|
underwater_fog_mod?: number;
|
||||||
|
water_fog_color?: number[]
|
||||||
|
water_fog_density?: number;
|
||||||
|
wave1_direction: number[];
|
||||||
|
wave2_direction: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLSettingsHazeConfig
|
||||||
|
{
|
||||||
|
ambient: Vector3;
|
||||||
|
blueDensity: Vector3;
|
||||||
|
blueHorizon: Vector3;
|
||||||
|
densityMultiplier: number;
|
||||||
|
distanceMultiplier: number;
|
||||||
|
hazeDensity: number;
|
||||||
|
hazeHorizon: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LLSettingsTermConfig
|
||||||
|
{
|
||||||
|
anisotropy?: number;
|
||||||
|
constantTerm: number;
|
||||||
|
expScale: number;
|
||||||
|
expTerm: number;
|
||||||
|
linearTerm: number;
|
||||||
|
width: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LLSettings
|
||||||
|
{
|
||||||
|
public absorptionConfig?: LLSettingsTermConfig[];
|
||||||
|
public bloomID?: UUID;
|
||||||
|
public cloudColor?: Vector3;
|
||||||
|
public cloudID?: UUID;
|
||||||
|
public cloudPosDensity1?: Vector3;
|
||||||
|
public cloudPosDensity2?: Vector3;
|
||||||
|
public cloudScale?: number;
|
||||||
|
public cloudScrollRate?: Vector2;
|
||||||
|
public cloudShadow?: number;
|
||||||
|
public cloudVariance?: number;
|
||||||
|
public domeOffset?: number;
|
||||||
|
public domeRadius?: number;
|
||||||
|
public dropletRadius?: number;
|
||||||
|
public gamma?: number;
|
||||||
|
public glow?: Vector3;
|
||||||
|
public haloID?: UUID;
|
||||||
|
public iceLevel?: number;
|
||||||
|
public legacyHaze?: LLSettingsHazeConfig;
|
||||||
|
public maxY?: number;
|
||||||
|
public mieConfig?: LLSettingsTermConfig[];
|
||||||
|
public moistureLevel?: number;
|
||||||
|
public moonBrightness?: number;
|
||||||
|
public moonID?: UUID;
|
||||||
|
public moonRotation?: Quaternion;
|
||||||
|
public moonScale?: number;
|
||||||
|
public name?: string;
|
||||||
|
public planetRadius?: number;
|
||||||
|
public rainbowID?: UUID;
|
||||||
|
public rayleighConfig?: LLSettingsTermConfig[];
|
||||||
|
public skyBottomRadius?: number;
|
||||||
|
public skyTopRadius?: number;
|
||||||
|
public starBrightness?: number;
|
||||||
|
public sunArcRadians?: number;
|
||||||
|
public sunID?: UUID;
|
||||||
|
public sunRotation?: Quaternion;
|
||||||
|
public sunScale?: number;
|
||||||
|
public sunlightColor?: Vector4;
|
||||||
|
public type?: string;
|
||||||
|
public tracks?: { keyKeyframe: number, keyName: string }[][];
|
||||||
|
public frames?: Map<string, LLSettings>;
|
||||||
|
public blurMultiplier?: number;
|
||||||
|
public fresnelOffset?: number;
|
||||||
|
public fresnelScale?: number;
|
||||||
|
public normalMap?: UUID;
|
||||||
|
public normalScale?: Vector3;
|
||||||
|
public scaleAbove?: number;
|
||||||
|
public scaleBelow?: number;
|
||||||
|
public underwaterFogMod?: number;
|
||||||
|
public waterFogColor?: Vector3;
|
||||||
|
public waterFogDensity?: number;
|
||||||
|
public wave1Direction?: Vector2;
|
||||||
|
public wave2Direction?: Vector2;
|
||||||
|
|
||||||
|
public constructor(data?: string | SettingsConfigLLSD)
|
||||||
|
{
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
let settings: SettingsConfigLLSD | null = null;
|
||||||
|
if (typeof data === 'string')
|
||||||
|
{
|
||||||
|
const result = LLSDNotationParser.parse(data);
|
||||||
|
if (!(result instanceof LLSDMap))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
settings = JSON.parse(JSON.stringify(result.toJSON())) as SettingsConfigLLSD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings = data;
|
||||||
|
}
|
||||||
|
if (settings.absorption_config !== undefined)
|
||||||
|
{
|
||||||
|
this.absorptionConfig = [];
|
||||||
|
for (const conf of settings.absorption_config)
|
||||||
|
{
|
||||||
|
this.absorptionConfig.push({
|
||||||
|
constantTerm: conf.constant_term,
|
||||||
|
expScale: conf.exp_scale,
|
||||||
|
expTerm: conf.exp_term,
|
||||||
|
linearTerm: conf.linear_term,
|
||||||
|
width: conf.width
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.bloom_id !== undefined)
|
||||||
|
{
|
||||||
|
this.bloomID = new UUID(settings.bloom_id.mUUID);
|
||||||
|
}
|
||||||
|
if (settings.cloud_color !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudColor = new Vector3(settings.cloud_color);
|
||||||
|
}
|
||||||
|
if (settings.cloud_id !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudID = new UUID(settings.cloud_id.mUUID);
|
||||||
|
}
|
||||||
|
if (settings.cloud_pos_density1 !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudPosDensity1 = new Vector3(settings.cloud_pos_density1);
|
||||||
|
}
|
||||||
|
if (settings.cloud_pos_density2 !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudPosDensity2 = new Vector3(settings.cloud_pos_density2);
|
||||||
|
}
|
||||||
|
if (settings.cloud_scale !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudScale = settings.cloud_scale;
|
||||||
|
}
|
||||||
|
if (settings.cloud_scroll_rate !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudScrollRate = new Vector2(settings.cloud_scroll_rate);
|
||||||
|
}
|
||||||
|
if (settings.cloud_shadow !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudShadow = settings.cloud_shadow;
|
||||||
|
}
|
||||||
|
if (settings.cloud_variance !== undefined)
|
||||||
|
{
|
||||||
|
this.cloudVariance = settings.cloud_variance;
|
||||||
|
}
|
||||||
|
if (settings.dome_offset !== undefined)
|
||||||
|
{
|
||||||
|
this.domeOffset = settings.dome_offset;
|
||||||
|
}
|
||||||
|
if (settings.dome_radius !== undefined)
|
||||||
|
{
|
||||||
|
this.domeRadius = settings.dome_radius;
|
||||||
|
}
|
||||||
|
if (settings.droplet_radius !== undefined)
|
||||||
|
{
|
||||||
|
this.dropletRadius = settings.droplet_radius;
|
||||||
|
}
|
||||||
|
if (settings.gamma !== undefined)
|
||||||
|
{
|
||||||
|
this.gamma = settings.gamma;
|
||||||
|
}
|
||||||
|
if (settings.glow !== undefined)
|
||||||
|
{
|
||||||
|
this.glow = new Vector3(settings.glow);
|
||||||
|
}
|
||||||
|
if (settings.halo_id !== undefined)
|
||||||
|
{
|
||||||
|
this.haloID = new UUID(settings.halo_id.mUUID);
|
||||||
|
}
|
||||||
|
if (settings.ice_level !== undefined)
|
||||||
|
{
|
||||||
|
this.iceLevel = settings.ice_level;
|
||||||
|
}
|
||||||
|
if (settings.legacy_haze !== undefined)
|
||||||
|
{
|
||||||
|
this.legacyHaze = {
|
||||||
|
ambient: new Vector3(settings.legacy_haze.ambient),
|
||||||
|
blueDensity: new Vector3(settings.legacy_haze.blue_density),
|
||||||
|
blueHorizon: new Vector3(settings.legacy_haze.blue_horizon),
|
||||||
|
densityMultiplier: settings.legacy_haze.density_multiplier,
|
||||||
|
distanceMultiplier: settings.legacy_haze.distance_multiplier,
|
||||||
|
hazeDensity: settings.legacy_haze.haze_density,
|
||||||
|
hazeHorizon: settings.legacy_haze.haze_horizon
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.max_y !== undefined)
|
||||||
|
{
|
||||||
|
this.maxY = settings.max_y;
|
||||||
|
}
|
||||||
|
if (settings.mie_config !== undefined)
|
||||||
|
{
|
||||||
|
this.mieConfig = [];
|
||||||
|
for (const mie of settings.mie_config)
|
||||||
|
{
|
||||||
|
this.mieConfig.push({
|
||||||
|
anisotropy: mie.anisotropy,
|
||||||
|
constantTerm: mie.constant_term,
|
||||||
|
expScale: mie.exp_scale,
|
||||||
|
expTerm: mie.exp_term,
|
||||||
|
linearTerm: mie.linear_term,
|
||||||
|
width: mie.width
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.moisture_level !== undefined)
|
||||||
|
{
|
||||||
|
this.moistureLevel = settings.moisture_level;
|
||||||
|
}
|
||||||
|
if (settings.moon_brightness !== undefined)
|
||||||
|
{
|
||||||
|
this.moonBrightness = settings.moon_brightness;
|
||||||
|
}
|
||||||
|
if (settings.moon_id !== undefined)
|
||||||
|
{
|
||||||
|
this.moonID = new UUID(settings.moon_id.mUUID);
|
||||||
|
}
|
||||||
|
if (settings.moon_rotation !== undefined)
|
||||||
|
{
|
||||||
|
this.moonRotation = new Quaternion(settings.moon_rotation);
|
||||||
|
}
|
||||||
|
if (settings.moon_scale !== undefined)
|
||||||
|
{
|
||||||
|
this.moonScale = settings.moon_scale;
|
||||||
|
}
|
||||||
|
if (settings.name !== undefined)
|
||||||
|
{
|
||||||
|
this.name = settings.name;
|
||||||
|
}
|
||||||
|
if (settings.planet_radius !== undefined)
|
||||||
|
{
|
||||||
|
this.planetRadius = settings.planet_radius;
|
||||||
|
}
|
||||||
|
if (settings.rainbow_id !== undefined)
|
||||||
|
{
|
||||||
|
this.rainbowID = new UUID(settings.rainbow_id.mUUID);
|
||||||
|
}
|
||||||
|
if (settings.rayleigh_config !== undefined)
|
||||||
|
{
|
||||||
|
this.rayleighConfig = [];
|
||||||
|
for (const ray of settings.rayleigh_config)
|
||||||
|
{
|
||||||
|
this.rayleighConfig.push({
|
||||||
|
anisotropy: ray.anisotropy,
|
||||||
|
constantTerm: ray.constant_term,
|
||||||
|
expScale: ray.exp_scale,
|
||||||
|
expTerm: ray.exp_term,
|
||||||
|
linearTerm: ray.linear_term,
|
||||||
|
width: ray.width
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.sky_bottom_radius !== undefined)
|
||||||
|
{
|
||||||
|
this.skyBottomRadius = settings.sky_bottom_radius;
|
||||||
|
}
|
||||||
|
if (settings.sky_top_radius !== undefined)
|
||||||
|
{
|
||||||
|
this.skyTopRadius = settings.sky_top_radius;
|
||||||
|
}
|
||||||
|
if (settings.star_brightness !== undefined)
|
||||||
|
{
|
||||||
|
this.starBrightness = settings.star_brightness;
|
||||||
|
}
|
||||||
|
if (settings.sun_arc_radians !== undefined)
|
||||||
|
{
|
||||||
|
this.sunArcRadians = settings.sun_arc_radians;
|
||||||
|
}
|
||||||
|
if (settings.sun_id !== undefined)
|
||||||
|
{
|
||||||
|
this.sunID = new UUID(settings.sun_id.mUUID);
|
||||||
|
}
|
||||||
|
if (settings.sun_rotation !== undefined)
|
||||||
|
{
|
||||||
|
this.sunRotation = new Quaternion(settings.sun_rotation);
|
||||||
|
}
|
||||||
|
if (settings.sun_scale !== undefined)
|
||||||
|
{
|
||||||
|
this.sunScale = settings.sun_scale;
|
||||||
|
}
|
||||||
|
if (settings.sunlight_color !== undefined)
|
||||||
|
{
|
||||||
|
this.sunlightColor = new Vector4(settings.sunlight_color);
|
||||||
|
}
|
||||||
|
if (settings.type !== undefined)
|
||||||
|
{
|
||||||
|
this.type = settings.type;
|
||||||
|
}
|
||||||
|
if (settings.tracks !== undefined)
|
||||||
|
{
|
||||||
|
this.tracks = [];
|
||||||
|
for (const track of settings.tracks)
|
||||||
|
{
|
||||||
|
const t: {
|
||||||
|
keyKeyframe: number,
|
||||||
|
keyName: string
|
||||||
|
}[] = [];
|
||||||
|
for (const tr of track)
|
||||||
|
{
|
||||||
|
t.push({
|
||||||
|
keyKeyframe: tr.key_keyframe,
|
||||||
|
keyName: tr.key_name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.tracks.push(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.frames !== undefined)
|
||||||
|
{
|
||||||
|
this.frames = new Map<string, LLSettings>();
|
||||||
|
for (const keyFrame of Object.keys(settings.frames))
|
||||||
|
{
|
||||||
|
const frame = settings.frames[keyFrame];
|
||||||
|
this.frames.set(keyFrame, new LLSettings(frame));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.blur_multiplier !== undefined)
|
||||||
|
{
|
||||||
|
this.blurMultiplier = settings.blur_multiplier;
|
||||||
|
}
|
||||||
|
if (settings.fresnel_offset !== undefined)
|
||||||
|
{
|
||||||
|
this.fresnelOffset = settings.fresnel_offset;
|
||||||
|
}
|
||||||
|
if (settings.fresnel_scale !== undefined)
|
||||||
|
{
|
||||||
|
this.fresnelScale = settings.fresnel_scale;
|
||||||
|
}
|
||||||
|
if (settings.normal_map !== undefined)
|
||||||
|
{
|
||||||
|
this.normalMap = new UUID(settings.normal_map.mUUID);
|
||||||
|
}
|
||||||
|
if (settings.normal_scale !== undefined)
|
||||||
|
{
|
||||||
|
this.normalScale = new Vector3(settings.normal_scale);
|
||||||
|
}
|
||||||
|
if (settings.scale_above !== undefined)
|
||||||
|
{
|
||||||
|
this.scaleAbove = settings.scale_above;
|
||||||
|
}
|
||||||
|
if (settings.scale_below !== undefined)
|
||||||
|
{
|
||||||
|
this.scaleBelow = settings.scale_below;
|
||||||
|
}
|
||||||
|
if (settings.underwater_fog_mod !== undefined)
|
||||||
|
{
|
||||||
|
this.underwaterFogMod = settings.underwater_fog_mod;
|
||||||
|
}
|
||||||
|
if (settings.water_fog_color !== undefined)
|
||||||
|
{
|
||||||
|
this.waterFogColor = new Vector3(settings.water_fog_color);
|
||||||
|
}
|
||||||
|
if (settings.water_fog_density !== undefined)
|
||||||
|
{
|
||||||
|
this.waterFogDensity = settings.water_fog_density;
|
||||||
|
}
|
||||||
|
if (settings.wave1_direction !== undefined)
|
||||||
|
{
|
||||||
|
this.wave1Direction = new Vector2(settings.wave1_direction);
|
||||||
|
}
|
||||||
|
if (settings.wave2_direction !== undefined)
|
||||||
|
{
|
||||||
|
this.wave2Direction = new Vector2(settings.wave2_direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,11 +19,10 @@ import * as Long from 'long';
|
|||||||
import { Packet } from './Packet';
|
import { Packet } from './Packet';
|
||||||
import { LayerDataMessage } from './messages/LayerData';
|
import { LayerDataMessage } from './messages/LayerData';
|
||||||
import { LayerType } from '../enums/LayerType';
|
import { LayerType } from '../enums/LayerType';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
import { BitPack } from './BitPack';
|
import { BitPack } from './BitPack';
|
||||||
import * as builder from 'xmlbuilder';
|
import * as builder from 'xmlbuilder';
|
||||||
import { SimAccessFlags } from '../enums/SimAccessFlags';
|
import { SimAccessFlags } from '../enums/SimAccessFlags';
|
||||||
import { Subject } from 'rxjs';
|
|
||||||
import { ParcelDwellRequestMessage } from './messages/ParcelDwellRequest';
|
import { ParcelDwellRequestMessage } from './messages/ParcelDwellRequest';
|
||||||
import { ParcelDwellReplyMessage } from './messages/ParcelDwellReply';
|
import { ParcelDwellReplyMessage } from './messages/ParcelDwellReply';
|
||||||
import { Parcel } from './public/Parcel';
|
import { Parcel } from './public/Parcel';
|
||||||
@@ -54,6 +53,8 @@ import { Avatar } from './public/Avatar';
|
|||||||
import { MoneyBalanceReplyMessage } from './messages/MoneyBalanceReply';
|
import { MoneyBalanceReplyMessage } from './messages/MoneyBalanceReply';
|
||||||
import { BalanceUpdatedEvent } from '../events/BalanceUpdatedEvent';
|
import { BalanceUpdatedEvent } from '../events/BalanceUpdatedEvent';
|
||||||
import { Logger } from './Logger';
|
import { Logger } from './Logger';
|
||||||
|
import { EconomyDataRequestMessage } from './messages/EconomyDataRequest';
|
||||||
|
import { EconomyDataMessage } from './messages/EconomyData';
|
||||||
|
|
||||||
export class Region
|
export class Region
|
||||||
{
|
{
|
||||||
@@ -156,6 +157,8 @@ export class Region
|
|||||||
|
|
||||||
agents: { [key: string]: Avatar } = {};
|
agents: { [key: string]: Avatar } = {};
|
||||||
|
|
||||||
|
private uploadCost: number;
|
||||||
|
|
||||||
private parcelOverlayReceived: { [key: number]: Buffer } = {};
|
private parcelOverlayReceived: { [key: number]: Buffer } = {};
|
||||||
|
|
||||||
static IDCTColumn16(linein: number[], lineout: number[], column: number): void
|
static IDCTColumn16(linein: number[], lineout: number[], column: number): void
|
||||||
@@ -988,6 +991,24 @@ export class Region
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getUploadCost(): Promise<number>
|
||||||
|
{
|
||||||
|
if (this.uploadCost !== undefined)
|
||||||
|
{
|
||||||
|
return this.uploadCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
const msg = new EconomyDataRequestMessage();
|
||||||
|
this.circuit.sendMessage(msg, PacketFlags.Reliable);
|
||||||
|
const economyReply = await this.circuit.waitForMessage<EconomyDataMessage>(Message.EconomyData, 10000, (_message: EconomyDataMessage): FilterResponse =>
|
||||||
|
{
|
||||||
|
return FilterResponse.Finish;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.uploadCost = economyReply.Info.PriceUpload;
|
||||||
|
return this.uploadCost;
|
||||||
|
}
|
||||||
|
|
||||||
public getParcelProperties(x: number, y: number): Promise<Parcel>
|
public getParcelProperties(x: number, y: number): Promise<Parcel>
|
||||||
{
|
{
|
||||||
return new Promise<Parcel>((resolve, reject) =>
|
return new Promise<Parcel>((resolve, reject) =>
|
||||||
|
|||||||
@@ -359,8 +359,12 @@ export class Utils
|
|||||||
return AssetType.Category;
|
return AssetType.Category;
|
||||||
case 'mesh':
|
case 'mesh':
|
||||||
return AssetType.Mesh;
|
return AssetType.Mesh;
|
||||||
|
case 'settings':
|
||||||
|
return AssetType.Settings;
|
||||||
|
case 'material':
|
||||||
|
return AssetType.Material;
|
||||||
default:
|
default:
|
||||||
|
console.error('Unrecognised cap inventory type: ' + capInventoryType);
|
||||||
return AssetType.Unknown
|
return AssetType.Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export class AssetCommands extends CommandsBase
|
|||||||
case HTTPAssets.ASSET_MATERIAL:
|
case HTTPAssets.ASSET_MATERIAL:
|
||||||
case HTTPAssets.ASSET_BODYPART:
|
case HTTPAssets.ASSET_BODYPART:
|
||||||
case HTTPAssets.ASSET_MESH:
|
case HTTPAssets.ASSET_MESH:
|
||||||
|
case HTTPAssets.ASSET_SETTINGS:
|
||||||
return this.currentRegion.caps.downloadAsset(uuid, type);
|
return this.currentRegion.caps.downloadAsset(uuid, type);
|
||||||
case HTTPAssets.ASSET_CALLINGCARD:
|
case HTTPAssets.ASSET_CALLINGCARD:
|
||||||
case HTTPAssets.ASSET_SCRIPT:
|
case HTTPAssets.ASSET_SCRIPT:
|
||||||
@@ -58,7 +59,6 @@ export class AssetCommands extends CommandsBase
|
|||||||
case HTTPAssets.ASSET_LINK_FOLDER:
|
case HTTPAssets.ASSET_LINK_FOLDER:
|
||||||
case HTTPAssets.ASSET_WIDGET:
|
case HTTPAssets.ASSET_WIDGET:
|
||||||
case HTTPAssets.ASSET_PERSON:
|
case HTTPAssets.ASSET_PERSON:
|
||||||
case HTTPAssets.ASSET_SETTINGS:
|
|
||||||
{
|
{
|
||||||
const transferParams = Buffer.allocUnsafe(20);
|
const transferParams = Buffer.allocUnsafe(20);
|
||||||
uuid.writeToBuffer(transferParams, 0);
|
uuid.writeToBuffer(transferParams, 0);
|
||||||
|
|||||||
@@ -191,6 +191,10 @@ export class LLSDNotationParser
|
|||||||
|
|
||||||
public static parse(input: string): LLSDType
|
public static parse(input: string): LLSDType
|
||||||
{
|
{
|
||||||
|
if (input.startsWith('<? llsd/notation ?>'))
|
||||||
|
{
|
||||||
|
input = input.substring(20);
|
||||||
|
}
|
||||||
const generator = this.tokenize(input);
|
const generator = this.tokenize(input);
|
||||||
const getToken: LLSDTokenGenerator = (): LLSDToken | undefined =>
|
const getToken: LLSDTokenGenerator = (): LLSDToken | undefined =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,4 +6,6 @@ export abstract class LLSDObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract toJSON(): unknown;
|
public abstract toJSON(): unknown;
|
||||||
|
|
||||||
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1602,7 +1602,9 @@ export class GameObject implements IGameObjectData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getXML(xml: XMLNode, rootPrim: GameObject, linkNum: number, rootNode?: string, skipInventory = false): Promise<void>
|
private async getXML(xml: XMLNode, rootPrim: GameObject, linkNum: number, rootNode?: string, skipInventory = false, skipResolve = false): Promise<void>
|
||||||
|
{
|
||||||
|
if (!skipResolve)
|
||||||
{
|
{
|
||||||
const resolver = this.region?.resolver;
|
const resolver = this.region?.resolver;
|
||||||
if (resolver)
|
if (resolver)
|
||||||
@@ -1641,6 +1643,7 @@ export class GameObject implements IGameObjectData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let root = xml;
|
let root = xml;
|
||||||
if (rootNode)
|
if (rootNode)
|
||||||
@@ -1890,25 +1893,25 @@ export class GameObject implements IGameObjectData
|
|||||||
this.region.objects.populateChildren(this);
|
this.region.objects.populateChildren(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async exportXMLElement(rootNode?: string, skipInventory = false): Promise<XMLElement>
|
async exportXMLElement(rootNode?: string, skipInventory = false, skipResolve = false): Promise<XMLElement>
|
||||||
{
|
{
|
||||||
const document = builder.create('SceneObjectGroup');
|
const document = builder.create('SceneObjectGroup');
|
||||||
let linkNum = 1;
|
let linkNum = 1;
|
||||||
await this.getXML(document, this, linkNum, rootNode, skipInventory);
|
await this.getXML(document, this, linkNum, rootNode, skipInventory, skipResolve);
|
||||||
if (this.children && this.children.length > 0)
|
if (this.children && this.children.length > 0)
|
||||||
{
|
{
|
||||||
const otherParts = document.ele('OtherParts');
|
const otherParts = document.ele('OtherParts');
|
||||||
for (const child of this.children)
|
for (const child of this.children)
|
||||||
{
|
{
|
||||||
await child.getXML(otherParts, this, ++linkNum, (rootNode !== undefined) ? 'Part' : undefined, skipInventory);
|
await child.getXML(otherParts, this, ++linkNum, (rootNode !== undefined) ? 'Part' : undefined, skipInventory, skipResolve);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return document;
|
return document;
|
||||||
}
|
}
|
||||||
|
|
||||||
async exportXML(rootNode?: string, skipInventory = false): Promise<string>
|
async exportXML(rootNode?: string, skipInventory = false, skipResolve = false): Promise<string>
|
||||||
{
|
{
|
||||||
return (await this.exportXMLElement(rootNode, skipInventory)).end({ pretty: true, allowEmpty: true });
|
return (await this.exportXMLElement(rootNode, skipInventory, skipResolve)).end({ pretty: true, allowEmpty: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
public toJSON(): IGameObjectData
|
public toJSON(): IGameObjectData
|
||||||
|
|||||||
@@ -32,21 +32,18 @@ export class LLMesh
|
|||||||
}
|
}
|
||||||
const startPos = parseInt(obj['position'], 10);
|
const startPos = parseInt(obj['position'], 10);
|
||||||
obj = obj['result'];
|
obj = obj['result'];
|
||||||
if (!obj['version'])
|
if (obj['creator'])
|
||||||
{
|
{
|
||||||
throw new Error('No version found');
|
|
||||||
}
|
|
||||||
if (!obj['creator'])
|
|
||||||
{
|
|
||||||
throw new Error('Creator UUID not found');
|
|
||||||
}
|
|
||||||
if (obj['date'] === undefined)
|
|
||||||
{
|
|
||||||
throw new Error('Date not found');
|
|
||||||
}
|
|
||||||
llmesh.creatorID = new UUID(obj['creator'].toString());
|
llmesh.creatorID = new UUID(obj['creator'].toString());
|
||||||
|
}
|
||||||
|
if (obj['date'])
|
||||||
|
{
|
||||||
llmesh.date = obj['date'];
|
llmesh.date = obj['date'];
|
||||||
|
}
|
||||||
|
if (obj['version'])
|
||||||
|
{
|
||||||
llmesh.version = parseInt(obj['version'], 10);
|
llmesh.version = parseInt(obj['version'], 10);
|
||||||
|
}
|
||||||
for (const key of Object.keys(obj))
|
for (const key of Object.keys(obj))
|
||||||
{
|
{
|
||||||
const o = obj[key];
|
const o = obj[key];
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ import { LLGLTFMaterial } from './classes/LLGLTFMaterial';
|
|||||||
import { ExtendedMeshData } from './classes/public/ExtendedMeshData';
|
import { ExtendedMeshData } from './classes/public/ExtendedMeshData';
|
||||||
import { ReflectionProbeData } from './classes/public/ReflectionProbeData';
|
import { ReflectionProbeData } from './classes/public/ReflectionProbeData';
|
||||||
import { RenderMaterialData } from './classes/public/RenderMaterialData';
|
import { RenderMaterialData } from './classes/public/RenderMaterialData';
|
||||||
|
import { LLSettings, LLSettingsHazeConfig, LLSettingsTermConfig } from './classes/LLSettings';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Bot,
|
Bot,
|
||||||
@@ -129,6 +130,9 @@ export {
|
|||||||
LLGestureSoundStep,
|
LLGestureSoundStep,
|
||||||
LLGestureChatStep,
|
LLGestureChatStep,
|
||||||
LLGestureWaitStep,
|
LLGestureWaitStep,
|
||||||
|
LLSettings,
|
||||||
|
LLSettingsTermConfig,
|
||||||
|
LLSettingsHazeConfig,
|
||||||
ParticleSystem,
|
ParticleSystem,
|
||||||
ExtraParams,
|
ExtraParams,
|
||||||
|
|
||||||
|
|||||||
10
lib/tools/LLMeshTest.ts
Normal file
10
lib/tools/LLMeshTest.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import { LLMesh } from '../classes/public/LLMesh';
|
||||||
|
const fileName = '/home/tom/projects/node-libnmv/assets/ce167705-00a3-4664-8c6c-a58edf9f0001_mesh.llmesh';
|
||||||
|
|
||||||
|
const buf = fs.readFileSync(fileName);
|
||||||
|
LLMesh.from(buf).then((mesh: LLMesh) =>
|
||||||
|
{
|
||||||
|
console.log(mesh);
|
||||||
|
});
|
||||||
|
|
||||||
14
lib/tools/LLSDSettingsTest.ts
Normal file
14
lib/tools/LLSDSettingsTest.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import * as fs from 'fs/promises'
|
||||||
|
import * as path from 'path';
|
||||||
|
import { LLSettings } from '../classes/LLSettings';
|
||||||
|
|
||||||
|
async function test()
|
||||||
|
{
|
||||||
|
const settings = await fs.readFile(path.join(__dirname, '..', '..', '..', 'testing', 'water.bin'));
|
||||||
|
const set = new LLSettings(settings.toString('utf-8'));
|
||||||
|
console.log(JSON.stringify(set, null, 4));
|
||||||
|
}
|
||||||
|
test().catch((e) =>
|
||||||
|
{
|
||||||
|
console.error(e);
|
||||||
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@caspertech/node-metaverse",
|
"name": "@caspertech/node-metaverse",
|
||||||
"version": "0.7.40",
|
"version": "0.7.50",
|
||||||
"description": "A node.js interface for Second Life.",
|
"description": "A node.js interface for Second Life.",
|
||||||
"main": "dist/lib/index.js",
|
"main": "dist/lib/index.js",
|
||||||
"types": "dist/lib/index.d.ts",
|
"types": "dist/lib/index.d.ts",
|
||||||
|
|||||||
2
testing/daycycle.bin
Normal file
2
testing/daycycle.bin
Normal file
File diff suppressed because one or more lines are too long
BIN
testing/sky.bin
Normal file
BIN
testing/sky.bin
Normal file
Binary file not shown.
BIN
testing/water.bin
Normal file
BIN
testing/water.bin
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user