Merge branch 'develop' of github.com:secondlife/viewer into rye/infinitemac
commit
ba30737d8f
|
|
@ -1,8 +1,5 @@
|
|||
* text eol=lf
|
||||
|
||||
# VSTool (normalization disabled)
|
||||
indra/tools/vstool/* -text
|
||||
|
||||
# Images
|
||||
*.bmp binary
|
||||
*.BMP binary
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
## Description
|
||||
|
||||
<!--
|
||||
Describe what this PR changes or adds. Include any relevant context or motivation.
|
||||
-->
|
||||
|
||||
## Related Issues
|
||||
|
||||
- [ ] **Please link to a relevant GitHub issue for additional context.**
|
||||
- **Bug Fix:** Link to an issue that includes reproduction steps and testing guidance.
|
||||
- **Feature/Enhancement:** Link to an issue with a write-up, rationale, and requirements.
|
||||
|
||||
Issue Link: <!-- e.g., closes #123 or relates to #456 -->
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Please ensure the following before requesting review:
|
||||
|
||||
- [ ] I have provided a clear title and detailed description for this pull request.
|
||||
- [ ] If useful, I have included media such as screenshots and video to show off my changes.
|
||||
- [ ] The PR is linked to a relevant issue with sufficient context.
|
||||
- [ ] I have tested the changes locally and verified they work as intended.
|
||||
- [ ] All new and existing tests pass.
|
||||
- [ ] Code follows the project's style guidelines.
|
||||
- [ ] Documentation has been updated if needed.
|
||||
- [ ] Any dependent changes have been merged and published in downstream modules
|
||||
- [ ] I have reviewed the [contributing guidelines](https://github.com/secondlife/viewer/blob/develop/CONTRIBUTING.md).
|
||||
|
||||
---
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!--
|
||||
Add any other information, screenshots, or suggestions for reviewers here.
|
||||
-->
|
||||
|
|
@ -0,0 +1 @@
|
|||
qatest.yaml -text eol=crlf
|
||||
|
|
@ -218,8 +218,10 @@ jobs:
|
|||
prefix=${ba[0]}
|
||||
if [ "$prefix" == "project" ]; then
|
||||
IFS='_' read -ra prj <<< "${ba[1]}"
|
||||
prj_str="${prj[*]}"
|
||||
# uppercase first letter of each word
|
||||
export viewer_channel="Second Life Project ${prj[*]^}"
|
||||
capitalized=$(echo "$prj_str" | awk '{for (i=1; i<=NF; i++) $i = toupper(substr($i,1,1)) substr($i,2); print}')
|
||||
export viewer_channel="Second Life Project $capitalized"
|
||||
elif [[ "$prefix" == "release" || "$prefix" == "main" ]];
|
||||
then
|
||||
export viewer_channel="Second Life Release"
|
||||
|
|
@ -304,7 +306,7 @@ jobs:
|
|||
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
needs: build
|
||||
runs-on: windows-large
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Sign and package Windows viewer
|
||||
if: env.AZURE_KEY_VAULT_URI && env.AZURE_CERT_NAME && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && env.AZURE_TENANT_ID
|
||||
|
|
@ -455,7 +457,6 @@ jobs:
|
|||
prerelease: true
|
||||
generate_release_notes: true
|
||||
target_commitish: ${{ github.sha }}
|
||||
previous_tag: release
|
||||
append_body: true
|
||||
fail_on_unmatched_files: true
|
||||
files: |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
name: Check PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-description:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check PR description
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const description = context.payload.pull_request.body || '';
|
||||
if (description.trim().length < 20) {
|
||||
core.setFailed("❌ PR description is too short. Please provide at least 20 characters.");
|
||||
}
|
||||
|
|
@ -0,0 +1,602 @@
|
|||
name: Run QA Test # Runs automated tests on self-hosted QA machines
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build"]
|
||||
types:
|
||||
- completed
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_id:
|
||||
description: 'Build workflow run ID (e.g. For github.com/secondlife/viewer/actions/runs/1234567890 the ID is 1234567890)'
|
||||
required: true
|
||||
default: '14806728332'
|
||||
|
||||
jobs:
|
||||
debug-workflow:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Debug Workflow Variables
|
||||
run: |
|
||||
echo "Workflow Conclusion: ${{ github.event.workflow_run.conclusion }}"
|
||||
echo "Workflow Head Branch: ${{ github.event.workflow_run.head_branch }}"
|
||||
echo "Workflow Run ID: ${{ github.event.workflow_run.id }}"
|
||||
echo "Head Commit Message: ${{ github.event.workflow_run.head_commit.message }}"
|
||||
echo "GitHub Ref: ${{ github.ref }}"
|
||||
echo "GitHub Ref Name: ${{ github.ref_name }}"
|
||||
echo "GitHub Event Name: ${{ github.event_name }}"
|
||||
echo "GitHub Workflow Name: ${{ github.workflow }}"
|
||||
|
||||
install-viewer-and-run-tests:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ matrix.runner }}
|
||||
cancel-in-progress: false # Prevents cancellation of in-progress jobs
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: windows
|
||||
runner: qa-windows-atlas
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: windows
|
||||
runner: qa-windows-asus-dan
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: windows
|
||||
runner: qa-windows-z600-dan
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: mac
|
||||
runner: qa-mac-atlas
|
||||
artifact: macOS-installer
|
||||
install-path: '$HOME/Documents/viewer-automation'
|
||||
fail-fast: false
|
||||
|
||||
runs-on: [self-hosted, "${{ matrix.runner }}"]
|
||||
# Run test only on successful builds of Second_Life_X branches or on manual dispatch
|
||||
if: >
|
||||
(github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
startsWith(github.event.workflow_run.head_branch, 'Second_Life')) ||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
|
||||
steps:
|
||||
# Windows-specific steps
|
||||
- name: Set Build ID
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
|
||||
echo "BUILD_ID=${{ github.event.inputs.build_id }}" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.inputs.build_id }}/artifacts" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
} else {
|
||||
echo "BUILD_ID=${{ github.event.workflow_run.id }}" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.workflow_run.id }}/artifacts" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
}
|
||||
|
||||
- name: Temporarily Allow PowerShell Scripts (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Set-ExecutionPolicy RemoteSigned -Scope Process -Force
|
||||
|
||||
- name: Verify viewer-automation-main Exists (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
if (-Not (Test-Path -Path '${{ matrix.install-path }}')) {
|
||||
Write-Host '❌ Error: viewer-automation folder not found on runner!'
|
||||
exit 1
|
||||
}
|
||||
Write-Host '✅ viewer-automation folder is provided.'
|
||||
|
||||
- name: Verify viewer-automation-main is Up-To-Date (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cd ${{ matrix.install-path }}
|
||||
Write-Host "Checking for repository updates..."
|
||||
|
||||
# Check if .git directory exists
|
||||
if (Test-Path -Path ".git") {
|
||||
try {
|
||||
# Save local changes instead of discarding them
|
||||
git stash push -m "Automated stash before update $(Get-Date)"
|
||||
Write-Host "Local changes saved (if any)"
|
||||
|
||||
# Update the repository
|
||||
git pull
|
||||
Write-Host "✅ Repository updated successfully"
|
||||
|
||||
# Try to restore local changes if any were stashed
|
||||
$stashList = git stash list
|
||||
if ($stashList -match "Automated stash before update") {
|
||||
try {
|
||||
git stash pop
|
||||
Write-Host "✅ Local changes restored successfully"
|
||||
} catch {
|
||||
Write-Host "⚠️ Conflict when restoring local changes"
|
||||
# Save the conflicted state in a new branch for later review
|
||||
$branchName = "conflict-recovery-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
git checkout -b $branchName
|
||||
Write-Host "✅ Created branch '$branchName' with conflicted state"
|
||||
|
||||
# For test execution, revert to a clean state
|
||||
git reset --hard HEAD
|
||||
Write-Host "✅ Reset to clean state for test execution"
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Host "⚠️ Could not update repository: $_"
|
||||
Write-Host "Continuing with existing files..."
|
||||
}
|
||||
} else {
|
||||
Write-Host "⚠️ Not a Git repository, using existing files"
|
||||
}
|
||||
|
||||
- name: Verify Python Installation (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
try {
|
||||
$pythonVersion = (python --version)
|
||||
Write-Host "✅ Python found: $pythonVersion"
|
||||
} catch {
|
||||
Write-Host "❌ Error: Python not found in PATH. Please install Python on this runner."
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Setup Python Virtual Environment (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
if (-Not (Test-Path -Path ".venv")) {
|
||||
Write-Host "Creating virtual environment..."
|
||||
python -m venv .venv
|
||||
} else {
|
||||
Write-Host "Using existing virtual environment"
|
||||
}
|
||||
|
||||
# Direct environment activation to avoid script execution issues
|
||||
$env:VIRTUAL_ENV = "$PWD\.venv"
|
||||
$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH"
|
||||
|
||||
# Install dependencies
|
||||
if (Test-Path -Path "requirements.txt") {
|
||||
Write-Host "Installing dependencies from requirements.txt..."
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Install Playwright browsers - add this line
|
||||
Write-Host "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
} else {
|
||||
pip install outleap requests behave playwright
|
||||
# Install Playwright browsers - add this line
|
||||
Write-Host "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
}
|
||||
|
||||
- name: Fetch & Download Installer Artifact (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$BUILD_ID = "${{ env.BUILD_ID }}"
|
||||
$ARTIFACTS_URL = "${{ env.ARTIFACTS_URL }}"
|
||||
|
||||
# Fetch the correct artifact URL
|
||||
$response = Invoke-RestMethod -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}" } -Uri $ARTIFACTS_URL
|
||||
$ARTIFACT_NAME = ($response.artifacts | Where-Object { $_.name -eq "${{ matrix.artifact }}" }).archive_download_url
|
||||
|
||||
if (-Not $ARTIFACT_NAME) {
|
||||
Write-Host "❌ Error: ${{ matrix.artifact }} artifact not found!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✅ Artifact found: $ARTIFACT_NAME"
|
||||
|
||||
# Secure download path
|
||||
$DownloadPath = "$env:TEMP\secondlife-build-$BUILD_ID"
|
||||
New-Item -ItemType Directory -Path $DownloadPath -Force | Out-Null
|
||||
$InstallerPath = "$DownloadPath\installer.zip"
|
||||
|
||||
# Download the ZIP
|
||||
Invoke-WebRequest -Uri $ARTIFACT_NAME -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}"} -OutFile $InstallerPath
|
||||
|
||||
# Ensure download succeeded
|
||||
if (-Not (Test-Path $InstallerPath)) {
|
||||
Write-Host "❌ Error: Failed to download ${{ matrix.artifact }}.zip"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Set the path for other steps
|
||||
echo "DOWNLOAD_PATH=$DownloadPath" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Extract Installer & Locate Executable (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$BUILD_ID = "${{ env.BUILD_ID }}"
|
||||
$ExtractPath = "${{ env.DOWNLOAD_PATH }}"
|
||||
$InstallerZip = "$ExtractPath\installer.zip"
|
||||
|
||||
# Print paths for debugging
|
||||
Write-Host "Extract Path: $ExtractPath"
|
||||
Write-Host "Installer ZIP Path: $InstallerZip"
|
||||
|
||||
# Verify ZIP exists before extracting
|
||||
if (-Not (Test-Path $InstallerZip)) {
|
||||
Write-Host "❌ Error: ZIP file not found at $InstallerZip!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✅ ZIP file exists and is valid. Extracting..."
|
||||
|
||||
Expand-Archive -Path $InstallerZip -DestinationPath $ExtractPath -Force
|
||||
|
||||
# Find installer executable
|
||||
$INSTALLER_PATH = (Get-ChildItem -Path $ExtractPath -Filter '*.exe' -Recurse | Select-Object -First 1).FullName
|
||||
|
||||
if (-Not $INSTALLER_PATH -or $INSTALLER_PATH -eq "") {
|
||||
Write-Host "❌ Error: No installer executable found in the extracted files!"
|
||||
Write-Host "📂 Extracted Files:"
|
||||
Get-ChildItem -Path $ExtractPath -Recurse | Format-Table -AutoSize
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✅ Installer found: $INSTALLER_PATH"
|
||||
echo "INSTALLER_PATH=$INSTALLER_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Install Second Life (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Windows - Use Task Scheduler to bypass UAC
|
||||
$action = New-ScheduledTaskAction -Execute "${{ env.INSTALLER_PATH }}" -Argument "/S"
|
||||
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
|
||||
$task = New-ScheduledTask -Action $action -Principal $principal
|
||||
Register-ScheduledTask -TaskName "SilentSLInstaller" -InputObject $task -Force
|
||||
Start-ScheduledTask -TaskName "SilentSLInstaller"
|
||||
|
||||
- name: Wait for Installation to Complete (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host "Waiting for the Second Life installer to finish..."
|
||||
do {
|
||||
Start-Sleep -Seconds 5
|
||||
$installerProcess = Get-Process | Where-Object { $_.Path -eq "${{ env.INSTALLER_PATH }}" }
|
||||
} while ($installerProcess)
|
||||
|
||||
Write-Host "✅ Installation completed!"
|
||||
|
||||
- name: Cleanup After Installation (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Cleanup Task Scheduler Entry
|
||||
Unregister-ScheduledTask -TaskName "SilentSLInstaller" -Confirm:$false
|
||||
Write-Host "✅ Task Scheduler entry removed."
|
||||
|
||||
# Delete Installer ZIP
|
||||
$DeletePath = "${{ env.DOWNLOAD_PATH }}\installer.zip"
|
||||
|
||||
Write-Host "Checking if installer ZIP exists: $DeletePath"
|
||||
|
||||
# Ensure the ZIP file exists before trying to delete it
|
||||
if (Test-Path $DeletePath) {
|
||||
Remove-Item -Path $DeletePath -Force
|
||||
Write-Host "✅ Successfully deleted: $DeletePath"
|
||||
} else {
|
||||
Write-Host "⚠️ Warning: ZIP file does not exist, skipping deletion."
|
||||
}
|
||||
|
||||
- name: Run QA Test Script (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host "Running QA Test script on Windows runner: ${{ matrix.runner }}..."
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
# Activate virtual environment
|
||||
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
|
||||
$env:VIRTUAL_ENV = "$PWD\.venv"
|
||||
$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH"
|
||||
|
||||
# Set runner name as environment variable
|
||||
$env:RUNNER_NAME = "${{ matrix.runner }}"
|
||||
|
||||
# Run the test script
|
||||
python runTests.py
|
||||
|
||||
# Mac-specific steps
|
||||
- name: Set Build ID (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
echo "BUILD_ID=${{ github.event.inputs.build_id }}" >> $GITHUB_ENV
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.inputs.build_id }}/artifacts" >> $GITHUB_ENV
|
||||
else
|
||||
echo "BUILD_ID=${{ github.event.workflow_run.id }}" >> $GITHUB_ENV
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.workflow_run.id }}/artifacts" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Verify viewer-automation-main Exists (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ! -d "${{ matrix.install-path }}" ]; then
|
||||
echo "❌ Error: viewer-automation folder not found on runner!"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ viewer-automation is provided."
|
||||
|
||||
- name: Verify viewer-automation-main is Up-To-Date (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cd ${{ matrix.install-path }}
|
||||
echo "Checking for repository updates..."
|
||||
|
||||
# Check if .git directory exists
|
||||
if [ -d ".git" ]; then
|
||||
# Save local changes instead of discarding them
|
||||
git stash push -m "Automated stash before update $(date)"
|
||||
echo "Local changes saved (if any)"
|
||||
|
||||
# Update the repository
|
||||
git pull || echo "⚠️ Could not update repository"
|
||||
echo "✅ Repository updated (or attempted update)"
|
||||
|
||||
# Try to restore local changes if any were stashed
|
||||
if git stash list | grep -q "Automated stash before update"; then
|
||||
# Try to pop the stash, but be prepared for conflicts
|
||||
if ! git stash pop; then
|
||||
echo "⚠️ Conflict when restoring local changes"
|
||||
# Save the conflicted state in a new branch for later review
|
||||
branch_name="conflict-recovery-$(date +%Y%m%d-%H%M%S)"
|
||||
git checkout -b "$branch_name"
|
||||
echo "✅ Created branch '$branch_name' with conflicted state"
|
||||
|
||||
# For test execution, revert to a clean state
|
||||
git reset --hard HEAD
|
||||
echo "✅ Reset to clean state for test execution"
|
||||
else
|
||||
echo "✅ Local changes restored successfully"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Not a Git repository, using existing files"
|
||||
fi
|
||||
|
||||
- name: Verify Python Installation (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
if command -v python3 &> /dev/null; then
|
||||
PYTHON_VERSION=$(python3 --version)
|
||||
echo "✅ Python found: $PYTHON_VERSION"
|
||||
else
|
||||
echo "❌ Error: Python3 not found in PATH. Please install Python on this runner."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Setup Python Virtual Environment (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
# Create virtual environment if it doesn't exist
|
||||
if [ ! -d ".venv" ]; then
|
||||
echo "Creating virtual environment..."
|
||||
python3 -m venv .venv
|
||||
else
|
||||
echo "Using existing virtual environment"
|
||||
fi
|
||||
|
||||
# Activate virtual environment
|
||||
source .venv/bin/activate
|
||||
|
||||
# Install dependencies
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip install -r requirements.txt
|
||||
echo "✅ Installed dependencies from requirements.txt"
|
||||
|
||||
# Install Playwright browsers - add this line
|
||||
echo "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
else
|
||||
pip install outleap requests behave playwright
|
||||
echo "⚠️ requirements.txt not found, installed basic dependencies"
|
||||
|
||||
# Install Playwright browsers - add this line
|
||||
echo "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
fi
|
||||
|
||||
- name: Fetch & Download Installer Artifact (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
# Mac-specific Bash commands
|
||||
response=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -s ${{ env.ARTIFACTS_URL }})
|
||||
ARTIFACT_NAME=$(echo $response | jq -r '.artifacts[] | select(.name=="${{ matrix.artifact }}") | .archive_download_url')
|
||||
|
||||
if [ -z "$ARTIFACT_NAME" ]; then
|
||||
echo "❌ Error: ${{ matrix.artifact }} artifact not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Artifact found: $ARTIFACT_NAME"
|
||||
|
||||
# Secure download path
|
||||
DOWNLOAD_PATH="/tmp/secondlife-build-${{ env.BUILD_ID }}"
|
||||
mkdir -p $DOWNLOAD_PATH
|
||||
INSTALLER_PATH="$DOWNLOAD_PATH/installer.zip"
|
||||
|
||||
# Download the ZIP
|
||||
curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -L $ARTIFACT_NAME -o $INSTALLER_PATH
|
||||
|
||||
# Ensure download succeeded
|
||||
if [ ! -f "$INSTALLER_PATH" ]; then
|
||||
echo "❌ Error: Failed to download ${{ matrix.artifact }}.zip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the path for other steps
|
||||
echo "DOWNLOAD_PATH=$DOWNLOAD_PATH" >> $GITHUB_ENV
|
||||
|
||||
- name: Extract Installer & Locate Executable (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
EXTRACT_PATH="${{ env.DOWNLOAD_PATH }}"
|
||||
INSTALLER_ZIP="$EXTRACT_PATH/installer.zip"
|
||||
|
||||
# Debug output
|
||||
echo "Extract Path: $EXTRACT_PATH"
|
||||
echo "Installer ZIP Path: $INSTALLER_ZIP"
|
||||
|
||||
# Verify ZIP exists
|
||||
if [ ! -f "$INSTALLER_ZIP" ]; then
|
||||
echo "❌ Error: ZIP file not found at $INSTALLER_ZIP!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ ZIP file exists and is valid. Extracting..."
|
||||
|
||||
# Extract the ZIP
|
||||
unzip -o "$INSTALLER_ZIP" -d "$EXTRACT_PATH"
|
||||
|
||||
# Find DMG file
|
||||
INSTALLER_PATH=$(find "$EXTRACT_PATH" -name "*.dmg" -type f | head -1)
|
||||
|
||||
if [ -z "$INSTALLER_PATH" ]; then
|
||||
echo "❌ Error: No installer DMG found in the extracted files!"
|
||||
echo "📂 Extracted Files:"
|
||||
ls -la "$EXTRACT_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Installer found: $INSTALLER_PATH"
|
||||
echo "INSTALLER_PATH=$INSTALLER_PATH" >> $GITHUB_ENV
|
||||
|
||||
- name: Install Second Life (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
# Mac installation
|
||||
echo "Mounting DMG installer..."
|
||||
MOUNT_POINT="/tmp/secondlife-dmg"
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
|
||||
# Mount the DMG
|
||||
hdiutil attach "$INSTALLER_PATH" -mountpoint "$MOUNT_POINT" -nobrowse
|
||||
|
||||
echo "✅ DMG mounted at $MOUNT_POINT"
|
||||
|
||||
echo "Installing application to default location from DMG..."
|
||||
|
||||
# Find the .app bundle in the DMG
|
||||
APP_PATH=$(find "$MOUNT_POINT" -name "*.app" -type d | head -1)
|
||||
|
||||
if [ -z "$APP_PATH" ]; then
|
||||
echo "❌ Error: No .app bundle found in the mounted DMG!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP_NAME=$(basename "$APP_PATH")
|
||||
DEST_PATH="/Applications/$APP_NAME"
|
||||
|
||||
# Handle existing installation
|
||||
if [ -d "$DEST_PATH" ]; then
|
||||
echo "Found existing installation at: $DEST_PATH"
|
||||
echo "Moving existing installation to trash..."
|
||||
|
||||
# Move to trash instead of force removing
|
||||
TRASH_PATH="$HOME/.Trash/$(date +%Y%m%d_%H%M%S)_$APP_NAME"
|
||||
mv "$DEST_PATH" "$TRASH_PATH" || {
|
||||
echo "⚠️ Could not move to trash, trying direct removal..."
|
||||
rm -rf "$DEST_PATH" || {
|
||||
echo "❌ Could not remove existing installation"
|
||||
echo "Please manually remove: $DEST_PATH"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
echo "✅ Existing installation handled successfully"
|
||||
fi
|
||||
|
||||
# Copy the .app to /Applications
|
||||
echo "Copying app from: $APP_PATH"
|
||||
echo "To destination: /Applications/"
|
||||
cp -R "$APP_PATH" /Applications/
|
||||
|
||||
# Verify the app was copied successfully
|
||||
if [ ! -d "$DEST_PATH" ]; then
|
||||
echo "❌ Error: Failed to install application to /Applications!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Application installed successfully to /Applications"
|
||||
|
||||
# Save mount point for cleanup
|
||||
echo "MOUNT_POINT=$MOUNT_POINT" >> $GITHUB_ENV
|
||||
|
||||
- name: Wait for Installation to Complete (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Waiting for installation to complete..."
|
||||
# Sleep to allow installation to finish (adjust as needed)
|
||||
sleep 30
|
||||
echo "✅ Installation completed"
|
||||
|
||||
- name: Cleanup After Installation (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
# Mac cleanup
|
||||
# Unmount the DMG
|
||||
echo "Unmounting DMG..."
|
||||
hdiutil detach "${{ env.MOUNT_POINT }}" -force
|
||||
|
||||
# Clean up temporary files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -rf "${{ env.DOWNLOAD_PATH }}"
|
||||
rm -rf "${{ env.MOUNT_POINT }}"
|
||||
|
||||
echo "✅ Cleanup completed"
|
||||
|
||||
- name: Run QA Test Script (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Running QA Test script on Mac runner: ${{ matrix.runner }}..."
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
# Activate virtual environment
|
||||
source .venv/bin/activate
|
||||
|
||||
# Set runner name as environment variable
|
||||
export RUNNER_NAME="${{ matrix.runner }}"
|
||||
|
||||
# Run the test script
|
||||
python runTests.py
|
||||
|
||||
# - name: Upload Test Results
|
||||
# if: always()
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: test-results-${{ matrix.runner }}
|
||||
# path: ${{ matrix.install-path }}/regressionTest/test_results.html
|
||||
|
|
@ -12,7 +12,7 @@ repos:
|
|||
- id: indent-with-spaces
|
||||
files: \.(cpp|c|h|inl|py|glsl|cmake)$
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: check-xml
|
||||
- id: mixed-line-ending
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ changes.
|
|||
## Table of contents
|
||||
|
||||
- [Communication](#communication)
|
||||
- [What to work on](#what-to-work-on)
|
||||
- [Reporting bugs and requesting features](#reporting-bugs-and-requesting-features)
|
||||
- [Contributing pull requests](#contributing-pull-requests)
|
||||
|
||||
|
|
@ -33,7 +34,18 @@ developer-to-developer or support.
|
|||
scripting, social topics and more.
|
||||
- The [opensource-dev mailing list][] is useful for announcements and
|
||||
discussion between viewer maintainers.
|
||||
- Our [discord channel](https://discord.com/channels/677442248157167619/1357059883400167585) is available for real-time discussion.
|
||||
|
||||
## What to work on
|
||||
|
||||
If you're looking for ways to contribute code, here are some ways to get involved:
|
||||
|
||||
- Explore existing issues on the [GitHub issue tracker](https://github.com/secondlife/viewer/issues) to find known problems, bugs, or enhancement discussions.
|
||||
- File new issues if you’ve discovered a bug or have a specific idea to propose. If your idea is user-facing, consider submitting it through feedback.secondlife.com so it can reach a broader audience and be prioritized by Linden Lab staff.
|
||||
- Look for the [help wanted](https://github.com/secondlife/viewer/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22help%20wanted%22) label. These are tasks the core maintainers have specifically identified as good candidates for community help.
|
||||
- Talk to maintainers before starting significant work. Even if an issue exists, discussing your approach first ensures alignment with ongoing efforts and increases the likelihood your pull request will be accepted.
|
||||
|
||||
Collaboration is essential. We encourage contributors to work closely with the Second Life engineering team and other developers to keep work consistent and maintainable.
|
||||
|
||||
## Reporting bugs and requesting features
|
||||
|
||||
|
|
|
|||
144
autobuild.xml
144
autobuild.xml
|
|
@ -1423,11 +1423,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>9e59c93c7110e87b4ff3db330f11a23c50e5000f</string>
|
||||
<string>7facda95e2f00c260513f3d4db42588fa8ba703c</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910560</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289774</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -1439,11 +1439,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>7ed994db5bafa9a7ad09a1b53da850a84715c65e</string>
|
||||
<string>01d08f13c7bc8d1b95b0330fa6833b7d8274e4d0</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910561</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289775</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1455,24 +1455,24 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>66824c02e0e5eabbfbe37bfb173360195f89697c</string>
|
||||
<string>6d00345c7d3471bc5f7c1218e014dd0f1a2c069b</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910562</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289778</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2010, Linden Research, Inc.</string>
|
||||
<key>license</key>
|
||||
<string>internal</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/llphysicsextensions.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2010, Linden Research, Inc.</string>
|
||||
<key>version</key>
|
||||
<string>1.0.66e6919</string>
|
||||
<string>1.0.11137145495</string>
|
||||
<key>name</key>
|
||||
<string>llphysicsextensions_source</string>
|
||||
</map>
|
||||
|
|
@ -2354,59 +2354,33 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>threejs</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>cfed00d8ea7265c035c2d86a234b28efb0b23756</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-darwin64-b8f6746.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9de1295b157c9913c28be81ff933c73493ecc132</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-linux64-b8f6746.tar.zst</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4141710fccbd1ea2b3b53d00e189bdfa2ee9d441</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-windows64-b8f6746.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright © 2010-2021 three.js authors</string>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/THREEJS_LICENSE.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright © 2010-2021 three.js authors</string>
|
||||
<key>version</key>
|
||||
<string>0.132.2</string>
|
||||
<key>name</key>
|
||||
<string>threejs</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>common</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>982c0fa427458082ea9e3cb9603904210732b64e</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-5da28d9/threejs-0.132.2-common-8454371083.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>0.132.2</string>
|
||||
</map>
|
||||
<key>tinygltf</key>
|
||||
<map>
|
||||
|
|
@ -2918,6 +2892,64 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>version</key>
|
||||
<string>1.0.9-5e8947c</string>
|
||||
</map>
|
||||
<key>discord_sdk</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>e11571bf76b27d15c244069988ae372eaa5afae9</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-discord-sdk/releases/assets/279333720</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>dc21df8b051c425163acf3eff8f06e32f407c9e0</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/3p-discord-sdk/releases/assets/279333706</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>license</key>
|
||||
<string>discord_sdk</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/discord_sdk.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Discord Inc.</string>
|
||||
<key>version</key>
|
||||
<string>1.4.9649.16733550144</string>
|
||||
<key>name</key>
|
||||
<string>discord_sdk</string>
|
||||
<key>vcs_branch</key>
|
||||
<string>main</string>
|
||||
<key>vcs_revision</key>
|
||||
<string>ef5c7c4a490ceac2df2b2f046788b1daf1bbb392</string>
|
||||
<key>vcs_url</key>
|
||||
<string>https://github.com/secondlife/3p-discord-sdk</string>
|
||||
<key>canonical_repo</key>
|
||||
<string>https://github.com/secondlife/3p-discord-sdk</string>
|
||||
<key>description</key>
|
||||
<string>Discord Social SDK</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>package_description</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
# Test plan for PRIM_MEDIA_FIRST_CLICK_INTERACT
|
||||
|
||||
## Requirements
|
||||
|
||||
- At least two accounts
|
||||
- At least one group
|
||||
- Land under your control
|
||||
|
||||
## Feature Brief
|
||||
|
||||
Historically media-on-a-prim (MOAP) in Second Life has been bound to a focus system which blocks mouse click/hover events, this feature creates exceptions to this focus system for a configurable set of objects to meet user preference.
|
||||
|
||||
## Testing
|
||||
|
||||
The following scripts and test cases cover each individual operational mode of the feature; in practice these modes can be combined by advanced users in any configuration they desire from debug settings. Even though the intended use case combines multiple modes, individual modes can be tested for functionality when tested as described below.
|
||||
|
||||
If testing an arbitrary combination of operational modes beyond what the GUI offers is desired, the parameters of the bitfield for calculation are located in lltoolpie.h under the MediaFirstClickTypes enum. As of writing there exists a total of ~127 possible unique/valid combinations, which is why testing each mode individually is considered the most efficient for a full functionality test.
|
||||
|
||||
### Scripts
|
||||
|
||||
#### Script A
|
||||
|
||||
This script creates a media surface that is eligible for media first-click interact. Depending on test conditions, this will exhibit new behavior.
|
||||
|
||||
```lsl
|
||||
default {
|
||||
state_entry() {
|
||||
llSetLinkMedia( LINK_THIS, 0, [
|
||||
PRIM_MEDIA_CURRENT_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_HOME_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_FIRST_CLICK_INTERACT, TRUE,
|
||||
PRIM_MEDIA_AUTO_PLAY, TRUE,
|
||||
PRIM_MEDIA_CONTROLS, PRIM_MEDIA_CONTROLS_MINI
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Script B
|
||||
|
||||
This script creates a media surface that is NOT eligible for media first-click interact. In all but one test case, this will behave the same way.
|
||||
|
||||
```lsl
|
||||
default {
|
||||
state_entry() {
|
||||
llSetLinkMedia( LINK_THIS, 0, [
|
||||
PRIM_MEDIA_CURRENT_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_HOME_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_FIRST_CLICK_INTERACT, FALSE,
|
||||
PRIM_MEDIA_AUTO_PLAY, TRUE,
|
||||
PRIM_MEDIA_CONTROLS, PRIM_MEDIA_CONTROLS_MINI
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Standard testing procedure
|
||||
|
||||
You will be asked to enable media faces on multiple cubes, make sure that the webpage loads on each, and interact with them in the following ways.
|
||||
|
||||
1. Enable media for the cube, and verify that it displays a webpage.
|
||||
2. Click on the terrain to clear any focus.
|
||||
3. Hover your mouse over UI elements of the webpage, and **observe** if they highlight/react to the mouse cursor.
|
||||
4. If hover events are not registered, clicking on the webpage and then **observe** if they begin reacting to hover events.
|
||||
5. Clicking on the terrain to clear any focus once again.
|
||||
6. Clicking on a UI element of the webpage and **observe** if it reacts to the first click, or requires a second click. *(Maximum of 2 clicks per attempt)*
|
||||
|
||||
These steps will be repeated for one or more pairs of cubes per test case to ensure that media first click interact is functioning within expectations. Unless otherwise mentioned for a specific test case, you simply need only be in the same region as the cubes to test with them.
|
||||
|
||||
## Test cases
|
||||
|
||||
All test cases begin with at least two cubes rezzed, one containing Script A henceforth referred to as Cube A and one with Script B referred to as Cube B. The steps of some test cases may impact the condition of the cubes, so keeping a spare set rezzed or in inventory to rapidly duplicate should improve efficiency if testing cases in series.
|
||||
|
||||
### Case 1 (MEDIA_FIRST_CLICK_NONE)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `0`
|
||||
|
||||
Starting with Cube A and Cube B, perform the testing procedure on each.
|
||||
|
||||
**Expected observations:** Both webpages do not react to hover events until clicked, both webpages do not react to clicks until clicked once to establish focus
|
||||
|
||||
### Case 2 (MEDIA_FIRST_CLICK_HUD)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `1`
|
||||
|
||||
Starting with Cube A and Cube B, attach them both to your HUD and perform the testing procedure on each. You may need to rotate or scale the cubes to fit on your screen before beginning testing. You may attach both at the same time, or only one at a time.
|
||||
|
||||
**Expected observations:** The webpage on Cube A will react to mouse cursor hover events and clicks without needing a focus click, but the webpage on Cube B will not.
|
||||
|
||||
### Case 3 (MEDIA_FIRST_CLICK_OWN)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `2`
|
||||
|
||||
This test case requires two pairs of cubes, and the second pair must not be owned by your testing account. What owns them is not important, it can be a group or your second testing account.
|
||||
|
||||
Perform the testing procedure on both sets of cubes.
|
||||
|
||||
**Expected observations:** The webpage on Cube A will react to mouse cursor hover events and clicks without needing a focus click, but the webpage on Cube B will not. The other pair of cubes will react the same as your Cube B.
|
||||
|
||||
### Case 4 (MEDIA_FIRST_CLICK_GROUP)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `4`
|
||||
|
||||
This test case requires two cubes, and the second cube must be deeded or set to a group that your testing account is a member of. As long as the second set of cubes is set to a group that your test account is a member of, the avatar that owns them does not matter.
|
||||
|
||||
Perform the testing procedure on both sets of cubes.
|
||||
|
||||
**Expected observations:** The cube owned by your primary account will not react to mouse cursor hover events and clicks without needing a focus click. The cube set to group will react to mouse cursor hover events and clicks without needing a focus click.
|
||||
|
||||
### Case 5 (MEDIA_FIRST_CLICK_FRIEND)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `8`
|
||||
|
||||
This test case requires three sets of cubes, one owned by you, one owned by another avatar on your friend list, and a third set owned by an avatar that is not on your friend list, or deeded to group. You can optionally use two sets of cubes, and dissolve friendship with your second account to test non-friend cubes.
|
||||
|
||||
Perform the testing procedure on all cubes
|
||||
|
||||
**Expected observations:** Cube A owned by a friended avatar will react to mouse cursor hover events and clicks without needing a focus click. All other cubes will not.
|
||||
|
||||
### Case 6 (MEDIA_FIRST_CLICK_LAND)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `16`
|
||||
|
||||
This is the most tricky test case due to the multiple combinations that this operational mode considers valid. You will need multiple cubes, and can omit Cube B for brevity unless running a full test pass. This is probably most efficiently tested from your second account, using your first account to adjust the test parameters to fit other sub-cases.
|
||||
|
||||
Note: This requires the avatar that is performing the tests to physically be in the same parcel as the test cube(s). If you are standing outside of the parcel the media cubes are in, they will never react to mouse cursor hover events and clicks without needing a focus click under this operational mode.
|
||||
|
||||
1. Place down a set of cubes owned by the same avatar as the land
|
||||
- The second account should see Cube A react to mouse cursor hover events and clicks without needing a focus click
|
||||
- Cube B if tested, will not react in all further sub-cases and will not be mentioned further.
|
||||
|
||||
2. Adjust the conditions of the cubes and parcel such that they are owned by another avatar, but have the same group as the land set
|
||||
- The second account should see Cube A react to mouse cursor hover events and clicks without needing a focus click
|
||||
|
||||
3. Adjust the conditions of the cubes and parcel such that they are deeded to the same group that the parcel is deeded to
|
||||
- The second account should see Cube A react to mouse cursor hover events and clicks without needing a focus click
|
||||
|
||||
4. Adjust the conditions of the cubes and parcel such that the parcel and cubes do not share an owner, or a group
|
||||
- The second account should see Cube A NOT react to mouse cursor hover events until clicked, and clicks WILL need a focus click before registering.
|
||||
|
||||
### Case 7 (MEDIA_FIRST_CLICK_ANY) (optional)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `32767`
|
||||
|
||||
Repeat test cases 1-6.
|
||||
|
||||
1. Test case 1 should fail
|
||||
2. Test cases 2-6 should pass
|
||||
|
||||
### Case 8 (MEDIA_FIRST_CLICK_BYPASS_MOAP_FLAG) (optional)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `65535`
|
||||
|
||||
Repeat test cases 1-6, there is no pass/fail for this run.
|
||||
|
||||
All cubes including B types should exhibit the same first-click interact behavior.
|
||||
|
|
@ -20,6 +20,7 @@ set(cmake_SOURCE_FILES
|
|||
Copy3rdPartyLibs.cmake
|
||||
DBusGlib.cmake
|
||||
DeploySharedLibs.cmake
|
||||
Discord.cmake
|
||||
DragDrop.cmake
|
||||
EXPAT.cmake
|
||||
FindAutobuild.cmake
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
|
||||
include(CMakeCopyIfDifferent)
|
||||
include(Linking)
|
||||
if (USE_DISCORD)
|
||||
include(Discord)
|
||||
endif ()
|
||||
include(OPENAL)
|
||||
|
||||
# When we copy our dependent libraries, we almost always want to copy them to
|
||||
|
|
@ -70,6 +73,10 @@ if(WINDOWS)
|
|||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
if (TARGET ll::discord_sdk)
|
||||
list(APPEND release_files discord_partner_sdk.dll)
|
||||
endif ()
|
||||
|
||||
if (TARGET ll::openal)
|
||||
list(APPEND release_files openal32.dll alut.dll)
|
||||
endif ()
|
||||
|
|
@ -166,6 +173,10 @@ elseif(DARWIN)
|
|||
libndofdev.dylib
|
||||
)
|
||||
|
||||
if (TARGET ll::discord_sdk)
|
||||
list(APPEND release_files libdiscord_partner_sdk.dylib)
|
||||
endif ()
|
||||
|
||||
if (TARGET ll::openal)
|
||||
list(APPEND release_files libalut.dylib libopenal.dylib)
|
||||
endif ()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
include(Prebuilt)
|
||||
|
||||
include_guard()
|
||||
|
||||
add_library(ll::discord_sdk INTERFACE IMPORTED)
|
||||
target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1)
|
||||
|
||||
use_prebuilt_binary(discord_sdk)
|
||||
|
||||
target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk)
|
||||
target_link_libraries(ll::discord_sdk INTERFACE discord_partner_sdk)
|
||||
|
|
@ -73,7 +73,6 @@ else()
|
|||
find_library(COCOA_LIBRARY Cocoa)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
|
||||
find_library(AGL_LIBRARY AGL)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
find_library(COREAUDIO_LIBRARY CoreAudio)
|
||||
find_library(COREGRAPHICS_LIBRARY CoreGraphics)
|
||||
|
|
@ -84,7 +83,6 @@ else()
|
|||
${IOKIT_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${CARBON_LIBRARY}
|
||||
${AGL_LIBRARY}
|
||||
${APPKIT_LIBRARY}
|
||||
${COREAUDIO_LIBRARY}
|
||||
${AUDIOTOOLBOX_LIBRARY}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ elseif (WINDOWS)
|
|||
foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE)
|
||||
# prefer more recent Python versions to older ones, if multiple versions
|
||||
# are installed
|
||||
foreach(pyver 3.12 3.11 3.10 3.9 3.8 3.7)
|
||||
foreach(pyver 3.13 3.12 3.11 3.10 3.9 3.8 3.7)
|
||||
list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]")
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -14,6 +14,7 @@ set(llappearance_SOURCE_FILES
|
|||
llavatarjoint.cpp
|
||||
llavatarjointmesh.cpp
|
||||
lldriverparam.cpp
|
||||
lljointdata.h
|
||||
lllocaltextureobject.cpp
|
||||
llpolyskeletaldistortion.cpp
|
||||
llpolymesh.cpp
|
||||
|
|
|
|||
|
|
@ -29,16 +29,17 @@
|
|||
#include "llavatarappearance.h"
|
||||
#include "llavatarappearancedefines.h"
|
||||
#include "llavatarjointmesh.h"
|
||||
#include "lljointdata.h"
|
||||
#include "llstl.h"
|
||||
#include "lldir.h"
|
||||
#include "llpolymorph.h"
|
||||
#include "llpolymesh.h"
|
||||
#include "llpolyskeletaldistortion.h"
|
||||
#include "llstl.h"
|
||||
#include "lltexglobalcolor.h"
|
||||
#include "llwearabledata.h"
|
||||
#include "boost/bind.hpp"
|
||||
#include "boost/tokenizer.hpp"
|
||||
#include "v4math.h"
|
||||
|
||||
using namespace LLAvatarAppearanceDefines;
|
||||
|
||||
|
|
@ -71,11 +72,13 @@ public:
|
|||
mChildren.clear();
|
||||
}
|
||||
bool parseXml(LLXmlTreeNode* node);
|
||||
glm::mat4 getJointMatrix();
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mSupport;
|
||||
std::string mAliases;
|
||||
std::string mGroup;
|
||||
bool mIsJoint;
|
||||
LLVector3 mPos;
|
||||
LLVector3 mEnd;
|
||||
|
|
@ -105,11 +108,17 @@ public:
|
|||
S32 getNumBones() const { return mNumBones; }
|
||||
S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
|
||||
|
||||
private:
|
||||
typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
|
||||
static void getJointMatricesAndHierarhy(
|
||||
LLAvatarBoneInfo* bone_info,
|
||||
LLJointData& data,
|
||||
const glm::mat4& parent_mat);
|
||||
|
||||
private:
|
||||
S32 mNumBones;
|
||||
S32 mNumCollisionVolumes;
|
||||
LLAvatarAppearance::joint_alias_map_t mJointAliasMap;
|
||||
typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
|
||||
bone_info_list_t mBoneInfoList;
|
||||
};
|
||||
|
||||
|
|
@ -1598,6 +1607,15 @@ bool LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
|
|||
mSupport = "base";
|
||||
}
|
||||
|
||||
// Skeleton has 133 bones, but shader only allows 110 (LL_MAX_JOINTS_PER_MESH_OBJECT)
|
||||
// Groups can be used by importer to cut out unused groups of joints
|
||||
static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
|
||||
if (!node->getFastAttributeString(group_string, mGroup))
|
||||
{
|
||||
LL_WARNS() << "Bone without group " << mName << LL_ENDL;
|
||||
mGroup = "global";
|
||||
}
|
||||
|
||||
if (mIsJoint)
|
||||
{
|
||||
static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
|
||||
|
|
@ -1623,6 +1641,21 @@ bool LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 LLAvatarBoneInfo::getJointMatrix()
|
||||
{
|
||||
glm::mat4 mat(1.0f);
|
||||
// 1. Scaling
|
||||
mat = glm::scale(mat, glm::vec3(mScale[0], mScale[1], mScale[2]));
|
||||
// 2. Rotation (Euler angles rad)
|
||||
mat = glm::rotate(mat, mRot[0], glm::vec3(1, 0, 0));
|
||||
mat = glm::rotate(mat, mRot[1], glm::vec3(0, 1, 0));
|
||||
mat = glm::rotate(mat, mRot[2], glm::vec3(0, 0, 1));
|
||||
// 3. Position
|
||||
mat = glm::translate(mat, glm::vec3(mPos[0], mPos[1], mPos[2]));
|
||||
return mat;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLAvatarSkeletonInfo::parseXml()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1653,6 +1686,25 @@ bool LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLAvatarSkeletonInfo::getJointMatricesAndHierarhy(
|
||||
LLAvatarBoneInfo* bone_info,
|
||||
LLJointData& data,
|
||||
const glm::mat4& parent_mat)
|
||||
{
|
||||
data.mName = bone_info->mName;
|
||||
data.mJointMatrix = bone_info->getJointMatrix();
|
||||
data.mScale = glm::vec3(bone_info->mScale[0], bone_info->mScale[1], bone_info->mScale[2]);
|
||||
data.mRotation = bone_info->mRot;
|
||||
data.mRestMatrix = parent_mat * data.mJointMatrix;
|
||||
data.mIsJoint = bone_info->mIsJoint;
|
||||
data.mGroup = bone_info->mGroup;
|
||||
for (LLAvatarBoneInfo* child_info : bone_info->mChildren)
|
||||
{
|
||||
LLJointData& child_data = data.mChildren.emplace_back();
|
||||
getJointMatricesAndHierarhy(child_info, child_data, data.mRestMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
//Make aliases for joint and push to map.
|
||||
void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info)
|
||||
{
|
||||
|
|
@ -1714,6 +1766,16 @@ const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases
|
|||
return mJointAliasMap;
|
||||
}
|
||||
|
||||
void LLAvatarAppearance::getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const
|
||||
{
|
||||
glm::mat4 identity(1.f);
|
||||
for (LLAvatarBoneInfo* bone_info : sAvatarSkeletonInfo->mBoneInfoList)
|
||||
{
|
||||
LLJointData& child_data = data.emplace_back();
|
||||
LLAvatarSkeletonInfo::getJointMatricesAndHierarhy(bone_info, child_data, identity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "lltexlayer.h"
|
||||
#include "llviewervisualparam.h"
|
||||
#include "llxmltree.h"
|
||||
#include "v4math.h"
|
||||
|
||||
class LLTexLayerSet;
|
||||
class LLTexGlobalColor;
|
||||
|
|
@ -41,6 +42,7 @@ class LLTexGlobalColorInfo;
|
|||
class LLWearableData;
|
||||
class LLAvatarBoneInfo;
|
||||
class LLAvatarSkeletonInfo;
|
||||
class LLJointData;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLAvatarAppearance
|
||||
|
|
@ -138,7 +140,7 @@ public:
|
|||
LLVector3 mHeadOffset{}; // current head position
|
||||
LLAvatarJoint* mRoot{ nullptr };
|
||||
|
||||
typedef std::map<std::string, LLJoint*> joint_map_t;
|
||||
typedef std::map<std::string, LLJoint*, std::less<>> joint_map_t;
|
||||
joint_map_t mJointMap;
|
||||
|
||||
typedef std::map<std::string, LLVector3> joint_state_map_t;
|
||||
|
|
@ -151,9 +153,11 @@ public:
|
|||
public:
|
||||
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
||||
const avatar_joint_list_t& getSkeleton() { return mSkeleton; }
|
||||
typedef std::map<std::string, std::string> joint_alias_map_t;
|
||||
typedef std::map<std::string, std::string, std::less<>> joint_alias_map_t;
|
||||
const joint_alias_map_t& getJointAliases();
|
||||
|
||||
typedef std::map<std::string, std::string> joint_parent_map_t; // matrix plus parent
|
||||
typedef std::map<std::string, glm::mat4> joint_rest_map_t;
|
||||
void getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const;
|
||||
|
||||
protected:
|
||||
static bool parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* @file lljointdata.h
|
||||
* @brief LLJointData class for holding individual joint data and skeleton
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2025, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLJOINTDATA_H
|
||||
#define LL_LLJOINTDATA_H
|
||||
|
||||
#include "v4math.h"
|
||||
|
||||
// may be just move LLAvatarBoneInfo
|
||||
class LLJointData
|
||||
{
|
||||
public:
|
||||
std::string mName;
|
||||
std::string mGroup;
|
||||
glm::mat4 mJointMatrix;
|
||||
glm::mat4 mRestMatrix;
|
||||
glm::vec3 mScale;
|
||||
LLVector3 mRotation;
|
||||
|
||||
typedef std::vector<LLJointData> bones_t;
|
||||
bones_t mChildren;
|
||||
|
||||
bool mIsJoint; // if not, collision_volume
|
||||
enum SupportCategory
|
||||
{
|
||||
SUPPORT_BASE,
|
||||
SUPPORT_EXTENDED
|
||||
};
|
||||
SupportCategory mSupport;
|
||||
void setSupport(const std::string& support)
|
||||
{
|
||||
if (support == "extended")
|
||||
{
|
||||
mSupport = SUPPORT_EXTENDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSupport = SUPPORT_BASE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif //LL_LLJOINTDATA_H
|
||||
|
|
@ -550,12 +550,12 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
|
|||
|
||||
mLastSex = avatar_sex;
|
||||
|
||||
// Check for NaN condition (NaN is detected if a variable doesn't equal itself.
|
||||
if (mCurWeight != mCurWeight)
|
||||
// Check for NaN condition
|
||||
if (llisnan(mCurWeight))
|
||||
{
|
||||
mCurWeight = 0.0;
|
||||
mCurWeight = 0.f;
|
||||
}
|
||||
if (mLastWeight != mLastWeight)
|
||||
if (llisnan(mLastWeight))
|
||||
{
|
||||
mLastWeight = mCurWeight+.001f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1293,7 +1293,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
{
|
||||
if (!force_render && !hasMorph())
|
||||
{
|
||||
LL_DEBUGS() << "skipping renderMorphMasks for " << getUUID() << LL_ENDL;
|
||||
LL_DEBUGS("Morph") << "skipping renderMorphMasks for " << getUUID() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
|
@ -1325,7 +1325,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
success &= param->render( x, y, width, height );
|
||||
if (!success && !force_render)
|
||||
{
|
||||
LL_DEBUGS() << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL;
|
||||
LL_DEBUGS("Morph") << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1365,7 +1365,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Skipping rendering of " << getInfo()->mStaticImageFileName
|
||||
LL_WARNS("Morph") << "Skipping rendering of " << getInfo()->mStaticImageFileName
|
||||
<< "; expected 1 or 4 components." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1404,8 +1404,8 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
// We can get bad morph masks during login, on minimize, and occasional gl errors.
|
||||
// We should only be doing this when we believe something has changed with respect to the user's appearance.
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL;
|
||||
// clear out a slot if we have filled our cache
|
||||
LL_DEBUGS("Morph") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL;
|
||||
// clear out a slot if we have filled our cache
|
||||
S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1;
|
||||
while ((S32)mAlphaCache.size() >= max_cache_entries)
|
||||
{
|
||||
|
|
@ -1444,13 +1444,20 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
|||
}
|
||||
|
||||
glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);
|
||||
|
||||
U8* alpha_cursor = alpha_data;
|
||||
U8* pixel = temp;
|
||||
for (int i = 0; i < pixels; i++)
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
*alpha_cursor++ = pixel[3];
|
||||
pixel += 4;
|
||||
LL_INFOS("Morph") << "GL Error while reading back morph texture. Error code: " << error << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
U8* alpha_cursor = alpha_data;
|
||||
U8* pixel = temp;
|
||||
for (int i = 0; i < pixels; i++)
|
||||
{
|
||||
*alpha_cursor++ = pixel[3];
|
||||
pixel += 4;
|
||||
}
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->disable();
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ LLQuaternion::Order bvhStringToOrder( char *str )
|
|||
// LLBVHLoader()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map )
|
||||
LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map )
|
||||
{
|
||||
reset();
|
||||
errorLine = 0;
|
||||
|
|
@ -156,9 +156,9 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
|
|||
}
|
||||
|
||||
// Recognize all names we've been told are legal.
|
||||
for (std::map<std::string, std::string>::value_type& alias_pair : joint_alias_map)
|
||||
for (const auto& [alias, joint] : joint_alias_map)
|
||||
{
|
||||
makeTranslation( alias_pair.first , alias_pair.second );
|
||||
makeTranslation(alias, joint);
|
||||
}
|
||||
|
||||
char error_text[128]; /* Flawfinder: ignore */
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ class LLBVHLoader
|
|||
friend class LLKeyframeMotion;
|
||||
public:
|
||||
// Constructor
|
||||
LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map );
|
||||
LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map );
|
||||
~LLBVHLoader();
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -77,12 +77,11 @@ LLCharacter::~LLCharacter()
|
|||
//-----------------------------------------------------------------------------
|
||||
// getJoint()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLJoint *LLCharacter::getJoint( const std::string &name )
|
||||
LLJoint* LLCharacter::getJoint(std::string_view name)
|
||||
{
|
||||
LLJoint* joint = NULL;
|
||||
LLJoint* joint = nullptr;
|
||||
|
||||
LLJoint *root = getRootJoint();
|
||||
if (root)
|
||||
if (LLJoint* root = getRootJoint())
|
||||
{
|
||||
joint = root->findJoint(name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public:
|
|||
// get the specified joint
|
||||
// default implementation does recursive search,
|
||||
// subclasses may optimize/cache results.
|
||||
virtual LLJoint *getJoint( const std::string &name );
|
||||
virtual LLJoint* getJoint(std::string_view name);
|
||||
|
||||
// get the position of the character
|
||||
virtual LLVector3 getCharacterPosition() = 0;
|
||||
|
|
@ -119,6 +119,8 @@ public:
|
|||
|
||||
virtual void addDebugText( const std::string& text ) = 0;
|
||||
|
||||
virtual std::string getDebugName() const { return getID().asString(); }
|
||||
|
||||
virtual const LLUUID& getID() const = 0;
|
||||
//-------------------------------------------------------------------------
|
||||
// End Interface
|
||||
|
|
|
|||
|
|
@ -242,21 +242,20 @@ LLJoint *LLJoint::getRoot()
|
|||
//-----------------------------------------------------------------------------
|
||||
// findJoint()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLJoint *LLJoint::findJoint( const std::string &name )
|
||||
LLJoint* LLJoint::findJoint(std::string_view name)
|
||||
{
|
||||
if (name == getName())
|
||||
return this;
|
||||
|
||||
for (LLJoint* joint : mChildren)
|
||||
{
|
||||
LLJoint *found = joint->findJoint(name);
|
||||
if (found)
|
||||
if (LLJoint* found = joint->findJoint(name))
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ public:
|
|||
LLJoint *getRoot();
|
||||
|
||||
// search for child joints by name
|
||||
LLJoint *findJoint( const std::string &name );
|
||||
LLJoint* findJoint(std::string_view name);
|
||||
|
||||
// add/remove children
|
||||
void addChild( LLJoint *joint );
|
||||
|
|
|
|||
|
|
@ -31,15 +31,15 @@
|
|||
|
||||
class LLUUID;
|
||||
|
||||
static const F32 REGION_WIDTH_METERS = 256.f;
|
||||
static const S32 REGION_WIDTH_UNITS = 256;
|
||||
static const U32 REGION_WIDTH_U32 = 256;
|
||||
static constexpr F32 REGION_WIDTH_METERS = 256.f;
|
||||
static constexpr S32 REGION_WIDTH_UNITS = 256;
|
||||
static constexpr U32 REGION_WIDTH_U32 = 256;
|
||||
|
||||
const F32 REGION_HEIGHT_METERS = 4096.f;
|
||||
constexpr F32 REGION_HEIGHT_METERS = 4096.f;
|
||||
|
||||
const F32 DEFAULT_AGENT_DEPTH = 0.45f;
|
||||
const F32 DEFAULT_AGENT_WIDTH = 0.60f;
|
||||
const F32 DEFAULT_AGENT_HEIGHT = 1.9f;
|
||||
constexpr F32 DEFAULT_AGENT_DEPTH = 0.45f;
|
||||
constexpr F32 DEFAULT_AGENT_WIDTH = 0.60f;
|
||||
constexpr F32 DEFAULT_AGENT_HEIGHT = 1.9f;
|
||||
|
||||
enum ETerrainBrushType
|
||||
{
|
||||
|
|
@ -67,112 +67,112 @@ enum EMouseClickType{
|
|||
|
||||
// keys
|
||||
// Bit masks for various keyboard modifier keys.
|
||||
const MASK MASK_NONE = 0x0000;
|
||||
const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs
|
||||
const MASK MASK_ALT = 0x0002;
|
||||
const MASK MASK_SHIFT = 0x0004;
|
||||
const MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys
|
||||
const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows
|
||||
const MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL;
|
||||
constexpr MASK MASK_NONE = 0x0000;
|
||||
constexpr MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs
|
||||
constexpr MASK MASK_ALT = 0x0002;
|
||||
constexpr MASK MASK_SHIFT = 0x0004;
|
||||
constexpr MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys
|
||||
constexpr MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows
|
||||
constexpr MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL;
|
||||
|
||||
// Special keys go into >128
|
||||
const KEY KEY_SPECIAL = 0x80; // special keys start here
|
||||
const KEY KEY_RETURN = 0x81;
|
||||
const KEY KEY_LEFT = 0x82;
|
||||
const KEY KEY_RIGHT = 0x83;
|
||||
const KEY KEY_UP = 0x84;
|
||||
const KEY KEY_DOWN = 0x85;
|
||||
const KEY KEY_ESCAPE = 0x86;
|
||||
const KEY KEY_BACKSPACE =0x87;
|
||||
const KEY KEY_DELETE = 0x88;
|
||||
const KEY KEY_SHIFT = 0x89;
|
||||
const KEY KEY_CONTROL = 0x8A;
|
||||
const KEY KEY_ALT = 0x8B;
|
||||
const KEY KEY_HOME = 0x8C;
|
||||
const KEY KEY_END = 0x8D;
|
||||
const KEY KEY_PAGE_UP = 0x8E;
|
||||
const KEY KEY_PAGE_DOWN = 0x8F;
|
||||
const KEY KEY_HYPHEN = 0x90;
|
||||
const KEY KEY_EQUALS = 0x91;
|
||||
const KEY KEY_INSERT = 0x92;
|
||||
const KEY KEY_CAPSLOCK = 0x93;
|
||||
const KEY KEY_TAB = 0x94;
|
||||
const KEY KEY_ADD = 0x95;
|
||||
const KEY KEY_SUBTRACT =0x96;
|
||||
const KEY KEY_MULTIPLY =0x97;
|
||||
const KEY KEY_DIVIDE = 0x98;
|
||||
const KEY KEY_F1 = 0xA1;
|
||||
const KEY KEY_F2 = 0xA2;
|
||||
const KEY KEY_F3 = 0xA3;
|
||||
const KEY KEY_F4 = 0xA4;
|
||||
const KEY KEY_F5 = 0xA5;
|
||||
const KEY KEY_F6 = 0xA6;
|
||||
const KEY KEY_F7 = 0xA7;
|
||||
const KEY KEY_F8 = 0xA8;
|
||||
const KEY KEY_F9 = 0xA9;
|
||||
const KEY KEY_F10 = 0xAA;
|
||||
const KEY KEY_F11 = 0xAB;
|
||||
const KEY KEY_F12 = 0xAC;
|
||||
constexpr KEY KEY_SPECIAL = 0x80; // special keys start here
|
||||
constexpr KEY KEY_RETURN = 0x81;
|
||||
constexpr KEY KEY_LEFT = 0x82;
|
||||
constexpr KEY KEY_RIGHT = 0x83;
|
||||
constexpr KEY KEY_UP = 0x84;
|
||||
constexpr KEY KEY_DOWN = 0x85;
|
||||
constexpr KEY KEY_ESCAPE = 0x86;
|
||||
constexpr KEY KEY_BACKSPACE =0x87;
|
||||
constexpr KEY KEY_DELETE = 0x88;
|
||||
constexpr KEY KEY_SHIFT = 0x89;
|
||||
constexpr KEY KEY_CONTROL = 0x8A;
|
||||
constexpr KEY KEY_ALT = 0x8B;
|
||||
constexpr KEY KEY_HOME = 0x8C;
|
||||
constexpr KEY KEY_END = 0x8D;
|
||||
constexpr KEY KEY_PAGE_UP = 0x8E;
|
||||
constexpr KEY KEY_PAGE_DOWN = 0x8F;
|
||||
constexpr KEY KEY_HYPHEN = 0x90;
|
||||
constexpr KEY KEY_EQUALS = 0x91;
|
||||
constexpr KEY KEY_INSERT = 0x92;
|
||||
constexpr KEY KEY_CAPSLOCK = 0x93;
|
||||
constexpr KEY KEY_TAB = 0x94;
|
||||
constexpr KEY KEY_ADD = 0x95;
|
||||
constexpr KEY KEY_SUBTRACT =0x96;
|
||||
constexpr KEY KEY_MULTIPLY =0x97;
|
||||
constexpr KEY KEY_DIVIDE = 0x98;
|
||||
constexpr KEY KEY_F1 = 0xA1;
|
||||
constexpr KEY KEY_F2 = 0xA2;
|
||||
constexpr KEY KEY_F3 = 0xA3;
|
||||
constexpr KEY KEY_F4 = 0xA4;
|
||||
constexpr KEY KEY_F5 = 0xA5;
|
||||
constexpr KEY KEY_F6 = 0xA6;
|
||||
constexpr KEY KEY_F7 = 0xA7;
|
||||
constexpr KEY KEY_F8 = 0xA8;
|
||||
constexpr KEY KEY_F9 = 0xA9;
|
||||
constexpr KEY KEY_F10 = 0xAA;
|
||||
constexpr KEY KEY_F11 = 0xAB;
|
||||
constexpr KEY KEY_F12 = 0xAC;
|
||||
|
||||
const KEY KEY_PAD_UP = 0xC0;
|
||||
const KEY KEY_PAD_DOWN = 0xC1;
|
||||
const KEY KEY_PAD_LEFT = 0xC2;
|
||||
const KEY KEY_PAD_RIGHT = 0xC3;
|
||||
const KEY KEY_PAD_HOME = 0xC4;
|
||||
const KEY KEY_PAD_END = 0xC5;
|
||||
const KEY KEY_PAD_PGUP = 0xC6;
|
||||
const KEY KEY_PAD_PGDN = 0xC7;
|
||||
const KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle
|
||||
const KEY KEY_PAD_INS = 0xC9;
|
||||
const KEY KEY_PAD_DEL = 0xCA;
|
||||
const KEY KEY_PAD_RETURN = 0xCB;
|
||||
const KEY KEY_PAD_ADD = 0xCC; // not used
|
||||
const KEY KEY_PAD_SUBTRACT = 0xCD; // not used
|
||||
const KEY KEY_PAD_MULTIPLY = 0xCE; // not used
|
||||
const KEY KEY_PAD_DIVIDE = 0xCF; // not used
|
||||
constexpr KEY KEY_PAD_UP = 0xC0;
|
||||
constexpr KEY KEY_PAD_DOWN = 0xC1;
|
||||
constexpr KEY KEY_PAD_LEFT = 0xC2;
|
||||
constexpr KEY KEY_PAD_RIGHT = 0xC3;
|
||||
constexpr KEY KEY_PAD_HOME = 0xC4;
|
||||
constexpr KEY KEY_PAD_END = 0xC5;
|
||||
constexpr KEY KEY_PAD_PGUP = 0xC6;
|
||||
constexpr KEY KEY_PAD_PGDN = 0xC7;
|
||||
constexpr KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle
|
||||
constexpr KEY KEY_PAD_INS = 0xC9;
|
||||
constexpr KEY KEY_PAD_DEL = 0xCA;
|
||||
constexpr KEY KEY_PAD_RETURN = 0xCB;
|
||||
constexpr KEY KEY_PAD_ADD = 0xCC; // not used
|
||||
constexpr KEY KEY_PAD_SUBTRACT = 0xCD; // not used
|
||||
constexpr KEY KEY_PAD_MULTIPLY = 0xCE; // not used
|
||||
constexpr KEY KEY_PAD_DIVIDE = 0xCF; // not used
|
||||
|
||||
const KEY KEY_BUTTON0 = 0xD0;
|
||||
const KEY KEY_BUTTON1 = 0xD1;
|
||||
const KEY KEY_BUTTON2 = 0xD2;
|
||||
const KEY KEY_BUTTON3 = 0xD3;
|
||||
const KEY KEY_BUTTON4 = 0xD4;
|
||||
const KEY KEY_BUTTON5 = 0xD5;
|
||||
const KEY KEY_BUTTON6 = 0xD6;
|
||||
const KEY KEY_BUTTON7 = 0xD7;
|
||||
const KEY KEY_BUTTON8 = 0xD8;
|
||||
const KEY KEY_BUTTON9 = 0xD9;
|
||||
const KEY KEY_BUTTON10 = 0xDA;
|
||||
const KEY KEY_BUTTON11 = 0xDB;
|
||||
const KEY KEY_BUTTON12 = 0xDC;
|
||||
const KEY KEY_BUTTON13 = 0xDD;
|
||||
const KEY KEY_BUTTON14 = 0xDE;
|
||||
const KEY KEY_BUTTON15 = 0xDF;
|
||||
constexpr KEY KEY_BUTTON0 = 0xD0;
|
||||
constexpr KEY KEY_BUTTON1 = 0xD1;
|
||||
constexpr KEY KEY_BUTTON2 = 0xD2;
|
||||
constexpr KEY KEY_BUTTON3 = 0xD3;
|
||||
constexpr KEY KEY_BUTTON4 = 0xD4;
|
||||
constexpr KEY KEY_BUTTON5 = 0xD5;
|
||||
constexpr KEY KEY_BUTTON6 = 0xD6;
|
||||
constexpr KEY KEY_BUTTON7 = 0xD7;
|
||||
constexpr KEY KEY_BUTTON8 = 0xD8;
|
||||
constexpr KEY KEY_BUTTON9 = 0xD9;
|
||||
constexpr KEY KEY_BUTTON10 = 0xDA;
|
||||
constexpr KEY KEY_BUTTON11 = 0xDB;
|
||||
constexpr KEY KEY_BUTTON12 = 0xDC;
|
||||
constexpr KEY KEY_BUTTON13 = 0xDD;
|
||||
constexpr KEY KEY_BUTTON14 = 0xDE;
|
||||
constexpr KEY KEY_BUTTON15 = 0xDF;
|
||||
|
||||
const KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only.
|
||||
constexpr KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only.
|
||||
|
||||
const S32 KEY_COUNT = 256;
|
||||
constexpr S32 KEY_COUNT = 256;
|
||||
|
||||
|
||||
const F32 DEFAULT_WATER_HEIGHT = 20.0f;
|
||||
constexpr F32 DEFAULT_WATER_HEIGHT = 20.0f;
|
||||
|
||||
// Maturity ratings for simulators
|
||||
const U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG
|
||||
const U8 SIM_ACCESS_PG = 13;
|
||||
const U8 SIM_ACCESS_MATURE = 21;
|
||||
const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
|
||||
const U8 SIM_ACCESS_DOWN = 254;
|
||||
const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
|
||||
constexpr U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG
|
||||
constexpr U8 SIM_ACCESS_PG = 13;
|
||||
constexpr U8 SIM_ACCESS_MATURE = 21;
|
||||
constexpr U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
|
||||
constexpr U8 SIM_ACCESS_DOWN = 254;
|
||||
constexpr U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
|
||||
|
||||
// attachment constants
|
||||
const U8 ATTACHMENT_ADD = 0x80;
|
||||
constexpr U8 ATTACHMENT_ADD = 0x80;
|
||||
|
||||
// god levels
|
||||
const U8 GOD_MAINTENANCE = 250;
|
||||
const U8 GOD_FULL = 200;
|
||||
const U8 GOD_LIAISON = 150;
|
||||
const U8 GOD_CUSTOMER_SERVICE = 100;
|
||||
const U8 GOD_LIKE = 1;
|
||||
const U8 GOD_NOT = 0;
|
||||
constexpr U8 GOD_MAINTENANCE = 250;
|
||||
constexpr U8 GOD_FULL = 200;
|
||||
constexpr U8 GOD_LIAISON = 150;
|
||||
constexpr U8 GOD_CUSTOMER_SERVICE = 100;
|
||||
constexpr U8 GOD_LIKE = 1;
|
||||
constexpr U8 GOD_NOT = 0;
|
||||
|
||||
// "agent id" for things that should be done to ALL agents
|
||||
LL_COMMON_API extern const LLUUID LL_UUID_ALL_AGENTS;
|
||||
|
|
@ -239,120 +239,120 @@ LL_COMMON_API extern const LLUUID BLANK_OBJECT_NORMAL;
|
|||
LL_COMMON_API extern const LLUUID BLANK_MATERIAL_ASSET_ID;
|
||||
|
||||
// radius within which a chat message is fully audible
|
||||
const F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
constexpr F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
|
||||
// media commands
|
||||
const U32 PARCEL_MEDIA_COMMAND_STOP = 0;
|
||||
const U32 PARCEL_MEDIA_COMMAND_PAUSE = 1;
|
||||
const U32 PARCEL_MEDIA_COMMAND_PLAY = 2;
|
||||
const U32 PARCEL_MEDIA_COMMAND_LOOP = 3;
|
||||
const U32 PARCEL_MEDIA_COMMAND_TEXTURE = 4;
|
||||
const U32 PARCEL_MEDIA_COMMAND_URL = 5;
|
||||
const U32 PARCEL_MEDIA_COMMAND_TIME = 6;
|
||||
const U32 PARCEL_MEDIA_COMMAND_AGENT = 7;
|
||||
const U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8;
|
||||
const U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9;
|
||||
const U32 PARCEL_MEDIA_COMMAND_TYPE = 10;
|
||||
const U32 PARCEL_MEDIA_COMMAND_SIZE = 11;
|
||||
const U32 PARCEL_MEDIA_COMMAND_DESC = 12;
|
||||
const U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_STOP = 0;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_PAUSE = 1;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_PLAY = 2;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_LOOP = 3;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_TEXTURE = 4;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_URL = 5;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_TIME = 6;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_AGENT = 7;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_TYPE = 10;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_SIZE = 11;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_DESC = 12;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13;
|
||||
|
||||
const S32 CHAT_CHANNEL_DEBUG = S32_MAX;
|
||||
|
||||
// agent constants
|
||||
const U32 CONTROL_AT_POS_INDEX = 0;
|
||||
const U32 CONTROL_AT_NEG_INDEX = 1;
|
||||
const U32 CONTROL_LEFT_POS_INDEX = 2;
|
||||
const U32 CONTROL_LEFT_NEG_INDEX = 3;
|
||||
const U32 CONTROL_UP_POS_INDEX = 4;
|
||||
const U32 CONTROL_UP_NEG_INDEX = 5;
|
||||
const U32 CONTROL_PITCH_POS_INDEX = 6;
|
||||
const U32 CONTROL_PITCH_NEG_INDEX = 7;
|
||||
const U32 CONTROL_YAW_POS_INDEX = 8;
|
||||
const U32 CONTROL_YAW_NEG_INDEX = 9;
|
||||
const U32 CONTROL_FAST_AT_INDEX = 10;
|
||||
const U32 CONTROL_FAST_LEFT_INDEX = 11;
|
||||
const U32 CONTROL_FAST_UP_INDEX = 12;
|
||||
const U32 CONTROL_FLY_INDEX = 13;
|
||||
const U32 CONTROL_STOP_INDEX = 14;
|
||||
const U32 CONTROL_FINISH_ANIM_INDEX = 15;
|
||||
const U32 CONTROL_STAND_UP_INDEX = 16;
|
||||
const U32 CONTROL_SIT_ON_GROUND_INDEX = 17;
|
||||
const U32 CONTROL_MOUSELOOK_INDEX = 18;
|
||||
const U32 CONTROL_NUDGE_AT_POS_INDEX = 19;
|
||||
const U32 CONTROL_NUDGE_AT_NEG_INDEX = 20;
|
||||
const U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21;
|
||||
const U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22;
|
||||
const U32 CONTROL_NUDGE_UP_POS_INDEX = 23;
|
||||
const U32 CONTROL_NUDGE_UP_NEG_INDEX = 24;
|
||||
const U32 CONTROL_TURN_LEFT_INDEX = 25;
|
||||
const U32 CONTROL_TURN_RIGHT_INDEX = 26;
|
||||
const U32 CONTROL_AWAY_INDEX = 27;
|
||||
const U32 CONTROL_LBUTTON_DOWN_INDEX = 28;
|
||||
const U32 CONTROL_LBUTTON_UP_INDEX = 29;
|
||||
const U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30;
|
||||
const U32 CONTROL_ML_LBUTTON_UP_INDEX = 31;
|
||||
const U32 TOTAL_CONTROLS = 32;
|
||||
constexpr U32 CONTROL_AT_POS_INDEX = 0;
|
||||
constexpr U32 CONTROL_AT_NEG_INDEX = 1;
|
||||
constexpr U32 CONTROL_LEFT_POS_INDEX = 2;
|
||||
constexpr U32 CONTROL_LEFT_NEG_INDEX = 3;
|
||||
constexpr U32 CONTROL_UP_POS_INDEX = 4;
|
||||
constexpr U32 CONTROL_UP_NEG_INDEX = 5;
|
||||
constexpr U32 CONTROL_PITCH_POS_INDEX = 6;
|
||||
constexpr U32 CONTROL_PITCH_NEG_INDEX = 7;
|
||||
constexpr U32 CONTROL_YAW_POS_INDEX = 8;
|
||||
constexpr U32 CONTROL_YAW_NEG_INDEX = 9;
|
||||
constexpr U32 CONTROL_FAST_AT_INDEX = 10;
|
||||
constexpr U32 CONTROL_FAST_LEFT_INDEX = 11;
|
||||
constexpr U32 CONTROL_FAST_UP_INDEX = 12;
|
||||
constexpr U32 CONTROL_FLY_INDEX = 13;
|
||||
constexpr U32 CONTROL_STOP_INDEX = 14;
|
||||
constexpr U32 CONTROL_FINISH_ANIM_INDEX = 15;
|
||||
constexpr U32 CONTROL_STAND_UP_INDEX = 16;
|
||||
constexpr U32 CONTROL_SIT_ON_GROUND_INDEX = 17;
|
||||
constexpr U32 CONTROL_MOUSELOOK_INDEX = 18;
|
||||
constexpr U32 CONTROL_NUDGE_AT_POS_INDEX = 19;
|
||||
constexpr U32 CONTROL_NUDGE_AT_NEG_INDEX = 20;
|
||||
constexpr U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21;
|
||||
constexpr U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22;
|
||||
constexpr U32 CONTROL_NUDGE_UP_POS_INDEX = 23;
|
||||
constexpr U32 CONTROL_NUDGE_UP_NEG_INDEX = 24;
|
||||
constexpr U32 CONTROL_TURN_LEFT_INDEX = 25;
|
||||
constexpr U32 CONTROL_TURN_RIGHT_INDEX = 26;
|
||||
constexpr U32 CONTROL_AWAY_INDEX = 27;
|
||||
constexpr U32 CONTROL_LBUTTON_DOWN_INDEX = 28;
|
||||
constexpr U32 CONTROL_LBUTTON_UP_INDEX = 29;
|
||||
constexpr U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30;
|
||||
constexpr U32 CONTROL_ML_LBUTTON_UP_INDEX = 31;
|
||||
constexpr U32 TOTAL_CONTROLS = 32;
|
||||
|
||||
const U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001
|
||||
const U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002
|
||||
const U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004
|
||||
const U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008
|
||||
const U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010
|
||||
const U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020
|
||||
const U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040
|
||||
const U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080
|
||||
const U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100
|
||||
const U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200
|
||||
constexpr U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001
|
||||
constexpr U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002
|
||||
constexpr U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004
|
||||
constexpr U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008
|
||||
constexpr U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010
|
||||
constexpr U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020
|
||||
constexpr U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040
|
||||
constexpr U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080
|
||||
constexpr U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100
|
||||
constexpr U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200
|
||||
|
||||
const U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400
|
||||
const U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800
|
||||
const U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000
|
||||
constexpr U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400
|
||||
constexpr U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800
|
||||
constexpr U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000
|
||||
|
||||
const U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000
|
||||
const U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000
|
||||
const U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000
|
||||
const U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000
|
||||
const U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000
|
||||
const U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000
|
||||
constexpr U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000
|
||||
constexpr U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000
|
||||
constexpr U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000
|
||||
constexpr U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000
|
||||
constexpr U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000
|
||||
constexpr U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000
|
||||
|
||||
const U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000
|
||||
const U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000
|
||||
const U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000
|
||||
const U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000
|
||||
const U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000
|
||||
const U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000
|
||||
const U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000
|
||||
const U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000
|
||||
constexpr U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000
|
||||
constexpr U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000
|
||||
|
||||
const U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000
|
||||
constexpr U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000
|
||||
|
||||
const U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000
|
||||
const U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000
|
||||
const U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000
|
||||
const U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000
|
||||
constexpr U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000
|
||||
constexpr U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000
|
||||
constexpr U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000
|
||||
constexpr U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000
|
||||
|
||||
// move these up so that we can hide them in "State" for object updates
|
||||
// (for now)
|
||||
const U32 AGENT_ATTACH_OFFSET = 4;
|
||||
const U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET;
|
||||
constexpr U32 AGENT_ATTACH_OFFSET = 4;
|
||||
constexpr U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET;
|
||||
|
||||
// RN: this method swaps the upper and lower nibbles to maintain backward
|
||||
// compatibility with old objects that only used the upper nibble
|
||||
#define ATTACHMENT_ID_FROM_STATE(state) ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4)))
|
||||
|
||||
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
|
||||
const U8 CLICK_ACTION_NONE = 0;
|
||||
const U8 CLICK_ACTION_TOUCH = 0;
|
||||
const U8 CLICK_ACTION_SIT = 1;
|
||||
const U8 CLICK_ACTION_BUY = 2;
|
||||
const U8 CLICK_ACTION_PAY = 3;
|
||||
const U8 CLICK_ACTION_OPEN = 4;
|
||||
const U8 CLICK_ACTION_PLAY = 5;
|
||||
const U8 CLICK_ACTION_OPEN_MEDIA = 6;
|
||||
const U8 CLICK_ACTION_ZOOM = 7;
|
||||
const U8 CLICK_ACTION_DISABLED = 8;
|
||||
const U8 CLICK_ACTION_IGNORE = 9;
|
||||
constexpr U8 CLICK_ACTION_NONE = 0;
|
||||
constexpr U8 CLICK_ACTION_TOUCH = 0;
|
||||
constexpr U8 CLICK_ACTION_SIT = 1;
|
||||
constexpr U8 CLICK_ACTION_BUY = 2;
|
||||
constexpr U8 CLICK_ACTION_PAY = 3;
|
||||
constexpr U8 CLICK_ACTION_OPEN = 4;
|
||||
constexpr U8 CLICK_ACTION_PLAY = 5;
|
||||
constexpr U8 CLICK_ACTION_OPEN_MEDIA = 6;
|
||||
constexpr U8 CLICK_ACTION_ZOOM = 7;
|
||||
constexpr U8 CLICK_ACTION_DISABLED = 8;
|
||||
constexpr U8 CLICK_ACTION_IGNORE = 9;
|
||||
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
|
||||
|
||||
constexpr U32 BEACON_SHOW_MAP = 0x0001;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llassettype.h"
|
||||
#include "lldictionary.h"
|
||||
#include "llmemory.h"
|
||||
#include "llsd.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -246,3 +247,19 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LLSD LLAssetType::getTypeNames()
|
||||
{
|
||||
LLSD type_names;
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
for (S32 type = AT_TEXTURE; type < AT_COUNT; ++type)
|
||||
{
|
||||
const AssetEntry *entry = dict->lookup((LLAssetType::EType) type);
|
||||
// skip llassettype_bad_lookup
|
||||
if (entry)
|
||||
{
|
||||
type_names.append(entry->mTypeName);
|
||||
}
|
||||
}
|
||||
return type_names;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,8 @@ public:
|
|||
static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
|
||||
static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
|
||||
|
||||
static LLSD getTypeNames();
|
||||
|
||||
static const std::string BADLOOKUP;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -171,13 +171,13 @@ constexpr U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 +
|
|||
|
||||
// recursion tail
|
||||
template <typename T>
|
||||
inline auto llmax(T data)
|
||||
constexpr auto llmax(T data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T0, typename T1, typename... Ts>
|
||||
inline auto llmax(T0 d0, T1 d1, Ts... rest)
|
||||
constexpr auto llmax(T0 d0, T1 d1, Ts... rest)
|
||||
{
|
||||
auto maxrest = llmax(d1, rest...);
|
||||
return (d0 > maxrest)? d0 : maxrest;
|
||||
|
|
@ -185,20 +185,20 @@ inline auto llmax(T0 d0, T1 d1, Ts... rest)
|
|||
|
||||
// recursion tail
|
||||
template <typename T>
|
||||
inline auto llmin(T data)
|
||||
constexpr auto llmin(T data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T0, typename T1, typename... Ts>
|
||||
inline auto llmin(T0 d0, T1 d1, Ts... rest)
|
||||
constexpr auto llmin(T0 d0, T1 d1, Ts... rest)
|
||||
{
|
||||
auto minrest = llmin(d1, rest...);
|
||||
return (d0 < minrest) ? d0 : minrest;
|
||||
}
|
||||
|
||||
template <typename A, typename MIN, typename MAX>
|
||||
inline A llclamp(A a, MIN minval, MAX maxval)
|
||||
constexpr A llclamp(A a, MIN minval, MAX maxval)
|
||||
{
|
||||
A aminval{ static_cast<A>(minval) }, amaxval{ static_cast<A>(maxval) };
|
||||
if ( a < aminval )
|
||||
|
|
@ -213,13 +213,13 @@ inline A llclamp(A a, MIN minval, MAX maxval)
|
|||
}
|
||||
|
||||
template <class LLDATATYPE>
|
||||
inline LLDATATYPE llclampf(LLDATATYPE a)
|
||||
constexpr LLDATATYPE llclampf(LLDATATYPE a)
|
||||
{
|
||||
return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(1));
|
||||
}
|
||||
|
||||
template <class LLDATATYPE>
|
||||
inline LLDATATYPE llclampb(LLDATATYPE a)
|
||||
constexpr LLDATATYPE llclampb(LLDATATYPE a)
|
||||
{
|
||||
return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(255));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -553,6 +553,45 @@ LLSD shallow(LLSD value, LLSD filter=LLSD()) { return llsd_shallow(value, filter
|
|||
|
||||
} // namespace llsd
|
||||
|
||||
/*****************************************************************************
|
||||
* LLSDParam<std::vector<T>>
|
||||
*****************************************************************************/
|
||||
// Given an LLSD array, return a const std::vector<T>&, where T is a type
|
||||
// supported by LLSDParam. Bonus: if the LLSD value is actually a scalar,
|
||||
// return a single-element vector containing the converted value.
|
||||
template <typename T>
|
||||
class LLSDParam<std::vector<T>>: public LLSDParamBase
|
||||
{
|
||||
public:
|
||||
LLSDParam(const LLSD& array)
|
||||
{
|
||||
// treat undefined "array" as empty vector
|
||||
if (array.isDefined())
|
||||
{
|
||||
// what if it's a scalar?
|
||||
if (! array.isArray())
|
||||
{
|
||||
v.push_back(LLSDParam<T>(array));
|
||||
}
|
||||
else // really is an array
|
||||
{
|
||||
// reserve space for the array entries
|
||||
v.reserve(array.size());
|
||||
for (const auto& item : llsd::inArray(array))
|
||||
{
|
||||
v.push_back(LLSDParam<T>(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator const std::vector<T>&() const { return v; }
|
||||
|
||||
private:
|
||||
std::vector<T> v;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* toArray(), toMap()
|
||||
*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "apr_portable.h"
|
||||
|
||||
#include "llapp.h"
|
||||
#include "llthread.h"
|
||||
#include "llmutex.h"
|
||||
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
#include "lltrace.h"
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "llexception.h"
|
||||
#include "workqueue.h"
|
||||
|
||||
#if LL_LINUX
|
||||
#include <sched.h>
|
||||
|
|
@ -106,6 +108,27 @@ namespace
|
|||
return s_thread_id;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
||||
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop)
|
||||
{
|
||||
if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop))
|
||||
{
|
||||
// Handled
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else if (code == STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
// C++ exception, go on
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// handle it, convert to std::exception
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
#endif // LL_WINDOWS
|
||||
} // anonymous namespace
|
||||
|
||||
LL_COMMON_API bool on_main_thread()
|
||||
|
|
@ -157,20 +180,11 @@ void LLThread::threadRun()
|
|||
// Run the user supplied function
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
run();
|
||||
}
|
||||
catch (const LLContinueError &e)
|
||||
{
|
||||
LL_WARNS("THREAD") << "ContinueException on thread '" << mName <<
|
||||
"' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL;
|
||||
//output possible call stacks to log file.
|
||||
LLError::LLCallStacks::print();
|
||||
|
||||
LOG_UNHANDLED_EXCEPTION("LLThread");
|
||||
continue;
|
||||
}
|
||||
#ifdef LL_WINDOWS
|
||||
sehHandle(); // Structured Exception Handling
|
||||
#else
|
||||
tryRun();
|
||||
#endif
|
||||
break;
|
||||
|
||||
} while (true);
|
||||
|
|
@ -188,6 +202,69 @@ void LLThread::threadRun()
|
|||
mStatus = STOPPED;
|
||||
}
|
||||
|
||||
void LLThread::tryRun()
|
||||
{
|
||||
try
|
||||
{
|
||||
run();
|
||||
}
|
||||
catch (const LLContinueError& e)
|
||||
{
|
||||
LL_WARNS("THREAD") << "ContinueException on thread '" << mName <<
|
||||
"'. Error what is: '" << e.what() << "'" << LL_ENDL;
|
||||
LLError::LLCallStacks::print();
|
||||
|
||||
LOG_UNHANDLED_EXCEPTION("LLThread");
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
// Todo: improve this, this is going to have a different callstack
|
||||
// instead of showing where it crashed
|
||||
LL_WARNS("THREAD") << "Out of memory in a thread: " << mName << LL_ENDL;
|
||||
|
||||
LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
|
||||
main_queue->post(
|
||||
// Bind the current exception, rethrow it in main loop.
|
||||
[]() {
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS("THREAD") << "Out of memory in a thread" << LL_ENDL;
|
||||
});
|
||||
}
|
||||
#ifndef LL_WINDOWS
|
||||
catch (...)
|
||||
{
|
||||
// Stash any other kind of uncaught exception to be rethrown by main thread.
|
||||
LL_WARNS("THREAD") << "Capturing and rethrowing uncaught exception in LLThread "
|
||||
<< mName << LL_ENDL;
|
||||
|
||||
LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
|
||||
main_queue->post(
|
||||
// Bind the current exception, rethrow it in main loop.
|
||||
[exc = std::current_exception()]() { std::rethrow_exception(exc); });
|
||||
}
|
||||
#endif // else LL_WINDOWS
|
||||
}
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
void LLThread::sehHandle()
|
||||
{
|
||||
__try
|
||||
{
|
||||
// handle stop and continue exceptions first
|
||||
tryRun();
|
||||
}
|
||||
__except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
|
||||
{
|
||||
// convert to C++ styled exception
|
||||
// Note: it might be better to use _se_set_translator
|
||||
// if you want exception to inherit full callstack
|
||||
char integer_string[512];
|
||||
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
|
||||
throw std::exception(integer_string);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
|
||||
mPaused(false),
|
||||
mName(name),
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public:
|
|||
// Called from MAIN THREAD.
|
||||
void pause();
|
||||
void unpause();
|
||||
bool isPaused() { return isStopped() || mPaused; }
|
||||
bool isPaused() const { return isStopped() || mPaused; }
|
||||
|
||||
// Cause the thread to wake up and check its condition
|
||||
void wake();
|
||||
|
|
@ -97,6 +97,11 @@ private:
|
|||
|
||||
// static function passed to APR thread creation routine
|
||||
void threadRun();
|
||||
void tryRun();
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
void sehHandle();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::string mName;
|
||||
|
|
|
|||
|
|
@ -164,14 +164,14 @@ private:
|
|||
FROM mValue;
|
||||
|
||||
public:
|
||||
narrow(FROM value): mValue(value) {}
|
||||
constexpr narrow(FROM value): mValue(value) {}
|
||||
|
||||
/*---------------------- Narrowing unsigned to signed ----------------------*/
|
||||
template <typename TO,
|
||||
typename std::enable_if<std::is_unsigned<FROM>::value &&
|
||||
std::is_signed<TO>::value,
|
||||
bool>::type = true>
|
||||
inline
|
||||
constexpr
|
||||
operator TO() const
|
||||
{
|
||||
// The reason we skip the
|
||||
|
|
@ -189,7 +189,7 @@ public:
|
|||
typename std::enable_if<! (std::is_unsigned<FROM>::value &&
|
||||
std::is_signed<TO>::value),
|
||||
bool>::type = true>
|
||||
inline
|
||||
constexpr
|
||||
operator TO() const
|
||||
{
|
||||
// two different assert()s so we can tell which condition failed
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ namespace LL
|
|||
* ThreadPool listens for application shutdown messages on the "LLApp"
|
||||
* LLEventPump. Call close() to shut down this ThreadPool early.
|
||||
*/
|
||||
virtual void close();
|
||||
void close();
|
||||
|
||||
std::string getName() const { return mName; }
|
||||
size_t getWidth() const { return mThreads.size(); }
|
||||
|
|
@ -122,7 +122,7 @@ namespace LL
|
|||
size_t threads=1,
|
||||
size_t capacity=1024*1024,
|
||||
bool auto_shutdown = true):
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity), auto_shutdown)
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity, false), auto_shutdown)
|
||||
{}
|
||||
~ThreadPoolUsing() override {}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "llcoros.h"
|
||||
#include LLCOROS_MUTEX_HEADER
|
||||
#include "llerror.h"
|
||||
#include "llevents.h"
|
||||
#include "llexception.h"
|
||||
#include "stringize.h"
|
||||
|
||||
|
|
@ -30,11 +31,38 @@ using Lock = LLCoros::LockType;
|
|||
/*****************************************************************************
|
||||
* WorkQueueBase
|
||||
*****************************************************************************/
|
||||
LL::WorkQueueBase::WorkQueueBase(const std::string& name):
|
||||
super(makeName(name))
|
||||
LL::WorkQueueBase::WorkQueueBase(const std::string& name, bool auto_shutdown)
|
||||
: super(makeName(name))
|
||||
{
|
||||
// TODO: register for "LLApp" events so we can implicitly close() on
|
||||
// viewer shutdown.
|
||||
if (auto_shutdown)
|
||||
{
|
||||
// Register for "LLApp" events so we can implicitly close() on viewer shutdown
|
||||
std::string listener_name = "WorkQueue:" + getKey();
|
||||
LLEventPumps::instance().obtain("LLApp").listen(
|
||||
listener_name,
|
||||
[this](const LLSD& stat)
|
||||
{
|
||||
std::string status(stat["status"]);
|
||||
if (status != "running")
|
||||
{
|
||||
// Viewer is shutting down, close this queue
|
||||
LL_DEBUGS("WorkQueue") << getKey() << " closing on app shutdown" << LL_ENDL;
|
||||
close();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Store the listener name so we can unregister in the destructor
|
||||
mListenerName = listener_name;
|
||||
}
|
||||
}
|
||||
|
||||
LL::WorkQueueBase::~WorkQueueBase()
|
||||
{
|
||||
if (!mListenerName.empty() && !LLEventPumps::wasDeleted())
|
||||
{
|
||||
LLEventPumps::instance().obtain("LLApp").stopListening(mListenerName);
|
||||
}
|
||||
}
|
||||
|
||||
void LL::WorkQueueBase::runUntilClose()
|
||||
|
|
@ -182,14 +210,22 @@ void LL::WorkQueueBase::callWork(const Work& work)
|
|||
}
|
||||
catch (...)
|
||||
{
|
||||
// Stash any other kind of uncaught exception to be rethrown by main thread.
|
||||
LL_WARNS("LLCoros") << "Capturing and rethrowing uncaught exception in WorkQueueBase "
|
||||
<< getKey() << LL_ENDL;
|
||||
if (getKey() != "mainloop")
|
||||
{
|
||||
// Stash any other kind of uncaught exception to be rethrown by main thread.
|
||||
LL_WARNS("LLCoros") << "Capturing and rethrowing uncaught exception in WorkQueueBase "
|
||||
<< getKey() << LL_ENDL;
|
||||
|
||||
LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
|
||||
main_queue->post(
|
||||
// Bind the current exception, rethrow it in main loop.
|
||||
[exc = std::current_exception()]() { std::rethrow_exception(exc); });
|
||||
LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
|
||||
main_queue->post(
|
||||
// Bind the current exception, rethrow it in main loop.
|
||||
[exc = std::current_exception()]() { std::rethrow_exception(exc); });
|
||||
}
|
||||
else
|
||||
{
|
||||
// let main loop crash
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#endif // else LL_WINDOWS
|
||||
}
|
||||
|
|
@ -212,8 +248,8 @@ void LL::WorkQueueBase::checkCoroutine(const std::string& method)
|
|||
/*****************************************************************************
|
||||
* WorkQueue
|
||||
*****************************************************************************/
|
||||
LL::WorkQueue::WorkQueue(const std::string& name, size_t capacity):
|
||||
super(name),
|
||||
LL::WorkQueue::WorkQueue(const std::string& name, size_t capacity, bool auto_shutdown):
|
||||
super(name, auto_shutdown),
|
||||
mQueue(capacity)
|
||||
{
|
||||
}
|
||||
|
|
@ -261,8 +297,8 @@ bool LL::WorkQueue::tryPop_(Work& work)
|
|||
/*****************************************************************************
|
||||
* WorkSchedule
|
||||
*****************************************************************************/
|
||||
LL::WorkSchedule::WorkSchedule(const std::string& name, size_t capacity):
|
||||
super(name),
|
||||
LL::WorkSchedule::WorkSchedule(const std::string& name, size_t capacity, bool auto_shutdown):
|
||||
super(name, auto_shutdown),
|
||||
mQueue(capacity)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ namespace LL
|
|||
* You may omit the WorkQueueBase name, in which case a unique name is
|
||||
* synthesized; for practical purposes that makes it anonymous.
|
||||
*/
|
||||
WorkQueueBase(const std::string& name);
|
||||
WorkQueueBase(const std::string& name, bool auto_shutdown);
|
||||
|
||||
virtual ~WorkQueueBase();
|
||||
|
||||
/**
|
||||
* Since the point of WorkQueue is to pass work to some other worker
|
||||
|
|
@ -197,6 +199,9 @@ namespace LL
|
|||
private:
|
||||
virtual Work pop_() = 0;
|
||||
virtual bool tryPop_(Work&) = 0;
|
||||
|
||||
// Name used for the LLApp event listener (empty if not registered)
|
||||
std::string mListenerName;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
@ -212,7 +217,7 @@ namespace LL
|
|||
* You may omit the WorkQueue name, in which case a unique name is
|
||||
* synthesized; for practical purposes that makes it anonymous.
|
||||
*/
|
||||
WorkQueue(const std::string& name = std::string(), size_t capacity=1024);
|
||||
WorkQueue(const std::string& name = std::string(), size_t capacity=1024, bool auto_shutdown = true);
|
||||
|
||||
/**
|
||||
* Since the point of WorkQueue is to pass work to some other worker
|
||||
|
|
@ -282,7 +287,7 @@ namespace LL
|
|||
* You may omit the WorkSchedule name, in which case a unique name is
|
||||
* synthesized; for practical purposes that makes it anonymous.
|
||||
*/
|
||||
WorkSchedule(const std::string& name = std::string(), size_t capacity=1024);
|
||||
WorkSchedule(const std::string& name = std::string(), size_t capacity=1024, bool auto_shutdown = true);
|
||||
|
||||
/**
|
||||
* Since the point of WorkSchedule is to pass work to some other worker
|
||||
|
|
|
|||
|
|
@ -538,6 +538,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
long sslHostV(0L);
|
||||
long dnsCacheTimeout(-1L);
|
||||
long nobody(0L);
|
||||
curl_off_t lastModified(0L);
|
||||
|
||||
if (mReqOptions)
|
||||
{
|
||||
|
|
@ -546,6 +547,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
|
||||
dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
|
||||
nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;
|
||||
lastModified = (curl_off_t)mReqOptions->getLastModified();
|
||||
}
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
|
||||
|
||||
|
|
@ -554,6 +556,17 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
|
||||
|
||||
if (lastModified)
|
||||
{
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||
#if (LIBCURL_VERSION_NUM >= 0x073B00)
|
||||
// requires curl 7.59.0
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE_LARGE, lastModified);
|
||||
#else
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE, (long)lastModified);
|
||||
#endif
|
||||
}
|
||||
|
||||
// The Linksys WRT54G V5 router has an issue with frequent
|
||||
// DNS lookups from LAN machines. If they happen too often,
|
||||
// like for every HTTP request, the router gets annoyed after
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ HttpOptions::HttpOptions() :
|
|||
mVerifyPeer(sDefaultVerifyPeer),
|
||||
mVerifyHost(false),
|
||||
mDNSCacheTimeout(-1L),
|
||||
mLastModified(0),
|
||||
mNoBody(false)
|
||||
{}
|
||||
|
||||
|
|
@ -129,6 +130,11 @@ void HttpOptions::setHeadersOnly(bool nobody)
|
|||
}
|
||||
}
|
||||
|
||||
void HttpOptions::setLastModified(time_t lastModified)
|
||||
{
|
||||
mLastModified = lastModified;
|
||||
}
|
||||
|
||||
void HttpOptions::setDefaultSSLVerifyPeer(bool verify)
|
||||
{
|
||||
sDefaultVerifyPeer = verify;
|
||||
|
|
|
|||
|
|
@ -178,6 +178,13 @@ public:
|
|||
return mNoBody;
|
||||
}
|
||||
|
||||
// Default: 0
|
||||
void setLastModified(time_t lastModified);
|
||||
time_t getLastModified() const
|
||||
{
|
||||
return mLastModified;
|
||||
}
|
||||
|
||||
/// Sets default behavior for verifying that the name in the
|
||||
/// security certificate matches the name of the host contacted.
|
||||
/// Defaults false if not set, but should be set according to
|
||||
|
|
@ -199,6 +206,7 @@ protected:
|
|||
bool mVerifyHost;
|
||||
int mDNSCacheTimeout;
|
||||
bool mNoBody;
|
||||
time_t mLastModified;
|
||||
|
||||
static bool sDefaultVerifyPeer;
|
||||
}; // end class HttpOptions
|
||||
|
|
|
|||
|
|
@ -110,9 +110,10 @@ std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname)
|
|||
|
||||
std::vector<std::string> v;
|
||||
|
||||
if (exists(p))
|
||||
boost::system::error_code ec;
|
||||
if (exists(p, ec) && !ec.failed())
|
||||
{
|
||||
if (is_directory(p))
|
||||
if (is_directory(p, ec) && !ec.failed())
|
||||
{
|
||||
boost::filesystem::directory_iterator end_iter;
|
||||
for (boost::filesystem::directory_iterator dir_itr(p);
|
||||
|
|
|
|||
|
|
@ -558,6 +558,12 @@ bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
|
|||
LL_INFOS() << "Dropping alpha information during BMP encoding" << LL_ENDL;
|
||||
}
|
||||
|
||||
if (raw_image->isBufferInvalid())
|
||||
{
|
||||
setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
setSize(raw_image->getWidth(), raw_image->getHeight(), dst_components);
|
||||
|
||||
U8 magic[14];
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
|
|||
bool LLImageDimensionsInfo::getImageDimensionsBmp()
|
||||
{
|
||||
// Make sure the file is long enough.
|
||||
const S32 DATA_LEN = 26; // BMP header (14) + DIB header size (4) + width (4) + height (4)
|
||||
constexpr S32 DATA_LEN = 26; // BMP header (14) + DIB header size (4) + width (4) + height (4)
|
||||
if (!checkFileLength(DATA_LEN))
|
||||
{
|
||||
LL_WARNS() << "Premature end of file" << LL_ENDL;
|
||||
|
|
@ -105,7 +105,7 @@ bool LLImageDimensionsInfo::getImageDimensionsBmp()
|
|||
|
||||
bool LLImageDimensionsInfo::getImageDimensionsTga()
|
||||
{
|
||||
const S32 TGA_FILE_HEADER_SIZE = 12;
|
||||
constexpr S32 TGA_FILE_HEADER_SIZE = 12;
|
||||
|
||||
// Make sure the file is long enough.
|
||||
if (!checkFileLength(TGA_FILE_HEADER_SIZE + 1 /* width */ + 1 /* height */))
|
||||
|
|
@ -124,7 +124,7 @@ bool LLImageDimensionsInfo::getImageDimensionsTga()
|
|||
|
||||
bool LLImageDimensionsInfo::getImageDimensionsPng()
|
||||
{
|
||||
const S32 PNG_MAGIC_SIZE = 8;
|
||||
constexpr S32 PNG_MAGIC_SIZE = 8;
|
||||
|
||||
// Make sure the file is long enough.
|
||||
if (!checkFileLength(PNG_MAGIC_SIZE + 8 + sizeof(S32) * 2 /* width, height */))
|
||||
|
|
@ -134,7 +134,7 @@ bool LLImageDimensionsInfo::getImageDimensionsPng()
|
|||
}
|
||||
|
||||
// Read PNG signature.
|
||||
const U8 png_magic[PNG_MAGIC_SIZE] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
||||
constexpr U8 png_magic[PNG_MAGIC_SIZE] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
||||
U8 signature[PNG_MAGIC_SIZE];
|
||||
mInfile.read((void*)signature, PNG_MAGIC_SIZE);
|
||||
|
||||
|
|
@ -166,34 +166,36 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg()
|
|||
{
|
||||
sJpegErrorEncountered = false;
|
||||
clean();
|
||||
FILE *fp = LLFile::fopen(mSrcFilename, "rb");
|
||||
if (fp == NULL)
|
||||
FILE* fp = LLFile::fopen(mSrcFilename, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
setLastError("Unable to open file for reading", mSrcFilename);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make sure this is a JPEG file. */
|
||||
const size_t JPEG_MAGIC_SIZE = 2;
|
||||
const U8 jpeg_magic[JPEG_MAGIC_SIZE] = {0xFF, 0xD8};
|
||||
constexpr size_t JPEG_MAGIC_SIZE = 2;
|
||||
constexpr U8 jpeg_magic[JPEG_MAGIC_SIZE] = {0xFF, 0xD8};
|
||||
U8 signature[JPEG_MAGIC_SIZE];
|
||||
|
||||
if (fread(signature, sizeof(signature), 1, fp) != 1)
|
||||
{
|
||||
LL_WARNS() << "Premature end of file" << LL_ENDL;
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
if (memcmp(signature, jpeg_magic, JPEG_MAGIC_SIZE) != 0)
|
||||
{
|
||||
LL_WARNS() << "Not a JPEG" << LL_ENDL;
|
||||
mWarning = "texture_load_format_error";
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
fseek(fp, 0, SEEK_SET); // go back to start of the file
|
||||
|
||||
/* Init jpeg */
|
||||
jpeg_error_mgr jerr;
|
||||
jpeg_decompress_struct cinfo;
|
||||
jpeg_decompress_struct cinfo{};
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
// Call our function instead of exit() if Libjpeg encounters an error.
|
||||
// This is done to avoid crash in this case (STORM-472).
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class LLImageDimensionsInfo
|
|||
{
|
||||
public:
|
||||
LLImageDimensionsInfo():
|
||||
mData(NULL)
|
||||
mData(nullptr)
|
||||
,mHeight(0)
|
||||
,mWidth(0)
|
||||
{}
|
||||
|
|
@ -67,7 +67,7 @@ protected:
|
|||
{
|
||||
mInfile.close();
|
||||
delete[] mData;
|
||||
mData = NULL;
|
||||
mData = nullptr;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,6 +329,12 @@ bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
|
|||
{
|
||||
llassert_always(raw_image);
|
||||
|
||||
if (raw_image->isBufferInvalid())
|
||||
{
|
||||
setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 ncomponents = raw_image->getComponents();
|
||||
EFileFormat format;
|
||||
switch (ncomponents)
|
||||
|
|
|
|||
|
|
@ -281,10 +281,11 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r
|
|||
S32 height = (h > 0) ? h : 2048;
|
||||
S32 max_dimension = llmax(width, height); // Find largest dimension
|
||||
S32 block_area = MAX_BLOCK_SIZE * MAX_BLOCK_SIZE; // Calculated initial block area from established max block size (currently 64)
|
||||
block_area *= llmax((max_dimension / MAX_BLOCK_SIZE / max_components), 1); // Adjust initial block area by ratio of largest dimension to block size per component
|
||||
S32 totalbytes = (S32) (block_area * max_components * precision); // First block layer computed before loop without compression rate
|
||||
S32 block_layers = 1; // Start at layer 1 since first block layer is computed outside loop
|
||||
while (block_layers < 6) // Walk five layers for the five discards in JPEG2000
|
||||
S32 max_layers = (S32)llmax(llround(log2f((float)max_dimension) - log2f((float)MAX_BLOCK_SIZE)), 4); // Find number of powers of two between extents and block size to a minimum of 4
|
||||
block_area *= llmax(max_layers, 1); // Adjust initial block area by max number of layers
|
||||
S32 totalbytes = (S32) (MIN_LAYER_SIZE * max_components * precision); // Start estimation with a minimum reasonable size
|
||||
S32 block_layers = 0;
|
||||
while (block_layers <= max_layers) // Walk the layers
|
||||
{
|
||||
if (block_layers <= (5 - discard_level)) // Walk backwards from discard 5 to required discard layer.
|
||||
totalbytes += (S32) (block_area * max_components * precision * rate); // Add each block layer reduced by assumed compression rate
|
||||
|
|
|
|||
|
|
@ -499,6 +499,12 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
|
|||
|
||||
resetLastError();
|
||||
|
||||
if (raw_image->isBufferInvalid())
|
||||
{
|
||||
setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
LLImageDataSharedLock lockIn(raw_image);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
// this is defined so that we get static linking.
|
||||
#include "openjpeg.h"
|
||||
|
||||
#define MAX_ENCODED_DISCARD_LEVELS 5
|
||||
|
||||
// Factory function: see declaration in llimagej2c.cpp
|
||||
LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
|
||||
{
|
||||
|
|
@ -112,73 +110,96 @@ public:
|
|||
|
||||
static OPJ_SIZE_T opj_read(void * buffer, OPJ_SIZE_T bytes, void* user_data)
|
||||
{
|
||||
llassert(user_data);
|
||||
llassert(user_data && buffer);
|
||||
|
||||
JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
|
||||
OPJ_SIZE_T remainder = (jpeg_codec->size - jpeg_codec->offset);
|
||||
if (remainder <= 0)
|
||||
|
||||
if (jpeg_codec->offset < 0 || static_cast<OPJ_SIZE_T>(jpeg_codec->offset) >= jpeg_codec->size)
|
||||
{
|
||||
jpeg_codec->offset = jpeg_codec->size;
|
||||
// Indicate end of stream (hacky?)
|
||||
return (OPJ_OFF_T)-1;
|
||||
return static_cast<OPJ_SIZE_T>(-1); // Indicate EOF
|
||||
}
|
||||
OPJ_SIZE_T to_read = llclamp(U32(bytes), U32(0), U32(remainder));
|
||||
|
||||
OPJ_SIZE_T remainder = jpeg_codec->size - static_cast<OPJ_SIZE_T>(jpeg_codec->offset);
|
||||
OPJ_SIZE_T to_read = (bytes < remainder) ? bytes : remainder;
|
||||
|
||||
memcpy(buffer, jpeg_codec->buffer + jpeg_codec->offset, to_read);
|
||||
jpeg_codec->offset += to_read;
|
||||
|
||||
return to_read;
|
||||
}
|
||||
|
||||
static OPJ_SIZE_T opj_write(void * buffer, OPJ_SIZE_T bytes, void* user_data)
|
||||
{
|
||||
llassert(user_data);
|
||||
llassert(user_data && buffer);
|
||||
|
||||
JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
|
||||
OPJ_SIZE_T remainder = jpeg_codec->size - jpeg_codec->offset;
|
||||
if (remainder < bytes)
|
||||
OPJ_OFF_T required_offset = jpeg_codec->offset + static_cast<OPJ_OFF_T>(bytes);
|
||||
|
||||
// Overflow check
|
||||
if (required_offset < jpeg_codec->offset)
|
||||
return 0; // Overflow detected
|
||||
|
||||
// Resize if needed (exponential growth)
|
||||
if (required_offset > static_cast<OPJ_OFF_T>(jpeg_codec->size))
|
||||
{
|
||||
OPJ_SIZE_T new_size = jpeg_codec->size + (bytes - remainder);
|
||||
OPJ_SIZE_T new_size = jpeg_codec->size ? jpeg_codec->size : 1024;
|
||||
while (required_offset > static_cast<OPJ_OFF_T>(new_size))
|
||||
new_size *= 2;
|
||||
|
||||
const OPJ_SIZE_T MAX_BUFFER_SIZE = 512 * 1024 * 1024; // 512 MB, increase if needed
|
||||
if (new_size > MAX_BUFFER_SIZE) return 0;
|
||||
|
||||
U8* new_buffer = (U8*)ll_aligned_malloc_16(new_size);
|
||||
memcpy(new_buffer, jpeg_codec->buffer, jpeg_codec->offset);
|
||||
U8* old_buffer = jpeg_codec->buffer;
|
||||
if (!new_buffer) return 0; // Allocation failed
|
||||
|
||||
if (jpeg_codec->offset > 0)
|
||||
memcpy(new_buffer, jpeg_codec->buffer, static_cast<size_t>(jpeg_codec->offset));
|
||||
|
||||
ll_aligned_free_16(jpeg_codec->buffer);
|
||||
jpeg_codec->buffer = new_buffer;
|
||||
ll_aligned_free_16(old_buffer);
|
||||
jpeg_codec->size = new_size;
|
||||
}
|
||||
memcpy(jpeg_codec->buffer + jpeg_codec->offset, buffer, bytes);
|
||||
jpeg_codec->offset += bytes;
|
||||
|
||||
memcpy(jpeg_codec->buffer + jpeg_codec->offset, buffer, static_cast<size_t>(bytes));
|
||||
jpeg_codec->offset = required_offset;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static OPJ_OFF_T opj_skip(OPJ_OFF_T bytes, void* user_data)
|
||||
{
|
||||
llassert(user_data);
|
||||
JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
|
||||
jpeg_codec->offset += bytes;
|
||||
|
||||
if (jpeg_codec->offset > (OPJ_OFF_T)jpeg_codec->size)
|
||||
OPJ_OFF_T new_offset = jpeg_codec->offset + bytes;
|
||||
|
||||
if (new_offset < 0 || new_offset > static_cast<OPJ_OFF_T>(jpeg_codec->size))
|
||||
{
|
||||
jpeg_codec->offset = jpeg_codec->size;
|
||||
// Indicate end of stream
|
||||
return (OPJ_OFF_T)-1;
|
||||
}
|
||||
|
||||
if (jpeg_codec->offset < 0)
|
||||
{
|
||||
// Shouldn't be possible?
|
||||
jpeg_codec->offset = 0;
|
||||
// Clamp and indicate EOF or error
|
||||
jpeg_codec->offset = llclamp<OPJ_OFF_T>(new_offset, 0, static_cast<OPJ_OFF_T>(jpeg_codec->size));
|
||||
return (OPJ_OFF_T)-1;
|
||||
}
|
||||
|
||||
jpeg_codec->offset = new_offset;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static OPJ_BOOL opj_seek(OPJ_OFF_T bytes, void * user_data)
|
||||
static OPJ_BOOL opj_seek(OPJ_OFF_T offset, void * user_data)
|
||||
{
|
||||
llassert(user_data);
|
||||
JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
|
||||
jpeg_codec->offset = bytes;
|
||||
jpeg_codec->offset = llclamp(U32(jpeg_codec->offset), U32(0), U32(jpeg_codec->size));
|
||||
|
||||
if (offset < 0 || offset > static_cast<OPJ_OFF_T>(jpeg_codec->size))
|
||||
return OPJ_FALSE;
|
||||
|
||||
jpeg_codec->offset = offset;
|
||||
return OPJ_TRUE;
|
||||
}
|
||||
|
||||
static void opj_free_user_data(void * user_data)
|
||||
{
|
||||
llassert(user_data);
|
||||
|
||||
JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
|
||||
// Don't free, data is managed externally
|
||||
jpeg_codec->buffer = nullptr;
|
||||
|
|
@ -188,14 +209,54 @@ static void opj_free_user_data(void * user_data)
|
|||
|
||||
static void opj_free_user_data_write(void * user_data)
|
||||
{
|
||||
llassert(user_data);
|
||||
|
||||
JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data);
|
||||
// Free, data was allocated here
|
||||
ll_aligned_free_16(jpeg_codec->buffer);
|
||||
jpeg_codec->buffer = nullptr;
|
||||
if (jpeg_codec->buffer)
|
||||
{
|
||||
ll_aligned_free_16(jpeg_codec->buffer);
|
||||
jpeg_codec->buffer = nullptr;
|
||||
}
|
||||
jpeg_codec->size = 0;
|
||||
jpeg_codec->offset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimates the number of layers necessary depending on the image surface (w x h)
|
||||
*/
|
||||
static U32 estimate_num_layers(U32 surface)
|
||||
{
|
||||
if (surface <= 1024) return 2; // Tiny (≤32×32)
|
||||
else if (surface <= 16384) return 3; // Small (≤128×128)
|
||||
else if (surface <= 262144) return 4; // Medium (≤512×512)
|
||||
else if (surface <= 1048576) return 5; // Up to ~1MP
|
||||
else return 6; // Up to ~1.5–2MP
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameters.tcp_rates according to the number of layers and a last tcp_rate value (which equals to the final compression ratio).
|
||||
*
|
||||
* Example for 6 layers:
|
||||
*
|
||||
* i = 5, parameters.tcp_rates[6 - 1 - 5] = 8.0f * (1 << (5 << 1)) = 8192 // Layer 5 (lowest quality)
|
||||
* i = 4, parameters.tcp_rates[6 - 1 - 4] = 8.0f * (1 << (4 << 1)) = 2048 // Layer 4
|
||||
* i = 3, parameters.tcp_rates[6 - 1 - 3] = 8.0f * (1 << (3 << 1)) = 512 // Layer 3
|
||||
* i = 2, parameters.tcp_rates[6 - 1 - 2] = 8.0f * (1 << (2 << 1)) = 128 // Layer 2
|
||||
* i = 1, parameters.tcp_rates[6 - 1 - 1] = 8.0f * (1 << (1 << 1)) = 32 // Layer 1
|
||||
* i = 0, parameters.tcp_rates[6 - 1 - 0] = 8.0f * (1 << (0 << 1)) = 8 // Layer 0 (highest quality)
|
||||
*
|
||||
*/
|
||||
static void set_tcp_rates(opj_cparameters_t* parameters, U32 num_layers = 1, F32 last_tcp_rate = LAST_TCP_RATE)
|
||||
{
|
||||
parameters->tcp_numlayers = num_layers;
|
||||
|
||||
for (int i = num_layers - 1; i >= 0; i--)
|
||||
{
|
||||
parameters->tcp_rates[num_layers - 1 - i] = last_tcp_rate * static_cast<F32>(1 << (i << 1));
|
||||
}
|
||||
}
|
||||
|
||||
class JPEG2KDecode : public JPEG2KBase
|
||||
{
|
||||
public:
|
||||
|
|
@ -406,15 +467,16 @@ public:
|
|||
|
||||
opj_set_default_encoder_parameters(¶meters);
|
||||
parameters.cod_format = OPJ_CODEC_J2K;
|
||||
parameters.cp_disto_alloc = 1;
|
||||
parameters.prog_order = OPJ_RLCP; // should be the default, but, just in case
|
||||
parameters.cp_disto_alloc = 1; // enable rate allocation by distortion
|
||||
parameters.max_cs_size = 0; // do not cap max size because we're using tcp_rates and also irrelevant with lossless.
|
||||
|
||||
if (reversible)
|
||||
{
|
||||
parameters.max_cs_size = 0; // do not limit size for reversible compression
|
||||
parameters.irreversible = 0; // should be the default, but, just in case
|
||||
parameters.tcp_numlayers = 1;
|
||||
/* documentation seems to be wrong, should be 0.0f for lossless, not 1.0f
|
||||
see https://github.com/uclouvain/openjpeg/blob/39e8c50a2f9bdcf36810ee3d41bcbf1cc78968ae/src/lib/openjp2/j2k.c#L7755
|
||||
see https://github.com/uclouvain/openjpeg/blob/e7453e398b110891778d8da19209792c69ca7169/src/lib/openjp2/j2k.c#L7817
|
||||
*/
|
||||
parameters.tcp_rates[0] = 0.0f;
|
||||
}
|
||||
|
|
@ -474,53 +536,22 @@ public:
|
|||
opj_set_warning_handler(encoder, warning_callback, nullptr);
|
||||
opj_set_info_handler(encoder, info_callback, nullptr);
|
||||
|
||||
parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0;
|
||||
parameters.cod_format = OPJ_CODEC_J2K;
|
||||
parameters.prog_order = OPJ_RLCP;
|
||||
parameters.cp_disto_alloc = 1;
|
||||
parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0; // no color transform for RGBA images
|
||||
|
||||
|
||||
// if not lossless compression, computes tcp_numlayers and max_cs_size depending on the image dimensions
|
||||
if( parameters.irreversible ) {
|
||||
if( parameters.irreversible )
|
||||
{
|
||||
|
||||
// computes a number of layers
|
||||
U32 surface = rawImageIn.getWidth() * rawImageIn.getHeight();
|
||||
U32 nb_layers = 1;
|
||||
U32 s = 64*64;
|
||||
while (surface > s)
|
||||
{
|
||||
nb_layers++;
|
||||
s *= 4;
|
||||
}
|
||||
nb_layers = llclamp(nb_layers, 1, 6);
|
||||
|
||||
parameters.tcp_numlayers = nb_layers;
|
||||
parameters.tcp_rates[nb_layers - 1] = (U32)(1.f / DEFAULT_COMPRESSION_RATE); // 1:8 by default
|
||||
// gets the necessary number of layers
|
||||
U32 nb_layers = estimate_num_layers(surface);
|
||||
|
||||
// for each subsequent layer, computes its rate and adds surface * numcomps * 1/rate to the max_cs_size
|
||||
U32 max_cs_size = (U32)(surface * image->numcomps * DEFAULT_COMPRESSION_RATE);
|
||||
U32 multiplier;
|
||||
for (int i = nb_layers - 2; i >= 0; i--)
|
||||
{
|
||||
if( i == nb_layers - 2 )
|
||||
{
|
||||
multiplier = 15;
|
||||
}
|
||||
else if( i == nb_layers - 3 )
|
||||
{
|
||||
multiplier = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
multiplier = 2;
|
||||
}
|
||||
parameters.tcp_rates[i] = parameters.tcp_rates[i + 1] * multiplier;
|
||||
max_cs_size += (U32)(surface * image->numcomps * (1 / parameters.tcp_rates[i]));
|
||||
}
|
||||
// fills parameters.tcp_rates and updates parameters.tcp_numlayers
|
||||
set_tcp_rates(¶meters, nb_layers, LAST_TCP_RATE);
|
||||
|
||||
//ensure that we have at least a minimal size
|
||||
max_cs_size = llmax(max_cs_size, (U32)FIRST_PACKET_SIZE);
|
||||
|
||||
parameters.max_cs_size = max_cs_size;
|
||||
}
|
||||
|
||||
if (!opj_setup_encoder(encoder, ¶meters, image))
|
||||
|
|
@ -528,7 +559,20 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
U32 tile_count = (rawImageIn.getWidth() >> 6) * (rawImageIn.getHeight() >> 6);
|
||||
U32 width_tiles = (rawImageIn.getWidth() >> 6);
|
||||
U32 height_tiles = (rawImageIn.getHeight() >> 6);
|
||||
|
||||
// Allow images with a width or height that are MIN_IMAGE_SIZE <= x < 64
|
||||
if (width_tiles == 0 && (rawImageIn.getWidth() >= MIN_IMAGE_SIZE))
|
||||
{
|
||||
width_tiles = 1;
|
||||
}
|
||||
if (height_tiles == 0 && (rawImageIn.getHeight() >= MIN_IMAGE_SIZE))
|
||||
{
|
||||
height_tiles = 1;
|
||||
}
|
||||
|
||||
U32 tile_count = width_tiles * height_tiles;
|
||||
U32 data_size_guess = tile_count * TILE_SIZE;
|
||||
|
||||
// will be freed in opj_free_user_data_write
|
||||
|
|
@ -543,7 +587,7 @@ public:
|
|||
opj_stream_destroy(stream);
|
||||
}
|
||||
|
||||
stream = opj_stream_create(data_size_guess, false);
|
||||
stream = opj_stream_create(data_size_guess, OPJ_FALSE);
|
||||
if (!stream)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -584,17 +628,15 @@ public:
|
|||
|
||||
void setImage(const LLImageRaw& raw)
|
||||
{
|
||||
opj_image_cmptparm_t cmptparm[MAX_ENCODED_DISCARD_LEVELS];
|
||||
memset(&cmptparm[0], 0, MAX_ENCODED_DISCARD_LEVELS * sizeof(opj_image_cmptparm_t));
|
||||
|
||||
S32 numcomps = raw.getComponents();
|
||||
S32 width = raw.getWidth();
|
||||
S32 height = raw.getHeight();
|
||||
S32 width = raw.getWidth();
|
||||
S32 height = raw.getHeight();
|
||||
|
||||
std::vector<opj_image_cmptparm_t> cmptparm(numcomps);
|
||||
|
||||
for (S32 c = 0; c < numcomps; c++)
|
||||
{
|
||||
cmptparm[c].prec = 8;
|
||||
cmptparm[c].bpp = 8;
|
||||
cmptparm[c].prec = 8; // replaces .bpp
|
||||
cmptparm[c].sgnd = 0;
|
||||
cmptparm[c].dx = parameters.subsampling_dx;
|
||||
cmptparm[c].dy = parameters.subsampling_dy;
|
||||
|
|
@ -602,7 +644,7 @@ public:
|
|||
cmptparm[c].h = height;
|
||||
}
|
||||
|
||||
image = opj_image_create(numcomps, &cmptparm[0], OPJ_CLRSPC_SRGB);
|
||||
image = opj_image_create(numcomps, cmptparm.data(), OPJ_CLRSPC_SRGB);
|
||||
|
||||
image->x1 = width;
|
||||
image->y1 = height;
|
||||
|
|
@ -614,7 +656,7 @@ public:
|
|||
{
|
||||
for (S32 x = 0; x < width; x++)
|
||||
{
|
||||
const U8 *pixel = src_datap + (y*width + x) * numcomps;
|
||||
const U8 *pixel = src_datap + (y * width + x) * numcomps;
|
||||
for (S32 c = 0; c < numcomps; c++)
|
||||
{
|
||||
image->comps[c].data[i] = *pixel;
|
||||
|
|
@ -831,14 +873,19 @@ bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||
|
||||
bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible)
|
||||
{
|
||||
if (raw_image.isBufferInvalid())
|
||||
{
|
||||
base.setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
JPEG2KEncode encode(comment_text, reversible);
|
||||
bool encoded = encode.encode(raw_image, base);
|
||||
if (encoded)
|
||||
if (!encoded)
|
||||
{
|
||||
LL_WARNS() << "Openjpeg encoding implementation isn't complete, returning false" << LL_ENDL;
|
||||
LL_WARNS() << "Openjpeg encoding was unsuccessful, returning false" << LL_ENDL;
|
||||
}
|
||||
return encoded;
|
||||
//return false;
|
||||
}
|
||||
|
||||
bool LLImageJ2COJ::getMetadata(LLImageJ2C &base)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "llimagej2c.h"
|
||||
|
||||
const F32 LAST_TCP_RATE = 1.f/DEFAULT_COMPRESSION_RATE; // should be 8, giving a 1:8 ratio
|
||||
|
||||
class LLImageJ2COJ : public LLImageJ2CImpl
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llfoldertype.h"
|
||||
#include "lldictionary.h"
|
||||
#include "llmemory.h"
|
||||
#include "llsd.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -220,3 +221,21 @@ const std::string &LLFolderType::badLookup()
|
|||
static const std::string sBadLookup = "llfoldertype_bad_lookup";
|
||||
return sBadLookup;
|
||||
}
|
||||
|
||||
LLSD LLFolderType::getTypeNames()
|
||||
{
|
||||
LLSD type_names;
|
||||
for (S32 type = FT_TEXTURE; type < FT_COUNT; ++type)
|
||||
{
|
||||
if (lookupIsEnsembleType((LLFolderType::EType)type))
|
||||
continue;
|
||||
|
||||
const FolderEntry* entry = LLFolderDictionary::getInstance()->lookup((LLFolderType::EType)type);
|
||||
// skip llfoldertype_bad_lookup
|
||||
if (entry)
|
||||
{
|
||||
type_names.append(entry->mName);
|
||||
}
|
||||
}
|
||||
return type_names;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ public:
|
|||
|
||||
static const std::string& badLookup(); // error string when a lookup fails
|
||||
|
||||
static LLSD getTypeNames();
|
||||
|
||||
protected:
|
||||
LLFolderType() {}
|
||||
~LLFolderType() {}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ static const std::string INV_ITEM_ID_LABEL("item_id");
|
|||
static const std::string INV_FOLDER_ID_LABEL("cat_id");
|
||||
static const std::string INV_PARENT_ID_LABEL("parent_id");
|
||||
static const std::string INV_THUMBNAIL_LABEL("thumbnail");
|
||||
static const std::string INV_FAVORITE_LABEL("favorite");
|
||||
static const std::string INV_THUMBNAIL_ID_LABEL("thumbnail_id");
|
||||
static const std::string INV_ASSET_TYPE_LABEL("type");
|
||||
static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
|
||||
|
|
@ -59,6 +60,7 @@ static const std::string INV_LINKED_ID_LABEL("linked_id");
|
|||
static const std::string INV_SALE_INFO_LABEL("sale_info");
|
||||
static const std::string INV_FLAGS_LABEL("flags");
|
||||
static const std::string INV_CREATION_DATE_LABEL("created_at");
|
||||
static const std::string INV_TOGGLED_LABEL("toggled");
|
||||
|
||||
// key used by agent-inventory-service
|
||||
static const std::string INV_ASSET_TYPE_LABEL_WS("type_default");
|
||||
|
|
@ -82,14 +84,16 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
|
|||
mParentUUID(parent_uuid),
|
||||
mType(type),
|
||||
mName(name),
|
||||
mCreationDate(0)
|
||||
mCreationDate(0),
|
||||
mFavorite(false)
|
||||
{
|
||||
correctInventoryName(mName);
|
||||
}
|
||||
|
||||
LLInventoryObject::LLInventoryObject()
|
||||
: mType(LLAssetType::AT_NONE),
|
||||
mCreationDate(0)
|
||||
mCreationDate(0),
|
||||
mFavorite(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +108,7 @@ void LLInventoryObject::copyObject(const LLInventoryObject* other)
|
|||
mType = other->mType;
|
||||
mName = other->mName;
|
||||
mThumbnailUUID = other->mThumbnailUUID;
|
||||
mFavorite = other->mFavorite;
|
||||
}
|
||||
|
||||
const LLUUID& LLInventoryObject::getUUID() const
|
||||
|
|
@ -121,6 +126,11 @@ const LLUUID& LLInventoryObject::getThumbnailUUID() const
|
|||
return mThumbnailUUID;
|
||||
}
|
||||
|
||||
bool LLInventoryObject::getIsFavorite() const
|
||||
{
|
||||
return mFavorite;
|
||||
}
|
||||
|
||||
const std::string& LLInventoryObject::getName() const
|
||||
{
|
||||
return mName;
|
||||
|
|
@ -175,6 +185,11 @@ void LLInventoryObject::setThumbnailUUID(const LLUUID& thumbnail_uuid)
|
|||
mThumbnailUUID = thumbnail_uuid;
|
||||
}
|
||||
|
||||
void LLInventoryObject::setFavorite(bool favorite)
|
||||
{
|
||||
mFavorite = favorite;
|
||||
}
|
||||
|
||||
void LLInventoryObject::setType(LLAssetType::EType type)
|
||||
{
|
||||
mType = type;
|
||||
|
|
@ -247,6 +262,23 @@ bool LLInventoryObject::importLegacyStream(std::istream& input_stream)
|
|||
{
|
||||
setThumbnailUUID(LLUUID::null);
|
||||
}
|
||||
|
||||
if (metadata.has("favorite"))
|
||||
{
|
||||
const LLSD& favorite = metadata["favorite"];
|
||||
if (favorite.has("toggled"))
|
||||
{
|
||||
setFavorite(favorite["toggled"].asBoolean());
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("name", keyword))
|
||||
{
|
||||
|
|
@ -735,6 +767,23 @@ bool LLInventoryItem::importLegacyStream(std::istream& input_stream)
|
|||
{
|
||||
setThumbnailUUID(LLUUID::null);
|
||||
}
|
||||
|
||||
if (metadata.has("favorite"))
|
||||
{
|
||||
const LLSD& favorite = metadata["favorite"];
|
||||
if (favorite.has("toggled"))
|
||||
{
|
||||
setFavorite(favorite["toggled"].asBoolean());
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("inv_type", keyword))
|
||||
{
|
||||
|
|
@ -879,7 +928,7 @@ bool LLInventoryItem::exportLegacyStream(std::ostream& output_stream, bool inclu
|
|||
|
||||
LLSD LLInventoryItem::asLLSD() const
|
||||
{
|
||||
LLSD sd = LLSD();
|
||||
LLSD sd;
|
||||
asLLSD(sd);
|
||||
return sd;
|
||||
}
|
||||
|
|
@ -888,13 +937,18 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
|
|||
{
|
||||
sd[INV_ITEM_ID_LABEL] = mUUID;
|
||||
sd[INV_PARENT_ID_LABEL] = mParentUUID;
|
||||
sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions);
|
||||
ll_fill_sd_from_permissions(sd[INV_PERMISSIONS_LABEL], mPermissions);
|
||||
|
||||
if (mThumbnailUUID.notNull())
|
||||
{
|
||||
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
if (mFavorite)
|
||||
{
|
||||
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
|
||||
U32 mask = mPermissions.getMaskBase();
|
||||
if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
|
||||
|| (mAssetUUID.isNull()))
|
||||
|
|
@ -909,19 +963,22 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
|
|||
cipher.encrypt(shadow_id.mData, UUID_BYTES);
|
||||
sd[INV_SHADOW_ID_LABEL] = shadow_id;
|
||||
}
|
||||
sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
|
||||
sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType;
|
||||
sd[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
|
||||
const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
|
||||
if(!inv_type_str.empty())
|
||||
{
|
||||
sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
sd[INV_INVENTORY_TYPE_LABEL] = (LLSD::Integer)mInventoryType;
|
||||
}
|
||||
//sd[INV_FLAGS_LABEL] = (S32)mFlags;
|
||||
sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags);
|
||||
sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD();
|
||||
mSaleInfo.asLLSD(sd[INV_SALE_INFO_LABEL]);
|
||||
sd[INV_NAME_LABEL] = mName;
|
||||
sd[INV_DESC_LABEL] = mDescription;
|
||||
sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate;
|
||||
sd[INV_CREATION_DATE_LABEL] = (LLSD::Integer)mCreationDate;
|
||||
}
|
||||
|
||||
bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
||||
|
|
@ -937,6 +994,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
|||
|
||||
// TODO - figure out if this should be moved into the noclobber fields above
|
||||
mThumbnailUUID.setNull();
|
||||
mFavorite = false;
|
||||
mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
|
||||
|
||||
// iterate as map to avoid making unnecessary temp copies of everything
|
||||
LLSD::map_const_iterator i, end;
|
||||
|
|
@ -982,9 +1041,20 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i->first == INV_FAVORITE_LABEL)
|
||||
{
|
||||
const LLSD& favorite_map = i->second;
|
||||
const std::string w = INV_TOGGLED_LABEL;
|
||||
if (favorite_map.has(w))
|
||||
{
|
||||
mFavorite = favorite_map[w].asBoolean();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i->first == INV_PERMISSIONS_LABEL)
|
||||
{
|
||||
mPermissions = ll_permissions_from_sd(i->second);
|
||||
mPermissions.importLLSD(i->second);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1177,6 +1247,11 @@ LLSD LLInventoryCategory::asLLSD() const
|
|||
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
if (mFavorite)
|
||||
{
|
||||
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
|
|
@ -1188,11 +1263,17 @@ LLSD LLInventoryCategory::asAISCreateCatLLSD() const
|
|||
S8 type = static_cast<S8>(mPreferredType);
|
||||
sd[INV_ASSET_TYPE_LABEL_WS] = type;
|
||||
sd[INV_NAME_LABEL] = mName;
|
||||
|
||||
if (mThumbnailUUID.notNull())
|
||||
{
|
||||
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
if (mFavorite)
|
||||
{
|
||||
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
|
|
@ -1240,6 +1321,17 @@ bool LLInventoryCategory::fromLLSD(const LLSD& sd)
|
|||
mThumbnailUUID = sd[w];
|
||||
}
|
||||
}
|
||||
mFavorite = false;
|
||||
w = INV_FAVORITE_LABEL;
|
||||
if (sd.has(w))
|
||||
{
|
||||
const LLSD& favorite_map = sd[w];
|
||||
w = INV_TOGGLED_LABEL;
|
||||
if (favorite_map.has(w))
|
||||
{
|
||||
mFavorite = favorite_map[w].asBoolean();
|
||||
}
|
||||
}
|
||||
w = INV_ASSET_TYPE_LABEL;
|
||||
if (sd.has(w))
|
||||
{
|
||||
|
|
@ -1362,6 +1454,23 @@ bool LLInventoryCategory::importLegacyStream(std::istream& input_stream)
|
|||
{
|
||||
setThumbnailUUID(LLUUID::null);
|
||||
}
|
||||
|
||||
if (metadata.has("favorite"))
|
||||
{
|
||||
const LLSD& favorite = metadata["favorite"];
|
||||
if (favorite.has("toggled"))
|
||||
{
|
||||
setFavorite(favorite["toggled"].asBoolean());
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1396,12 +1505,11 @@ bool LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, bool)
|
|||
return true;
|
||||
}
|
||||
|
||||
LLSD LLInventoryCategory::exportLLSD() const
|
||||
void LLInventoryCategory::exportLLSD(LLSD& cat_data) const
|
||||
{
|
||||
LLSD cat_data;
|
||||
cat_data[INV_FOLDER_ID_LABEL] = mUUID;
|
||||
cat_data[INV_PARENT_ID_LABEL] = mParentUUID;
|
||||
cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
|
||||
cat_data[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
|
||||
cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);
|
||||
cat_data[INV_NAME_LABEL] = mName;
|
||||
|
||||
|
|
@ -1409,49 +1517,76 @@ LLSD LLInventoryCategory::exportLLSD() const
|
|||
{
|
||||
cat_data[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
return cat_data;
|
||||
if (mFavorite)
|
||||
{
|
||||
cat_data[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
|
||||
bool LLInventoryCategory::importLLSDMap(const LLSD& cat_data)
|
||||
{
|
||||
if (cat_data.has(INV_FOLDER_ID_LABEL))
|
||||
LLSD::map_const_iterator i, end;
|
||||
end = cat_data.endMap();
|
||||
for ( i = cat_data.beginMap(); i != end; ++i)
|
||||
{
|
||||
setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID());
|
||||
importLLSD(i->first, i->second);
|
||||
}
|
||||
if (cat_data.has(INV_PARENT_ID_LABEL))
|
||||
{
|
||||
setParent(cat_data[INV_PARENT_ID_LABEL].asUUID());
|
||||
}
|
||||
if (cat_data.has(INV_ASSET_TYPE_LABEL))
|
||||
{
|
||||
setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString()));
|
||||
}
|
||||
if (cat_data.has(INV_PREFERRED_TYPE_LABEL))
|
||||
{
|
||||
setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString()));
|
||||
}
|
||||
if (cat_data.has(INV_THUMBNAIL_LABEL))
|
||||
{
|
||||
LLUUID thumbnail_uuid;
|
||||
const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL];
|
||||
if (thumbnail_data.has(INV_ASSET_ID_LABEL))
|
||||
{
|
||||
thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID();
|
||||
}
|
||||
setThumbnailUUID(thumbnail_uuid);
|
||||
}
|
||||
if (cat_data.has(INV_NAME_LABEL))
|
||||
{
|
||||
mName = cat_data[INV_NAME_LABEL].asString();
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLInventoryCategory::importLLSD(const std::string& label, const LLSD& value)
|
||||
{
|
||||
if (label == INV_FOLDER_ID_LABEL)
|
||||
{
|
||||
setUUID(value.asUUID());
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_PARENT_ID_LABEL)
|
||||
{
|
||||
setParent(value.asUUID());
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_ASSET_TYPE_LABEL)
|
||||
{
|
||||
setType(LLAssetType::lookup(value.asString()));
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_PREFERRED_TYPE_LABEL)
|
||||
{
|
||||
setPreferredType(LLFolderType::lookup(value.asString()));
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_THUMBNAIL_LABEL)
|
||||
{
|
||||
LLUUID thumbnail_uuid;
|
||||
if (value.has(INV_ASSET_ID_LABEL))
|
||||
{
|
||||
thumbnail_uuid = value[INV_ASSET_ID_LABEL].asUUID();
|
||||
}
|
||||
setThumbnailUUID(thumbnail_uuid);
|
||||
return true;
|
||||
}
|
||||
if (label == INV_FAVORITE_LABEL)
|
||||
{
|
||||
bool favorite = false;
|
||||
if (value.has(INV_TOGGLED_LABEL))
|
||||
{
|
||||
favorite = value[INV_TOGGLED_LABEL].asBoolean();
|
||||
}
|
||||
setFavorite(favorite);
|
||||
}
|
||||
else if (label == INV_NAME_LABEL)
|
||||
{
|
||||
mName = value.asString();
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
/// Local function definitions for testing purposes
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public:
|
|||
virtual const LLUUID& getLinkedUUID() const; // inventoryID that this item points to, else this item's inventoryID
|
||||
const LLUUID& getParentUUID() const;
|
||||
virtual const LLUUID& getThumbnailUUID() const;
|
||||
virtual bool getIsFavorite() const;
|
||||
virtual const std::string& getName() const;
|
||||
virtual LLAssetType::EType getType() const;
|
||||
LLAssetType::EType getActualType() const; // bypasses indirection for linked items
|
||||
|
|
@ -86,6 +87,7 @@ public:
|
|||
virtual void rename(const std::string& new_name);
|
||||
void setParent(const LLUUID& new_parent);
|
||||
virtual void setThumbnailUUID(const LLUUID& thumbnail_uuid);
|
||||
virtual void setFavorite(bool favorite);
|
||||
void setType(LLAssetType::EType type);
|
||||
virtual void setCreationDate(time_t creation_date_utc); // only stored for items
|
||||
|
||||
|
|
@ -111,6 +113,7 @@ protected:
|
|||
LLUUID mUUID;
|
||||
LLUUID mParentUUID; // Parent category. Root categories have LLUUID::NULL.
|
||||
LLUUID mThumbnailUUID;
|
||||
bool mFavorite;
|
||||
LLAssetType::EType mType;
|
||||
std::string mName;
|
||||
time_t mCreationDate; // seconds from 1/1/1970, UTC
|
||||
|
|
@ -270,8 +273,9 @@ public:
|
|||
virtual bool importLegacyStream(std::istream& input_stream);
|
||||
virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
|
||||
|
||||
LLSD exportLLSD() const;
|
||||
bool importLLSD(const LLSD& cat_data);
|
||||
virtual void exportLLSD(LLSD& sd) const;
|
||||
bool importLLSDMap(const LLSD& cat_data);
|
||||
virtual bool importLLSD(const std::string& label, const LLSD& value);
|
||||
//--------------------------------------------------------------------
|
||||
// Member Variables
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -285,6 +289,7 @@ protected:
|
|||
//
|
||||
// These functions convert between structured data and an inventory
|
||||
// item, appropriate for serialization.
|
||||
// Not up to date (no favorites, nor thumbnails), for testing purposes
|
||||
//-----------------------------------------------------------------------------
|
||||
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item);
|
||||
LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat);
|
||||
|
|
|
|||
|
|
@ -37,98 +37,98 @@
|
|||
#include "llsettingsdaycycle.h"
|
||||
|
||||
// Grid out of which parcels taken is stepped every 4 meters.
|
||||
const F32 PARCEL_GRID_STEP_METERS = 4.f;
|
||||
constexpr F32 PARCEL_GRID_STEP_METERS = 4.f;
|
||||
|
||||
// Area of one "square" of parcel
|
||||
const S32 PARCEL_UNIT_AREA = 16;
|
||||
constexpr S32 PARCEL_UNIT_AREA = 16;
|
||||
|
||||
// Height _above_ground_ that parcel boundary ends
|
||||
const F32 PARCEL_HEIGHT = 50.f;
|
||||
constexpr F32 PARCEL_HEIGHT = 50.f;
|
||||
|
||||
//Height above ground which parcel boundries exist for explicitly banned avatars
|
||||
const F32 BAN_HEIGHT = 5000.f;
|
||||
constexpr F32 BAN_HEIGHT = 5000.f;
|
||||
|
||||
// Maximum number of entries in an access list
|
||||
const S32 PARCEL_MAX_ACCESS_LIST = 300;
|
||||
constexpr S32 PARCEL_MAX_ACCESS_LIST = 300;
|
||||
//Maximum number of entires in an update packet
|
||||
//for access/ban lists.
|
||||
const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;
|
||||
constexpr F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f;
|
||||
|
||||
// Maximum number of experiences
|
||||
const S32 PARCEL_MAX_EXPERIENCE_LIST = 24;
|
||||
constexpr S32 PARCEL_MAX_EXPERIENCE_LIST = 24;
|
||||
|
||||
// Weekly charge for listing a parcel in the directory
|
||||
const S32 PARCEL_DIRECTORY_FEE = 30;
|
||||
constexpr S32 PARCEL_DIRECTORY_FEE = 30;
|
||||
|
||||
const S32 PARCEL_PASS_PRICE_DEFAULT = 10;
|
||||
const F32 PARCEL_PASS_HOURS_DEFAULT = 1.f;
|
||||
constexpr S32 PARCEL_PASS_PRICE_DEFAULT = 10;
|
||||
constexpr F32 PARCEL_PASS_HOURS_DEFAULT = 1.f;
|
||||
|
||||
// Number of "chunks" in which parcel overlay data is sent
|
||||
// Chunk 0 = southern rows, entire width
|
||||
const S32 PARCEL_OVERLAY_CHUNKS = 4;
|
||||
constexpr S32 PARCEL_OVERLAY_CHUNKS = 4;
|
||||
|
||||
// Bottom three bits are a color index for the land overlay
|
||||
const U8 PARCEL_COLOR_MASK = 0x07;
|
||||
const U8 PARCEL_PUBLIC = 0x00;
|
||||
const U8 PARCEL_OWNED = 0x01;
|
||||
const U8 PARCEL_GROUP = 0x02;
|
||||
const U8 PARCEL_SELF = 0x03;
|
||||
const U8 PARCEL_FOR_SALE = 0x04;
|
||||
const U8 PARCEL_AUCTION = 0x05;
|
||||
constexpr U8 PARCEL_COLOR_MASK = 0x07;
|
||||
constexpr U8 PARCEL_PUBLIC = 0x00;
|
||||
constexpr U8 PARCEL_OWNED = 0x01;
|
||||
constexpr U8 PARCEL_GROUP = 0x02;
|
||||
constexpr U8 PARCEL_SELF = 0x03;
|
||||
constexpr U8 PARCEL_FOR_SALE = 0x04;
|
||||
constexpr U8 PARCEL_AUCTION = 0x05;
|
||||
// unused 0x06
|
||||
// unused 0x07
|
||||
// flag, unused 0x08
|
||||
const U8 PARCEL_HIDDENAVS = 0x10; // avatars not visible outside of parcel. Used for 'see avs' feature, but must be off for compatibility
|
||||
const U8 PARCEL_SOUND_LOCAL = 0x20;
|
||||
const U8 PARCEL_WEST_LINE = 0x40; // flag, property line on west edge
|
||||
const U8 PARCEL_SOUTH_LINE = 0x80; // flag, property line on south edge
|
||||
constexpr U8 PARCEL_HIDDENAVS = 0x10; // avatars not visible outside of parcel. Used for 'see avs' feature, but must be off for compatibility
|
||||
constexpr U8 PARCEL_SOUND_LOCAL = 0x20;
|
||||
constexpr U8 PARCEL_WEST_LINE = 0x40; // flag, property line on west edge
|
||||
constexpr U8 PARCEL_SOUTH_LINE = 0x80; // flag, property line on south edge
|
||||
|
||||
// Transmission results for parcel properties
|
||||
const S32 PARCEL_RESULT_NO_DATA = -1;
|
||||
const S32 PARCEL_RESULT_SUCCESS = 0; // got exactly one parcel
|
||||
const S32 PARCEL_RESULT_MULTIPLE = 1; // got multiple parcels
|
||||
constexpr S32 PARCEL_RESULT_NO_DATA = -1;
|
||||
constexpr S32 PARCEL_RESULT_SUCCESS = 0; // got exactly one parcel
|
||||
constexpr S32 PARCEL_RESULT_MULTIPLE = 1; // got multiple parcels
|
||||
|
||||
const S32 SELECTED_PARCEL_SEQ_ID = -10000;
|
||||
const S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID = -20000;
|
||||
const S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000;
|
||||
const S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID = -40000;
|
||||
const S32 HOVERED_PARCEL_SEQ_ID = -50000;
|
||||
constexpr S32 SELECTED_PARCEL_SEQ_ID = -10000;
|
||||
constexpr S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID = -20000;
|
||||
constexpr S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000;
|
||||
constexpr S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID = -40000;
|
||||
constexpr S32 HOVERED_PARCEL_SEQ_ID = -50000;
|
||||
|
||||
const U32 RT_NONE = 0x1 << 0;
|
||||
const U32 RT_OWNER = 0x1 << 1;
|
||||
const U32 RT_GROUP = 0x1 << 2;
|
||||
const U32 RT_OTHER = 0x1 << 3;
|
||||
const U32 RT_LIST = 0x1 << 4;
|
||||
const U32 RT_SELL = 0x1 << 5;
|
||||
constexpr U32 RT_NONE = 0x1 << 0;
|
||||
constexpr U32 RT_OWNER = 0x1 << 1;
|
||||
constexpr U32 RT_GROUP = 0x1 << 2;
|
||||
constexpr U32 RT_OTHER = 0x1 << 3;
|
||||
constexpr U32 RT_LIST = 0x1 << 4;
|
||||
constexpr U32 RT_SELL = 0x1 << 5;
|
||||
|
||||
const S32 INVALID_PARCEL_ID = -1;
|
||||
constexpr S32 INVALID_PARCEL_ID = -1;
|
||||
|
||||
const S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2;
|
||||
constexpr S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2;
|
||||
// if Region settings are used, parcel env. version is -1
|
||||
const S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1;
|
||||
constexpr S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1;
|
||||
|
||||
// Timeouts for parcels
|
||||
// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000
|
||||
const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);
|
||||
constexpr U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);
|
||||
// ***** TESTING is 10 minutes
|
||||
//const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000);
|
||||
|
||||
// group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000
|
||||
const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000);
|
||||
constexpr U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000);
|
||||
// ***** TESTING is 10 minutes
|
||||
//const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000);
|
||||
|
||||
// default sale timeout is 2 days -> 172800000000
|
||||
const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000);
|
||||
constexpr U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000);
|
||||
// ***** TESTING is 10 minutes
|
||||
//const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000);
|
||||
|
||||
// more grace period extensions.
|
||||
const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000);
|
||||
constexpr U64 SEVEN_DAYS_IN_USEC = U64L(604800000000);
|
||||
|
||||
// if more than 100,000s before sale revert, and no extra extension
|
||||
// has been given, go ahead and extend it more. That's about 1.2 days.
|
||||
const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000;
|
||||
constexpr S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000;
|
||||
|
||||
|
||||
|
||||
|
|
@ -250,9 +250,9 @@ public:
|
|||
void setMediaURL(const std::string& url);
|
||||
void setMediaType(const std::string& type);
|
||||
void setMediaDesc(const std::string& desc);
|
||||
void setMediaID(const LLUUID& id) { mMediaID = id; }
|
||||
void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; }
|
||||
void setMediaLoop (U8 loop) { mMediaLoop = loop; }
|
||||
void setMediaID(const LLUUID& id) { mMediaID = id; }
|
||||
void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; }
|
||||
void setMediaLoop(U8 loop) { mMediaLoop = loop; }
|
||||
void setMediaWidth(S32 width);
|
||||
void setMediaHeight(S32 height);
|
||||
void setMediaCurrentURL(const std::string& url);
|
||||
|
|
@ -262,6 +262,8 @@ public:
|
|||
|
||||
void setMediaURLResetTimer(F32 time);
|
||||
virtual void setLocalID(S32 local_id);
|
||||
void setRegionID(const LLUUID& id) { mRegionID = id; }
|
||||
const LLUUID& getRegionID() const { return mRegionID; }
|
||||
|
||||
// blow away all the extra stuff lurking in parcels, including urls, access lists, etc
|
||||
void clearParcel();
|
||||
|
|
@ -651,6 +653,7 @@ public:
|
|||
S32 mLocalID;
|
||||
LLUUID mBanListTransactionID;
|
||||
LLUUID mAccessListTransactionID;
|
||||
LLUUID mRegionID;
|
||||
std::map<LLUUID,LLAccessEntry> mAccessList;
|
||||
std::map<LLUUID,LLAccessEntry> mBanList;
|
||||
std::map<LLUUID,LLAccessEntry> mTempBanList;
|
||||
|
|
|
|||
|
|
@ -704,6 +704,79 @@ bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const
|
|||
return true;
|
||||
}
|
||||
|
||||
static const std::string PERM_CREATOR_ID_LABEL("creator_id");
|
||||
static const std::string PERM_OWNER_ID_LABEL("owner_id");
|
||||
static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
|
||||
static const std::string PERM_GROUP_ID_LABEL("group_id");
|
||||
static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
|
||||
static const std::string PERM_BASE_MASK_LABEL("base_mask");
|
||||
static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
|
||||
static const std::string PERM_GROUP_MASK_LABEL("group_mask");
|
||||
static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
|
||||
static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
|
||||
|
||||
void LLPermissions::importLLSD(const LLSD& sd_perm)
|
||||
{
|
||||
LLSD::map_const_iterator i, end;
|
||||
end = sd_perm.endMap();
|
||||
for (i = sd_perm.beginMap(); i != end; ++i)
|
||||
{
|
||||
const std::string& label = i->first;
|
||||
if (label == PERM_CREATOR_ID_LABEL)
|
||||
{
|
||||
mCreator = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_OWNER_ID_LABEL)
|
||||
{
|
||||
mOwner = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_LAST_OWNER_ID_LABEL)
|
||||
{
|
||||
mLastOwner = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_GROUP_ID_LABEL)
|
||||
{
|
||||
mGroup = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_BASE_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskBase = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_OWNER_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskOwner = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_EVERYONE_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskEveryone = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_GROUP_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskGroup = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_NEXT_OWNER_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskNextOwner = mask;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fix();
|
||||
}
|
||||
|
||||
bool LLPermissions::operator==(const LLPermissions &rhs) const
|
||||
{
|
||||
return
|
||||
|
|
@ -998,55 +1071,30 @@ std::string mask_to_string(U32 mask)
|
|||
///----------------------------------------------------------------------------
|
||||
/// exported functions
|
||||
///----------------------------------------------------------------------------
|
||||
static const std::string PERM_CREATOR_ID_LABEL("creator_id");
|
||||
static const std::string PERM_OWNER_ID_LABEL("owner_id");
|
||||
static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
|
||||
static const std::string PERM_GROUP_ID_LABEL("group_id");
|
||||
static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
|
||||
static const std::string PERM_BASE_MASK_LABEL("base_mask");
|
||||
static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
|
||||
static const std::string PERM_GROUP_MASK_LABEL("group_mask");
|
||||
static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
|
||||
static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
|
||||
|
||||
LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
|
||||
{
|
||||
LLSD rv;
|
||||
ll_fill_sd_from_permissions(rv, perm);
|
||||
return rv;
|
||||
}
|
||||
void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm)
|
||||
{
|
||||
rv[PERM_CREATOR_ID_LABEL] = perm.getCreator();
|
||||
rv[PERM_OWNER_ID_LABEL] = perm.getOwner();
|
||||
rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner();
|
||||
rv[PERM_GROUP_ID_LABEL] = perm.getGroup();
|
||||
rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned();
|
||||
rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase();
|
||||
rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner();
|
||||
rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup();
|
||||
rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone();
|
||||
rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner();
|
||||
return rv;
|
||||
rv[PERM_BASE_MASK_LABEL] = (LLSD::Integer)perm.getMaskBase();
|
||||
rv[PERM_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskOwner();
|
||||
rv[PERM_GROUP_MASK_LABEL] = (LLSD::Integer)perm.getMaskGroup();
|
||||
rv[PERM_EVERYONE_MASK_LABEL] = (LLSD::Integer)perm.getMaskEveryone();
|
||||
rv[PERM_NEXT_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskNextOwner();
|
||||
}
|
||||
|
||||
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
|
||||
{
|
||||
LLPermissions rv;
|
||||
rv.init(
|
||||
sd_perm[PERM_CREATOR_ID_LABEL].asUUID(),
|
||||
sd_perm[PERM_OWNER_ID_LABEL].asUUID(),
|
||||
sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(),
|
||||
sd_perm[PERM_GROUP_ID_LABEL].asUUID());
|
||||
|
||||
// We do a cast to U32 here since LLSD does not attempt to
|
||||
// represent unsigned ints.
|
||||
PermissionMask mask;
|
||||
mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger());
|
||||
rv.setMaskBase(mask);
|
||||
mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger());
|
||||
rv.setMaskOwner(mask);
|
||||
mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger());
|
||||
rv.setMaskEveryone(mask);
|
||||
mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger());
|
||||
rv.setMaskGroup(mask);
|
||||
mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger());
|
||||
rv.setMaskNext(mask);
|
||||
rv.fix();
|
||||
rv.importLLSD(sd_perm);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ public:
|
|||
bool importLegacyStream(std::istream& input_stream);
|
||||
bool exportLegacyStream(std::ostream& output_stream) const;
|
||||
|
||||
void importLLSD(const LLSD& sd_perm);
|
||||
|
||||
bool operator==(const LLPermissions &rhs) const;
|
||||
bool operator!=(const LLPermissions &rhs) const;
|
||||
|
||||
|
|
@ -435,6 +437,7 @@ protected:
|
|||
// like 'creator_id', 'owner_id', etc, with the value copied from the
|
||||
// permission object.
|
||||
LLSD ll_create_sd_from_permissions(const LLPermissions& perm);
|
||||
void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm);
|
||||
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -90,15 +90,20 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
|
|||
LLSD LLSaleInfo::asLLSD() const
|
||||
{
|
||||
LLSD sd;
|
||||
asLLSD(sd);
|
||||
return sd;
|
||||
}
|
||||
|
||||
void LLSaleInfo::asLLSD(LLSD& sd) const
|
||||
{
|
||||
const char* type = lookup(mSaleType);
|
||||
if (!type)
|
||||
{
|
||||
LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL;
|
||||
type = lookup(LLSaleInfo::FS_NOT);
|
||||
}
|
||||
sd["sale_type"] = type;
|
||||
sd["sale_type"] = std::string(type);
|
||||
sd["sale_price"] = mSalePrice;
|
||||
return sd;
|
||||
}
|
||||
|
||||
bool LLSaleInfo::fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask)
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public:
|
|||
|
||||
bool exportLegacyStream(std::ostream& output_stream) const;
|
||||
LLSD asLLSD() const;
|
||||
void asLLSD(LLSD &sd) const;
|
||||
operator LLSD() const { return asLLSD(); }
|
||||
bool fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask);
|
||||
bool importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask);
|
||||
|
|
|
|||
|
|
@ -361,14 +361,12 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD
|
|||
new_array = q.getValue();
|
||||
}
|
||||
else
|
||||
{ // TODO: We could expand this to inspect the type and do a deep lerp based on type.
|
||||
// for now assume a heterogeneous array of reals.
|
||||
{
|
||||
size_t len = std::max(value.size(), other_value.size());
|
||||
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
|
||||
new_array[i] = lerp((F32)value[i].asReal(), (F32)other_value[i].asReal(), (F32)mix);
|
||||
new_array[i] = interpolateSDValue(key_name, value[i], other_value[i], defaults, mix, skip, slerps);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ protected:
|
|||
|
||||
private:
|
||||
bool mLLSDDirty;
|
||||
bool mDirty;
|
||||
bool mDirty; // gates updateSettings
|
||||
bool mReplaced; // super dirty!
|
||||
|
||||
static LLSD combineSDMaps(const LLSD &first, const LLSD &other);
|
||||
|
|
|
|||
|
|
@ -657,15 +657,16 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf)
|
|||
mHasLegacyHaze |= lerp_legacy_float(mHazeDensity, mLegacyHazeDensity, other->mHazeDensity, other->mLegacyHazeDensity, 0.7f, (F32)blendf);
|
||||
mHasLegacyHaze |= lerp_legacy_float(mDistanceMultiplier, mLegacyDistanceMultiplier, other->mDistanceMultiplier, other->mLegacyDistanceMultiplier, 0.8f, (F32)blendf);
|
||||
mHasLegacyHaze |= lerp_legacy_float(mDensityMultiplier, mLegacyDensityMultiplier, other->mDensityMultiplier, other->mLegacyDensityMultiplier, 0.0001f, (F32)blendf);
|
||||
mHasLegacyHaze |= lerp_legacy_color(mAmbientColor, mLegacyAmbientColor, other->mAmbientColor, other->mLegacyAmbientColor, LLColor3(0.25f, 0.25f, 0.25f), (F32)blendf);
|
||||
mHasLegacyHaze |= lerp_legacy_color(mBlueHorizon, mLegacyBlueHorizon, other->mBlueHorizon, other->mLegacyBlueHorizon, LLColor3(0.4954f, 0.4954f, 0.6399f), (F32)blendf);
|
||||
mHasLegacyHaze |= lerp_legacy_color(mBlueDensity, mLegacyBlueDensity, other->mBlueDensity, other->mLegacyBlueDensity, LLColor3(0.2447f, 0.4487f, 0.7599f), (F32)blendf);
|
||||
|
||||
parammapping_t defaults = other->getParameterMap();
|
||||
stringset_t skip = getSkipInterpolateKeys();
|
||||
stringset_t slerps = getSlerpKeys();
|
||||
mAbsorptionConfigs = interpolateSDMap(mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps);
|
||||
mMieConfigs = interpolateSDMap(mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps);
|
||||
mRayleighConfigs = interpolateSDMap(mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps);
|
||||
mAbsorptionConfigs = interpolateSDValue("absorption_config", mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps);
|
||||
mMieConfigs = interpolateSDValue("mie_config", mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps);
|
||||
mRayleighConfigs = interpolateSDValue("rayleigh_config", mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps);
|
||||
|
||||
setDirtyFlag(true);
|
||||
setReplaced();
|
||||
|
|
@ -1932,6 +1933,7 @@ LLUUID LLSettingsSky::getCloudNoiseTextureId() const
|
|||
void LLSettingsSky::setCloudNoiseTextureId(const LLUUID &id)
|
||||
{
|
||||
mCloudTextureId = id;
|
||||
setDirtyFlag(true);
|
||||
setLLSDDirty();
|
||||
}
|
||||
|
||||
|
|
@ -1976,6 +1978,7 @@ LLVector2 LLSettingsSky::getCloudScrollRate() const
|
|||
void LLSettingsSky::setCloudScrollRate(const LLVector2 &val)
|
||||
{
|
||||
mScrollRate = val;
|
||||
setDirtyFlag(true);
|
||||
setLLSDDirty();
|
||||
}
|
||||
|
||||
|
|
@ -2134,6 +2137,7 @@ LLUUID LLSettingsSky::getMoonTextureId() const
|
|||
void LLSettingsSky::setMoonTextureId(LLUUID id)
|
||||
{
|
||||
mMoonTextureId = id;
|
||||
setDirtyFlag(true);
|
||||
setLLSDDirty();
|
||||
}
|
||||
|
||||
|
|
@ -2218,6 +2222,7 @@ LLUUID LLSettingsSky::getSunTextureId() const
|
|||
void LLSettingsSky::setSunTextureId(LLUUID id)
|
||||
{
|
||||
mSunTextureId = id;
|
||||
setDirtyFlag(true);
|
||||
setLLSDDirty();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,34 @@
|
|||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
|
||||
void set_random_inventory_metadata(LLInventoryObject* obj)
|
||||
{
|
||||
S32 extra = rand() % 4;
|
||||
switch (extra)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
LLUUID thumbnail_id;
|
||||
thumbnail_id.generate();
|
||||
obj->setThumbnailUUID(thumbnail_id);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
obj->setFavorite(true);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
LLUUID thumbnail_id;
|
||||
thumbnail_id.generate();
|
||||
obj->setThumbnailUUID(thumbnail_id);
|
||||
obj->setFavorite(true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LLPointer<LLInventoryItem> create_random_inventory_item()
|
||||
{
|
||||
LLUUID item_id;
|
||||
|
|
@ -75,6 +103,7 @@ LLPointer<LLInventoryItem> create_random_inventory_item()
|
|||
sale_info,
|
||||
flags,
|
||||
creation);
|
||||
set_random_inventory_metadata(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +119,7 @@ LLPointer<LLInventoryCategory> create_random_inventory_cat()
|
|||
parent_id,
|
||||
LLFolderType::FT_NONE,
|
||||
std::string("Sample category"));
|
||||
set_random_inventory_metadata(cat);
|
||||
return cat;
|
||||
}
|
||||
|
||||
|
|
@ -290,6 +320,7 @@ namespace tut
|
|||
src->setCreationDate(new_creation);
|
||||
|
||||
// test a save/load cycle to LLSD and back again
|
||||
// Note: ll_create_sd_from_inventory_item does not support metadata
|
||||
LLSD sd = ll_create_sd_from_inventory_item(src);
|
||||
LLPointer<LLInventoryItem> dst = new LLInventoryItem;
|
||||
bool successful_parse = dst->fromLLSD(sd);
|
||||
|
|
@ -329,7 +360,9 @@ namespace tut
|
|||
}
|
||||
|
||||
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl;
|
||||
LLSD sd;
|
||||
src1->asLLSD(sd);
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
|
||||
fileXML.close();
|
||||
|
||||
|
||||
|
|
@ -364,13 +397,13 @@ namespace tut
|
|||
ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
|
||||
ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
|
||||
|
||||
ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void inventory_object::test<8>()
|
||||
{
|
||||
|
||||
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
|
||||
|
||||
std::ostringstream ostream;
|
||||
|
|
@ -390,8 +423,8 @@ namespace tut
|
|||
ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
|
||||
ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
|
||||
|
||||
|
||||
ensure_equals("11.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("12.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // not supposed to carry over
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
|
|
@ -421,6 +454,8 @@ namespace tut
|
|||
ensure_equals("10.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription());
|
||||
ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
|
||||
ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());
|
||||
}
|
||||
|
||||
//******class LLInventoryCategory*******//
|
||||
|
|
@ -458,7 +493,9 @@ namespace tut
|
|||
}
|
||||
|
||||
LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl;
|
||||
LLSD sd;
|
||||
src1->exportLLSD(sd);
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
|
||||
fileXML.close();
|
||||
|
||||
llifstream file(filename.c_str());
|
||||
|
|
@ -481,13 +518,15 @@ namespace tut
|
|||
file.close();
|
||||
|
||||
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
|
||||
src2->importLLSD(s_item);
|
||||
src2->importLLSDMap(s_item);
|
||||
|
||||
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
|
||||
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
|
||||
ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
|
||||
ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
|
||||
ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("6.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("7.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
|
|
@ -507,6 +546,7 @@ namespace tut
|
|||
ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
|
||||
ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
|
||||
ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
|
||||
|
||||
ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("14.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // currently not supposed to carry over
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,103 +280,118 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
|
|||
{
|
||||
LLImageDataLock lock(&base);
|
||||
|
||||
S32 data_size = base.getDataSize();
|
||||
S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
|
||||
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
mCodeStreamp.reset();
|
||||
|
||||
// It's not clear to nat under what circumstances we would reuse a
|
||||
// pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of
|
||||
// two U32s and a pointer, so it's not as if it would be a huge overhead
|
||||
// to allocate a new one every time.
|
||||
// Also -- why is base.getData() tested specifically here? If that returns
|
||||
// nullptr, shouldn't we bail out of the whole method?
|
||||
if (!mInputp && base.getData())
|
||||
try
|
||||
{
|
||||
// The compressed data has been loaded
|
||||
// Setup the source for the codestream
|
||||
mInputp = std::make_unique<LLKDUMemSource>(base.getData(), data_size);
|
||||
}
|
||||
|
||||
if (mInputp)
|
||||
{
|
||||
// This is LLKDUMemSource::reset(), not std::unique_ptr::reset().
|
||||
mInputp->reset();
|
||||
}
|
||||
S32 data_size = base.getDataSize();
|
||||
S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);
|
||||
|
||||
mCodeStreamp->create(mInputp.get());
|
||||
//
|
||||
// Initialization
|
||||
//
|
||||
mCodeStreamp.reset();
|
||||
|
||||
// Set the maximum number of bytes to use from the codestream
|
||||
// *TODO: This seems to be wrong. The base class should have no idea of
|
||||
// how j2c compression works so no good way of computing what's the byte
|
||||
// range to be used.
|
||||
// It's not clear to nat under what circumstances we would reuse a
|
||||
// pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of
|
||||
// two U32s and a pointer, so it's not as if it would be a huge overhead
|
||||
// to allocate a new one every time.
|
||||
// Also -- why is base.getData() tested specifically here? If that returns
|
||||
// nullptr, shouldn't we bail out of the whole method?
|
||||
if (!mInputp && base.getData())
|
||||
{
|
||||
// The compressed data has been loaded
|
||||
// Setup the source for the codestream
|
||||
mInputp = std::make_unique<LLKDUMemSource>(base.getData(), data_size);
|
||||
}
|
||||
|
||||
if (mInputp)
|
||||
{
|
||||
// This is LLKDUMemSource::reset(), not std::unique_ptr::reset().
|
||||
mInputp->reset();
|
||||
}
|
||||
|
||||
mCodeStreamp->create(mInputp.get());
|
||||
|
||||
// Set the maximum number of bytes to use from the codestream
|
||||
// *TODO: This seems to be wrong. The base class should have no idea of
|
||||
// how j2c compression works so no good way of computing what's the byte
|
||||
// range to be used.
|
||||
mCodeStreamp->set_max_bytes(max_bytes);
|
||||
|
||||
// If you want to flip or rotate the image for some reason, change
|
||||
// the resolution, or identify a restricted region of interest, this is
|
||||
// the place to do it. You may use "kdu_codestream::change_appearance"
|
||||
// and "kdu_codestream::apply_input_restrictions" for this purpose.
|
||||
// If you wish to truncate the code-stream prior to decompression, you
|
||||
// may use "kdu_codestream::set_max_bytes".
|
||||
// If you wish to retain all compressed data so that the material
|
||||
// can be decompressed multiple times, possibly with different appearance
|
||||
// parameters, you should call "kdu_codestream::set_persistent" here.
|
||||
// There are a variety of other features which must be enabled at
|
||||
// this point if you want to take advantage of them. See the
|
||||
// descriptions appearing with the "kdu_codestream" interface functions
|
||||
// in "kdu_compressed.h" for an itemized account of these capabilities.
|
||||
// If you want to flip or rotate the image for some reason, change
|
||||
// the resolution, or identify a restricted region of interest, this is
|
||||
// the place to do it. You may use "kdu_codestream::change_appearance"
|
||||
// and "kdu_codestream::apply_input_restrictions" for this purpose.
|
||||
// If you wish to truncate the code-stream prior to decompression, you
|
||||
// may use "kdu_codestream::set_max_bytes".
|
||||
// If you wish to retain all compressed data so that the material
|
||||
// can be decompressed multiple times, possibly with different appearance
|
||||
// parameters, you should call "kdu_codestream::set_persistent" here.
|
||||
// There are a variety of other features which must be enabled at
|
||||
// this point if you want to take advantage of them. See the
|
||||
// descriptions appearing with the "kdu_codestream" interface functions
|
||||
// in "kdu_compressed.h" for an itemized account of these capabilities.
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case MODE_FAST:
|
||||
mCodeStreamp->set_fast();
|
||||
break;
|
||||
case MODE_RESILIENT:
|
||||
mCodeStreamp->set_resilient();
|
||||
break;
|
||||
case MODE_FUSSY:
|
||||
mCodeStreamp->set_fussy();
|
||||
break;
|
||||
default:
|
||||
llassert(0);
|
||||
mCodeStreamp->set_fast();
|
||||
}
|
||||
|
||||
kdu_dims dims;
|
||||
mCodeStreamp->get_dims(0,dims);
|
||||
|
||||
S32 components = mCodeStreamp->get_num_components();
|
||||
|
||||
// Check that components have consistent dimensions (for PPM file)
|
||||
for (int idx = 1; idx < components; ++idx)
|
||||
{
|
||||
kdu_dims other_dims;
|
||||
mCodeStreamp->get_dims(idx, other_dims);
|
||||
if (other_dims != dims)
|
||||
switch (mode)
|
||||
{
|
||||
// This method is only called from methods that catch KDUError.
|
||||
// We want to fail the image load, not crash the viewer.
|
||||
LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions "
|
||||
<< stringize(other_dims)
|
||||
<< " do not match component 0 dimensions "
|
||||
<< stringize(dims) << "!")));
|
||||
case MODE_FAST:
|
||||
mCodeStreamp->set_fast();
|
||||
break;
|
||||
case MODE_RESILIENT:
|
||||
mCodeStreamp->set_resilient();
|
||||
break;
|
||||
case MODE_FUSSY:
|
||||
mCodeStreamp->set_fussy();
|
||||
break;
|
||||
default:
|
||||
llassert(0);
|
||||
mCodeStreamp->set_fast();
|
||||
}
|
||||
|
||||
kdu_dims dims;
|
||||
mCodeStreamp->get_dims(0, dims);
|
||||
|
||||
S32 components = mCodeStreamp->get_num_components();
|
||||
|
||||
// Check that components have consistent dimensions (for PPM file)
|
||||
for (int idx = 1; idx < components; ++idx)
|
||||
{
|
||||
kdu_dims other_dims;
|
||||
mCodeStreamp->get_dims(idx, other_dims);
|
||||
if (other_dims != dims)
|
||||
{
|
||||
// This method is only called from methods that catch KDUError.
|
||||
// We want to fail the image load, not crash the viewer.
|
||||
LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions "
|
||||
<< stringize(other_dims)
|
||||
<< " do not match component 0 dimensions "
|
||||
<< stringize(dims) << "!")));
|
||||
}
|
||||
}
|
||||
|
||||
// Get the number of resolution levels in that image
|
||||
mLevels = mCodeStreamp->get_min_dwt_levels();
|
||||
|
||||
// Set the base dimensions
|
||||
base.setSize(dims.size.x, dims.size.y, components);
|
||||
base.setLevels(mLevels);
|
||||
|
||||
if (!keep_codestream)
|
||||
{
|
||||
mCodeStreamp.reset();
|
||||
mInputp.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the number of resolution levels in that image
|
||||
mLevels = mCodeStreamp->get_min_dwt_levels();
|
||||
|
||||
// Set the base dimensions
|
||||
base.setSize(dims.size.x, dims.size.y, components);
|
||||
base.setLevels(mLevels);
|
||||
|
||||
if (!keep_codestream)
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
mCodeStreamp.reset();
|
||||
mInputp.reset();
|
||||
// we are in a thread, can't show an 'out of memory' here,
|
||||
// main thread will keep going
|
||||
throw;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LLTHROW(KDUError(STRINGIZE("Unknown J2C error : " +
|
||||
boost::current_exception_diagnostic_information() << "!")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -647,6 +662,12 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
|
|||
bool vflip = true;
|
||||
bool hflip = false;
|
||||
|
||||
if (raw_image.isBufferInvalid())
|
||||
{
|
||||
base.setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Set up input image files
|
||||
|
|
|
|||
|
|
@ -33,23 +33,23 @@
|
|||
#include "llplane.h"
|
||||
#include "llvector4a.h"
|
||||
|
||||
const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD;
|
||||
const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f;
|
||||
const F32 DEFAULT_NEAR_PLANE = 0.25f;
|
||||
const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions
|
||||
constexpr F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD;
|
||||
constexpr F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f;
|
||||
constexpr F32 DEFAULT_NEAR_PLANE = 0.25f;
|
||||
constexpr F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions
|
||||
|
||||
const F32 MAX_ASPECT_RATIO = 50.0f;
|
||||
const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends
|
||||
const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though.
|
||||
const F32 MAX_FAR_CLIP = 512.0f;
|
||||
constexpr F32 MAX_ASPECT_RATIO = 50.0f;
|
||||
constexpr F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends
|
||||
constexpr F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though.
|
||||
constexpr F32 MAX_FAR_CLIP = 512.0f;
|
||||
|
||||
const F32 MIN_ASPECT_RATIO = 0.02f;
|
||||
const F32 MIN_NEAR_PLANE = 0.1f;
|
||||
const F32 MIN_FAR_PLANE = 0.2f;
|
||||
constexpr F32 MIN_ASPECT_RATIO = 0.02f;
|
||||
constexpr F32 MIN_NEAR_PLANE = 0.1f;
|
||||
constexpr F32 MIN_FAR_PLANE = 0.2f;
|
||||
|
||||
// Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio.
|
||||
static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD;
|
||||
static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
|
||||
constexpr F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD;
|
||||
constexpr F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
|
||||
|
||||
// An LLCamera is an LLCoorFrame with a view frustum.
|
||||
// This means that it has several methods for moving it around
|
||||
|
|
|
|||
|
|
@ -328,28 +328,30 @@ void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix)
|
|||
}
|
||||
|
||||
|
||||
// Rotate 2 normalized orthogonal vectors in direction from `source` to `target`
|
||||
static void rotate2(LLVector3& source, LLVector3& target, F32 angle)
|
||||
{
|
||||
F32 sx = source[VX], sy = source[VY], sz = source[VZ];
|
||||
F32 tx = target[VX], ty = target[VY], tz = target[VZ];
|
||||
F32 c = cosf(angle), s = sinf(angle);
|
||||
|
||||
source.set(sx * c + tx * s, sy * c + ty * s, sz * c + tz * s);
|
||||
target.set(tx * c - sx * s, ty * c - sy * s, tz * c - sz * s);
|
||||
}
|
||||
|
||||
void LLCoordFrame::roll(F32 angle)
|
||||
{
|
||||
LLQuaternion q(angle, mXAxis);
|
||||
LLMatrix3 rotation_matrix(q);
|
||||
rotate(rotation_matrix);
|
||||
CHECK_FINITE_OBJ();
|
||||
rotate2(mYAxis, mZAxis, angle);
|
||||
}
|
||||
|
||||
void LLCoordFrame::pitch(F32 angle)
|
||||
{
|
||||
LLQuaternion q(angle, mYAxis);
|
||||
LLMatrix3 rotation_matrix(q);
|
||||
rotate(rotation_matrix);
|
||||
CHECK_FINITE_OBJ();
|
||||
rotate2(mZAxis, mXAxis, angle);
|
||||
}
|
||||
|
||||
void LLCoordFrame::yaw(F32 angle)
|
||||
{
|
||||
LLQuaternion q(angle, mZAxis);
|
||||
LLMatrix3 rotation_matrix(q);
|
||||
rotate(rotation_matrix);
|
||||
CHECK_FINITE_OBJ();
|
||||
rotate2(mXAxis, mYAxis, angle);
|
||||
}
|
||||
|
||||
// get*() routines
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public:
|
|||
//LLCoordFrame(const F32 *origin, const F32 *rotation); // Assumes "origin" is 1x3 and "rotation" is 1x9 array
|
||||
//LLCoordFrame(const F32 *origin_and_rotation); // Assumes "origin_and_rotation" is 1x12 array
|
||||
|
||||
bool isFinite() { return mOrigin.isFinite() && mXAxis.isFinite() && mYAxis.isFinite() && mZAxis.isFinite(); }
|
||||
bool isFinite() const { return mOrigin.isFinite() && mXAxis.isFinite() && mYAxis.isFinite() && mZAxis.isFinite(); }
|
||||
|
||||
void reset();
|
||||
void resetAxes();
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
#include "stdtypes.h"
|
||||
#include "v3math.h"
|
||||
|
||||
const F32 DEFAULT_INTERSECTION_ERROR = 0.000001f;
|
||||
constexpr F32 DEFAULT_INTERSECTION_ERROR = 0.000001f;
|
||||
|
||||
class LLLine
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,18 +39,8 @@
|
|||
// llcommon depend on llmath.
|
||||
#include "is_approx_equal_fraction.h"
|
||||
|
||||
// work around for Windows & older gcc non-standard function names.
|
||||
#if LL_WINDOWS
|
||||
#include <float.h>
|
||||
#define llisnan(val) _isnan(val)
|
||||
#define llfinite(val) _finite(val)
|
||||
#elif (LL_LINUX && __GNUC__ <= 2)
|
||||
#define llisnan(val) isnan(val)
|
||||
#define llfinite(val) isfinite(val)
|
||||
#else
|
||||
#define llisnan(val) std::isnan(val)
|
||||
#define llfinite(val) std::isfinite(val)
|
||||
#endif
|
||||
#define llisnan(val) std::isnan(val)
|
||||
#define llfinite(val) std::isfinite(val)
|
||||
|
||||
// Single Precision Floating Point Routines
|
||||
// (There used to be more defined here, but they appeared to be redundant and
|
||||
|
|
@ -75,7 +65,7 @@ constexpr F32 DEG_TO_RAD = 0.017453292519943295769236907684886f;
|
|||
constexpr F32 RAD_TO_DEG = 57.295779513082320876798154814105f;
|
||||
constexpr F32 F_APPROXIMATELY_ZERO = 0.00001f;
|
||||
constexpr F32 F_LN10 = 2.3025850929940456840179914546844f;
|
||||
constexpr F32 OO_LN10 = 0.43429448190325182765112891891661;
|
||||
constexpr F32 OO_LN10 = 0.43429448190325182765112891891661f;
|
||||
constexpr F32 F_LN2 = 0.69314718056f;
|
||||
constexpr F32 OO_LN2 = 1.4426950408889634073599246810019f;
|
||||
|
||||
|
|
@ -89,7 +79,7 @@ constexpr F32 GIMBAL_THRESHOLD = 0.000436f; // sets the gimballock threshold 0
|
|||
constexpr F32 FP_MAG_THRESHOLD = 0.0000001f;
|
||||
|
||||
// TODO: Replace with logic like is_approx_equal
|
||||
inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
|
||||
constexpr bool is_approx_zero(F32 f) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
|
||||
|
||||
// These functions work by interpreting sign+exp+mantissa as an unsigned
|
||||
// integer.
|
||||
|
|
@ -148,33 +138,17 @@ inline F64 llabs(const F64 a)
|
|||
return F64(std::fabs(a));
|
||||
}
|
||||
|
||||
inline S32 lltrunc( F32 f )
|
||||
constexpr S32 lltrunc(F32 f)
|
||||
{
|
||||
#if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32)
|
||||
// Avoids changing the floating point control word.
|
||||
// Add or subtract 0.5 - epsilon and then round
|
||||
const static U32 zpfp[] = { 0xBEFFFFFF, 0x3EFFFFFF };
|
||||
S32 result;
|
||||
__asm {
|
||||
fld f
|
||||
mov eax, f
|
||||
shr eax, 29
|
||||
and eax, 4
|
||||
fadd dword ptr [zpfp + eax]
|
||||
fistp result
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
return (S32)f;
|
||||
#endif
|
||||
return narrow(f);
|
||||
}
|
||||
|
||||
inline S32 lltrunc( F64 f )
|
||||
constexpr S32 lltrunc(F64 f)
|
||||
{
|
||||
return (S32)f;
|
||||
return narrow(f);
|
||||
}
|
||||
|
||||
inline S32 llfloor( F32 f )
|
||||
inline S32 llfloor(F32 f)
|
||||
{
|
||||
#if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32)
|
||||
// Avoids changing the floating point control word.
|
||||
|
|
@ -284,7 +258,7 @@ constexpr F32 FAST_MAG_BETA = 0.397824734759f;
|
|||
//constexpr F32 FAST_MAG_ALPHA = 0.948059448969f;
|
||||
//constexpr F32 FAST_MAG_BETA = 0.392699081699f;
|
||||
|
||||
inline F32 fastMagnitude(F32 a, F32 b)
|
||||
constexpr F32 fastMagnitude(F32 a, F32 b)
|
||||
{
|
||||
a = (a > 0) ? a : -a;
|
||||
b = (b > 0) ? b : -b;
|
||||
|
|
@ -342,7 +316,7 @@ inline F32 llfastpow(const F32 x, const F32 y)
|
|||
}
|
||||
|
||||
|
||||
inline F32 snap_to_sig_figs(F32 foo, S32 sig_figs)
|
||||
constexpr F32 snap_to_sig_figs(F32 foo, S32 sig_figs)
|
||||
{
|
||||
// compute the power of ten
|
||||
F32 bar = 1.f;
|
||||
|
|
@ -358,12 +332,9 @@ inline F32 snap_to_sig_figs(F32 foo, S32 sig_figs)
|
|||
return new_foo;
|
||||
}
|
||||
|
||||
inline F32 lerp(F32 a, F32 b, F32 u)
|
||||
{
|
||||
return a + ((b - a) * u);
|
||||
}
|
||||
using std::lerp;
|
||||
|
||||
inline F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v)
|
||||
constexpr F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v)
|
||||
{
|
||||
F32 a = x00 + (x01-x00)*u;
|
||||
F32 b = x10 + (x11-x10)*u;
|
||||
|
|
@ -371,17 +342,17 @@ inline F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v)
|
|||
return r;
|
||||
}
|
||||
|
||||
inline F32 ramp(F32 x, F32 a, F32 b)
|
||||
constexpr F32 ramp(F32 x, F32 a, F32 b)
|
||||
{
|
||||
return (a == b) ? 0.0f : ((a - x) / (a - b));
|
||||
}
|
||||
|
||||
inline F32 rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)
|
||||
constexpr F32 rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)
|
||||
{
|
||||
return lerp(y1, y2, ramp(x, x1, x2));
|
||||
}
|
||||
|
||||
inline F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)
|
||||
constexpr F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)
|
||||
{
|
||||
if (y1 < y2)
|
||||
{
|
||||
|
|
@ -394,7 +365,7 @@ inline F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)
|
|||
}
|
||||
|
||||
|
||||
inline F32 cubic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )
|
||||
constexpr F32 cubic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )
|
||||
{
|
||||
if (x <= x0)
|
||||
return s0;
|
||||
|
|
@ -407,14 +378,14 @@ inline F32 cubic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )
|
|||
return s0 + (s1 - s0) * (f * f) * (3.0f - 2.0f * f);
|
||||
}
|
||||
|
||||
inline F32 cubic_step( F32 x )
|
||||
constexpr F32 cubic_step( F32 x )
|
||||
{
|
||||
x = llclampf(x);
|
||||
|
||||
return (x * x) * (3.0f - 2.0f * x);
|
||||
}
|
||||
|
||||
inline F32 quadratic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )
|
||||
constexpr F32 quadratic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )
|
||||
{
|
||||
if (x <= x0)
|
||||
return s0;
|
||||
|
|
@ -428,7 +399,7 @@ inline F32 quadratic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 )
|
|||
return (s0 * (1.f - f_squared)) + ((s1 - s0) * f_squared);
|
||||
}
|
||||
|
||||
inline F32 llsimple_angle(F32 angle)
|
||||
constexpr F32 llsimple_angle(F32 angle)
|
||||
{
|
||||
while(angle <= -F_PI)
|
||||
angle += F_TWO_PI;
|
||||
|
|
@ -438,7 +409,7 @@ inline F32 llsimple_angle(F32 angle)
|
|||
}
|
||||
|
||||
//SDK - Renamed this to get_lower_power_two, since this is what this actually does.
|
||||
inline U32 get_lower_power_two(U32 val, U32 max_power_two)
|
||||
constexpr U32 get_lower_power_two(U32 val, U32 max_power_two)
|
||||
{
|
||||
if(!max_power_two)
|
||||
{
|
||||
|
|
@ -460,7 +431,7 @@ inline U32 get_lower_power_two(U32 val, U32 max_power_two)
|
|||
// number of digits, then add one. We subtract 1 initially to handle
|
||||
// the case where the number passed in is actually a power of two.
|
||||
// WARNING: this only works with 32 bit ints.
|
||||
inline U32 get_next_power_two(U32 val, U32 max_power_two)
|
||||
constexpr U32 get_next_power_two(U32 val, U32 max_power_two)
|
||||
{
|
||||
if(!max_power_two)
|
||||
{
|
||||
|
|
@ -486,7 +457,7 @@ inline U32 get_next_power_two(U32 val, U32 max_power_two)
|
|||
//get the gaussian value given the linear distance from axis x and guassian value o
|
||||
inline F32 llgaussian(F32 x, F32 o)
|
||||
{
|
||||
return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o));
|
||||
return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2.f*o*o));
|
||||
}
|
||||
|
||||
//helper function for removing outliers
|
||||
|
|
@ -539,7 +510,8 @@ inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
|
|||
// Note: in our code, values labeled as sRGB are ALWAYS gamma corrected linear values, NOT linear values with monitor gamma applied
|
||||
// Note: stored color values should always be gamma corrected linear (i.e. the values returned from an on-screen color swatch)
|
||||
// Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses
|
||||
inline float linearTosRGB(const float val) {
|
||||
inline float linearTosRGB(const float val)
|
||||
{
|
||||
if (val < 0.0031308f) {
|
||||
return val * 12.92f;
|
||||
}
|
||||
|
|
@ -554,7 +526,8 @@ inline float linearTosRGB(const float val) {
|
|||
// Note: Stored color values should generally be gamma corrected sRGB.
|
||||
// If you're serializing the return value of this function, you're probably doing it wrong.
|
||||
// Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses.
|
||||
inline float sRGBtoLinear(const float val) {
|
||||
inline float sRGBtoLinear(const float val)
|
||||
{
|
||||
if (val < 0.04045f) {
|
||||
return val / 12.92f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "llquaternion.h"
|
||||
|
||||
//#include "vmath.h"
|
||||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v4math.h"
|
||||
|
|
@ -58,7 +57,7 @@ LLQuaternion::LLQuaternion(const LLMatrix3 &mat)
|
|||
|
||||
LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec)
|
||||
{
|
||||
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
|
||||
F32 mag = vec.length();
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
angle *= 0.5;
|
||||
|
|
@ -77,7 +76,7 @@ LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec)
|
|||
|
||||
LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec)
|
||||
{
|
||||
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
|
||||
F32 mag = vec.length();
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
angle *= 0.5;
|
||||
|
|
|
|||
|
|
@ -1294,10 +1294,11 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
|
|||
c = cos(ang)*lerp(radius_start, radius_end, t);
|
||||
|
||||
|
||||
pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
|
||||
pt->mPos.set(0 + lerp(0.f, params.getShear().mV[VX], s)
|
||||
+ lerp(-skew ,skew, t) * 0.5f,
|
||||
c + lerp(0,params.getShear().mV[1],s),
|
||||
c + lerp(0.f, params.getShear().mV[VY], s),
|
||||
s);
|
||||
|
||||
pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
|
||||
hole_y * lerp(taper_y_begin, taper_y_end, t),
|
||||
0,1);
|
||||
|
|
@ -1327,9 +1328,9 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
|
|||
c = cos(ang)*lerp(radius_start, radius_end, t);
|
||||
s = sin(ang)*lerp(radius_start, radius_end, t);
|
||||
|
||||
pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
|
||||
pt->mPos.set(0 + lerp(0.f, params.getShear().mV[VX], s)
|
||||
+ lerp(-skew ,skew, t) * 0.5f,
|
||||
c + lerp(0,params.getShear().mV[1],s),
|
||||
c + lerp(0.f, params.getShear().mV[VY], s),
|
||||
s);
|
||||
|
||||
pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
|
||||
|
|
@ -1354,9 +1355,9 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en
|
|||
c = cos(ang)*lerp(radius_start, radius_end, t);
|
||||
s = sin(ang)*lerp(radius_start, radius_end, t);
|
||||
|
||||
pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s)
|
||||
pt->mPos.set(0 + lerp(0.f, params.getShear().mV[VX], s)
|
||||
+ lerp(-skew ,skew, t) * 0.5f,
|
||||
c + lerp(0,params.getShear().mV[1],s),
|
||||
c + lerp(0.f, params.getShear().mV[VY], s),
|
||||
s);
|
||||
pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t),
|
||||
hole_y * lerp(taper_y_begin, taper_y_end, t),
|
||||
|
|
@ -1494,8 +1495,8 @@ bool LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
|
|||
for (S32 i=0;i<np;i++)
|
||||
{
|
||||
F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep);
|
||||
mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t),
|
||||
lerp(0,params.getShear().mV[1],t),
|
||||
mPath[i].mPos.set(lerp(0.f, params.getShear().mV[VX], t),
|
||||
lerp(0.f ,params.getShear().mV[VY], t),
|
||||
t - 0.5f);
|
||||
LLQuaternion quat;
|
||||
quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1);
|
||||
|
|
@ -1559,10 +1560,10 @@ bool LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
|
|||
{
|
||||
F32 t = (F32)i * mStep;
|
||||
mPath[i].mPos.set(0,
|
||||
lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t),
|
||||
lerp(-0.5f, cos(F_PI*params.getTwist()*t)*0.5f,t));
|
||||
mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t),
|
||||
lerp(1,params.getScale().mV[1],t), 0,1);
|
||||
lerp(0.f, -sin(F_PI*params.getTwist() * t) * 0.5f, t),
|
||||
lerp(-0.5f, cos(F_PI*params.getTwist() * t) * 0.5f, t));
|
||||
mPath[i].mScale.set(lerp(1.f, params.getScale().mV[VX], t),
|
||||
lerp(1.f, params.getScale().mV[VY], t), 0.f, 1.f);
|
||||
mPath[i].mTexT = t;
|
||||
LLQuaternion quat;
|
||||
quat.setQuat(F_PI * params.getTwist() * t,1,0,0);
|
||||
|
|
@ -5710,7 +5711,15 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
S32 vert_count = 0;
|
||||
if (!data.p.empty())
|
||||
{
|
||||
vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
|
||||
try
|
||||
{
|
||||
vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS("LLCoros") << "Failed to allocate memory for VertexRemap: " << (S32)data.p.size() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if (vert_count < 65535 && vert_count != 0)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ class LLVolumeOctree;
|
|||
|
||||
#include "lluuid.h"
|
||||
#include "v4color.h"
|
||||
//#include "vmath.h"
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
//#include "vmath.h"
|
||||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v4math.h"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
//#include "vmath.h"
|
||||
#include "v3math.h"
|
||||
#include "v4math.h"
|
||||
#include "m4math.h"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include "math.h"
|
||||
//#include "vmath.h"
|
||||
#include "v3math.h"
|
||||
#include "llquaternion.h"
|
||||
#include "m3math.h"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
//#include "vmath.h"
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
#include "v4math.h"
|
||||
|
|
@ -47,8 +46,8 @@ bool LLVector2::abs()
|
|||
{
|
||||
bool ret{ false };
|
||||
|
||||
if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = true; }
|
||||
if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = true; }
|
||||
if (mV[VX] < 0.f) { mV[VX] = -mV[VX]; ret = true; }
|
||||
if (mV[VY] < 0.f) { mV[VY] = -mV[VY]; ret = true; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -67,14 +66,21 @@ F32 angle_between(const LLVector2& a, const LLVector2& b)
|
|||
return angle;
|
||||
}
|
||||
|
||||
bool are_parallel(const LLVector2 &a, const LLVector2 &b, float epsilon)
|
||||
F32 signed_angle_between(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
F32 angle = angle_between(a, b);
|
||||
F32 rhombus_square = a[VX] * b[VY] - b[VX] * a[VY];
|
||||
return rhombus_square < 0 ? -angle : angle;
|
||||
}
|
||||
|
||||
bool are_parallel(const LLVector2& a, const LLVector2& b, F32 epsilon)
|
||||
{
|
||||
LLVector2 an = a;
|
||||
LLVector2 bn = b;
|
||||
an.normVec();
|
||||
bn.normVec();
|
||||
F32 dot = an * bn;
|
||||
if ( (1.0f - fabs(dot)) < epsilon)
|
||||
if ((1.0f - fabs(dot)) < epsilon)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -82,28 +88,28 @@ bool are_parallel(const LLVector2 &a, const LLVector2 &b, float epsilon)
|
|||
}
|
||||
|
||||
|
||||
F32 dist_vec(const LLVector2 &a, const LLVector2 &b)
|
||||
F32 dist_vec(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 x = a.mV[VX] - b.mV[VX];
|
||||
F32 y = a.mV[VY] - b.mV[VY];
|
||||
return (F32) sqrt( x*x + y*y );
|
||||
}
|
||||
|
||||
F32 dist_vec_squared(const LLVector2 &a, const LLVector2 &b)
|
||||
F32 dist_vec_squared(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 x = a.mV[VX] - b.mV[VX];
|
||||
F32 y = a.mV[VY] - b.mV[VY];
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
F32 dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b)
|
||||
F32 dist_vec_squared2D(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 x = a.mV[VX] - b.mV[VX];
|
||||
F32 y = a.mV[VY] - b.mV[VY];
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u)
|
||||
LLVector2 lerp(const LLVector2& a, const LLVector2& b, F32 u)
|
||||
{
|
||||
return LLVector2(
|
||||
a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
|
||||
|
|
@ -113,14 +119,14 @@ LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u)
|
|||
LLSD LLVector2::getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mV[0];
|
||||
ret[1] = mV[1];
|
||||
ret[VX] = mV[VX];
|
||||
ret[VY] = mV[VY];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLVector2::setValue(const LLSD& sd)
|
||||
{
|
||||
mV[0] = (F32) sd[0].asReal();
|
||||
mV[1] = (F32) sd[1].asReal();
|
||||
mV[VX] = (F32) sd[0].asReal();
|
||||
mV[VY] = (F32) sd[1].asReal();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class LLQuaternion;
|
|||
|
||||
// Llvector2 = |x y z w|
|
||||
|
||||
static const U32 LENGTHOFVECTOR2 = 2;
|
||||
static constexpr U32 LENGTHOFVECTOR2 = 2;
|
||||
|
||||
class LLVector2
|
||||
{
|
||||
|
|
@ -82,7 +82,7 @@ class LLVector2
|
|||
|
||||
const LLVector2& scaleVec(const LLVector2& vec); // scales per component by vec
|
||||
|
||||
bool isNull(); // Returns true if vector has a _very_small_ length
|
||||
bool isNull() const; // Returns true if vector has a _very_small_ length
|
||||
bool isExactlyZero() const { return !mV[VX] && !mV[VY]; }
|
||||
|
||||
F32 operator[](int idx) const { return mV[idx]; }
|
||||
|
|
@ -107,7 +107,7 @@ class LLVector2
|
|||
|
||||
friend LLVector2 operator-(const LLVector2 &a); // Return vector -a
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLVector2 &a); // Stream a
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLVector2 &a); // Stream a
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_copyable<LLVector2>::value, "LLVector2 must be trivial copy");
|
||||
|
|
@ -116,37 +116,34 @@ static_assert(std::is_standard_layout<LLVector2>::value, "LLVector2 must be a st
|
|||
|
||||
// Non-member functions
|
||||
|
||||
F32 angle_between(const LLVector2 &a, const LLVector2 &b); // Returns angle (radians) between a and b
|
||||
bool are_parallel(const LLVector2 &a, const LLVector2 &b, F32 epsilon=F_APPROXIMATELY_ZERO); // Returns true if a and b are very close to parallel
|
||||
F32 dist_vec(const LLVector2 &a, const LLVector2 &b); // Returns distance between a and b
|
||||
F32 dist_vec_squared(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b
|
||||
F32 dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b ignoring Z component
|
||||
LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
|
||||
F32 angle_between(const LLVector2& a, const LLVector2& b); // Returns angle (radians) between a and b
|
||||
F32 signed_angle_between(const LLVector2& a, const LLVector2& b); // Returns signed angle (radians) between a and b
|
||||
bool are_parallel(const LLVector2& a, const LLVector2& b, F32 epsilon = F_APPROXIMATELY_ZERO); // Returns true if a and b are very close to parallel
|
||||
F32 dist_vec(const LLVector2& a, const LLVector2& b); // Returns distance between a and b
|
||||
F32 dist_vec_squared(const LLVector2& a, const LLVector2& b);// Returns distance squared between a and b
|
||||
F32 dist_vec_squared2D(const LLVector2& a, const LLVector2& b);// Returns distance squared between a and b ignoring Z component
|
||||
LLVector2 lerp(const LLVector2& a, const LLVector2& b, F32 u); // Returns a vector that is a linear interpolation between a and b
|
||||
|
||||
// Constructors
|
||||
|
||||
inline LLVector2::LLVector2(void)
|
||||
inline LLVector2::LLVector2()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(F32 x, F32 y)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
set(x, y);
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(const LLVector3 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
set(vec.mV);
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(const LLSD &sd)
|
||||
|
|
@ -156,30 +153,26 @@ inline LLVector2::LLVector2(const LLSD &sd)
|
|||
|
||||
// Clear and Assignment Functions
|
||||
|
||||
inline void LLVector2::clear(void)
|
||||
inline void LLVector2::clear()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VX] = mV[VY] = 0.f;
|
||||
}
|
||||
|
||||
inline void LLVector2::setZero(void)
|
||||
inline void LLVector2::setZero()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::clearVec(void)
|
||||
inline void LLVector2::clearVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::zeroVec(void)
|
||||
inline void LLVector2::zeroVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector2::set(F32 x, F32 y)
|
||||
|
|
@ -190,108 +183,84 @@ inline void LLVector2::set(F32 x, F32 y)
|
|||
|
||||
inline void LLVector2::set(const LLVector2 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
set(vec.mV);
|
||||
}
|
||||
|
||||
inline void LLVector2::set(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
set(vec[VX], vec[VY]);
|
||||
}
|
||||
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::setVec(F32 x, F32 y)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
set(x, y);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::setVec(const LLVector2 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::setVec(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
|
||||
// LLVector2 Magnitude and Normalization Functions
|
||||
|
||||
inline F32 LLVector2::length(void) const
|
||||
inline F32 LLVector2::length() const
|
||||
{
|
||||
return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]);
|
||||
return sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
inline F32 LLVector2::lengthSquared(void) const
|
||||
inline F32 LLVector2::lengthSquared() const
|
||||
{
|
||||
return mV[0]*mV[0] + mV[1]*mV[1];
|
||||
return mV[VX]*mV[VX] + mV[VY]*mV[VY];
|
||||
}
|
||||
|
||||
inline F32 LLVector2::normalize(void)
|
||||
inline F32 LLVector2::normalize()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]);
|
||||
F32 oomag;
|
||||
F32 mag = length();
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[0] *= oomag;
|
||||
mV[1] *= oomag;
|
||||
*this /= mag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
clear();
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// checker
|
||||
inline bool LLVector2::isFinite() const
|
||||
{
|
||||
return (llfinite(mV[VX]) && llfinite(mV[VY]));
|
||||
return llfinite(mV[VX]) && llfinite(mV[VY]);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector2::magVec(void) const
|
||||
inline F32 LLVector2::magVec() const
|
||||
{
|
||||
return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]);
|
||||
return length();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector2::magVecSquared(void) const
|
||||
inline F32 LLVector2::magVecSquared() const
|
||||
{
|
||||
return mV[0]*mV[0] + mV[1]*mV[1];
|
||||
return lengthSquared();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector2::normVec(void)
|
||||
inline F32 LLVector2::normVec()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[0] *= oomag;
|
||||
mV[1] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return normalize();
|
||||
}
|
||||
|
||||
inline const LLVector2& LLVector2::scaleVec(const LLVector2& vec)
|
||||
|
|
@ -302,22 +271,18 @@ inline const LLVector2& LLVector2::scaleVec(const LLVector2& vec)
|
|||
return *this;
|
||||
}
|
||||
|
||||
inline bool LLVector2::isNull()
|
||||
inline bool LLVector2::isNull() const
|
||||
{
|
||||
if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY];
|
||||
}
|
||||
|
||||
|
||||
// LLVector2 Operators
|
||||
|
||||
// For sorting. By convention, x is "more significant" than y.
|
||||
inline bool operator<(const LLVector2 &a, const LLVector2 &b)
|
||||
inline bool operator<(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
if( a.mV[VX] == b.mV[VX] )
|
||||
if (a.mV[VX] == b.mV[VX])
|
||||
{
|
||||
return a.mV[VY] < b.mV[VY];
|
||||
}
|
||||
|
|
@ -328,95 +293,92 @@ inline bool operator<(const LLVector2 &a, const LLVector2 &b)
|
|||
}
|
||||
|
||||
|
||||
inline LLVector2 operator+(const LLVector2 &a, const LLVector2 &b)
|
||||
inline LLVector2 operator+(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
LLVector2 c(a);
|
||||
return c += b;
|
||||
}
|
||||
|
||||
inline LLVector2 operator-(const LLVector2 &a, const LLVector2 &b)
|
||||
inline LLVector2 operator-(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
LLVector2 c(a);
|
||||
return c -= b;
|
||||
}
|
||||
|
||||
inline F32 operator*(const LLVector2 &a, const LLVector2 &b)
|
||||
inline F32 operator*(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1]);
|
||||
return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY]);
|
||||
}
|
||||
|
||||
inline LLVector2 operator%(const LLVector2 &a, const LLVector2 &b)
|
||||
inline LLVector2 operator%(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
return LLVector2(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]);
|
||||
return LLVector2(a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY], a.mV[VY]*b.mV[VX] - b.mV[VY]*a.mV[VX]);
|
||||
}
|
||||
|
||||
inline LLVector2 operator/(const LLVector2 &a, F32 k)
|
||||
inline LLVector2 operator/(const LLVector2& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
return LLVector2( a.mV[0] * t, a.mV[1] * t );
|
||||
return LLVector2( a.mV[VX] * t, a.mV[VY] * t );
|
||||
}
|
||||
|
||||
inline LLVector2 operator*(const LLVector2 &a, F32 k)
|
||||
inline LLVector2 operator*(const LLVector2& a, F32 k)
|
||||
{
|
||||
return LLVector2( a.mV[0] * k, a.mV[1] * k );
|
||||
return LLVector2( a.mV[VX] * k, a.mV[VY] * k );
|
||||
}
|
||||
|
||||
inline LLVector2 operator*(F32 k, const LLVector2 &a)
|
||||
inline LLVector2 operator*(F32 k, const LLVector2& a)
|
||||
{
|
||||
return LLVector2( a.mV[0] * k, a.mV[1] * k );
|
||||
return LLVector2( a.mV[VX] * k, a.mV[VY] * k );
|
||||
}
|
||||
|
||||
inline bool operator==(const LLVector2 &a, const LLVector2 &b)
|
||||
inline bool operator==(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
return ( (a.mV[0] == b.mV[0])
|
||||
&&(a.mV[1] == b.mV[1]));
|
||||
return ( (a.mV[VX] == b.mV[VX])
|
||||
&&(a.mV[VY] == b.mV[VY]));
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLVector2 &a, const LLVector2 &b)
|
||||
inline bool operator!=(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
return ( (a.mV[0] != b.mV[0])
|
||||
||(a.mV[1] != b.mV[1]));
|
||||
return ( (a.mV[VX] != b.mV[VX])
|
||||
||(a.mV[VY] != b.mV[VY]));
|
||||
}
|
||||
|
||||
inline const LLVector2& operator+=(LLVector2 &a, const LLVector2 &b)
|
||||
inline const LLVector2& operator+=(LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
a.mV[0] += b.mV[0];
|
||||
a.mV[1] += b.mV[1];
|
||||
a.mV[VX] += b.mV[VX];
|
||||
a.mV[VY] += b.mV[VY];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector2& operator-=(LLVector2 &a, const LLVector2 &b)
|
||||
inline const LLVector2& operator-=(LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
a.mV[0] -= b.mV[0];
|
||||
a.mV[1] -= b.mV[1];
|
||||
a.mV[VX] -= b.mV[VX];
|
||||
a.mV[VY] -= b.mV[VY];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector2& operator%=(LLVector2 &a, const LLVector2 &b)
|
||||
inline const LLVector2& operator%=(LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
LLVector2 ret(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]);
|
||||
LLVector2 ret(a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY], a.mV[VY]*b.mV[VX] - b.mV[VY]*a.mV[VX]);
|
||||
a = ret;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector2& operator*=(LLVector2 &a, F32 k)
|
||||
inline const LLVector2& operator*=(LLVector2& a, F32 k)
|
||||
{
|
||||
a.mV[0] *= k;
|
||||
a.mV[1] *= k;
|
||||
a.mV[VX] *= k;
|
||||
a.mV[VY] *= k;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector2& operator/=(LLVector2 &a, F32 k)
|
||||
inline const LLVector2& operator/=(LLVector2& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
a.mV[0] *= t;
|
||||
a.mV[1] *= t;
|
||||
return a;
|
||||
return a *= 1.f / k;
|
||||
}
|
||||
|
||||
inline LLVector2 operator-(const LLVector2 &a)
|
||||
inline LLVector2 operator-(const LLVector2& a)
|
||||
{
|
||||
return LLVector2( -a.mV[0], -a.mV[1] );
|
||||
return LLVector2( -a.mV[VX], -a.mV[VY] );
|
||||
}
|
||||
|
||||
inline void update_min_max(LLVector2& min, LLVector2& max, const LLVector2& pos)
|
||||
|
|
@ -434,7 +396,7 @@ inline void update_min_max(LLVector2& min, LLVector2& max, const LLVector2& pos)
|
|||
}
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& s, const LLVector2 &a)
|
||||
inline std::ostream& operator<<(std::ostream& s, const LLVector2& a)
|
||||
{
|
||||
s << "{ " << a.mV[VX] << ", " << a.mV[VY] << " }";
|
||||
return s;
|
||||
|
|
|
|||
|
|
@ -32,74 +32,79 @@
|
|||
|
||||
LLColor3 LLColor3::white(1.0f, 1.0f, 1.0f);
|
||||
LLColor3 LLColor3::black(0.0f, 0.0f, 0.0f);
|
||||
LLColor3 LLColor3::grey (0.5f, 0.5f, 0.5f);
|
||||
LLColor3 LLColor3::grey(0.5f, 0.5f, 0.5f);
|
||||
|
||||
LLColor3::LLColor3(const LLColor4 &a)
|
||||
LLColor3::LLColor3(const LLColor4& a)
|
||||
{
|
||||
mV[0] = a.mV[0];
|
||||
mV[1] = a.mV[1];
|
||||
mV[2] = a.mV[2];
|
||||
mV[VRED] = a.mV[VRED];
|
||||
mV[VGREEN] = a.mV[VGREEN];
|
||||
mV[VBLUE] = a.mV[VBLUE];
|
||||
}
|
||||
|
||||
LLColor3::LLColor3(const LLVector4 &a)
|
||||
LLColor3::LLColor3(const LLVector4& a)
|
||||
{
|
||||
mV[0] = a.mV[0];
|
||||
mV[1] = a.mV[1];
|
||||
mV[2] = a.mV[2];
|
||||
mV[VRED] = a.mV[VRED];
|
||||
mV[VGREEN] = a.mV[VGREEN];
|
||||
mV[VBLUE] = a.mV[VBLUE];
|
||||
}
|
||||
|
||||
LLColor3::LLColor3(const LLSD &sd)
|
||||
LLColor3::LLColor3(const LLSD& sd)
|
||||
{
|
||||
setValue(sd);
|
||||
}
|
||||
|
||||
const LLColor3& LLColor3::operator=(const LLColor4 &a)
|
||||
const LLColor3& LLColor3::operator=(const LLColor4& a)
|
||||
{
|
||||
mV[0] = a.mV[0];
|
||||
mV[1] = a.mV[1];
|
||||
mV[2] = a.mV[2];
|
||||
mV[VRED] = a.mV[VRED];
|
||||
mV[VGREEN] = a.mV[VGREEN];
|
||||
mV[VBLUE] = a.mV[VBLUE];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLColor3 &a)
|
||||
std::ostream& operator<<(std::ostream& s, const LLColor3& a)
|
||||
{
|
||||
s << "{ " << a.mV[VRED] << ", " << a.mV[VGREEN] << ", " << a.mV[VBLUE] << " }";
|
||||
return s;
|
||||
}
|
||||
|
||||
static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
|
||||
static F32 hueToRgb(F32 val1In, F32 val2In, F32 valHUeIn)
|
||||
{
|
||||
if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
|
||||
if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
|
||||
if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn );
|
||||
if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In );
|
||||
if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f );
|
||||
return ( val1In );
|
||||
if (valHUeIn < 0.0f)
|
||||
valHUeIn += 1.0f;
|
||||
if (valHUeIn > 1.0f)
|
||||
valHUeIn -= 1.0f;
|
||||
if ((6.0f * valHUeIn) < 1.0f)
|
||||
return (val1In + (val2In - val1In) * 6.0f * valHUeIn);
|
||||
if ((2.0f * valHUeIn) < 1.0f)
|
||||
return (val2In);
|
||||
if ((3.0f * valHUeIn) < 2.0f)
|
||||
return (val1In + (val2In - val1In) * ((2.0f / 3.0f) - valHUeIn) * 6.0f);
|
||||
return (val1In);
|
||||
}
|
||||
|
||||
void LLColor3::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)
|
||||
void LLColor3::setHSL(F32 hValIn, F32 sValIn, F32 lValIn)
|
||||
{
|
||||
if ( sValIn < 0.00001f )
|
||||
if (sValIn < 0.00001f)
|
||||
{
|
||||
mV[VRED] = lValIn;
|
||||
mV[VRED] = lValIn;
|
||||
mV[VGREEN] = lValIn;
|
||||
mV[VBLUE] = lValIn;
|
||||
mV[VBLUE] = lValIn;
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 interVal1;
|
||||
F32 interVal2;
|
||||
|
||||
if ( lValIn < 0.5f )
|
||||
interVal2 = lValIn * ( 1.0f + sValIn );
|
||||
if (lValIn < 0.5f)
|
||||
interVal2 = lValIn * (1.0f + sValIn);
|
||||
else
|
||||
interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn );
|
||||
interVal2 = (lValIn + sValIn) - (sValIn * lValIn);
|
||||
|
||||
interVal1 = 2.0f * lValIn - interVal2;
|
||||
|
||||
mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) );
|
||||
mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn );
|
||||
mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) );
|
||||
mV[VRED] = hueToRgb(interVal1, interVal2, hValIn + (1.f / 3.f));
|
||||
mV[VGREEN] = hueToRgb(interVal1, interVal2, hValIn);
|
||||
mV[VBLUE] = hueToRgb(interVal1, interVal2, hValIn - (1.f / 3.f));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,45 +114,48 @@ void LLColor3::calcHSL(F32* hue, F32* saturation, F32* luminance) const
|
|||
F32 var_G = mV[VGREEN];
|
||||
F32 var_B = mV[VBLUE];
|
||||
|
||||
F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) );
|
||||
F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) );
|
||||
F32 var_Min = (var_R < (var_G < var_B ? var_G : var_B) ? var_R : (var_G < var_B ? var_G : var_B));
|
||||
F32 var_Max = (var_R > (var_G > var_B ? var_G : var_B) ? var_R : (var_G > var_B ? var_G : var_B));
|
||||
|
||||
F32 del_Max = var_Max - var_Min;
|
||||
|
||||
F32 L = ( var_Max + var_Min ) / 2.0f;
|
||||
F32 L = (var_Max + var_Min) / 2.0f;
|
||||
F32 H = 0.0f;
|
||||
F32 S = 0.0f;
|
||||
|
||||
if ( del_Max == 0.0f )
|
||||
if (del_Max == 0.0f)
|
||||
{
|
||||
H = 0.0f;
|
||||
S = 0.0f;
|
||||
H = 0.0f;
|
||||
S = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( L < 0.5 )
|
||||
S = del_Max / ( var_Max + var_Min );
|
||||
if (L < 0.5)
|
||||
S = del_Max / (var_Max + var_Min);
|
||||
else
|
||||
S = del_Max / ( 2.0f - var_Max - var_Min );
|
||||
S = del_Max / (2.0f - var_Max - var_Min);
|
||||
|
||||
F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max;
|
||||
F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max;
|
||||
F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max;
|
||||
F32 del_R = (((var_Max - var_R) / 6.0f) + (del_Max / 2.0f)) / del_Max;
|
||||
F32 del_G = (((var_Max - var_G) / 6.0f) + (del_Max / 2.0f)) / del_Max;
|
||||
F32 del_B = (((var_Max - var_B) / 6.0f) + (del_Max / 2.0f)) / del_Max;
|
||||
|
||||
if ( var_R >= var_Max )
|
||||
if (var_R >= var_Max)
|
||||
H = del_B - del_G;
|
||||
else
|
||||
if ( var_G >= var_Max )
|
||||
H = ( 1.0f / 3.0f ) + del_R - del_B;
|
||||
else
|
||||
if ( var_B >= var_Max )
|
||||
H = ( 2.0f / 3.0f ) + del_G - del_R;
|
||||
else if (var_G >= var_Max)
|
||||
H = (1.0f / 3.0f) + del_R - del_B;
|
||||
else if (var_B >= var_Max)
|
||||
H = (2.0f / 3.0f) + del_G - del_R;
|
||||
|
||||
if ( H < 0.0f ) H += 1.0f;
|
||||
if ( H > 1.0f ) H -= 1.0f;
|
||||
if (H < 0.0f)
|
||||
H += 1.0f;
|
||||
if (H > 1.0f)
|
||||
H -= 1.0f;
|
||||
}
|
||||
|
||||
if (hue) *hue = H;
|
||||
if (saturation) *saturation = S;
|
||||
if (luminance) *luminance = L;
|
||||
if (hue)
|
||||
*hue = H;
|
||||
if (saturation)
|
||||
*saturation = S;
|
||||
if (luminance)
|
||||
*luminance = L;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ class LLVector4;
|
|||
#include "llerror.h"
|
||||
#include "llmath.h"
|
||||
#include "llsd.h"
|
||||
#include "v3math.h" // needed for linearColor3v implemtation below
|
||||
#include "v3math.h" // needed for linearColor3v implemtation below
|
||||
#include <string.h>
|
||||
|
||||
// LLColor3 = |r g b|
|
||||
|
||||
static const U32 LENGTHOFCOLOR3 = 3;
|
||||
static constexpr U32 LENGTHOFCOLOR3 = 3;
|
||||
|
||||
class LLColor3
|
||||
{
|
||||
|
|
@ -50,44 +50,43 @@ public:
|
|||
static LLColor3 grey;
|
||||
|
||||
public:
|
||||
LLColor3(); // Initializes LLColor3 to (0, 0, 0)
|
||||
LLColor3(F32 r, F32 g, F32 b); // Initializes LLColor3 to (r, g, b)
|
||||
LLColor3(const F32 *vec); // Initializes LLColor3 to (vec[0]. vec[1], vec[2])
|
||||
LLColor3(const char *color_string); // html format color ie "#FFDDEE"
|
||||
explicit LLColor3(const LLColor4& color4); // "explicit" to avoid automatic conversion
|
||||
explicit LLColor3(const LLVector4& vector4); // "explicit" to avoid automatic conversion
|
||||
LLColor3(); // Initializes LLColor3 to (0, 0, 0)
|
||||
LLColor3(F32 r, F32 g, F32 b); // Initializes LLColor3 to (r, g, b)
|
||||
LLColor3(const F32* vec); // Initializes LLColor3 to (vec[0]. vec[1], vec[2])
|
||||
LLColor3(const char* color_string); // html format color ie "#FFDDEE"
|
||||
explicit LLColor3(const LLColor4& color4); // "explicit" to avoid automatic conversion
|
||||
explicit LLColor3(const LLVector4& vector4); // "explicit" to avoid automatic conversion
|
||||
LLColor3(const LLSD& sd);
|
||||
|
||||
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mV[0];
|
||||
ret[1] = mV[1];
|
||||
ret[2] = mV[2];
|
||||
ret[VRED] = mV[VRED];
|
||||
ret[VGREEN] = mV[VGREEN];
|
||||
ret[VBLUE] = mV[VBLUE];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setValue(const LLSD& sd)
|
||||
{
|
||||
mV[0] = (F32) sd[0].asReal();;
|
||||
mV[1] = (F32) sd[1].asReal();;
|
||||
mV[2] = (F32) sd[2].asReal();;
|
||||
mV[VRED] = (F32)sd[VRED].asReal();
|
||||
mV[VGREEN] = (F32)sd[VGREEN].asReal();
|
||||
mV[VBLUE] = (F32)sd[VBLUE].asReal();
|
||||
}
|
||||
|
||||
void setHSL(F32 hue, F32 saturation, F32 luminance);
|
||||
void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
|
||||
|
||||
const LLColor3& setToBlack(); // Clears LLColor3 to (0, 0, 0)
|
||||
const LLColor3& setToWhite(); // Zero LLColor3 to (0, 0, 0)
|
||||
const LLColor3& setToBlack(); // Clears LLColor3 to (0, 0, 0)
|
||||
const LLColor3& setToWhite(); // Zero LLColor3 to (0, 0, 0)
|
||||
|
||||
const LLColor3& setVec(F32 x, F32 y, F32 z); // deprecated
|
||||
const LLColor3& setVec(const LLColor3 &vec); // deprecated
|
||||
const LLColor3& setVec(const F32 *vec); // deprecated
|
||||
const LLColor3& setVec(F32 x, F32 y, F32 z); // deprecated
|
||||
const LLColor3& setVec(const LLColor3& vec); // deprecated
|
||||
const LLColor3& setVec(const F32* vec); // deprecated
|
||||
|
||||
const LLColor3& set(F32 x, F32 y, F32 z); // Sets LLColor3 to (x, y, z)
|
||||
const LLColor3& set(const LLColor3 &vec); // Sets LLColor3 to vec
|
||||
const LLColor3& set(const F32 *vec); // Sets LLColor3 to vec
|
||||
const LLColor3& set(F32 x, F32 y, F32 z); // Sets LLColor3 to (x, y, z)
|
||||
const LLColor3& set(const LLColor3& vec); // Sets LLColor3 to vec
|
||||
const LLColor3& set(const F32* vec); // Sets LLColor3 to vec
|
||||
|
||||
// set from a vector of unknown type and size
|
||||
// may leave some data unmodified
|
||||
|
|
@ -99,56 +98,50 @@ public:
|
|||
template<typename T>
|
||||
void write(std::vector<T>& v) const;
|
||||
|
||||
F32 magVec() const; // deprecated
|
||||
F32 magVecSquared() const; // deprecated
|
||||
F32 normVec(); // deprecated
|
||||
F32 magVec() const; // deprecated
|
||||
F32 magVecSquared() const; // deprecated
|
||||
F32 normVec(); // deprecated
|
||||
|
||||
F32 length() const; // Returns magnitude of LLColor3
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLColor3
|
||||
F32 normalize(); // Normalizes and returns the magnitude of LLColor3
|
||||
F32 length() const; // Returns magnitude of LLColor3
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLColor3
|
||||
F32 normalize(); // Normalizes and returns the magnitude of LLColor3
|
||||
|
||||
F32 brightness() const; // Returns brightness of LLColor3
|
||||
F32 brightness() const; // Returns brightness of LLColor3
|
||||
|
||||
const LLColor3& operator=(const LLColor4 &a);
|
||||
const LLColor3& operator=(const LLColor4& a);
|
||||
|
||||
LL_FORCE_INLINE LLColor3 divide(const LLColor3 &col2)
|
||||
LL_FORCE_INLINE LLColor3 divide(const LLColor3& col2) const
|
||||
{
|
||||
return LLColor3(
|
||||
mV[0] / col2.mV[0],
|
||||
mV[1] / col2.mV[1],
|
||||
mV[2] / col2.mV[2] );
|
||||
return LLColor3(mV[VRED] / col2.mV[VRED], mV[VGREEN] / col2.mV[VGREEN], mV[VBLUE] / col2.mV[VBLUE]);
|
||||
}
|
||||
|
||||
LL_FORCE_INLINE LLColor3 color_norm()
|
||||
LL_FORCE_INLINE LLColor3 color_norm() const
|
||||
{
|
||||
F32 l = length();
|
||||
return LLColor3(
|
||||
mV[0] / l,
|
||||
mV[1] / l,
|
||||
mV[2] / l );
|
||||
return LLColor3(mV[VRED] / l, mV[VGREEN] / l, mV[VBLUE] / l);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLColor3 &a); // Print a
|
||||
friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b); // Return vector a + b
|
||||
friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b); // Return vector a minus b
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLColor3& a); // Print a
|
||||
friend LLColor3 operator+(const LLColor3& a, const LLColor3& b); // Return vector a + b
|
||||
friend LLColor3 operator-(const LLColor3& a, const LLColor3& b); // Return vector a minus b
|
||||
|
||||
friend const LLColor3& operator+=(LLColor3 &a, const LLColor3 &b); // Return vector a + b
|
||||
friend const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b); // Return vector a minus b
|
||||
friend const LLColor3& operator*=(LLColor3 &a, const LLColor3 &b);
|
||||
friend const LLColor3& operator+=(LLColor3& a, const LLColor3& b); // Return vector a + b
|
||||
friend const LLColor3& operator-=(LLColor3& a, const LLColor3& b); // Return vector a minus b
|
||||
friend const LLColor3& operator*=(LLColor3& a, const LLColor3& b);
|
||||
|
||||
friend LLColor3 operator*(const LLColor3 &a, const LLColor3 &b); // Return component wise a * b
|
||||
friend LLColor3 operator*(const LLColor3 &a, F32 k); // Return a times scaler k
|
||||
friend LLColor3 operator*(F32 k, const LLColor3 &a); // Return a times scaler k
|
||||
friend LLColor3 operator*(const LLColor3& a, const LLColor3& b); // Return component wise a * b
|
||||
friend LLColor3 operator*(const LLColor3& a, F32 k); // Return a times scaler k
|
||||
friend LLColor3 operator*(F32 k, const LLColor3& a); // Return a times scaler k
|
||||
|
||||
friend bool operator==(const LLColor3 &a, const LLColor3 &b); // Return a == b
|
||||
friend bool operator!=(const LLColor3 &a, const LLColor3 &b); // Return a != b
|
||||
friend bool operator==(const LLColor3& a, const LLColor3& b); // Return a == b
|
||||
friend bool operator!=(const LLColor3& a, const LLColor3& b); // Return a != b
|
||||
|
||||
friend const LLColor3& operator*=(LLColor3 &a, F32 k); // Return a times scaler k
|
||||
friend const LLColor3& operator*=(LLColor3& a, F32 k); // Return a times scaler k
|
||||
|
||||
friend LLColor3 operator-(const LLColor3 &a); // Return vector 1-rgb (inverse)
|
||||
friend LLColor3 operator-(const LLColor3& a); // Return vector 1-rgb (inverse)
|
||||
|
||||
inline void clamp();
|
||||
inline void exp(); // Do an exponential on the color
|
||||
inline void exp(); // Do an exponential on the color
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_copyable<LLColor3>::value, "LLColor3 must be trivial copy");
|
||||
|
|
@ -156,360 +149,342 @@ static_assert(std::is_trivially_move_assignable<LLColor3>::value, "LLColor3 must
|
|||
static_assert(std::is_standard_layout<LLColor3>::value, "LLColor3 must be a standard layout type");
|
||||
|
||||
LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u);
|
||||
|
||||
void LLColor3::clamp()
|
||||
{
|
||||
// Clamp the color...
|
||||
if (mV[0] < 0.f)
|
||||
if (mV[VRED] < 0.f)
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[VRED] = 0.f;
|
||||
}
|
||||
else if (mV[0] > 1.f)
|
||||
else if (mV[VRED] > 1.f)
|
||||
{
|
||||
mV[0] = 1.f;
|
||||
mV[VRED] = 1.f;
|
||||
}
|
||||
if (mV[1] < 0.f)
|
||||
if (mV[VGREEN] < 0.f)
|
||||
{
|
||||
mV[1] = 0.f;
|
||||
mV[VGREEN] = 0.f;
|
||||
}
|
||||
else if (mV[1] > 1.f)
|
||||
else if (mV[VGREEN] > 1.f)
|
||||
{
|
||||
mV[1] = 1.f;
|
||||
mV[VGREEN] = 1.f;
|
||||
}
|
||||
if (mV[2] < 0.f)
|
||||
if (mV[VBLUE] < 0.f)
|
||||
{
|
||||
mV[2] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
}
|
||||
else if (mV[2] > 1.f)
|
||||
else if (mV[VBLUE] > 1.f)
|
||||
{
|
||||
mV[2] = 1.f;
|
||||
mV[VBLUE] = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
// Non-member functions
|
||||
F32 distVec(const LLColor3 &a, const LLColor3 &b); // Returns distance between a and b
|
||||
F32 distVec_squared(const LLColor3 &a, const LLColor3 &b);// Returns distance squared between a and b
|
||||
F32 distVec(const LLColor3& a, const LLColor3& b); // Returns distance between a and b
|
||||
F32 distVec_squared(const LLColor3& a, const LLColor3& b); // Returns distance squared between a and b
|
||||
|
||||
inline LLColor3::LLColor3(void)
|
||||
inline LLColor3::LLColor3()
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
mV[VRED] = 0.f;
|
||||
mV[VGREEN] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
}
|
||||
|
||||
inline LLColor3::LLColor3(F32 r, F32 g, F32 b)
|
||||
{
|
||||
mV[VRED] = r;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
mV[VBLUE] = b;
|
||||
}
|
||||
|
||||
|
||||
inline LLColor3::LLColor3(const F32 *vec)
|
||||
inline LLColor3::LLColor3(const F32* vec)
|
||||
{
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
}
|
||||
|
||||
inline LLColor3::LLColor3(const char* color_string) // takes a string of format "RRGGBB" where RR is hex 00..FF
|
||||
{
|
||||
if (strlen(color_string) < 6) /* Flawfinder: ignore */
|
||||
if (strlen(color_string) < 6) /* Flawfinder: ignore */
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
mV[VRED] = 0.f;
|
||||
mV[VGREEN] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
return;
|
||||
}
|
||||
|
||||
char tempstr[7];
|
||||
strncpy(tempstr,color_string,6); /* Flawfinder: ignore */
|
||||
strncpy(tempstr, color_string, 6); /* Flawfinder: ignore */
|
||||
tempstr[6] = '\0';
|
||||
mV[VBLUE] = (F32)strtol(&tempstr[4],NULL,16)/255.f;
|
||||
mV[VBLUE] = (F32)strtol(&tempstr[4], nullptr, 16) / 255.f;
|
||||
tempstr[4] = '\0';
|
||||
mV[VGREEN] = (F32)strtol(&tempstr[2],NULL,16)/255.f;
|
||||
mV[VGREEN] = (F32)strtol(&tempstr[2], nullptr, 16) / 255.f;
|
||||
tempstr[2] = '\0';
|
||||
mV[VRED] = (F32)strtol(&tempstr[0],NULL,16)/255.f;
|
||||
mV[VRED] = (F32)strtol(&tempstr[0], nullptr, 16) / 255.f;
|
||||
}
|
||||
|
||||
inline const LLColor3& LLColor3::setToBlack(void)
|
||||
inline const LLColor3& LLColor3::setToBlack()
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
mV[VRED] = 0.f;
|
||||
mV[VGREEN] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor3& LLColor3::setToWhite(void)
|
||||
inline const LLColor3& LLColor3::setToWhite()
|
||||
{
|
||||
mV[0] = 1.f;
|
||||
mV[1] = 1.f;
|
||||
mV[2] = 1.f;
|
||||
mV[VRED] = 1.f;
|
||||
mV[VGREEN] = 1.f;
|
||||
mV[VBLUE] = 1.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor3& LLColor3::set(F32 r, F32 g, F32 b)
|
||||
inline const LLColor3& LLColor3::set(F32 r, F32 g, F32 b)
|
||||
{
|
||||
mV[0] = r;
|
||||
mV[1] = g;
|
||||
mV[2] = b;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor3& LLColor3::set(const LLColor3 &vec)
|
||||
inline const LLColor3& LLColor3::set(const LLColor3& vec)
|
||||
{
|
||||
mV[0] = vec.mV[0];
|
||||
mV[1] = vec.mV[1];
|
||||
mV[2] = vec.mV[2];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor3& LLColor3::set(const F32 *vec)
|
||||
inline const LLColor3& LLColor3::set(const F32* vec)
|
||||
{
|
||||
mV[0] = vec[0];
|
||||
mV[1] = vec[1];
|
||||
mV[2] = vec[2];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor3& LLColor3::setVec(F32 r, F32 g, F32 b)
|
||||
inline const LLColor3& LLColor3::setVec(F32 r, F32 g, F32 b)
|
||||
{
|
||||
mV[0] = r;
|
||||
mV[1] = g;
|
||||
mV[2] = b;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor3& LLColor3::setVec(const LLColor3 &vec)
|
||||
inline const LLColor3& LLColor3::setVec(const LLColor3& vec)
|
||||
{
|
||||
mV[0] = vec.mV[0];
|
||||
mV[1] = vec.mV[1];
|
||||
mV[2] = vec.mV[2];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor3& LLColor3::setVec(const F32 *vec)
|
||||
inline const LLColor3& LLColor3::setVec(const F32* vec)
|
||||
{
|
||||
mV[0] = vec[0];
|
||||
mV[1] = vec[1];
|
||||
mV[2] = vec[2];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline F32 LLColor3::brightness(void) const
|
||||
inline F32 LLColor3::brightness() const
|
||||
{
|
||||
return (mV[0] + mV[1] + mV[2]) / 3.0f;
|
||||
return (mV[VRED] + mV[VGREEN] + mV[VBLUE]) / 3.0f;
|
||||
}
|
||||
|
||||
inline F32 LLColor3::length(void) const
|
||||
inline F32 LLColor3::length() const
|
||||
{
|
||||
return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
}
|
||||
|
||||
inline F32 LLColor3::lengthSquared(void) const
|
||||
inline F32 LLColor3::lengthSquared() const
|
||||
{
|
||||
return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
|
||||
return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE];
|
||||
}
|
||||
|
||||
inline F32 LLColor3::normalize(void)
|
||||
inline F32 LLColor3::normalize()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[0] *= oomag;
|
||||
mV[1] *= oomag;
|
||||
mV[2] *= oomag;
|
||||
oomag = 1.f / mag;
|
||||
mV[VRED] *= oomag;
|
||||
mV[VGREEN] *= oomag;
|
||||
mV[VBLUE] *= oomag;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor3::magVec(void) const
|
||||
inline F32 LLColor3::magVec() const
|
||||
{
|
||||
return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor3::magVecSquared(void) const
|
||||
inline F32 LLColor3::magVecSquared() const
|
||||
{
|
||||
return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
|
||||
return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE];
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor3::normVec(void)
|
||||
inline F32 LLColor3::normVec()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[0] *= oomag;
|
||||
mV[1] *= oomag;
|
||||
mV[2] *= oomag;
|
||||
oomag = 1.f / mag;
|
||||
mV[VRED] *= oomag;
|
||||
mV[VGREEN] *= oomag;
|
||||
mV[VBLUE] *= oomag;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
inline void LLColor3::exp()
|
||||
{
|
||||
#if 0
|
||||
mV[0] = ::exp(mV[0]);
|
||||
mV[1] = ::exp(mV[1]);
|
||||
mV[2] = ::exp(mV[2]);
|
||||
mV[VRED] = ::exp(mV[VRED]);
|
||||
mV[VGREEN] = ::exp(mV[VGREEN]);
|
||||
mV[VBLUE] = ::exp(mV[VBLUE]);
|
||||
#else
|
||||
mV[0] = (F32)LL_FAST_EXP(mV[0]);
|
||||
mV[1] = (F32)LL_FAST_EXP(mV[1]);
|
||||
mV[2] = (F32)LL_FAST_EXP(mV[2]);
|
||||
mV[VRED] = (F32)LL_FAST_EXP(mV[VRED]);
|
||||
mV[VGREEN] = (F32)LL_FAST_EXP(mV[VGREEN]);
|
||||
mV[VBLUE] = (F32)LL_FAST_EXP(mV[VBLUE]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline LLColor3 operator+(const LLColor3 &a, const LLColor3 &b)
|
||||
inline LLColor3 operator+(const LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
return LLColor3(
|
||||
a.mV[0] + b.mV[0],
|
||||
a.mV[1] + b.mV[1],
|
||||
a.mV[2] + b.mV[2]);
|
||||
return LLColor3(a.mV[VRED] + b.mV[VRED], a.mV[VGREEN] + b.mV[VGREEN], a.mV[VBLUE] + b.mV[VBLUE]);
|
||||
}
|
||||
|
||||
inline LLColor3 operator-(const LLColor3 &a, const LLColor3 &b)
|
||||
inline LLColor3 operator-(const LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
return LLColor3(
|
||||
a.mV[0] - b.mV[0],
|
||||
a.mV[1] - b.mV[1],
|
||||
a.mV[2] - b.mV[2]);
|
||||
return LLColor3(a.mV[VRED] - b.mV[VRED], a.mV[VGREEN] - b.mV[VGREEN], a.mV[VBLUE] - b.mV[VBLUE]);
|
||||
}
|
||||
|
||||
inline LLColor3 operator*(const LLColor3 &a, const LLColor3 &b)
|
||||
inline LLColor3 operator*(const LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
return LLColor3(
|
||||
a.mV[0] * b.mV[0],
|
||||
a.mV[1] * b.mV[1],
|
||||
a.mV[2] * b.mV[2]);
|
||||
return LLColor3(a.mV[VRED] * b.mV[VRED], a.mV[VGREEN] * b.mV[VGREEN], a.mV[VBLUE] * b.mV[VBLUE]);
|
||||
}
|
||||
|
||||
inline LLColor3 operator*(const LLColor3 &a, F32 k)
|
||||
inline LLColor3 operator*(const LLColor3& a, F32 k)
|
||||
{
|
||||
return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
|
||||
return LLColor3(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k);
|
||||
}
|
||||
|
||||
inline LLColor3 operator*(F32 k, const LLColor3 &a)
|
||||
inline LLColor3 operator*(F32 k, const LLColor3& a)
|
||||
{
|
||||
return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
|
||||
return LLColor3(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k);
|
||||
}
|
||||
|
||||
inline bool operator==(const LLColor3 &a, const LLColor3 &b)
|
||||
inline bool operator==(const LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
return ( (a.mV[0] == b.mV[0])
|
||||
&&(a.mV[1] == b.mV[1])
|
||||
&&(a.mV[2] == b.mV[2]));
|
||||
return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE]));
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLColor3 &a, const LLColor3 &b)
|
||||
inline bool operator!=(const LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
return ( (a.mV[0] != b.mV[0])
|
||||
||(a.mV[1] != b.mV[1])
|
||||
||(a.mV[2] != b.mV[2]));
|
||||
return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE]));
|
||||
}
|
||||
|
||||
inline const LLColor3 &operator*=(LLColor3 &a, const LLColor3 &b)
|
||||
inline const LLColor3& operator*=(LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
a.mV[0] *= b.mV[0];
|
||||
a.mV[1] *= b.mV[1];
|
||||
a.mV[2] *= b.mV[2];
|
||||
a.mV[VRED] *= b.mV[VRED];
|
||||
a.mV[VGREEN] *= b.mV[VGREEN];
|
||||
a.mV[VBLUE] *= b.mV[VBLUE];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor3& operator+=(LLColor3 &a, const LLColor3 &b)
|
||||
inline const LLColor3& operator+=(LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
a.mV[0] += b.mV[0];
|
||||
a.mV[1] += b.mV[1];
|
||||
a.mV[2] += b.mV[2];
|
||||
a.mV[VRED] += b.mV[VRED];
|
||||
a.mV[VGREEN] += b.mV[VGREEN];
|
||||
a.mV[VBLUE] += b.mV[VBLUE];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b)
|
||||
inline const LLColor3& operator-=(LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
a.mV[0] -= b.mV[0];
|
||||
a.mV[1] -= b.mV[1];
|
||||
a.mV[2] -= b.mV[2];
|
||||
a.mV[VRED] -= b.mV[VRED];
|
||||
a.mV[VGREEN] -= b.mV[VGREEN];
|
||||
a.mV[VBLUE] -= b.mV[VBLUE];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor3& operator*=(LLColor3 &a, F32 k)
|
||||
inline const LLColor3& operator*=(LLColor3& a, F32 k)
|
||||
{
|
||||
a.mV[0] *= k;
|
||||
a.mV[1] *= k;
|
||||
a.mV[2] *= k;
|
||||
a.mV[VRED] *= k;
|
||||
a.mV[VGREEN] *= k;
|
||||
a.mV[VBLUE] *= k;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline LLColor3 operator-(const LLColor3 &a)
|
||||
inline LLColor3 operator-(const LLColor3& a)
|
||||
{
|
||||
return LLColor3(
|
||||
1.f - a.mV[0],
|
||||
1.f - a.mV[1],
|
||||
1.f - a.mV[2] );
|
||||
return LLColor3(1.f - a.mV[VRED], 1.f - a.mV[VGREEN], 1.f - a.mV[VBLUE]);
|
||||
}
|
||||
|
||||
// Non-member functions
|
||||
|
||||
inline F32 distVec(const LLColor3 &a, const LLColor3 &b)
|
||||
inline F32 distVec(const LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 z = a.mV[2] - b.mV[2];
|
||||
return (F32) sqrt( x*x + y*y + z*z );
|
||||
F32 x = a.mV[VRED] - b.mV[VRED];
|
||||
F32 y = a.mV[VGREEN] - b.mV[VGREEN];
|
||||
F32 z = a.mV[VBLUE] - b.mV[VBLUE];
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
inline F32 distVec_squared(const LLColor3 &a, const LLColor3 &b)
|
||||
inline F32 distVec_squared(const LLColor3& a, const LLColor3& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 z = a.mV[2] - b.mV[2];
|
||||
return x*x + y*y + z*z;
|
||||
F32 x = a.mV[VRED] - b.mV[VRED];
|
||||
F32 y = a.mV[VGREEN] - b.mV[VGREEN];
|
||||
F32 z = a.mV[VBLUE] - b.mV[VBLUE];
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
inline LLColor3 lerp(const LLColor3 &a, const LLColor3 &b, F32 u)
|
||||
inline LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u)
|
||||
{
|
||||
return LLColor3(
|
||||
a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
|
||||
a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u,
|
||||
a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
|
||||
return LLColor3(a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
|
||||
}
|
||||
|
||||
inline const LLColor3 srgbColor3(const LLColor3 &a) {
|
||||
inline const LLColor3 srgbColor3(const LLColor3& a)
|
||||
{
|
||||
LLColor3 srgbColor;
|
||||
srgbColor.mV[0] = linearTosRGB(a.mV[0]);
|
||||
srgbColor.mV[1] = linearTosRGB(a.mV[1]);
|
||||
srgbColor.mV[2] = linearTosRGB(a.mV[2]);
|
||||
srgbColor.mV[VRED] = linearTosRGB(a.mV[VRED]);
|
||||
srgbColor.mV[VGREEN] = linearTosRGB(a.mV[VGREEN]);
|
||||
srgbColor.mV[VBLUE] = linearTosRGB(a.mV[VBLUE]);
|
||||
|
||||
return srgbColor;
|
||||
}
|
||||
|
||||
inline const LLColor3 linearColor3p(const F32* v) {
|
||||
inline const LLColor3 linearColor3p(const F32* v)
|
||||
{
|
||||
LLColor3 linearColor;
|
||||
linearColor.mV[0] = sRGBtoLinear(v[0]);
|
||||
linearColor.mV[1] = sRGBtoLinear(v[1]);
|
||||
linearColor.mV[2] = sRGBtoLinear(v[2]);
|
||||
linearColor.mV[VRED] = sRGBtoLinear(v[VRED]);
|
||||
linearColor.mV[VGREEN] = sRGBtoLinear(v[VGREEN]);
|
||||
linearColor.mV[VBLUE] = sRGBtoLinear(v[VBLUE]);
|
||||
|
||||
return linearColor;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline const LLColor3 linearColor3(const T& a) {
|
||||
inline const LLColor3 linearColor3(const T& a)
|
||||
{
|
||||
return linearColor3p(a.mV);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline const LLVector3 linearColor3v(const T& a) {
|
||||
inline const LLVector3 linearColor3v(const T& a)
|
||||
{
|
||||
return LLVector3(linearColor3p(a.mV).mV);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,59 +30,46 @@
|
|||
#include "v3color.h"
|
||||
#include "v4color.h"
|
||||
|
||||
inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
|
||||
inline LLColor3 componentDiv(const LLColor3& left, const LLColor3& right)
|
||||
{
|
||||
return LLColor3(left.mV[0] / right.mV[0],
|
||||
left.mV[1] / right.mV[1],
|
||||
left.mV[2] / right.mV[2]);
|
||||
return LLColor3(left.mV[VRED] / right.mV[VRED], left.mV[VGREEN] / right.mV[VGREEN], left.mV[VBLUE] / right.mV[VBLUE]);
|
||||
}
|
||||
|
||||
|
||||
inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
|
||||
inline LLColor3 componentMult(const LLColor3& left, const LLColor3& right)
|
||||
{
|
||||
return LLColor3(left.mV[0] * right.mV[0],
|
||||
left.mV[1] * right.mV[1],
|
||||
left.mV[2] * right.mV[2]);
|
||||
return LLColor3(left.mV[VRED] * right.mV[VRED], left.mV[VGREEN] * right.mV[VGREEN], left.mV[VBLUE] * right.mV[VBLUE]);
|
||||
}
|
||||
|
||||
|
||||
inline LLColor3 componentExp(LLColor3 const &v)
|
||||
inline LLColor3 componentExp(const LLColor3& v)
|
||||
{
|
||||
return LLColor3(exp(v.mV[0]),
|
||||
exp(v.mV[1]),
|
||||
exp(v.mV[2]));
|
||||
return LLColor3(exp(v.mV[VRED]), exp(v.mV[VGREEN]), exp(v.mV[VBLUE]));
|
||||
}
|
||||
|
||||
inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
|
||||
inline LLColor3 componentPow(const LLColor3& v, F32 exponent)
|
||||
{
|
||||
return LLColor3(pow(v.mV[0], exponent),
|
||||
pow(v.mV[1], exponent),
|
||||
pow(v.mV[2], exponent));
|
||||
return LLColor3(pow(v.mV[VRED], exponent), pow(v.mV[VGREEN], exponent), pow(v.mV[VBLUE], exponent));
|
||||
}
|
||||
|
||||
inline LLColor3 componentSaturate(LLColor3 const &v)
|
||||
inline LLColor3 componentSaturate(const LLColor3& v)
|
||||
{
|
||||
return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
|
||||
std::max(std::min(v.mV[1], 1.f), 0.f),
|
||||
std::max(std::min(v.mV[2], 1.f), 0.f));
|
||||
return LLColor3(std::max(std::min(v.mV[VRED], 1.f), 0.f),
|
||||
std::max(std::min(v.mV[VGREEN], 1.f), 0.f),
|
||||
std::max(std::min(v.mV[VBLUE], 1.f), 0.f));
|
||||
}
|
||||
|
||||
|
||||
inline LLColor3 componentSqrt(LLColor3 const &v)
|
||||
inline LLColor3 componentSqrt(const LLColor3& v)
|
||||
{
|
||||
return LLColor3(sqrt(v.mV[0]),
|
||||
sqrt(v.mV[1]),
|
||||
sqrt(v.mV[2]));
|
||||
return LLColor3(sqrt(v.mV[VRED]), sqrt(v.mV[VGREEN]), sqrt(v.mV[VBLUE]));
|
||||
}
|
||||
|
||||
inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
|
||||
inline void componentMultBy(LLColor3& left, const LLColor3& right)
|
||||
{
|
||||
left.mV[0] *= right.mV[0];
|
||||
left.mV[1] *= right.mV[1];
|
||||
left.mV[2] *= right.mV[2];
|
||||
left.mV[VRED] *= right.mV[VRED];
|
||||
left.mV[VGREEN] *= right.mV[VGREEN];
|
||||
left.mV[VBLUE] *= right.mV[VBLUE];
|
||||
}
|
||||
|
||||
inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
|
||||
inline LLColor3 colorMix(const LLColor3& left, const LLColor3& right, F32 amount)
|
||||
{
|
||||
return (left + ((right - left) * amount));
|
||||
}
|
||||
|
|
@ -92,25 +79,24 @@ inline LLColor3 smear(F32 val)
|
|||
return LLColor3(val, val, val);
|
||||
}
|
||||
|
||||
inline F32 color_intens(const LLColor3 &col)
|
||||
inline F32 color_intens(const LLColor3& col)
|
||||
{
|
||||
return col.mV[0] + col.mV[1] + col.mV[2];
|
||||
return col.mV[VRED] + col.mV[VGREEN] + col.mV[VBLUE];
|
||||
}
|
||||
|
||||
inline F32 color_max(const LLColor3 &col)
|
||||
inline F32 color_max(const LLColor3& col)
|
||||
{
|
||||
return llmax(col.mV[0], col.mV[1], col.mV[2]);
|
||||
return llmax(col.mV[VRED], col.mV[VGREEN], col.mV[VBLUE]);
|
||||
}
|
||||
|
||||
inline F32 color_max(const LLColor4 &col)
|
||||
inline F32 color_max(const LLColor4& col)
|
||||
{
|
||||
return llmax(col.mV[0], col.mV[1], col.mV[2]);
|
||||
return llmax(col.mV[VRED], col.mV[VGREEN], col.mV[VBLUE]);
|
||||
}
|
||||
|
||||
|
||||
inline F32 color_min(const LLColor3 &col)
|
||||
inline F32 color_min(const LLColor3& col)
|
||||
{
|
||||
return llmin(col.mV[0], col.mV[1], col.mV[2]);
|
||||
return llmin(col.mV[VRED], col.mV[VGREEN], col.mV[VBLUE]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "v3dmath.h"
|
||||
|
||||
//#include "vmath.h"
|
||||
#include "v4math.h"
|
||||
#include "m4math.h"
|
||||
#include "m3math.h"
|
||||
|
|
@ -57,13 +56,13 @@ bool LLVector3d::clamp(F64 min, F64 max)
|
|||
{
|
||||
bool ret{ false };
|
||||
|
||||
if (mdV[0] < min) { mdV[0] = min; ret = true; }
|
||||
if (mdV[1] < min) { mdV[1] = min; ret = true; }
|
||||
if (mdV[2] < min) { mdV[2] = min; ret = true; }
|
||||
if (mdV[VX] < min) { mdV[VX] = min; ret = true; }
|
||||
if (mdV[VY] < min) { mdV[VY] = min; ret = true; }
|
||||
if (mdV[VZ] < min) { mdV[VZ] = min; ret = true; }
|
||||
|
||||
if (mdV[0] > max) { mdV[0] = max; ret = true; }
|
||||
if (mdV[1] > max) { mdV[1] = max; ret = true; }
|
||||
if (mdV[2] > max) { mdV[2] = max; ret = true; }
|
||||
if (mdV[VX] > max) { mdV[VX] = max; ret = true; }
|
||||
if (mdV[VY] > max) { mdV[VY] = max; ret = true; }
|
||||
if (mdV[VZ] > max) { mdV[VZ] = max; ret = true; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -74,9 +73,9 @@ bool LLVector3d::abs()
|
|||
{
|
||||
bool ret{ false };
|
||||
|
||||
if (mdV[0] < 0.0) { mdV[0] = -mdV[0]; ret = true; }
|
||||
if (mdV[1] < 0.0) { mdV[1] = -mdV[1]; ret = true; }
|
||||
if (mdV[2] < 0.0) { mdV[2] = -mdV[2]; ret = true; }
|
||||
if (mdV[VX] < 0.0) { mdV[VX] = -mdV[VX]; ret = true; }
|
||||
if (mdV[VY] < 0.0) { mdV[VY] = -mdV[VY]; ret = true; }
|
||||
if (mdV[VZ] < 0.0) { mdV[VZ] = -mdV[VZ]; ret = true; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -89,37 +88,37 @@ std::ostream& operator<<(std::ostream& s, const LLVector3d &a)
|
|||
|
||||
const LLVector3d& LLVector3d::operator=(const LLVector4 &a)
|
||||
{
|
||||
mdV[0] = a.mV[0];
|
||||
mdV[1] = a.mV[1];
|
||||
mdV[2] = a.mV[2];
|
||||
mdV[VX] = a.mV[VX];
|
||||
mdV[VY] = a.mV[VY];
|
||||
mdV[VZ] = a.mV[VZ];
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3d& LLVector3d::rotVec(const LLMatrix3 &mat)
|
||||
const LLVector3d& LLVector3d::rotVec(const LLMatrix3& mat)
|
||||
{
|
||||
*this = *this * mat;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3d& LLVector3d::rotVec(const LLQuaternion &q)
|
||||
const LLVector3d& LLVector3d::rotVec(const LLQuaternion& q)
|
||||
{
|
||||
*this = *this * q;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3d& LLVector3d::rotVec(F64 angle, const LLVector3d &vec)
|
||||
const LLVector3d& LLVector3d::rotVec(F64 angle, const LLVector3d& vec)
|
||||
{
|
||||
if ( !vec.isExactlyZero() && angle )
|
||||
if (!vec.isExactlyZero() && angle)
|
||||
{
|
||||
*this = *this * LLMatrix3((F32)angle, vec);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3d& LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z)
|
||||
const LLVector3d& LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z)
|
||||
{
|
||||
LLVector3d vec(x, y, z);
|
||||
if ( !vec.isExactlyZero() && angle )
|
||||
if (!vec.isExactlyZero() && angle)
|
||||
{
|
||||
*this = *this * LLMatrix3((F32)angle, vec);
|
||||
}
|
||||
|
|
@ -129,16 +128,16 @@ const LLVector3d& LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z)
|
|||
|
||||
bool LLVector3d::parseVector3d(const std::string& buf, LLVector3d* value)
|
||||
{
|
||||
if( buf.empty() || value == nullptr)
|
||||
if (buf.empty() || value == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLVector3d v;
|
||||
S32 count = sscanf( buf.c_str(), "%lf %lf %lf", v.mdV + 0, v.mdV + 1, v.mdV + 2 );
|
||||
if( 3 == count )
|
||||
S32 count = sscanf(buf.c_str(), "%lf %lf %lf", v.mdV + VX, v.mdV + VY, v.mdV + VZ);
|
||||
if (3 == count)
|
||||
{
|
||||
value->setVec( v );
|
||||
value->setVec(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,102 +32,101 @@
|
|||
|
||||
class LLVector3d
|
||||
{
|
||||
public:
|
||||
F64 mdV[3];
|
||||
public:
|
||||
F64 mdV[3];
|
||||
|
||||
const static LLVector3d zero;
|
||||
const static LLVector3d x_axis;
|
||||
const static LLVector3d y_axis;
|
||||
const static LLVector3d z_axis;
|
||||
const static LLVector3d x_axis_neg;
|
||||
const static LLVector3d y_axis_neg;
|
||||
const static LLVector3d z_axis_neg;
|
||||
const static LLVector3d zero;
|
||||
const static LLVector3d x_axis;
|
||||
const static LLVector3d y_axis;
|
||||
const static LLVector3d z_axis;
|
||||
const static LLVector3d x_axis_neg;
|
||||
const static LLVector3d y_axis_neg;
|
||||
const static LLVector3d z_axis_neg;
|
||||
|
||||
inline LLVector3d(); // Initializes LLVector3d to (0, 0, 0)
|
||||
inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z)
|
||||
inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2])
|
||||
inline explicit LLVector3d(const LLVector3 &vec);
|
||||
explicit LLVector3d(const LLSD& sd)
|
||||
{
|
||||
setValue(sd);
|
||||
}
|
||||
inline LLVector3d(); // Initializes LLVector3d to (0, 0, 0)
|
||||
inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z)
|
||||
inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2])
|
||||
inline explicit LLVector3d(const LLVector3 &vec);
|
||||
explicit LLVector3d(const LLSD& sd)
|
||||
{
|
||||
setValue(sd);
|
||||
}
|
||||
|
||||
void setValue(const LLSD& sd)
|
||||
{
|
||||
mdV[0] = sd[0].asReal();
|
||||
mdV[1] = sd[1].asReal();
|
||||
mdV[2] = sd[2].asReal();
|
||||
}
|
||||
void setValue(const LLSD& sd)
|
||||
{
|
||||
mdV[VX] = sd[0].asReal();
|
||||
mdV[VY] = sd[1].asReal();
|
||||
mdV[VZ] = sd[2].asReal();
|
||||
}
|
||||
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mdV[0];
|
||||
ret[1] = mdV[1];
|
||||
ret[2] = mdV[2];
|
||||
return ret;
|
||||
}
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mdV[VX];
|
||||
ret[1] = mdV[VY];
|
||||
ret[2] = mdV[VZ];
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline bool isFinite() const; // checks to see if all values of LLVector3d are finite
|
||||
bool clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns true if data changed
|
||||
bool abs(); // sets all values to absolute value of original value (first octant), returns true if changed
|
||||
inline bool isFinite() const; // checks to see if all values of LLVector3d are finite
|
||||
bool clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns true if data changed
|
||||
bool abs(); // sets all values to absolute value of original value (first octant), returns true if changed
|
||||
|
||||
inline const LLVector3d& clear(); // Clears LLVector3d to (0, 0, 0, 1)
|
||||
inline const LLVector3d& clearVec(); // deprecated
|
||||
inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0)
|
||||
inline const LLVector3d& zeroVec(); // deprecated
|
||||
inline const LLVector3d& set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1)
|
||||
inline const LLVector3d& set(const LLVector3d &vec); // Sets LLVector3d to vec
|
||||
inline const LLVector3d& set(const F64 *vec); // Sets LLVector3d to vec
|
||||
inline const LLVector3d& set(const LLVector3 &vec);
|
||||
inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // deprecated
|
||||
inline const LLVector3d& setVec(const LLVector3d &vec); // deprecated
|
||||
inline const LLVector3d& setVec(const F64 *vec); // deprecated
|
||||
inline const LLVector3d& setVec(const LLVector3 &vec); // deprecated
|
||||
inline const LLVector3d& clear(); // Clears LLVector3d to (0, 0, 0, 1)
|
||||
inline const LLVector3d& clearVec(); // deprecated
|
||||
inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0)
|
||||
inline const LLVector3d& zeroVec(); // deprecated
|
||||
inline const LLVector3d& set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1)
|
||||
inline const LLVector3d& set(const LLVector3d &vec); // Sets LLVector3d to vec
|
||||
inline const LLVector3d& set(const F64 *vec); // Sets LLVector3d to vec
|
||||
inline const LLVector3d& set(const LLVector3 &vec);
|
||||
inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // deprecated
|
||||
inline const LLVector3d& setVec(const LLVector3d &vec); // deprecated
|
||||
inline const LLVector3d& setVec(const F64 *vec); // deprecated
|
||||
inline const LLVector3d& setVec(const LLVector3 &vec); // deprecated
|
||||
|
||||
F64 magVec() const; // deprecated
|
||||
F64 magVecSquared() const; // deprecated
|
||||
inline F64 normVec(); // deprecated
|
||||
F64 magVec() const; // deprecated
|
||||
F64 magVecSquared() const; // deprecated
|
||||
inline F64 normVec(); // deprecated
|
||||
|
||||
F64 length() const; // Returns magnitude of LLVector3d
|
||||
F64 lengthSquared() const; // Returns magnitude squared of LLVector3d
|
||||
inline F64 normalize(); // Normalizes and returns the magnitude of LLVector3d
|
||||
F64 length() const; // Returns magnitude of LLVector3d
|
||||
F64 lengthSquared() const; // Returns magnitude squared of LLVector3d
|
||||
inline F64 normalize(); // Normalizes and returns the magnitude of LLVector3d
|
||||
|
||||
const LLVector3d& rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians
|
||||
const LLVector3d& rotVec(const F64 angle, const F64 x, const F64 y, const F64 z); // Rotates about x,y,z by angle radians
|
||||
const LLVector3d& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
|
||||
const LLVector3d& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
|
||||
const LLVector3d& rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians
|
||||
const LLVector3d& rotVec(const F64 angle, const F64 x, const F64 y, const F64 z); // Rotates about x,y,z by angle radians
|
||||
const LLVector3d& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
|
||||
const LLVector3d& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
|
||||
|
||||
bool isNull() const; // Returns true if vector has a _very_small_ length
|
||||
bool isExactlyZero() const { return !mdV[VX] && !mdV[VY] && !mdV[VZ]; }
|
||||
bool isNull() const; // Returns true if vector has a _very_small_ length
|
||||
bool isExactlyZero() const { return !mdV[VX] && !mdV[VY] && !mdV[VZ]; }
|
||||
|
||||
const LLVector3d& operator=(const LLVector4 &a);
|
||||
const LLVector3d& operator=(const LLVector4 &a);
|
||||
|
||||
F64 operator[](int idx) const { return mdV[idx]; }
|
||||
F64 &operator[](int idx) { return mdV[idx]; }
|
||||
F64 operator[](int idx) const { return mdV[idx]; }
|
||||
F64 &operator[](int idx) { return mdV[idx]; }
|
||||
|
||||
friend LLVector3d operator+(const LLVector3d& a, const LLVector3d& b); // Return vector a + b
|
||||
friend LLVector3d operator-(const LLVector3d& a, const LLVector3d& b); // Return vector a minus b
|
||||
friend F64 operator*(const LLVector3d& a, const LLVector3d& b); // Return a dot b
|
||||
friend LLVector3d operator%(const LLVector3d& a, const LLVector3d& b); // Return a cross b
|
||||
friend LLVector3d operator*(const LLVector3d& a, const F64 k); // Return a times scaler k
|
||||
friend LLVector3d operator/(const LLVector3d& a, const F64 k); // Return a divided by scaler k
|
||||
friend LLVector3d operator*(const F64 k, const LLVector3d& a); // Return a times scaler k
|
||||
friend bool operator==(const LLVector3d& a, const LLVector3d& b); // Return a == b
|
||||
friend bool operator!=(const LLVector3d& a, const LLVector3d& b); // Return a != b
|
||||
friend LLVector3d operator+(const LLVector3d& a, const LLVector3d& b); // Return vector a + b
|
||||
friend LLVector3d operator-(const LLVector3d& a, const LLVector3d& b); // Return vector a minus b
|
||||
friend F64 operator*(const LLVector3d& a, const LLVector3d& b); // Return a dot b
|
||||
friend LLVector3d operator%(const LLVector3d& a, const LLVector3d& b); // Return a cross b
|
||||
friend LLVector3d operator*(const LLVector3d& a, const F64 k); // Return a times scaler k
|
||||
friend LLVector3d operator/(const LLVector3d& a, const F64 k); // Return a divided by scaler k
|
||||
friend LLVector3d operator*(const F64 k, const LLVector3d& a); // Return a times scaler k
|
||||
friend bool operator==(const LLVector3d& a, const LLVector3d& b); // Return a == b
|
||||
friend bool operator!=(const LLVector3d& a, const LLVector3d& b); // Return a != b
|
||||
|
||||
friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b); // Return vector a + b
|
||||
friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b); // Return vector a minus b
|
||||
friend const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b); // Return a cross b
|
||||
friend const LLVector3d& operator*=(LLVector3d& a, const F64 k); // Return a times scaler k
|
||||
friend const LLVector3d& operator/=(LLVector3d& a, const F64 k); // Return a divided by scaler k
|
||||
friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b); // Return vector a + b
|
||||
friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b); // Return vector a minus b
|
||||
friend const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b); // Return a cross b
|
||||
friend const LLVector3d& operator*=(LLVector3d& a, const F64 k); // Return a times scaler k
|
||||
friend const LLVector3d& operator/=(LLVector3d& a, const F64 k); // Return a divided by scaler k
|
||||
|
||||
friend LLVector3d operator-(const LLVector3d& a); // Return vector -a
|
||||
friend LLVector3d operator-(const LLVector3d& a); // Return vector -a
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLVector3d& a); // Stream a
|
||||
|
||||
static bool parseVector3d(const std::string& buf, LLVector3d* value);
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLVector3d& a); // Stream a
|
||||
|
||||
static bool parseVector3d(const std::string& buf, LLVector3d* value);
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_copyable<LLVector3d>::value, "LLVector3d must be trivial copy");
|
||||
|
|
@ -138,26 +137,26 @@ typedef LLVector3d LLGlobalVec;
|
|||
|
||||
inline const LLVector3d &LLVector3d::set(const LLVector3 &vec)
|
||||
{
|
||||
mdV[0] = vec.mV[0];
|
||||
mdV[1] = vec.mV[1];
|
||||
mdV[2] = vec.mV[2];
|
||||
mdV[VX] = vec.mV[VX];
|
||||
mdV[VY] = vec.mV[VY];
|
||||
mdV[VZ] = vec.mV[VZ];
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const LLVector3d &LLVector3d::setVec(const LLVector3 &vec)
|
||||
{
|
||||
mdV[0] = vec.mV[0];
|
||||
mdV[1] = vec.mV[1];
|
||||
mdV[2] = vec.mV[2];
|
||||
mdV[VX] = vec.mV[VX];
|
||||
mdV[VY] = vec.mV[VY];
|
||||
mdV[VZ] = vec.mV[VZ];
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline LLVector3d::LLVector3d(void)
|
||||
{
|
||||
mdV[0] = 0.f;
|
||||
mdV[1] = 0.f;
|
||||
mdV[2] = 0.f;
|
||||
mdV[VX] = 0.f;
|
||||
mdV[VY] = 0.f;
|
||||
mdV[VZ] = 0.f;
|
||||
}
|
||||
|
||||
inline LLVector3d::LLVector3d(const F64 x, const F64 y, const F64 z)
|
||||
|
|
@ -203,33 +202,33 @@ inline bool LLVector3d::isFinite() const
|
|||
|
||||
inline const LLVector3d& LLVector3d::clear(void)
|
||||
{
|
||||
mdV[0] = 0.f;
|
||||
mdV[1] = 0.f;
|
||||
mdV[2]= 0.f;
|
||||
mdV[VX] = 0.f;
|
||||
mdV[VY] = 0.f;
|
||||
mdV[VZ] = 0.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLVector3d& LLVector3d::clearVec(void)
|
||||
{
|
||||
mdV[0] = 0.f;
|
||||
mdV[1] = 0.f;
|
||||
mdV[2]= 0.f;
|
||||
mdV[VX] = 0.f;
|
||||
mdV[VY] = 0.f;
|
||||
mdV[VZ] = 0.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLVector3d& LLVector3d::setZero(void)
|
||||
{
|
||||
mdV[0] = 0.f;
|
||||
mdV[1] = 0.f;
|
||||
mdV[2] = 0.f;
|
||||
mdV[VX] = 0.f;
|
||||
mdV[VY] = 0.f;
|
||||
mdV[VZ] = 0.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLVector3d& LLVector3d::zeroVec(void)
|
||||
{
|
||||
mdV[0] = 0.f;
|
||||
mdV[1] = 0.f;
|
||||
mdV[2] = 0.f;
|
||||
mdV[VX] = 0.f;
|
||||
mdV[VY] = 0.f;
|
||||
mdV[VZ] = 0.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
|
@ -243,17 +242,17 @@ inline const LLVector3d& LLVector3d::set(const F64 x, const F64 y, const F64
|
|||
|
||||
inline const LLVector3d& LLVector3d::set(const LLVector3d &vec)
|
||||
{
|
||||
mdV[0] = vec.mdV[0];
|
||||
mdV[1] = vec.mdV[1];
|
||||
mdV[2] = vec.mdV[2];
|
||||
mdV[VX] = vec.mdV[VX];
|
||||
mdV[VY] = vec.mdV[VY];
|
||||
mdV[VZ] = vec.mdV[VZ];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLVector3d& LLVector3d::set(const F64 *vec)
|
||||
{
|
||||
mdV[0] = vec[0];
|
||||
mdV[1] = vec[1];
|
||||
mdV[2] = vec[2];
|
||||
mdV[VX] = vec[0];
|
||||
mdV[VY] = vec[1];
|
||||
mdV[VZ] = vec[2];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
|
@ -265,61 +264,62 @@ inline const LLVector3d& LLVector3d::setVec(const F64 x, const F64 y, const F
|
|||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLVector3d& LLVector3d::setVec(const LLVector3d &vec)
|
||||
inline const LLVector3d& LLVector3d::setVec(const LLVector3d& vec)
|
||||
{
|
||||
mdV[0] = vec.mdV[0];
|
||||
mdV[1] = vec.mdV[1];
|
||||
mdV[2] = vec.mdV[2];
|
||||
mdV[VX] = vec.mdV[VX];
|
||||
mdV[VY] = vec.mdV[VY];
|
||||
mdV[VZ] = vec.mdV[VZ];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLVector3d& LLVector3d::setVec(const F64 *vec)
|
||||
inline const LLVector3d& LLVector3d::setVec(const F64* vec)
|
||||
{
|
||||
mdV[0] = vec[0];
|
||||
mdV[1] = vec[1];
|
||||
mdV[2] = vec[2];
|
||||
mdV[VX] = vec[VX];
|
||||
mdV[VY] = vec[VY];
|
||||
mdV[VZ] = vec[VZ];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline F64 LLVector3d::normVec(void)
|
||||
inline F64 LLVector3d::normVec()
|
||||
{
|
||||
F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
|
||||
F64 mag = (F32)sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]); // This explicit cast to F32 limits the precision for numerical stability.
|
||||
// Without it, Unit test "v3dmath_h" fails at "1:angle_between" on macos.
|
||||
F64 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mdV[0] *= oomag;
|
||||
mdV[1] *= oomag;
|
||||
mdV[2] *= oomag;
|
||||
oomag = 1.0/mag;
|
||||
mdV[VX] *= oomag;
|
||||
mdV[VY] *= oomag;
|
||||
mdV[VZ] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdV[0] = 0.f;
|
||||
mdV[1] = 0.f;
|
||||
mdV[2] = 0.f;
|
||||
mdV[VX] = 0.0;
|
||||
mdV[VY] = 0.0;
|
||||
mdV[VZ] = 0.0;
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
}
|
||||
|
||||
inline F64 LLVector3d::normalize(void)
|
||||
inline F64 LLVector3d::normalize()
|
||||
{
|
||||
F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
|
||||
F64 mag = (F32)sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]); // Same as in normVec() above.
|
||||
F64 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mdV[0] *= oomag;
|
||||
mdV[1] *= oomag;
|
||||
mdV[2] *= oomag;
|
||||
oomag = 1.0/mag;
|
||||
mdV[VX] *= oomag;
|
||||
mdV[VY] *= oomag;
|
||||
mdV[VZ] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mdV[0] = 0.f;
|
||||
mdV[1] = 0.f;
|
||||
mdV[2] = 0.f;
|
||||
mdV[VX] = 0.0;
|
||||
mdV[VY] = 0.0;
|
||||
mdV[VZ] = 0.0;
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
|
|
@ -327,24 +327,24 @@ inline F64 LLVector3d::normalize(void)
|
|||
|
||||
// LLVector3d Magnitude and Normalization Functions
|
||||
|
||||
inline F64 LLVector3d::magVec(void) const
|
||||
inline F64 LLVector3d::magVec() const
|
||||
{
|
||||
return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
|
||||
return sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]);
|
||||
}
|
||||
|
||||
inline F64 LLVector3d::magVecSquared(void) const
|
||||
inline F64 LLVector3d::magVecSquared() const
|
||||
{
|
||||
return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
|
||||
return mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ];
|
||||
}
|
||||
|
||||
inline F64 LLVector3d::length(void) const
|
||||
inline F64 LLVector3d::length() const
|
||||
{
|
||||
return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]);
|
||||
return sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]);
|
||||
}
|
||||
|
||||
inline F64 LLVector3d::lengthSquared(void) const
|
||||
inline F64 LLVector3d::lengthSquared() const
|
||||
{
|
||||
return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2];
|
||||
return mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ];
|
||||
}
|
||||
|
||||
inline LLVector3d operator+(const LLVector3d& a, const LLVector3d& b)
|
||||
|
|
@ -361,109 +361,109 @@ inline LLVector3d operator-(const LLVector3d& a, const LLVector3d& b)
|
|||
|
||||
inline F64 operator*(const LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]);
|
||||
return (a.mdV[VX]*b.mdV[VX] + a.mdV[VY]*b.mdV[VY] + a.mdV[VZ]*b.mdV[VZ]);
|
||||
}
|
||||
|
||||
inline LLVector3d operator%(const LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] );
|
||||
return LLVector3d( a.mdV[VY]*b.mdV[VZ] - b.mdV[VY]*a.mdV[VZ], a.mdV[VZ]*b.mdV[VX] - b.mdV[VZ]*a.mdV[VX], a.mdV[VX]*b.mdV[VY] - b.mdV[VX]*a.mdV[VY] );
|
||||
}
|
||||
|
||||
inline LLVector3d operator/(const LLVector3d& a, const F64 k)
|
||||
{
|
||||
F64 t = 1.f / k;
|
||||
return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t );
|
||||
return LLVector3d( a.mdV[VX] * t, a.mdV[VY] * t, a.mdV[VZ] * t );
|
||||
}
|
||||
|
||||
inline LLVector3d operator*(const LLVector3d& a, const F64 k)
|
||||
{
|
||||
return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
|
||||
return LLVector3d( a.mdV[VX] * k, a.mdV[VY] * k, a.mdV[VZ] * k );
|
||||
}
|
||||
|
||||
inline LLVector3d operator*(F64 k, const LLVector3d& a)
|
||||
{
|
||||
return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k );
|
||||
return LLVector3d( a.mdV[VX] * k, a.mdV[VY] * k, a.mdV[VZ] * k );
|
||||
}
|
||||
|
||||
inline bool operator==(const LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
return ( (a.mdV[0] == b.mdV[0])
|
||||
&&(a.mdV[1] == b.mdV[1])
|
||||
&&(a.mdV[2] == b.mdV[2]));
|
||||
return ( (a.mdV[VX] == b.mdV[VX])
|
||||
&&(a.mdV[VY] == b.mdV[VY])
|
||||
&&(a.mdV[VZ] == b.mdV[VZ]));
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
return ( (a.mdV[0] != b.mdV[0])
|
||||
||(a.mdV[1] != b.mdV[1])
|
||||
||(a.mdV[2] != b.mdV[2]));
|
||||
return ( (a.mdV[VX] != b.mdV[VX])
|
||||
||(a.mdV[VY] != b.mdV[VY])
|
||||
||(a.mdV[VZ] != b.mdV[VZ]));
|
||||
}
|
||||
|
||||
inline const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
a.mdV[0] += b.mdV[0];
|
||||
a.mdV[1] += b.mdV[1];
|
||||
a.mdV[2] += b.mdV[2];
|
||||
a.mdV[VX] += b.mdV[VX];
|
||||
a.mdV[VY] += b.mdV[VY];
|
||||
a.mdV[VZ] += b.mdV[VZ];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
a.mdV[0] -= b.mdV[0];
|
||||
a.mdV[1] -= b.mdV[1];
|
||||
a.mdV[2] -= b.mdV[2];
|
||||
a.mdV[VX] -= b.mdV[VX];
|
||||
a.mdV[VY] -= b.mdV[VY];
|
||||
a.mdV[VZ] -= b.mdV[VZ];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]);
|
||||
LLVector3d ret( a.mdV[VY]*b.mdV[VZ] - b.mdV[VY]*a.mdV[VZ], a.mdV[VZ]*b.mdV[VX] - b.mdV[VZ]*a.mdV[VX], a.mdV[VX]*b.mdV[VY] - b.mdV[VX]*a.mdV[VY]);
|
||||
a = ret;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3d& operator*=(LLVector3d& a, const F64 k)
|
||||
{
|
||||
a.mdV[0] *= k;
|
||||
a.mdV[1] *= k;
|
||||
a.mdV[2] *= k;
|
||||
a.mdV[VX] *= k;
|
||||
a.mdV[VY] *= k;
|
||||
a.mdV[VZ] *= k;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3d& operator/=(LLVector3d& a, const F64 k)
|
||||
{
|
||||
F64 t = 1.f / k;
|
||||
a.mdV[0] *= t;
|
||||
a.mdV[1] *= t;
|
||||
a.mdV[2] *= t;
|
||||
a.mdV[VX] *= t;
|
||||
a.mdV[VY] *= t;
|
||||
a.mdV[VZ] *= t;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline LLVector3d operator-(const LLVector3d& a)
|
||||
{
|
||||
return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] );
|
||||
return LLVector3d( -a.mdV[VX], -a.mdV[VY], -a.mdV[VZ] );
|
||||
}
|
||||
|
||||
inline F64 dist_vec(const LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
F64 x = a.mdV[0] - b.mdV[0];
|
||||
F64 y = a.mdV[1] - b.mdV[1];
|
||||
F64 z = a.mdV[2] - b.mdV[2];
|
||||
F64 x = a.mdV[VX] - b.mdV[VX];
|
||||
F64 y = a.mdV[VY] - b.mdV[VY];
|
||||
F64 z = a.mdV[VZ] - b.mdV[VZ];
|
||||
return (F32) sqrt( x*x + y*y + z*z );
|
||||
}
|
||||
|
||||
inline F64 dist_vec_squared(const LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
F64 x = a.mdV[0] - b.mdV[0];
|
||||
F64 y = a.mdV[1] - b.mdV[1];
|
||||
F64 z = a.mdV[2] - b.mdV[2];
|
||||
F64 x = a.mdV[VX] - b.mdV[VX];
|
||||
F64 y = a.mdV[VY] - b.mdV[VY];
|
||||
F64 z = a.mdV[VZ] - b.mdV[VZ];
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
inline F64 dist_vec_squared2D(const LLVector3d& a, const LLVector3d& b)
|
||||
{
|
||||
F64 x = a.mdV[0] - b.mdV[0];
|
||||
F64 y = a.mdV[1] - b.mdV[1];
|
||||
F64 x = a.mdV[VX] - b.mdV[VX];
|
||||
F64 y = a.mdV[VY] - b.mdV[VY];
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "v3math.h"
|
||||
|
||||
//#include "vmath.h"
|
||||
#include "v2math.h"
|
||||
#include "v4math.h"
|
||||
#include "m4math.h"
|
||||
|
|
@ -58,13 +57,13 @@ bool LLVector3::clamp(F32 min, F32 max)
|
|||
{
|
||||
bool ret{ false };
|
||||
|
||||
if (mV[0] < min) { mV[0] = min; ret = true; }
|
||||
if (mV[1] < min) { mV[1] = min; ret = true; }
|
||||
if (mV[2] < min) { mV[2] = min; ret = true; }
|
||||
if (mV[VX] < min) { mV[VX] = min; ret = true; }
|
||||
if (mV[VY] < min) { mV[VY] = min; ret = true; }
|
||||
if (mV[VZ] < min) { mV[VZ] = min; ret = true; }
|
||||
|
||||
if (mV[0] > max) { mV[0] = max; ret = true; }
|
||||
if (mV[1] > max) { mV[1] = max; ret = true; }
|
||||
if (mV[2] > max) { mV[2] = max; ret = true; }
|
||||
if (mV[VX] > max) { mV[VX] = max; ret = true; }
|
||||
if (mV[VY] > max) { mV[VY] = max; ret = true; }
|
||||
if (mV[VZ] > max) { mV[VZ] = max; ret = true; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -85,9 +84,9 @@ bool LLVector3::clampLength( F32 length_limit )
|
|||
{
|
||||
length_limit = 0.f;
|
||||
}
|
||||
mV[0] *= length_limit;
|
||||
mV[1] *= length_limit;
|
||||
mV[2] *= length_limit;
|
||||
mV[VX] *= length_limit;
|
||||
mV[VY] *= length_limit;
|
||||
mV[VZ] *= length_limit;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -116,35 +115,35 @@ bool LLVector3::clampLength( F32 length_limit )
|
|||
{
|
||||
// yes it can be salvaged -->
|
||||
// bring the components down before we normalize
|
||||
mV[0] /= max_abs_component;
|
||||
mV[1] /= max_abs_component;
|
||||
mV[2] /= max_abs_component;
|
||||
mV[VX] /= max_abs_component;
|
||||
mV[VY] /= max_abs_component;
|
||||
mV[VZ] /= max_abs_component;
|
||||
normalize();
|
||||
|
||||
if (length_limit < 0.f)
|
||||
{
|
||||
length_limit = 0.f;
|
||||
}
|
||||
mV[0] *= length_limit;
|
||||
mV[1] *= length_limit;
|
||||
mV[2] *= length_limit;
|
||||
mV[VX] *= length_limit;
|
||||
mV[VY] *= length_limit;
|
||||
mV[VZ] *= length_limit;
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec)
|
||||
bool LLVector3::clamp(const LLVector3& min_vec, const LLVector3& max_vec)
|
||||
{
|
||||
bool ret{ false };
|
||||
|
||||
if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = true; }
|
||||
if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = true; }
|
||||
if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = true; }
|
||||
if (mV[VX] < min_vec[0]) { mV[VX] = min_vec[0]; ret = true; }
|
||||
if (mV[VY] < min_vec[1]) { mV[VY] = min_vec[1]; ret = true; }
|
||||
if (mV[VZ] < min_vec[2]) { mV[VZ] = min_vec[2]; ret = true; }
|
||||
|
||||
if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = true; }
|
||||
if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = true; }
|
||||
if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = true; }
|
||||
if (mV[VX] > max_vec[0]) { mV[VX] = max_vec[0]; ret = true; }
|
||||
if (mV[VY] > max_vec[1]) { mV[VY] = max_vec[1]; ret = true; }
|
||||
if (mV[VZ] > max_vec[2]) { mV[VZ] = max_vec[2]; ret = true; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -156,15 +155,15 @@ bool LLVector3::abs()
|
|||
{
|
||||
bool ret{ false };
|
||||
|
||||
if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = true; }
|
||||
if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = true; }
|
||||
if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = true; }
|
||||
if (mV[VX] < 0.f) { mV[VX] = -mV[VX]; ret = true; }
|
||||
if (mV[VY] < 0.f) { mV[VY] = -mV[VY]; ret = true; }
|
||||
if (mV[VZ] < 0.f) { mV[VZ] = -mV[VZ]; ret = true; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Quatizations
|
||||
void LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)
|
||||
void LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)
|
||||
{
|
||||
F32 x = mV[VX];
|
||||
F32 y = mV[VY];
|
||||
|
|
@ -179,7 +178,7 @@ void LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)
|
|||
mV[VZ] = z;
|
||||
}
|
||||
|
||||
void LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)
|
||||
void LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)
|
||||
{
|
||||
mV[VX] = U8_to_F32(F32_to_U8(mV[VX], lowerxy, upperxy), lowerxy, upperxy);;
|
||||
mV[VY] = U8_to_F32(F32_to_U8(mV[VY], lowerxy, upperxy), lowerxy, upperxy);
|
||||
|
|
@ -187,20 +186,20 @@ void LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz)
|
|||
}
|
||||
|
||||
|
||||
void LLVector3::snap(S32 sig_digits)
|
||||
void LLVector3::snap(S32 sig_digits)
|
||||
{
|
||||
mV[VX] = snap_to_sig_figs(mV[VX], sig_digits);
|
||||
mV[VY] = snap_to_sig_figs(mV[VY], sig_digits);
|
||||
mV[VZ] = snap_to_sig_figs(mV[VZ], sig_digits);
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::rotVec(const LLMatrix3 &mat)
|
||||
const LLVector3& LLVector3::rotVec(const LLMatrix3& mat)
|
||||
{
|
||||
*this = *this * mat;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::rotVec(const LLQuaternion &q)
|
||||
const LLVector3& LLVector3::rotVec(const LLQuaternion& q)
|
||||
{
|
||||
*this = *this * q;
|
||||
return *this;
|
||||
|
|
@ -228,26 +227,26 @@ const LLVector3& LLVector3::transVec(const LLMatrix4& mat)
|
|||
}
|
||||
|
||||
|
||||
const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3 &vec)
|
||||
const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3& vec)
|
||||
{
|
||||
if ( !vec.isExactlyZero() && angle )
|
||||
if (!vec.isExactlyZero() && angle)
|
||||
{
|
||||
*this = *this * LLQuaternion(angle, vec);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::rotVec(F32 angle, F32 x, F32 y, F32 z)
|
||||
const LLVector3& LLVector3::rotVec(F32 angle, F32 x, F32 y, F32 z)
|
||||
{
|
||||
LLVector3 vec(x, y, z);
|
||||
if ( !vec.isExactlyZero() && angle )
|
||||
if (!vec.isExactlyZero() && angle)
|
||||
{
|
||||
*this = *this * LLQuaternion(angle, vec);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::scaleVec(const LLVector3& vec)
|
||||
const LLVector3& LLVector3::scaleVec(const LLVector3& vec)
|
||||
{
|
||||
mV[VX] *= vec.mV[VX];
|
||||
mV[VY] *= vec.mV[VY];
|
||||
|
|
@ -256,42 +255,42 @@ const LLVector3& LLVector3::scaleVec(const LLVector3& vec)
|
|||
return *this;
|
||||
}
|
||||
|
||||
LLVector3 LLVector3::scaledVec(const LLVector3& vec) const
|
||||
LLVector3 LLVector3::scaledVec(const LLVector3& vec) const
|
||||
{
|
||||
LLVector3 ret = LLVector3(*this);
|
||||
ret.scaleVec(vec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::set(const LLVector3d &vec)
|
||||
const LLVector3& LLVector3::set(const LLVector3d& vec)
|
||||
{
|
||||
mV[0] = (F32)vec.mdV[0];
|
||||
mV[1] = (F32)vec.mdV[1];
|
||||
mV[2] = (F32)vec.mdV[2];
|
||||
mV[VX] = (F32)vec.mdV[VX];
|
||||
mV[VY] = (F32)vec.mdV[VY];
|
||||
mV[VZ] = (F32)vec.mdV[VZ];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::set(const LLVector4 &vec)
|
||||
const LLVector3& LLVector3::set(const LLVector4& vec)
|
||||
{
|
||||
mV[0] = vec.mV[0];
|
||||
mV[1] = vec.mV[1];
|
||||
mV[2] = vec.mV[2];
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::setVec(const LLVector3d &vec)
|
||||
const LLVector3& LLVector3::setVec(const LLVector3d& vec)
|
||||
{
|
||||
mV[0] = (F32)vec.mdV[0];
|
||||
mV[1] = (F32)vec.mdV[1];
|
||||
mV[2] = (F32)vec.mdV[2];
|
||||
mV[VX] = (F32)vec.mdV[0];
|
||||
mV[VY] = (F32)vec.mdV[1];
|
||||
mV[VZ] = (F32)vec.mdV[2];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::setVec(const LLVector4 &vec)
|
||||
const LLVector3& LLVector3::setVec(const LLVector4& vec)
|
||||
{
|
||||
mV[0] = vec.mV[0];
|
||||
mV[1] = vec.mV[1];
|
||||
mV[2] = vec.mV[2];
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
|
@ -299,17 +298,17 @@ LLVector3::LLVector3(const LLVector2 &vec)
|
|||
{
|
||||
mV[VX] = (F32)vec.mV[VX];
|
||||
mV[VY] = (F32)vec.mV[VY];
|
||||
mV[VZ] = 0;
|
||||
mV[VZ] = 0.f;
|
||||
}
|
||||
|
||||
LLVector3::LLVector3(const LLVector3d &vec)
|
||||
LLVector3::LLVector3(const LLVector3d& vec)
|
||||
{
|
||||
mV[VX] = (F32)vec.mdV[VX];
|
||||
mV[VY] = (F32)vec.mdV[VY];
|
||||
mV[VZ] = (F32)vec.mdV[VZ];
|
||||
}
|
||||
|
||||
LLVector3::LLVector3(const LLVector4 &vec)
|
||||
LLVector3::LLVector3(const LLVector4& vec)
|
||||
{
|
||||
mV[VX] = (F32)vec.mV[VX];
|
||||
mV[VY] = (F32)vec.mV[VY];
|
||||
|
|
@ -319,7 +318,6 @@ LLVector3::LLVector3(const LLVector4 &vec)
|
|||
LLVector3::LLVector3(const LLVector4a& vec)
|
||||
: LLVector3(vec.getF32ptr())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LLVector3::LLVector3(const LLSD& sd)
|
||||
|
|
@ -330,20 +328,20 @@ LLVector3::LLVector3(const LLSD& sd)
|
|||
LLSD LLVector3::getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mV[0];
|
||||
ret[1] = mV[1];
|
||||
ret[2] = mV[2];
|
||||
ret[VX] = mV[VX];
|
||||
ret[VY] = mV[VY];
|
||||
ret[VZ] = mV[VZ];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLVector3::setValue(const LLSD& sd)
|
||||
{
|
||||
mV[0] = (F32) sd[0].asReal();
|
||||
mV[1] = (F32) sd[1].asReal();
|
||||
mV[2] = (F32) sd[2].asReal();
|
||||
mV[VX] = (F32) sd[VX].asReal();
|
||||
mV[VY] = (F32) sd[VY].asReal();
|
||||
mV[VZ] = (F32) sd[VZ].asReal();
|
||||
}
|
||||
|
||||
const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot)
|
||||
const LLVector3& operator*=(LLVector3& a, const LLQuaternion& rot)
|
||||
{
|
||||
const F32 rw = - rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] - rot.mQ[VZ] * a.mV[VZ];
|
||||
const F32 rx = rot.mQ[VW] * a.mV[VX] + rot.mQ[VY] * a.mV[VZ] - rot.mQ[VZ] * a.mV[VY];
|
||||
|
|
@ -360,16 +358,16 @@ const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot)
|
|||
// static
|
||||
bool LLVector3::parseVector3(const std::string& buf, LLVector3* value)
|
||||
{
|
||||
if( buf.empty() || value == nullptr)
|
||||
if (buf.empty() || value == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLVector3 v;
|
||||
S32 count = sscanf( buf.c_str(), "%f %f %f", v.mV + 0, v.mV + 1, v.mV + 2 );
|
||||
if( 3 == count )
|
||||
S32 count = sscanf(buf.c_str(), "%f %f %f", v.mV + VX, v.mV + VY, v.mV + VZ);
|
||||
if (3 == count)
|
||||
{
|
||||
value->setVec( v );
|
||||
value->setVec(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +379,7 @@ bool LLVector3::parseVector3(const std::string& buf, LLVector3* value)
|
|||
LLVector3 point_to_box_offset(LLVector3& pos, const LLVector3* box)
|
||||
{
|
||||
LLVector3 offset;
|
||||
for (S32 k=0; k<3; k++)
|
||||
for (S32 k = 0; k < 3; k++)
|
||||
{
|
||||
offset[k] = 0;
|
||||
if (pos[k] < box[0][k])
|
||||
|
|
@ -410,4 +408,3 @@ bool box_valid_and_non_zero(const LLVector3* box)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class LLQuaternion;
|
|||
|
||||
// LLvector3 = |x y z w|
|
||||
|
||||
static const U32 LENGTHOFVECTOR3 = 3;
|
||||
static constexpr U32 LENGTHOFVECTOR3 = 3;
|
||||
|
||||
class LLVector3
|
||||
{
|
||||
|
|
@ -112,24 +112,24 @@ class LLVector3
|
|||
const LLVector3& setVec(const LLVector4 &vec); // deprecated
|
||||
const LLVector3& setVec(const LLVector3d &vec); // deprecated
|
||||
|
||||
F32 length() const; // Returns magnitude of LLVector3
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLVector3
|
||||
F32 magVec() const; // deprecated
|
||||
F32 magVecSquared() const; // deprecated
|
||||
F32 length() const; // Returns magnitude of LLVector3
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLVector3
|
||||
F32 magVec() const; // deprecated
|
||||
F32 magVecSquared() const; // deprecated
|
||||
|
||||
inline F32 normalize(); // Normalizes and returns the magnitude of LLVector3
|
||||
inline F32 normVec(); // deprecated
|
||||
inline F32 normalize(); // Normalizes and returns the magnitude of LLVector3
|
||||
inline F32 normVec(); // deprecated
|
||||
|
||||
inline bool inRange( F32 min, F32 max ) const; // Returns true if all values of the vector are between min and max
|
||||
inline bool inRange(F32 min, F32 max) const; // Returns true if all values of the vector are between min and max
|
||||
|
||||
const LLVector3& rotVec(F32 angle, const LLVector3 &vec); // Rotates about vec by angle radians
|
||||
const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians
|
||||
const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
|
||||
const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
|
||||
const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v)
|
||||
const LLVector3& rotVec(F32 angle, const LLVector3 &vec); // Rotates about vec by angle radians
|
||||
const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians
|
||||
const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
|
||||
const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
|
||||
const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v)
|
||||
|
||||
const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec
|
||||
LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec
|
||||
const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec
|
||||
LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec
|
||||
|
||||
bool isNull() const; // Returns true if vector has a _very_small_ length
|
||||
bool isExactlyZero() const { return !mV[VX] && !mV[VY] && !mV[VZ]; }
|
||||
|
|
@ -185,25 +185,19 @@ LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vect
|
|||
LLVector3 point_to_box_offset(LLVector3& pos, const LLVector3* box); // Displacement from query point to nearest point on bounding box.
|
||||
bool box_valid_and_non_zero(const LLVector3* box);
|
||||
|
||||
inline LLVector3::LLVector3(void)
|
||||
inline LLVector3::LLVector3()
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
inline LLVector3::LLVector3(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline LLVector3::LLVector3(const glm::vec3& vec)
|
||||
|
|
@ -234,38 +228,30 @@ inline LLVector3::LLVector3(const LLVector3 ©)
|
|||
// checker
|
||||
inline bool LLVector3::isFinite() const
|
||||
{
|
||||
return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]));
|
||||
return llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]);
|
||||
}
|
||||
|
||||
|
||||
// Clear and Assignment Functions
|
||||
|
||||
inline void LLVector3::clear(void)
|
||||
inline void LLVector3::clear()
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
set(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
inline void LLVector3::setZero(void)
|
||||
inline void LLVector3::setZero()
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector3::clearVec(void)
|
||||
inline void LLVector3::clearVec()
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector3::zeroVec(void)
|
||||
inline void LLVector3::zeroVec()
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector3::set(F32 x, F32 y, F32 z)
|
||||
|
|
@ -275,18 +261,14 @@ inline void LLVector3::set(F32 x, F32 y, F32 z)
|
|||
mV[VZ] = z;
|
||||
}
|
||||
|
||||
inline void LLVector3::set(const LLVector3 &vec)
|
||||
inline void LLVector3::set(const LLVector3& vec)
|
||||
{
|
||||
mV[0] = vec.mV[0];
|
||||
mV[1] = vec.mV[1];
|
||||
mV[2] = vec.mV[2];
|
||||
set(vec.mV[VX], vec.mV[VY], vec.mV[VZ]);
|
||||
}
|
||||
|
||||
inline void LLVector3::set(const F32 *vec)
|
||||
inline void LLVector3::set(const F32* vec)
|
||||
{
|
||||
mV[0] = vec[0];
|
||||
mV[1] = vec[1];
|
||||
mV[2] = vec[2];
|
||||
set(vec[VX], vec[VY], vec[VZ]);
|
||||
}
|
||||
|
||||
inline void LLVector3::set(const glm::vec4& vec)
|
||||
|
|
@ -306,213 +288,181 @@ inline void LLVector3::set(const glm::vec3& vec)
|
|||
// deprecated
|
||||
inline void LLVector3::setVec(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector3::setVec(const LLVector3 &vec)
|
||||
inline void LLVector3::setVec(const LLVector3& vec)
|
||||
{
|
||||
mV[0] = vec.mV[0];
|
||||
mV[1] = vec.mV[1];
|
||||
mV[2] = vec.mV[2];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector3::setVec(const F32 *vec)
|
||||
inline void LLVector3::setVec(const F32* vec)
|
||||
{
|
||||
mV[0] = vec[0];
|
||||
mV[1] = vec[1];
|
||||
mV[2] = vec[2];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline F32 LLVector3::normalize(void)
|
||||
inline F32 LLVector3::normalize()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
F32 oomag;
|
||||
F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[0] *= oomag;
|
||||
mV[1] *= oomag;
|
||||
mV[2] *= oomag;
|
||||
*this /= mag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
clear();
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector3::normVec(void)
|
||||
inline F32 LLVector3::normVec()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[0] *= oomag;
|
||||
mV[1] *= oomag;
|
||||
mV[2] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return normalize();
|
||||
}
|
||||
|
||||
// LLVector3 Magnitude and Normalization Functions
|
||||
|
||||
inline F32 LLVector3::length(void) const
|
||||
inline F32 LLVector3::length() const
|
||||
{
|
||||
return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
return sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
inline F32 LLVector3::lengthSquared(void) const
|
||||
inline F32 LLVector3::lengthSquared() const
|
||||
{
|
||||
return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
|
||||
return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
|
||||
}
|
||||
|
||||
inline F32 LLVector3::magVec(void) const
|
||||
inline F32 LLVector3::magVec() const
|
||||
{
|
||||
return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]);
|
||||
return length();
|
||||
}
|
||||
|
||||
inline F32 LLVector3::magVecSquared(void) const
|
||||
inline F32 LLVector3::magVecSquared() const
|
||||
{
|
||||
return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2];
|
||||
return lengthSquared();
|
||||
}
|
||||
|
||||
inline bool LLVector3::inRange( F32 min, F32 max ) const
|
||||
inline bool LLVector3::inRange(F32 min, F32 max) const
|
||||
{
|
||||
return mV[0] >= min && mV[0] <= max &&
|
||||
mV[1] >= min && mV[1] <= max &&
|
||||
mV[2] >= min && mV[2] <= max;
|
||||
return mV[VX] >= min && mV[VX] <= max &&
|
||||
mV[VY] >= min && mV[VY] <= max &&
|
||||
mV[VZ] >= min && mV[VZ] <= max;
|
||||
}
|
||||
|
||||
inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b)
|
||||
inline LLVector3 operator+(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
LLVector3 c(a);
|
||||
return c += b;
|
||||
}
|
||||
|
||||
inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b)
|
||||
inline LLVector3 operator-(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
LLVector3 c(a);
|
||||
return c -= b;
|
||||
}
|
||||
|
||||
inline F32 operator*(const LLVector3 &a, const LLVector3 &b)
|
||||
inline F32 operator*(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]);
|
||||
return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]);
|
||||
}
|
||||
|
||||
inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b)
|
||||
inline LLVector3 operator%(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
return LLVector3( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1] );
|
||||
return LLVector3(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]);
|
||||
}
|
||||
|
||||
inline LLVector3 operator/(const LLVector3 &a, F32 k)
|
||||
inline LLVector3 operator/(const LLVector3& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t );
|
||||
return LLVector3( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t );
|
||||
}
|
||||
|
||||
inline LLVector3 operator*(const LLVector3 &a, F32 k)
|
||||
inline LLVector3 operator*(const LLVector3& a, F32 k)
|
||||
{
|
||||
return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
|
||||
return LLVector3( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
|
||||
}
|
||||
|
||||
inline LLVector3 operator*(F32 k, const LLVector3 &a)
|
||||
inline LLVector3 operator*(F32 k, const LLVector3& a)
|
||||
{
|
||||
return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k );
|
||||
return LLVector3( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
|
||||
}
|
||||
|
||||
inline bool operator==(const LLVector3 &a, const LLVector3 &b)
|
||||
inline bool operator==(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
return ( (a.mV[0] == b.mV[0])
|
||||
&&(a.mV[1] == b.mV[1])
|
||||
&&(a.mV[2] == b.mV[2]));
|
||||
return ( (a.mV[VX] == b.mV[VX])
|
||||
&&(a.mV[VY] == b.mV[VY])
|
||||
&&(a.mV[VZ] == b.mV[VZ]));
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLVector3 &a, const LLVector3 &b)
|
||||
inline bool operator!=(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
return ( (a.mV[0] != b.mV[0])
|
||||
||(a.mV[1] != b.mV[1])
|
||||
||(a.mV[2] != b.mV[2]));
|
||||
return ( (a.mV[VX] != b.mV[VX])
|
||||
||(a.mV[VY] != b.mV[VY])
|
||||
||(a.mV[VZ] != b.mV[VZ]));
|
||||
}
|
||||
|
||||
inline bool operator<(const LLVector3 &a, const LLVector3 &b)
|
||||
inline bool operator<(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
return (a.mV[0] < b.mV[0]
|
||||
|| (a.mV[0] == b.mV[0]
|
||||
&& (a.mV[1] < b.mV[1]
|
||||
|| ((a.mV[1] == b.mV[1])
|
||||
&& a.mV[2] < b.mV[2]))));
|
||||
return (a.mV[VX] < b.mV[VX]
|
||||
|| (a.mV[VX] == b.mV[VX]
|
||||
&& (a.mV[VY] < b.mV[VY]
|
||||
|| ((a.mV[VY] == b.mV[VY])
|
||||
&& a.mV[VZ] < b.mV[VZ]))));
|
||||
}
|
||||
|
||||
inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b)
|
||||
inline const LLVector3& operator+=(LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
a.mV[0] += b.mV[0];
|
||||
a.mV[1] += b.mV[1];
|
||||
a.mV[2] += b.mV[2];
|
||||
a.mV[VX] += b.mV[VX];
|
||||
a.mV[VY] += b.mV[VY];
|
||||
a.mV[VZ] += b.mV[VZ];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b)
|
||||
inline const LLVector3& operator-=(LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
a.mV[0] -= b.mV[0];
|
||||
a.mV[1] -= b.mV[1];
|
||||
a.mV[2] -= b.mV[2];
|
||||
a.mV[VX] -= b.mV[VX];
|
||||
a.mV[VY] -= b.mV[VY];
|
||||
a.mV[VZ] -= b.mV[VZ];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b)
|
||||
inline const LLVector3& operator%=(LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
LLVector3 ret( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1]);
|
||||
LLVector3 ret(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]);
|
||||
a = ret;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3& operator*=(LLVector3 &a, F32 k)
|
||||
inline const LLVector3& operator*=(LLVector3& a, F32 k)
|
||||
{
|
||||
a.mV[0] *= k;
|
||||
a.mV[1] *= k;
|
||||
a.mV[2] *= k;
|
||||
a.mV[VX] *= k;
|
||||
a.mV[VY] *= k;
|
||||
a.mV[VZ] *= k;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b)
|
||||
inline const LLVector3& operator*=(LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
a.mV[0] *= b.mV[0];
|
||||
a.mV[1] *= b.mV[1];
|
||||
a.mV[2] *= b.mV[2];
|
||||
a.mV[VX] *= b.mV[VX];
|
||||
a.mV[VY] *= b.mV[VY];
|
||||
a.mV[VZ] *= b.mV[VZ];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector3& operator/=(LLVector3 &a, F32 k)
|
||||
inline const LLVector3& operator/=(LLVector3& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
a.mV[0] *= t;
|
||||
a.mV[1] *= t;
|
||||
a.mV[2] *= t;
|
||||
a *= 1.f / k;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline LLVector3 operator-(const LLVector3 &a)
|
||||
inline LLVector3 operator-(const LLVector3& a)
|
||||
{
|
||||
return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );
|
||||
return LLVector3(-a.mV[VX], -a.mV[VY], -a.mV[VZ]);
|
||||
}
|
||||
|
||||
inline LLVector3::operator glm::vec3() const
|
||||
|
|
@ -526,40 +476,37 @@ inline LLVector3::operator glm::vec4() const
|
|||
return glm::vec4(mV[VX], mV[VY], mV[VZ], 1.f);
|
||||
}
|
||||
|
||||
inline F32 dist_vec(const LLVector3 &a, const LLVector3 &b)
|
||||
inline F32 dist_vec(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 z = a.mV[2] - b.mV[2];
|
||||
return (F32) sqrt( x*x + y*y + z*z );
|
||||
F32 x = a.mV[VX] - b.mV[VX];
|
||||
F32 y = a.mV[VY] - b.mV[VY];
|
||||
F32 z = a.mV[VZ] - b.mV[VZ];
|
||||
return sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
inline F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b)
|
||||
inline F32 dist_vec_squared(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 z = a.mV[2] - b.mV[2];
|
||||
F32 x = a.mV[VX] - b.mV[VX];
|
||||
F32 y = a.mV[VY] - b.mV[VY];
|
||||
F32 z = a.mV[VZ] - b.mV[VZ];
|
||||
return x*x + y*y + z*z;
|
||||
}
|
||||
|
||||
inline F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b)
|
||||
inline F32 dist_vec_squared2D(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
F32 x = a.mV[0] - b.mV[0];
|
||||
F32 y = a.mV[1] - b.mV[1];
|
||||
F32 x = a.mV[VX] - b.mV[VX];
|
||||
F32 y = a.mV[VY] - b.mV[VY];
|
||||
return x*x + y*y;
|
||||
}
|
||||
|
||||
inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
|
||||
inline LLVector3 projected_vec(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
F32 bb = b * b;
|
||||
if (bb > FP_MAG_THRESHOLD * FP_MAG_THRESHOLD)
|
||||
{
|
||||
return ((a * b) / bb) * b;
|
||||
}
|
||||
else
|
||||
{
|
||||
return b.zero;
|
||||
}
|
||||
return b.zero;
|
||||
}
|
||||
|
||||
inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b)
|
||||
|
|
@ -574,18 +521,18 @@ inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b)
|
|||
return normalized_a * (b_length / dot_product);
|
||||
}
|
||||
|
||||
inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
|
||||
inline LLVector3 parallel_component(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
return projected_vec(a, b);
|
||||
}
|
||||
|
||||
inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b)
|
||||
inline LLVector3 orthogonal_component(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
return a - projected_vec(a, b);
|
||||
}
|
||||
|
||||
|
||||
inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
|
||||
inline LLVector3 lerp(const LLVector3& a, const LLVector3& b, F32 u)
|
||||
{
|
||||
return LLVector3(
|
||||
a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
|
||||
|
|
@ -596,11 +543,7 @@ inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
|
|||
|
||||
inline bool LLVector3::isNull() const
|
||||
{
|
||||
if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
|
||||
}
|
||||
|
||||
inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
|
||||
|
|
@ -641,17 +584,17 @@ inline F32 angle_between(const LLVector3& a, const LLVector3& b)
|
|||
ab = 0.0f; // get rid of negative zero
|
||||
}
|
||||
LLVector3 c = a % b; // crossproduct
|
||||
return atan2f(sqrtf(c * c), ab); // return the angle
|
||||
return atan2f(c.length(), ab); // return the angle
|
||||
}
|
||||
|
||||
inline bool are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon)
|
||||
inline bool are_parallel(const LLVector3& a, const LLVector3& b, F32 epsilon)
|
||||
{
|
||||
LLVector3 an = a;
|
||||
LLVector3 bn = b;
|
||||
an.normalize();
|
||||
bn.normalize();
|
||||
F32 dot = an * bn;
|
||||
if ( (1.0f - fabs(dot)) < epsilon)
|
||||
if (1.0f - fabs(dot) < epsilon)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,65 +124,64 @@ LLColor4 LLColor4::cyan6(0.2f, 0.6f, 0.6f, 1.0f);
|
|||
// conversion
|
||||
LLColor4::operator LLColor4U() const
|
||||
{
|
||||
return LLColor4U(
|
||||
(U8)llclampb(ll_round(mV[VRED]*255.f)),
|
||||
(U8)llclampb(ll_round(mV[VGREEN]*255.f)),
|
||||
(U8)llclampb(ll_round(mV[VBLUE]*255.f)),
|
||||
(U8)llclampb(ll_round(mV[VALPHA]*255.f)));
|
||||
return LLColor4U((U8)llclampb(ll_round(mV[VRED] * 255.f)),
|
||||
(U8)llclampb(ll_round(mV[VGREEN] * 255.f)),
|
||||
(U8)llclampb(ll_round(mV[VBLUE] * 255.f)),
|
||||
(U8)llclampb(ll_round(mV[VALPHA] * 255.f)));
|
||||
}
|
||||
|
||||
LLColor4::LLColor4(const LLColor3 &vec, F32 a)
|
||||
LLColor4::LLColor4(const LLColor3& vec, F32 a)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = a;
|
||||
}
|
||||
|
||||
LLColor4::LLColor4(const LLColor4U& color4u)
|
||||
{
|
||||
const F32 SCALE = 1.f/255.f;
|
||||
mV[VRED] = color4u.mV[VRED] * SCALE;
|
||||
mV[VGREEN] = color4u.mV[VGREEN] * SCALE;
|
||||
mV[VBLUE] = color4u.mV[VBLUE] * SCALE;
|
||||
mV[VALPHA] = color4u.mV[VALPHA] * SCALE;
|
||||
constexpr F32 SCALE = 1.f / 255.f;
|
||||
mV[VRED] = color4u.mV[VRED] * SCALE;
|
||||
mV[VGREEN] = color4u.mV[VGREEN] * SCALE;
|
||||
mV[VBLUE] = color4u.mV[VBLUE] * SCALE;
|
||||
mV[VALPHA] = color4u.mV[VALPHA] * SCALE;
|
||||
}
|
||||
|
||||
LLColor4::LLColor4(const LLVector4& vector4)
|
||||
{
|
||||
mV[VRED] = vector4.mV[VRED];
|
||||
mV[VRED] = vector4.mV[VRED];
|
||||
mV[VGREEN] = vector4.mV[VGREEN];
|
||||
mV[VBLUE] = vector4.mV[VBLUE];
|
||||
mV[VBLUE] = vector4.mV[VBLUE];
|
||||
mV[VALPHA] = vector4.mV[VALPHA];
|
||||
}
|
||||
|
||||
const LLColor4& LLColor4::set(const LLColor4U& color4u)
|
||||
{
|
||||
const F32 SCALE = 1.f/255.f;
|
||||
mV[VRED] = color4u.mV[VRED] * SCALE;
|
||||
mV[VGREEN] = color4u.mV[VGREEN] * SCALE;
|
||||
mV[VBLUE] = color4u.mV[VBLUE] * SCALE;
|
||||
mV[VALPHA] = color4u.mV[VALPHA] * SCALE;
|
||||
constexpr F32 SCALE = 1.f / 255.f;
|
||||
mV[VRED] = color4u.mV[VRED] * SCALE;
|
||||
mV[VGREEN] = color4u.mV[VGREEN] * SCALE;
|
||||
mV[VBLUE] = color4u.mV[VBLUE] * SCALE;
|
||||
mV[VALPHA] = color4u.mV[VALPHA] * SCALE;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LLColor4& LLColor4::set(const LLColor3 &vec)
|
||||
const LLColor4& LLColor4::set(const LLColor3& vec)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LLColor4& LLColor4::set(const LLColor3 &vec, F32 a)
|
||||
const LLColor4& LLColor4::set(const LLColor3& vec, F32 a)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = a;
|
||||
return (*this);
|
||||
}
|
||||
|
|
@ -190,33 +189,33 @@ const LLColor4& LLColor4::set(const LLColor3 &vec, F32 a)
|
|||
// deprecated -- use set()
|
||||
const LLColor4& LLColor4::setVec(const LLColor4U& color4u)
|
||||
{
|
||||
const F32 SCALE = 1.f/255.f;
|
||||
mV[VRED] = color4u.mV[VRED] * SCALE;
|
||||
mV[VGREEN] = color4u.mV[VGREEN] * SCALE;
|
||||
mV[VBLUE] = color4u.mV[VBLUE] * SCALE;
|
||||
mV[VALPHA] = color4u.mV[VALPHA] * SCALE;
|
||||
constexpr F32 SCALE = 1.f / 255.f;
|
||||
mV[VRED] = color4u.mV[VRED] * SCALE;
|
||||
mV[VGREEN] = color4u.mV[VGREEN] * SCALE;
|
||||
mV[VBLUE] = color4u.mV[VBLUE] * SCALE;
|
||||
mV[VALPHA] = color4u.mV[VALPHA] * SCALE;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated -- use set()
|
||||
const LLColor4& LLColor4::setVec(const LLColor3 &vec)
|
||||
const LLColor4& LLColor4::setVec(const LLColor3& vec)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated -- use set()
|
||||
const LLColor4& LLColor4::setVec(const LLColor3 &vec, F32 a)
|
||||
const LLColor4& LLColor4::setVec(const LLColor3& vec, F32 a)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = a;
|
||||
return (*this);
|
||||
}
|
||||
|
|
@ -228,110 +227,110 @@ void LLColor4::setValue(const LLSD& sd)
|
|||
F32 val;
|
||||
bool out_of_range = false;
|
||||
val = sd[0].asReal();
|
||||
mV[0] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range = mV[0] != val;
|
||||
mV[VRED] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range = mV[VRED] != val;
|
||||
|
||||
val = sd[1].asReal();
|
||||
mV[1] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range |= mV[1] != val;
|
||||
mV[VGREEN] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range |= mV[VGREEN] != val;
|
||||
|
||||
val = sd[2].asReal();
|
||||
mV[2] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range |= mV[2] != val;
|
||||
mV[VBLUE] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range |= mV[VBLUE] != val;
|
||||
|
||||
val = sd[3].asReal();
|
||||
mV[3] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range |= mV[3] != val;
|
||||
mV[VALPHA] = llclamp(val, 0.f, 1.f);
|
||||
out_of_range |= mV[VALPHA] != val;
|
||||
|
||||
if (out_of_range)
|
||||
{
|
||||
LL_WARNS() << "LLSD color value out of range!" << LL_ENDL;
|
||||
}
|
||||
#else
|
||||
mV[0] = (F32) sd[0].asReal();
|
||||
mV[1] = (F32) sd[1].asReal();
|
||||
mV[2] = (F32) sd[2].asReal();
|
||||
mV[3] = (F32) sd[3].asReal();
|
||||
mV[VRED] = (F32)sd[VRED].asReal();
|
||||
mV[VGREEN] = (F32)sd[VGREEN].asReal();
|
||||
mV[VBLUE] = (F32)sd[VBLUE].asReal();
|
||||
mV[VALPHA] = (F32)sd[VALPHA].asReal();
|
||||
#endif
|
||||
}
|
||||
|
||||
const LLColor4& LLColor4::operator=(const LLColor3 &a)
|
||||
const LLColor4& LLColor4::operator=(const LLColor3& a)
|
||||
{
|
||||
mV[VRED] = a.mV[VRED];
|
||||
mV[VRED] = a.mV[VRED];
|
||||
mV[VGREEN] = a.mV[VGREEN];
|
||||
mV[VBLUE] = a.mV[VBLUE];
|
||||
mV[VBLUE] = a.mV[VBLUE];
|
||||
|
||||
// converting from an rgb sets a=1 (opaque)
|
||||
// converting from an rgb sets a=1 (opaque)
|
||||
mV[VALPHA] = 1.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLColor4 &a)
|
||||
std::ostream& operator<<(std::ostream& s, const LLColor4& a)
|
||||
{
|
||||
s << "{ " << a.mV[VRED] << ", " << a.mV[VGREEN] << ", " << a.mV[VBLUE] << ", " << a.mV[VALPHA] << " }";
|
||||
return s;
|
||||
}
|
||||
|
||||
bool operator==(const LLColor4 &a, const LLColor3 &b)
|
||||
bool operator==(const LLColor4& a, const LLColor3& b)
|
||||
{
|
||||
return ( (a.mV[VRED] == b.mV[VRED])
|
||||
&&(a.mV[VGREEN] == b.mV[VGREEN])
|
||||
&&(a.mV[VBLUE] == b.mV[VBLUE]));
|
||||
return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE]));
|
||||
}
|
||||
|
||||
bool operator!=(const LLColor4 &a, const LLColor3 &b)
|
||||
bool operator!=(const LLColor4& a, const LLColor3& b)
|
||||
{
|
||||
return ( (a.mV[VRED] != b.mV[VRED])
|
||||
||(a.mV[VGREEN] != b.mV[VGREEN])
|
||||
||(a.mV[VBLUE] != b.mV[VBLUE]));
|
||||
return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE]));
|
||||
}
|
||||
|
||||
LLColor3 vec4to3(const LLColor4 &vec)
|
||||
LLColor3 vec4to3(const LLColor4& vec)
|
||||
{
|
||||
LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]);
|
||||
LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]);
|
||||
return temp;
|
||||
}
|
||||
|
||||
LLColor4 vec3to4(const LLColor3 &vec)
|
||||
LLColor4 vec3to4(const LLColor3& vec)
|
||||
{
|
||||
LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]);
|
||||
LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]);
|
||||
return temp;
|
||||
}
|
||||
|
||||
static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn )
|
||||
static F32 hueToRgb(F32 val1In, F32 val2In, F32 valHUeIn)
|
||||
{
|
||||
if ( valHUeIn < 0.0f ) valHUeIn += 1.0f;
|
||||
if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f;
|
||||
if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn );
|
||||
if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In );
|
||||
if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f );
|
||||
return ( val1In );
|
||||
if (valHUeIn < 0.0f)
|
||||
valHUeIn += 1.0f;
|
||||
if (valHUeIn > 1.0f)
|
||||
valHUeIn -= 1.0f;
|
||||
if ((6.0f * valHUeIn) < 1.0f)
|
||||
return (val1In + (val2In - val1In) * 6.0f * valHUeIn);
|
||||
if ((2.0f * valHUeIn) < 1.0f)
|
||||
return (val2In);
|
||||
if ((3.0f * valHUeIn) < 2.0f)
|
||||
return (val1In + (val2In - val1In) * ((2.0f / 3.0f) - valHUeIn) * 6.0f);
|
||||
return (val1In);
|
||||
}
|
||||
|
||||
void LLColor4::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn)
|
||||
void LLColor4::setHSL(F32 hValIn, F32 sValIn, F32 lValIn)
|
||||
{
|
||||
if ( sValIn < 0.00001f )
|
||||
if (sValIn < 0.00001f)
|
||||
{
|
||||
mV[VRED] = lValIn;
|
||||
mV[VRED] = lValIn;
|
||||
mV[VGREEN] = lValIn;
|
||||
mV[VBLUE] = lValIn;
|
||||
mV[VBLUE] = lValIn;
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 interVal1;
|
||||
F32 interVal2;
|
||||
|
||||
if ( lValIn < 0.5f )
|
||||
interVal2 = lValIn * ( 1.0f + sValIn );
|
||||
if (lValIn < 0.5f)
|
||||
interVal2 = lValIn * (1.0f + sValIn);
|
||||
else
|
||||
interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn );
|
||||
interVal2 = (lValIn + sValIn) - (sValIn * lValIn);
|
||||
|
||||
interVal1 = 2.0f * lValIn - interVal2;
|
||||
|
||||
mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) );
|
||||
mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn );
|
||||
mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) );
|
||||
mV[VRED] = hueToRgb(interVal1, interVal2, hValIn + (1.f / 3.f));
|
||||
mV[VGREEN] = hueToRgb(interVal1, interVal2, hValIn);
|
||||
mV[VBLUE] = hueToRgb(interVal1, interVal2, hValIn - (1.f / 3.f));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -341,58 +340,61 @@ void LLColor4::calcHSL(F32* hue, F32* saturation, F32* luminance) const
|
|||
F32 var_G = mV[VGREEN];
|
||||
F32 var_B = mV[VBLUE];
|
||||
|
||||
F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) );
|
||||
F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) );
|
||||
F32 var_Min = (var_R < (var_G < var_B ? var_G : var_B) ? var_R : (var_G < var_B ? var_G : var_B));
|
||||
F32 var_Max = (var_R > (var_G > var_B ? var_G : var_B) ? var_R : (var_G > var_B ? var_G : var_B));
|
||||
|
||||
F32 del_Max = var_Max - var_Min;
|
||||
|
||||
F32 L = ( var_Max + var_Min ) / 2.0f;
|
||||
F32 L = (var_Max + var_Min) / 2.0f;
|
||||
F32 H = 0.0f;
|
||||
F32 S = 0.0f;
|
||||
|
||||
if ( del_Max == 0.0f )
|
||||
if (del_Max == 0.0f)
|
||||
{
|
||||
H = 0.0f;
|
||||
S = 0.0f;
|
||||
H = 0.0f;
|
||||
S = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( L < 0.5 )
|
||||
S = del_Max / ( var_Max + var_Min );
|
||||
if (L < 0.5f)
|
||||
S = del_Max / (var_Max + var_Min);
|
||||
else
|
||||
S = del_Max / ( 2.0f - var_Max - var_Min );
|
||||
S = del_Max / (2.0f - var_Max - var_Min);
|
||||
|
||||
F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max;
|
||||
F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max;
|
||||
F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max;
|
||||
F32 del_R = (((var_Max - var_R) / 6.0f) + (del_Max / 2.0f)) / del_Max;
|
||||
F32 del_G = (((var_Max - var_G) / 6.0f) + (del_Max / 2.0f)) / del_Max;
|
||||
F32 del_B = (((var_Max - var_B) / 6.0f) + (del_Max / 2.0f)) / del_Max;
|
||||
|
||||
if ( var_R >= var_Max )
|
||||
if (var_R >= var_Max)
|
||||
H = del_B - del_G;
|
||||
else
|
||||
if ( var_G >= var_Max )
|
||||
H = ( 1.0f / 3.0f ) + del_R - del_B;
|
||||
else
|
||||
if ( var_B >= var_Max )
|
||||
H = ( 2.0f / 3.0f ) + del_G - del_R;
|
||||
else if (var_G >= var_Max)
|
||||
H = (1.0f / 3.0f) + del_R - del_B;
|
||||
else if (var_B >= var_Max)
|
||||
H = (2.0f / 3.0f) + del_G - del_R;
|
||||
|
||||
if ( H < 0.0f ) H += 1.0f;
|
||||
if ( H > 1.0f ) H -= 1.0f;
|
||||
if (H < 0.0f)
|
||||
H += 1.0f;
|
||||
if (H > 1.0f)
|
||||
H -= 1.0f;
|
||||
}
|
||||
|
||||
if (hue) *hue = H;
|
||||
if (saturation) *saturation = S;
|
||||
if (luminance) *luminance = L;
|
||||
if (hue)
|
||||
*hue = H;
|
||||
if (saturation)
|
||||
*saturation = S;
|
||||
if (luminance)
|
||||
*luminance = L;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLColor4::parseColor(const std::string& buf, LLColor4* color)
|
||||
{
|
||||
if( buf.empty() || color == nullptr)
|
||||
if (buf.empty() || color == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boost_tokenizer tokens(buf, boost::char_separator<char>(", "));
|
||||
boost_tokenizer tokens(buf, boost::char_separator<char>(", "));
|
||||
boost_tokenizer::iterator token_iter = tokens.begin();
|
||||
if (token_iter == tokens.end())
|
||||
{
|
||||
|
|
@ -401,16 +403,16 @@ bool LLColor4::parseColor(const std::string& buf, LLColor4* color)
|
|||
|
||||
// Grab the first token into a string, since we don't know
|
||||
// if this is a float or a color name.
|
||||
std::string color_name( (*token_iter) );
|
||||
std::string color_name((*token_iter));
|
||||
++token_iter;
|
||||
|
||||
if (token_iter != tokens.end())
|
||||
{
|
||||
// There are more tokens to read. This must be a vector.
|
||||
LLColor4 v;
|
||||
LLStringUtil::convertToF32( color_name, v.mV[VRED] );
|
||||
LLStringUtil::convertToF32( *token_iter, v.mV[VGREEN] );
|
||||
v.mV[VBLUE] = 0.0f;
|
||||
LLStringUtil::convertToF32(color_name, v.mV[VRED]);
|
||||
LLStringUtil::convertToF32(*token_iter, v.mV[VGREEN]);
|
||||
v.mV[VBLUE] = 0.0f;
|
||||
v.mV[VALPHA] = 1.0f;
|
||||
|
||||
++token_iter;
|
||||
|
|
@ -422,283 +424,284 @@ bool LLColor4::parseColor(const std::string& buf, LLColor4* color)
|
|||
else
|
||||
{
|
||||
// There is a z-component.
|
||||
LLStringUtil::convertToF32( *token_iter, v.mV[VBLUE] );
|
||||
LLStringUtil::convertToF32(*token_iter, v.mV[VBLUE]);
|
||||
|
||||
++token_iter;
|
||||
if (token_iter != tokens.end())
|
||||
{
|
||||
// There is an alpha component.
|
||||
LLStringUtil::convertToF32( *token_iter, v.mV[VALPHA] );
|
||||
LLStringUtil::convertToF32(*token_iter, v.mV[VALPHA]);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure all values are between 0 and 1.
|
||||
if (v.mV[VRED] > 1.f || v.mV[VGREEN] > 1.f || v.mV[VBLUE] > 1.f || v.mV[VALPHA] > 1.f)
|
||||
{
|
||||
v = v * (1.f / 255.f);
|
||||
constexpr F32 SCALE{ 1.f / 255.f };
|
||||
v *= SCALE;
|
||||
}
|
||||
color->set( v );
|
||||
color->set(v);
|
||||
}
|
||||
else // Single value. Read as a named color.
|
||||
{
|
||||
// We have a color name
|
||||
if ( "red" == color_name )
|
||||
if ("red" == color_name)
|
||||
{
|
||||
color->set(LLColor4::red);
|
||||
}
|
||||
else if ( "red1" == color_name )
|
||||
else if ("red1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::red1);
|
||||
}
|
||||
else if ( "red2" == color_name )
|
||||
else if ("red2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::red2);
|
||||
}
|
||||
else if ( "red3" == color_name )
|
||||
else if ("red3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::red3);
|
||||
}
|
||||
else if ( "red4" == color_name )
|
||||
else if ("red4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::red4);
|
||||
}
|
||||
else if ( "red5" == color_name )
|
||||
else if ("red5" == color_name)
|
||||
{
|
||||
color->set(LLColor4::red5);
|
||||
}
|
||||
else if( "green" == color_name )
|
||||
else if ("green" == color_name)
|
||||
{
|
||||
color->set(LLColor4::green);
|
||||
}
|
||||
else if( "green1" == color_name )
|
||||
else if ("green1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::green1);
|
||||
}
|
||||
else if( "green2" == color_name )
|
||||
else if ("green2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::green2);
|
||||
}
|
||||
else if( "green3" == color_name )
|
||||
else if ("green3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::green3);
|
||||
}
|
||||
else if( "green4" == color_name )
|
||||
else if ("green4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::green4);
|
||||
}
|
||||
else if( "green5" == color_name )
|
||||
else if ("green5" == color_name)
|
||||
{
|
||||
color->set(LLColor4::green5);
|
||||
}
|
||||
else if( "green6" == color_name )
|
||||
else if ("green6" == color_name)
|
||||
{
|
||||
color->set(LLColor4::green6);
|
||||
}
|
||||
else if( "blue" == color_name )
|
||||
else if ("blue" == color_name)
|
||||
{
|
||||
color->set(LLColor4::blue);
|
||||
}
|
||||
else if( "blue1" == color_name )
|
||||
else if ("blue1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::blue1);
|
||||
}
|
||||
else if( "blue2" == color_name )
|
||||
else if ("blue2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::blue2);
|
||||
}
|
||||
else if( "blue3" == color_name )
|
||||
else if ("blue3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::blue3);
|
||||
}
|
||||
else if( "blue4" == color_name )
|
||||
else if ("blue4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::blue4);
|
||||
}
|
||||
else if( "blue5" == color_name )
|
||||
else if ("blue5" == color_name)
|
||||
{
|
||||
color->set(LLColor4::blue5);
|
||||
}
|
||||
else if( "blue6" == color_name )
|
||||
else if ("blue6" == color_name)
|
||||
{
|
||||
color->set(LLColor4::blue6);
|
||||
}
|
||||
else if( "black" == color_name )
|
||||
else if ("black" == color_name)
|
||||
{
|
||||
color->set(LLColor4::black);
|
||||
}
|
||||
else if( "white" == color_name )
|
||||
else if ("white" == color_name)
|
||||
{
|
||||
color->set(LLColor4::white);
|
||||
}
|
||||
else if( "yellow" == color_name )
|
||||
else if ("yellow" == color_name)
|
||||
{
|
||||
color->set(LLColor4::yellow);
|
||||
}
|
||||
else if( "yellow1" == color_name )
|
||||
else if ("yellow1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::yellow1);
|
||||
}
|
||||
else if( "yellow2" == color_name )
|
||||
else if ("yellow2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::yellow2);
|
||||
}
|
||||
else if( "yellow3" == color_name )
|
||||
else if ("yellow3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::yellow3);
|
||||
}
|
||||
else if( "yellow4" == color_name )
|
||||
else if ("yellow4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::yellow4);
|
||||
}
|
||||
else if( "yellow5" == color_name )
|
||||
else if ("yellow5" == color_name)
|
||||
{
|
||||
color->set(LLColor4::yellow5);
|
||||
}
|
||||
else if( "yellow6" == color_name )
|
||||
else if ("yellow6" == color_name)
|
||||
{
|
||||
color->set(LLColor4::yellow6);
|
||||
}
|
||||
else if( "magenta" == color_name )
|
||||
else if ("magenta" == color_name)
|
||||
{
|
||||
color->set(LLColor4::magenta);
|
||||
}
|
||||
else if( "magenta1" == color_name )
|
||||
else if ("magenta1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::magenta1);
|
||||
}
|
||||
else if( "magenta2" == color_name )
|
||||
else if ("magenta2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::magenta2);
|
||||
}
|
||||
else if( "magenta3" == color_name )
|
||||
else if ("magenta3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::magenta3);
|
||||
}
|
||||
else if( "magenta4" == color_name )
|
||||
else if ("magenta4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::magenta4);
|
||||
}
|
||||
else if( "purple" == color_name )
|
||||
else if ("purple" == color_name)
|
||||
{
|
||||
color->set(LLColor4::purple);
|
||||
}
|
||||
else if( "purple1" == color_name )
|
||||
else if ("purple1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::purple1);
|
||||
}
|
||||
else if( "purple2" == color_name )
|
||||
else if ("purple2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::purple2);
|
||||
}
|
||||
else if( "purple3" == color_name )
|
||||
else if ("purple3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::purple3);
|
||||
}
|
||||
else if( "purple4" == color_name )
|
||||
else if ("purple4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::purple4);
|
||||
}
|
||||
else if( "purple5" == color_name )
|
||||
else if ("purple5" == color_name)
|
||||
{
|
||||
color->set(LLColor4::purple5);
|
||||
}
|
||||
else if( "purple6" == color_name )
|
||||
else if ("purple6" == color_name)
|
||||
{
|
||||
color->set(LLColor4::purple6);
|
||||
}
|
||||
else if( "pink" == color_name )
|
||||
else if ("pink" == color_name)
|
||||
{
|
||||
color->set(LLColor4::pink);
|
||||
}
|
||||
else if( "pink1" == color_name )
|
||||
else if ("pink1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::pink1);
|
||||
}
|
||||
else if( "pink2" == color_name )
|
||||
else if ("pink2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::pink2);
|
||||
}
|
||||
else if( "cyan" == color_name )
|
||||
else if ("cyan" == color_name)
|
||||
{
|
||||
color->set(LLColor4::cyan);
|
||||
}
|
||||
else if( "cyan1" == color_name )
|
||||
else if ("cyan1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::cyan1);
|
||||
}
|
||||
else if( "cyan2" == color_name )
|
||||
else if ("cyan2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::cyan2);
|
||||
}
|
||||
else if( "cyan3" == color_name )
|
||||
else if ("cyan3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::cyan3);
|
||||
}
|
||||
else if( "cyan4" == color_name )
|
||||
else if ("cyan4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::cyan4);
|
||||
}
|
||||
else if( "cyan5" == color_name )
|
||||
else if ("cyan5" == color_name)
|
||||
{
|
||||
color->set(LLColor4::cyan5);
|
||||
}
|
||||
else if( "cyan6" == color_name )
|
||||
else if ("cyan6" == color_name)
|
||||
{
|
||||
color->set(LLColor4::cyan6);
|
||||
}
|
||||
else if( "smoke" == color_name )
|
||||
else if ("smoke" == color_name)
|
||||
{
|
||||
color->set(LLColor4::smoke);
|
||||
}
|
||||
else if( "grey" == color_name )
|
||||
else if ("grey" == color_name)
|
||||
{
|
||||
color->set(LLColor4::grey);
|
||||
}
|
||||
else if( "grey1" == color_name )
|
||||
else if ("grey1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::grey1);
|
||||
}
|
||||
else if( "grey2" == color_name )
|
||||
else if ("grey2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::grey2);
|
||||
}
|
||||
else if( "grey3" == color_name )
|
||||
else if ("grey3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::grey3);
|
||||
}
|
||||
else if( "grey4" == color_name )
|
||||
else if ("grey4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::grey4);
|
||||
}
|
||||
else if( "orange" == color_name )
|
||||
else if ("orange" == color_name)
|
||||
{
|
||||
color->set(LLColor4::orange);
|
||||
}
|
||||
else if( "orange1" == color_name )
|
||||
else if ("orange1" == color_name)
|
||||
{
|
||||
color->set(LLColor4::orange1);
|
||||
}
|
||||
else if( "orange2" == color_name )
|
||||
else if ("orange2" == color_name)
|
||||
{
|
||||
color->set(LLColor4::orange2);
|
||||
}
|
||||
else if( "orange3" == color_name )
|
||||
else if ("orange3" == color_name)
|
||||
{
|
||||
color->set(LLColor4::orange3);
|
||||
}
|
||||
else if( "orange4" == color_name )
|
||||
else if ("orange4" == color_name)
|
||||
{
|
||||
color->set(LLColor4::orange4);
|
||||
}
|
||||
else if( "orange5" == color_name )
|
||||
else if ("orange5" == color_name)
|
||||
{
|
||||
color->set(LLColor4::orange5);
|
||||
}
|
||||
else if( "orange6" == color_name )
|
||||
else if ("orange6" == color_name)
|
||||
{
|
||||
color->set(LLColor4::orange6);
|
||||
}
|
||||
else if ( "clear" == color_name )
|
||||
else if ("clear" == color_name)
|
||||
{
|
||||
color->set(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
|
@ -714,21 +717,21 @@ bool LLColor4::parseColor(const std::string& buf, LLColor4* color)
|
|||
// static
|
||||
bool LLColor4::parseColor4(const std::string& buf, LLColor4* value)
|
||||
{
|
||||
if( buf.empty() || value == nullptr)
|
||||
if (buf.empty() || value == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLColor4 v;
|
||||
S32 count = sscanf( buf.c_str(), "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 );
|
||||
if (1 == count )
|
||||
S32 count = sscanf(buf.c_str(), "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3);
|
||||
if (1 == count)
|
||||
{
|
||||
// try this format
|
||||
count = sscanf( buf.c_str(), "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 );
|
||||
count = sscanf(buf.c_str(), "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3);
|
||||
}
|
||||
if( 4 == count )
|
||||
if (4 == count)
|
||||
{
|
||||
value->setVec( v );
|
||||
value->setVec(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@
|
|||
#define LL_V4COLOR_H
|
||||
|
||||
#include "llerror.h"
|
||||
//#include "vmath.h"
|
||||
#include "llmath.h"
|
||||
#include "llsd.h"
|
||||
|
||||
|
|
@ -38,198 +37,198 @@ class LLVector4;
|
|||
|
||||
// LLColor4 = |x y z w|
|
||||
|
||||
static const U32 LENGTHOFCOLOR4 = 4;
|
||||
static constexpr U32 LENGTHOFCOLOR4 = 4;
|
||||
|
||||
static const U32 MAX_LENGTH_OF_COLOR_NAME = 15; //Give plenty of room for additional colors...
|
||||
static constexpr U32 MAX_LENGTH_OF_COLOR_NAME = 15; // Give plenty of room for additional colors...
|
||||
|
||||
class LLColor4
|
||||
{
|
||||
public:
|
||||
F32 mV[LENGTHOFCOLOR4];
|
||||
LLColor4(); // Initializes LLColor4 to (0, 0, 0, 1)
|
||||
LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1)
|
||||
LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a)
|
||||
LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
|
||||
explicit LLColor4(const LLSD& sd);
|
||||
explicit LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
|
||||
explicit LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
|
||||
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion
|
||||
explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion
|
||||
public:
|
||||
F32 mV[LENGTHOFCOLOR4];
|
||||
LLColor4(); // Initializes LLColor4 to (0, 0, 0, 1)
|
||||
LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1)
|
||||
LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a)
|
||||
LLColor4(const LLColor3& vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a)
|
||||
explicit LLColor4(const LLSD& sd);
|
||||
explicit LLColor4(const F32* vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
|
||||
explicit LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc))
|
||||
explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion
|
||||
explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion
|
||||
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mV[0];
|
||||
ret[1] = mV[1];
|
||||
ret[2] = mV[2];
|
||||
ret[3] = mV[3];
|
||||
return ret;
|
||||
}
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[VRED] = mV[VRED];
|
||||
ret[VGREEN] = mV[VGREEN];
|
||||
ret[VBLUE] = mV[VBLUE];
|
||||
ret[VALPHA] = mV[VALPHA];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setValue(const LLSD& sd);
|
||||
void setValue(const LLSD& sd);
|
||||
|
||||
void setHSL(F32 hue, F32 saturation, F32 luminance);
|
||||
void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
|
||||
void setHSL(F32 hue, F32 saturation, F32 luminance);
|
||||
void calcHSL(F32* hue, F32* saturation, F32* luminance) const;
|
||||
|
||||
const LLColor4& setToBlack(); // zero LLColor4 to (0, 0, 0, 1)
|
||||
const LLColor4& setToWhite(); // zero LLColor4 to (0, 0, 0, 1)
|
||||
const LLColor4& setToBlack(); // zero LLColor4 to (0, 0, 0, 1)
|
||||
const LLColor4& setToWhite(); // zero LLColor4 to (0, 0, 0, 1)
|
||||
|
||||
const LLColor4& setVec(F32 r, F32 g, F32 b, F32 a); // deprecated -- use set()
|
||||
const LLColor4& setVec(F32 r, F32 g, F32 b); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor4 &vec); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor3 &vec); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor3 &vec, F32 a); // deprecated -- use set()
|
||||
const LLColor4& setVec(const F32 *vec); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor4U& color4u); // deprecated -- use set()
|
||||
const LLColor4& setVec(F32 r, F32 g, F32 b, F32 a); // deprecated -- use set()
|
||||
const LLColor4& setVec(F32 r, F32 g, F32 b); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor4& vec); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor3& vec); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor3& vec, F32 a); // deprecated -- use set()
|
||||
const LLColor4& setVec(const F32* vec); // deprecated -- use set()
|
||||
const LLColor4& setVec(const LLColor4U& color4u); // deprecated -- use set()
|
||||
|
||||
const LLColor4& set(F32 r, F32 g, F32 b, F32 a); // Sets LLColor4 to (r, g, b, a)
|
||||
const LLColor4& set(F32 r, F32 g, F32 b); // Sets LLColor4 to (r, g, b) (no change in a)
|
||||
const LLColor4& set(const LLColor4 &vec); // Sets LLColor4 to vec
|
||||
const LLColor4& set(const LLColor3 &vec); // Sets LLColor4 to LLColor3 vec (no change in alpha)
|
||||
const LLColor4& set(const LLColor3 &vec, F32 a); // Sets LLColor4 to LLColor3 vec, with alpha specified
|
||||
const LLColor4& set(const F32 *vec); // Sets LLColor4 to vec
|
||||
const LLColor4& set(const F64 *vec); // Sets LLColor4 to (double)vec
|
||||
const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled.
|
||||
const LLColor4& set(F32 r, F32 g, F32 b, F32 a); // Sets LLColor4 to (r, g, b, a)
|
||||
const LLColor4& set(F32 r, F32 g, F32 b); // Sets LLColor4 to (r, g, b) (no change in a)
|
||||
const LLColor4& set(const LLColor4& vec); // Sets LLColor4 to vec
|
||||
const LLColor4& set(const LLColor3& vec); // Sets LLColor4 to LLColor3 vec (no change in alpha)
|
||||
const LLColor4& set(const LLColor3& vec, F32 a); // Sets LLColor4 to LLColor3 vec, with alpha specified
|
||||
const LLColor4& set(const F32* vec); // Sets LLColor4 to vec
|
||||
const LLColor4& set(const F64* vec); // Sets LLColor4 to (double)vec
|
||||
const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled.
|
||||
|
||||
// set from a vector of unknown type and size
|
||||
// may leave some data unmodified
|
||||
template<typename T>
|
||||
const LLColor4& set(const std::vector<T>& v);
|
||||
// set from a vector of unknown type and size
|
||||
// may leave some data unmodified
|
||||
template<typename T>
|
||||
const LLColor4& set(const std::vector<T>& v);
|
||||
|
||||
// write to a vector of unknown type and size
|
||||
// maye leave some data unmodified
|
||||
template<typename T>
|
||||
void write(std::vector<T>& v) const;
|
||||
// write to a vector of unknown type and size
|
||||
// maye leave some data unmodified
|
||||
template<typename T>
|
||||
void write(std::vector<T>& v) const;
|
||||
|
||||
const LLColor4& setAlpha(F32 a);
|
||||
const LLColor4& setAlpha(F32 a);
|
||||
|
||||
F32 magVec() const; // deprecated -- use length()
|
||||
F32 magVecSquared() const; // deprecated -- use lengthSquared()
|
||||
F32 normVec(); // deprecated -- use normalize()
|
||||
F32 magVec() const; // deprecated -- use length()
|
||||
F32 magVecSquared() const; // deprecated -- use lengthSquared()
|
||||
F32 normVec(); // deprecated -- use normalize()
|
||||
|
||||
F32 length() const; // Returns magnitude of LLColor4
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLColor4
|
||||
F32 normalize(); // deprecated -- use normalize()
|
||||
F32 length() const; // Returns magnitude of LLColor4
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLColor4
|
||||
F32 normalize(); // deprecated -- use normalize()
|
||||
|
||||
bool isOpaque() { return mV[VALPHA] == 1.f; }
|
||||
bool isOpaque() const { return mV[VALPHA] == 1.f; }
|
||||
|
||||
F32 operator[](int idx) const { return mV[idx]; }
|
||||
F32 &operator[](int idx) { return mV[idx]; }
|
||||
F32 operator[](int idx) const { return mV[idx]; }
|
||||
F32& operator[](int idx) { return mV[idx]; }
|
||||
|
||||
const LLColor4& operator=(const LLColor3 &a); // Assigns vec3 to vec4 and returns vec4
|
||||
const LLColor4& operator=(const LLColor3& a); // Assigns vec3 to vec4 and returns vec4
|
||||
|
||||
bool operator<(const LLColor4& rhs) const;
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a
|
||||
friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b
|
||||
friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b
|
||||
friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b
|
||||
friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change)
|
||||
friend LLColor4 operator/(const LLColor4 &a, F32 k); // Return rgb divided by scalar k (no alpha change)
|
||||
friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change)
|
||||
friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change)
|
||||
friend LLColor4 operator%(F32 k, const LLColor4 &a); // Return alpha times scaler k (no rgb change)
|
||||
bool operator<(const LLColor4& rhs) const;
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLColor4& a); // Print a
|
||||
friend LLColor4 operator+(const LLColor4& a, const LLColor4& b); // Return vector a + b
|
||||
friend LLColor4 operator-(const LLColor4& a, const LLColor4& b); // Return vector a minus b
|
||||
friend LLColor4 operator*(const LLColor4& a, const LLColor4& b); // Return component wise a * b
|
||||
friend LLColor4 operator*(const LLColor4& a, F32 k); // Return rgb times scaler k (no alpha change)
|
||||
friend LLColor4 operator/(const LLColor4& a, F32 k); // Return rgb divided by scalar k (no alpha change)
|
||||
friend LLColor4 operator*(F32 k, const LLColor4& a); // Return rgb times scaler k (no alpha change)
|
||||
friend LLColor4 operator%(const LLColor4& a, F32 k); // Return alpha times scaler k (no rgb change)
|
||||
friend LLColor4 operator%(F32 k, const LLColor4& a); // Return alpha times scaler k (no rgb change)
|
||||
|
||||
friend bool operator==(const LLColor4 &a, const LLColor4 &b); // Return a == b
|
||||
friend bool operator!=(const LLColor4 &a, const LLColor4 &b); // Return a != b
|
||||
friend bool operator==(const LLColor4& a, const LLColor4& b); // Return a == b
|
||||
friend bool operator!=(const LLColor4& a, const LLColor4& b); // Return a != b
|
||||
|
||||
friend bool operator==(const LLColor4 &a, const LLColor3 &b); // Return a == b
|
||||
friend bool operator!=(const LLColor4 &a, const LLColor3 &b); // Return a != b
|
||||
friend bool operator==(const LLColor4& a, const LLColor3& b); // Return a == b
|
||||
friend bool operator!=(const LLColor4& a, const LLColor3& b); // Return a != b
|
||||
|
||||
friend const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b); // Return vector a + b
|
||||
friend const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b); // Return vector a minus b
|
||||
friend const LLColor4& operator*=(LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change)
|
||||
friend const LLColor4& operator%=(LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change)
|
||||
friend const LLColor4& operator+=(LLColor4& a, const LLColor4& b); // Return vector a + b
|
||||
friend const LLColor4& operator-=(LLColor4& a, const LLColor4& b); // Return vector a minus b
|
||||
friend const LLColor4& operator*=(LLColor4& a, F32 k); // Return rgb times scaler k (no alpha change)
|
||||
friend const LLColor4& operator%=(LLColor4& a, F32 k); // Return alpha times scaler k (no rgb change)
|
||||
|
||||
friend const LLColor4& operator*=(LLColor4 &a, const LLColor4 &b); // Doesn't multiply alpha! (for lighting)
|
||||
friend const LLColor4& operator*=(LLColor4& a, const LLColor4& b); // Doesn't multiply alpha! (for lighting)
|
||||
|
||||
// conversion
|
||||
operator LLColor4U() const;
|
||||
// conversion
|
||||
operator LLColor4U() const;
|
||||
|
||||
// Basic color values.
|
||||
static LLColor4 red;
|
||||
static LLColor4 green;
|
||||
static LLColor4 blue;
|
||||
static LLColor4 black;
|
||||
static LLColor4 white;
|
||||
static LLColor4 yellow;
|
||||
static LLColor4 magenta;
|
||||
static LLColor4 cyan;
|
||||
static LLColor4 smoke;
|
||||
static LLColor4 grey;
|
||||
static LLColor4 orange;
|
||||
static LLColor4 purple;
|
||||
static LLColor4 pink;
|
||||
static LLColor4 transparent;
|
||||
// Basic color values.
|
||||
static LLColor4 red;
|
||||
static LLColor4 green;
|
||||
static LLColor4 blue;
|
||||
static LLColor4 black;
|
||||
static LLColor4 white;
|
||||
static LLColor4 yellow;
|
||||
static LLColor4 magenta;
|
||||
static LLColor4 cyan;
|
||||
static LLColor4 smoke;
|
||||
static LLColor4 grey;
|
||||
static LLColor4 orange;
|
||||
static LLColor4 purple;
|
||||
static LLColor4 pink;
|
||||
static LLColor4 transparent;
|
||||
|
||||
// Extra color values.
|
||||
static LLColor4 grey1;
|
||||
static LLColor4 grey2;
|
||||
static LLColor4 grey3;
|
||||
static LLColor4 grey4;
|
||||
// Extra color values.
|
||||
static LLColor4 grey1;
|
||||
static LLColor4 grey2;
|
||||
static LLColor4 grey3;
|
||||
static LLColor4 grey4;
|
||||
|
||||
static LLColor4 red1;
|
||||
static LLColor4 red2;
|
||||
static LLColor4 red3;
|
||||
static LLColor4 red4;
|
||||
static LLColor4 red5;
|
||||
static LLColor4 red1;
|
||||
static LLColor4 red2;
|
||||
static LLColor4 red3;
|
||||
static LLColor4 red4;
|
||||
static LLColor4 red5;
|
||||
|
||||
static LLColor4 green1;
|
||||
static LLColor4 green2;
|
||||
static LLColor4 green3;
|
||||
static LLColor4 green4;
|
||||
static LLColor4 green5;
|
||||
static LLColor4 green6;
|
||||
static LLColor4 green1;
|
||||
static LLColor4 green2;
|
||||
static LLColor4 green3;
|
||||
static LLColor4 green4;
|
||||
static LLColor4 green5;
|
||||
static LLColor4 green6;
|
||||
|
||||
static LLColor4 blue1;
|
||||
static LLColor4 blue2;
|
||||
static LLColor4 blue3;
|
||||
static LLColor4 blue4;
|
||||
static LLColor4 blue5;
|
||||
static LLColor4 blue6;
|
||||
static LLColor4 blue1;
|
||||
static LLColor4 blue2;
|
||||
static LLColor4 blue3;
|
||||
static LLColor4 blue4;
|
||||
static LLColor4 blue5;
|
||||
static LLColor4 blue6;
|
||||
|
||||
static LLColor4 yellow1;
|
||||
static LLColor4 yellow2;
|
||||
static LLColor4 yellow3;
|
||||
static LLColor4 yellow4;
|
||||
static LLColor4 yellow5;
|
||||
static LLColor4 yellow6;
|
||||
static LLColor4 yellow7;
|
||||
static LLColor4 yellow8;
|
||||
static LLColor4 yellow9;
|
||||
static LLColor4 yellow1;
|
||||
static LLColor4 yellow2;
|
||||
static LLColor4 yellow3;
|
||||
static LLColor4 yellow4;
|
||||
static LLColor4 yellow5;
|
||||
static LLColor4 yellow6;
|
||||
static LLColor4 yellow7;
|
||||
static LLColor4 yellow8;
|
||||
static LLColor4 yellow9;
|
||||
|
||||
static LLColor4 orange1;
|
||||
static LLColor4 orange2;
|
||||
static LLColor4 orange3;
|
||||
static LLColor4 orange4;
|
||||
static LLColor4 orange5;
|
||||
static LLColor4 orange6;
|
||||
static LLColor4 orange1;
|
||||
static LLColor4 orange2;
|
||||
static LLColor4 orange3;
|
||||
static LLColor4 orange4;
|
||||
static LLColor4 orange5;
|
||||
static LLColor4 orange6;
|
||||
|
||||
static LLColor4 magenta1;
|
||||
static LLColor4 magenta2;
|
||||
static LLColor4 magenta3;
|
||||
static LLColor4 magenta4;
|
||||
static LLColor4 magenta1;
|
||||
static LLColor4 magenta2;
|
||||
static LLColor4 magenta3;
|
||||
static LLColor4 magenta4;
|
||||
|
||||
static LLColor4 purple1;
|
||||
static LLColor4 purple2;
|
||||
static LLColor4 purple3;
|
||||
static LLColor4 purple4;
|
||||
static LLColor4 purple5;
|
||||
static LLColor4 purple6;
|
||||
static LLColor4 purple1;
|
||||
static LLColor4 purple2;
|
||||
static LLColor4 purple3;
|
||||
static LLColor4 purple4;
|
||||
static LLColor4 purple5;
|
||||
static LLColor4 purple6;
|
||||
|
||||
static LLColor4 pink1;
|
||||
static LLColor4 pink2;
|
||||
static LLColor4 pink1;
|
||||
static LLColor4 pink2;
|
||||
|
||||
static LLColor4 cyan1;
|
||||
static LLColor4 cyan2;
|
||||
static LLColor4 cyan3;
|
||||
static LLColor4 cyan4;
|
||||
static LLColor4 cyan5;
|
||||
static LLColor4 cyan6;
|
||||
static LLColor4 cyan1;
|
||||
static LLColor4 cyan2;
|
||||
static LLColor4 cyan3;
|
||||
static LLColor4 cyan4;
|
||||
static LLColor4 cyan5;
|
||||
static LLColor4 cyan6;
|
||||
|
||||
static bool parseColor(const std::string& buf, LLColor4* color);
|
||||
static bool parseColor4(const std::string& buf, LLColor4* color);
|
||||
static bool parseColor(const std::string& buf, LLColor4* color);
|
||||
static bool parseColor4(const std::string& buf, LLColor4* color);
|
||||
|
||||
inline void clamp();
|
||||
inline void clamp();
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_copyable<LLColor4>::value, "LLColor4 must be trivial copy");
|
||||
|
|
@ -237,17 +236,17 @@ static_assert(std::is_trivially_move_assignable<LLColor4>::value, "LLColor4 must
|
|||
static_assert(std::is_standard_layout<LLColor4>::value, "LLColor4 must be a standard layout type");
|
||||
|
||||
// Non-member functions
|
||||
F32 distVec(const LLColor4 &a, const LLColor4 &b); // Returns distance between a and b
|
||||
F32 distVec_squared(const LLColor4 &a, const LLColor4 &b); // Returns distance squared between a and b
|
||||
LLColor3 vec4to3(const LLColor4 &vec);
|
||||
LLColor4 vec3to4(const LLColor3 &vec);
|
||||
LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u);
|
||||
F32 distVec(const LLColor4& a, const LLColor4& b); // Returns distance between a and b
|
||||
F32 distVec_squared(const LLColor4& a, const LLColor4& b); // Returns distance squared between a and b
|
||||
LLColor3 vec4to3(const LLColor4& vec);
|
||||
LLColor4 vec3to4(const LLColor3& vec);
|
||||
LLColor4 lerp(const LLColor4& a, const LLColor4& b, F32 u);
|
||||
|
||||
inline LLColor4::LLColor4(void)
|
||||
inline LLColor4::LLColor4()
|
||||
{
|
||||
mV[VRED] = 0.f;
|
||||
mV[VRED] = 0.f;
|
||||
mV[VGREEN] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
mV[VALPHA] = 1.f;
|
||||
}
|
||||
|
||||
|
|
@ -258,149 +257,146 @@ inline LLColor4::LLColor4(const LLSD& sd)
|
|||
|
||||
inline LLColor4::LLColor4(F32 r, F32 g, F32 b)
|
||||
{
|
||||
mV[VRED] = r;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
mV[VBLUE] = b;
|
||||
mV[VALPHA] = 1.f;
|
||||
}
|
||||
|
||||
inline LLColor4::LLColor4(F32 r, F32 g, F32 b, F32 a)
|
||||
{
|
||||
mV[VRED] = r;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
mV[VBLUE] = b;
|
||||
mV[VALPHA] = a;
|
||||
}
|
||||
|
||||
inline LLColor4::LLColor4(U32 clr)
|
||||
{
|
||||
mV[VRED] = (clr&0xff) * (1.0f/255.0f);
|
||||
mV[VGREEN] = ((clr>>8)&0xff) * (1.0f/255.0f);
|
||||
mV[VBLUE] = ((clr>>16)&0xff) * (1.0f/255.0f);
|
||||
mV[VALPHA] = (clr>>24) * (1.0f/255.0f);
|
||||
mV[VRED] = (clr & 0xff) * (1.0f / 255.0f);
|
||||
mV[VGREEN] = ((clr >> 8) & 0xff) * (1.0f / 255.0f);
|
||||
mV[VBLUE] = ((clr >> 16) & 0xff) * (1.0f / 255.0f);
|
||||
mV[VALPHA] = (clr >> 24) * (1.0f / 255.0f);
|
||||
}
|
||||
|
||||
|
||||
inline LLColor4::LLColor4(const F32 *vec)
|
||||
inline LLColor4::LLColor4(const F32* vec)
|
||||
{
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VALPHA] = vec[VALPHA];
|
||||
}
|
||||
|
||||
inline const LLColor4& LLColor4::setToBlack(void)
|
||||
inline const LLColor4& LLColor4::setToBlack(void)
|
||||
{
|
||||
mV[VRED] = 0.f;
|
||||
mV[VRED] = 0.f;
|
||||
mV[VGREEN] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
mV[VALPHA] = 1.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4& LLColor4::setToWhite(void)
|
||||
inline const LLColor4& LLColor4::setToWhite(void)
|
||||
{
|
||||
mV[VRED] = 1.f;
|
||||
mV[VRED] = 1.f;
|
||||
mV[VGREEN] = 1.f;
|
||||
mV[VBLUE] = 1.f;
|
||||
mV[VBLUE] = 1.f;
|
||||
mV[VALPHA] = 1.f;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z)
|
||||
inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VRED] = x;
|
||||
mV[VRED] = x;
|
||||
mV[VGREEN] = y;
|
||||
mV[VBLUE] = z;
|
||||
mV[VBLUE] = z;
|
||||
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z, F32 a)
|
||||
inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z, F32 a)
|
||||
{
|
||||
mV[VRED] = x;
|
||||
mV[VRED] = x;
|
||||
mV[VGREEN] = y;
|
||||
mV[VBLUE] = z;
|
||||
mV[VBLUE] = z;
|
||||
mV[VALPHA] = a;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4& LLColor4::set(const LLColor4 &vec)
|
||||
inline const LLColor4& LLColor4::set(const LLColor4& vec)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = vec.mV[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
inline const LLColor4& LLColor4::set(const F32 *vec)
|
||||
inline const LLColor4& LLColor4::set(const F32* vec)
|
||||
{
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VALPHA] = vec[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4& LLColor4::set(const F64 *vec)
|
||||
inline const LLColor4& LLColor4::set(const F64* vec)
|
||||
{
|
||||
mV[VRED] = static_cast<F32>(vec[VRED]);
|
||||
mV[VRED] = static_cast<F32>(vec[VRED]);
|
||||
mV[VGREEN] = static_cast<F32>(vec[VGREEN]);
|
||||
mV[VBLUE] = static_cast<F32>(vec[VBLUE]);
|
||||
mV[VBLUE] = static_cast<F32>(vec[VBLUE]);
|
||||
mV[VALPHA] = static_cast<F32>(vec[VALPHA]);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z)
|
||||
inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VRED] = x;
|
||||
mV[VRED] = x;
|
||||
mV[VGREEN] = y;
|
||||
mV[VBLUE] = z;
|
||||
mV[VBLUE] = z;
|
||||
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 1.f;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z, F32 a)
|
||||
inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z, F32 a)
|
||||
{
|
||||
mV[VRED] = x;
|
||||
mV[VRED] = x;
|
||||
mV[VGREEN] = y;
|
||||
mV[VBLUE] = z;
|
||||
mV[VBLUE] = z;
|
||||
mV[VALPHA] = a;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor4& LLColor4::setVec(const LLColor4 &vec)
|
||||
inline const LLColor4& LLColor4::setVec(const LLColor4& vec)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = vec.mV[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
// deprecated
|
||||
inline const LLColor4& LLColor4::setVec(const F32 *vec)
|
||||
inline const LLColor4& LLColor4::setVec(const F32* vec)
|
||||
{
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VALPHA] = vec[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4& LLColor4::setAlpha(F32 a)
|
||||
inline const LLColor4& LLColor4::setAlpha(F32 a)
|
||||
{
|
||||
mV[VALPHA] = a;
|
||||
return (*this);
|
||||
|
|
@ -408,155 +404,116 @@ inline const LLColor4& LLColor4::setAlpha(F32 a)
|
|||
|
||||
// LLColor4 Magnitude and Normalization Functions
|
||||
|
||||
inline F32 LLColor4::length(void) const
|
||||
inline F32 LLColor4::length() const
|
||||
{
|
||||
return (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]);
|
||||
return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
}
|
||||
|
||||
inline F32 LLColor4::lengthSquared(void) const
|
||||
inline F32 LLColor4::lengthSquared() const
|
||||
{
|
||||
return mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE];
|
||||
return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE];
|
||||
}
|
||||
|
||||
inline F32 LLColor4::normalize(void)
|
||||
inline F32 LLColor4::normalize()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]);
|
||||
F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
oomag = 1.f / mag;
|
||||
mV[VRED] *= oomag;
|
||||
mV[VGREEN] *= oomag;
|
||||
mV[VBLUE] *= oomag;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor4::magVec(void) const
|
||||
inline F32 LLColor4::magVec() const
|
||||
{
|
||||
return (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]);
|
||||
return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor4::magVecSquared(void) const
|
||||
inline F32 LLColor4::magVecSquared() const
|
||||
{
|
||||
return mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE];
|
||||
return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE];
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor4::normVec(void)
|
||||
inline F32 LLColor4::normVec()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]);
|
||||
F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
oomag = 1.f / mag;
|
||||
mV[VRED] *= oomag;
|
||||
mV[VGREEN] *= oomag;
|
||||
mV[VBLUE] *= oomag;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// LLColor4 Operators
|
||||
|
||||
|
||||
inline LLColor4 operator+(const LLColor4 &a, const LLColor4 &b)
|
||||
inline LLColor4 operator+(const LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
return LLColor4(
|
||||
a.mV[VRED] + b.mV[VRED],
|
||||
a.mV[VGREEN] + b.mV[VGREEN],
|
||||
a.mV[VBLUE] + b.mV[VBLUE],
|
||||
a.mV[VALPHA] + b.mV[VALPHA]);
|
||||
return LLColor4(a.mV[VRED] + b.mV[VRED], a.mV[VGREEN] + b.mV[VGREEN], a.mV[VBLUE] + b.mV[VBLUE], a.mV[VALPHA] + b.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4 operator-(const LLColor4 &a, const LLColor4 &b)
|
||||
inline LLColor4 operator-(const LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
return LLColor4(
|
||||
a.mV[VRED] - b.mV[VRED],
|
||||
a.mV[VGREEN] - b.mV[VGREEN],
|
||||
a.mV[VBLUE] - b.mV[VBLUE],
|
||||
a.mV[VALPHA] - b.mV[VALPHA]);
|
||||
return LLColor4(a.mV[VRED] - b.mV[VRED], a.mV[VGREEN] - b.mV[VGREEN], a.mV[VBLUE] - b.mV[VBLUE], a.mV[VALPHA] - b.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4 operator*(const LLColor4 &a, const LLColor4 &b)
|
||||
inline LLColor4 operator*(const LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
return LLColor4(
|
||||
a.mV[VRED] * b.mV[VRED],
|
||||
a.mV[VGREEN] * b.mV[VGREEN],
|
||||
a.mV[VBLUE] * b.mV[VBLUE],
|
||||
a.mV[VALPHA] * b.mV[VALPHA]);
|
||||
return LLColor4(a.mV[VRED] * b.mV[VRED], a.mV[VGREEN] * b.mV[VGREEN], a.mV[VBLUE] * b.mV[VBLUE], a.mV[VALPHA] * b.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4 operator*(const LLColor4 &a, F32 k)
|
||||
inline LLColor4 operator*(const LLColor4& a, F32 k)
|
||||
{
|
||||
// only affects rgb (not a!)
|
||||
return LLColor4(
|
||||
a.mV[VRED] * k,
|
||||
a.mV[VGREEN] * k,
|
||||
a.mV[VBLUE] * k,
|
||||
a.mV[VALPHA]);
|
||||
return LLColor4(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k, a.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4 operator/(const LLColor4 &a, F32 k)
|
||||
inline LLColor4 operator/(const LLColor4& a, F32 k)
|
||||
{
|
||||
return LLColor4(
|
||||
a.mV[VRED] / k,
|
||||
a.mV[VGREEN] / k,
|
||||
a.mV[VBLUE] / k,
|
||||
a.mV[VALPHA]);
|
||||
return LLColor4(a.mV[VRED] / k, a.mV[VGREEN] / k, a.mV[VBLUE] / k, a.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4 operator*(F32 k, const LLColor4 &a)
|
||||
inline LLColor4 operator*(F32 k, const LLColor4& a)
|
||||
{
|
||||
// only affects rgb (not a!)
|
||||
return LLColor4(
|
||||
a.mV[VRED] * k,
|
||||
a.mV[VGREEN] * k,
|
||||
a.mV[VBLUE] * k,
|
||||
a.mV[VALPHA]);
|
||||
return LLColor4(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k, a.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4 operator%(F32 k, const LLColor4 &a)
|
||||
inline LLColor4 operator%(F32 k, const LLColor4& a)
|
||||
{
|
||||
// only affects alpha (not rgb!)
|
||||
return LLColor4(
|
||||
a.mV[VRED],
|
||||
a.mV[VGREEN],
|
||||
a.mV[VBLUE],
|
||||
a.mV[VALPHA] * k);
|
||||
return LLColor4(a.mV[VRED], a.mV[VGREEN], a.mV[VBLUE], a.mV[VALPHA] * k);
|
||||
}
|
||||
|
||||
inline LLColor4 operator%(const LLColor4 &a, F32 k)
|
||||
inline LLColor4 operator%(const LLColor4& a, F32 k)
|
||||
{
|
||||
// only affects alpha (not rgb!)
|
||||
return LLColor4(
|
||||
a.mV[VRED],
|
||||
a.mV[VGREEN],
|
||||
a.mV[VBLUE],
|
||||
a.mV[VALPHA] * k);
|
||||
return LLColor4(a.mV[VRED], a.mV[VGREEN], a.mV[VBLUE], a.mV[VALPHA] * k);
|
||||
}
|
||||
|
||||
inline bool operator==(const LLColor4 &a, const LLColor4 &b)
|
||||
inline bool operator==(const LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
return ( (a.mV[VRED] == b.mV[VRED])
|
||||
&&(a.mV[VGREEN] == b.mV[VGREEN])
|
||||
&&(a.mV[VBLUE] == b.mV[VBLUE])
|
||||
&&(a.mV[VALPHA] == b.mV[VALPHA]));
|
||||
return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE]) && (a.mV[VALPHA] == b.mV[VALPHA]));
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLColor4 &a, const LLColor4 &b)
|
||||
inline bool operator!=(const LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
return ( (a.mV[VRED] != b.mV[VRED])
|
||||
||(a.mV[VGREEN] != b.mV[VGREEN])
|
||||
||(a.mV[VBLUE] != b.mV[VBLUE])
|
||||
||(a.mV[VALPHA] != b.mV[VALPHA]));
|
||||
return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE]) || (a.mV[VALPHA] != b.mV[VALPHA]));
|
||||
}
|
||||
|
||||
inline const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b)
|
||||
inline const LLColor4& operator+=(LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
a.mV[VRED] += b.mV[VRED];
|
||||
a.mV[VGREEN] += b.mV[VGREEN];
|
||||
|
|
@ -565,7 +522,7 @@ inline const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b)
|
||||
inline const LLColor4& operator-=(LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
a.mV[VRED] -= b.mV[VRED];
|
||||
a.mV[VGREEN] -= b.mV[VGREEN];
|
||||
|
|
@ -574,7 +531,7 @@ inline const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor4& operator*=(LLColor4 &a, F32 k)
|
||||
inline const LLColor4& operator*=(LLColor4& a, F32 k)
|
||||
{
|
||||
// only affects rgb (not a!)
|
||||
a.mV[VRED] *= k;
|
||||
|
|
@ -583,121 +540,120 @@ inline const LLColor4& operator*=(LLColor4 &a, F32 k)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor4& operator *=(LLColor4 &a, const LLColor4 &b)
|
||||
inline const LLColor4& operator*=(LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
a.mV[VRED] *= b.mV[VRED];
|
||||
a.mV[VGREEN] *= b.mV[VGREEN];
|
||||
a.mV[VBLUE] *= b.mV[VBLUE];
|
||||
// a.mV[VALPHA] *= b.mV[VALPHA];
|
||||
// a.mV[VALPHA] *= b.mV[VALPHA];
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor4& operator%=(LLColor4 &a, F32 k)
|
||||
inline const LLColor4& operator%=(LLColor4& a, F32 k)
|
||||
{
|
||||
// only affects alpha (not rgb!)
|
||||
a.mV[VALPHA] *= k;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
// Non-member functions
|
||||
|
||||
inline F32 distVec(const LLColor4 &a, const LLColor4 &b)
|
||||
inline F32 distVec(const LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
LLColor4 vec = a - b;
|
||||
return (vec.length());
|
||||
return vec.length();
|
||||
}
|
||||
|
||||
inline F32 distVec_squared(const LLColor4 &a, const LLColor4 &b)
|
||||
inline F32 distVec_squared(const LLColor4& a, const LLColor4& b)
|
||||
{
|
||||
LLColor4 vec = a - b;
|
||||
return (vec.lengthSquared());
|
||||
return vec.lengthSquared();
|
||||
}
|
||||
|
||||
inline LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u)
|
||||
inline LLColor4 lerp(const LLColor4& a, const LLColor4& b, F32 u)
|
||||
{
|
||||
return LLColor4(
|
||||
a.mV[VRED] + (b.mV[VRED] - a.mV[VRED]) * u,
|
||||
a.mV[VGREEN] + (b.mV[VGREEN] - a.mV[VGREEN]) * u,
|
||||
a.mV[VBLUE] + (b.mV[VBLUE] - a.mV[VBLUE]) * u,
|
||||
a.mV[VALPHA] + (b.mV[VALPHA] - a.mV[VALPHA]) * u);
|
||||
return LLColor4(a.mV[VRED] + (b.mV[VRED] - a.mV[VRED]) * u,
|
||||
a.mV[VGREEN] + (b.mV[VGREEN] - a.mV[VGREEN]) * u,
|
||||
a.mV[VBLUE] + (b.mV[VBLUE] - a.mV[VBLUE]) * u,
|
||||
a.mV[VALPHA] + (b.mV[VALPHA] - a.mV[VALPHA]) * u);
|
||||
}
|
||||
|
||||
inline bool LLColor4::operator<(const LLColor4& rhs) const
|
||||
{
|
||||
if (mV[0] != rhs.mV[0])
|
||||
if (mV[VRED] != rhs.mV[VRED])
|
||||
{
|
||||
return mV[0] < rhs.mV[0];
|
||||
return mV[VRED] < rhs.mV[VRED];
|
||||
}
|
||||
if (mV[1] != rhs.mV[1])
|
||||
if (mV[VGREEN] != rhs.mV[VGREEN])
|
||||
{
|
||||
return mV[1] < rhs.mV[1];
|
||||
return mV[VGREEN] < rhs.mV[VGREEN];
|
||||
}
|
||||
if (mV[2] != rhs.mV[2])
|
||||
if (mV[VBLUE] != rhs.mV[VBLUE])
|
||||
{
|
||||
return mV[2] < rhs.mV[2];
|
||||
return mV[VBLUE] < rhs.mV[VBLUE];
|
||||
}
|
||||
|
||||
return mV[3] < rhs.mV[3];
|
||||
return mV[VALPHA] < rhs.mV[VALPHA];
|
||||
}
|
||||
|
||||
void LLColor4::clamp()
|
||||
{
|
||||
// Clamp the color...
|
||||
if (mV[0] < 0.f)
|
||||
if (mV[VRED] < 0.f)
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[VRED] = 0.f;
|
||||
}
|
||||
else if (mV[0] > 1.f)
|
||||
else if (mV[VRED] > 1.f)
|
||||
{
|
||||
mV[0] = 1.f;
|
||||
mV[VRED] = 1.f;
|
||||
}
|
||||
if (mV[1] < 0.f)
|
||||
if (mV[VGREEN] < 0.f)
|
||||
{
|
||||
mV[1] = 0.f;
|
||||
mV[VGREEN] = 0.f;
|
||||
}
|
||||
else if (mV[1] > 1.f)
|
||||
else if (mV[VGREEN] > 1.f)
|
||||
{
|
||||
mV[1] = 1.f;
|
||||
mV[VGREEN] = 1.f;
|
||||
}
|
||||
if (mV[2] < 0.f)
|
||||
if (mV[VBLUE] < 0.f)
|
||||
{
|
||||
mV[2] = 0.f;
|
||||
mV[VBLUE] = 0.f;
|
||||
}
|
||||
else if (mV[2] > 1.f)
|
||||
else if (mV[VBLUE] > 1.f)
|
||||
{
|
||||
mV[2] = 1.f;
|
||||
mV[VBLUE] = 1.f;
|
||||
}
|
||||
if (mV[3] < 0.f)
|
||||
if (mV[VALPHA] < 0.f)
|
||||
{
|
||||
mV[3] = 0.f;
|
||||
mV[VALPHA] = 0.f;
|
||||
}
|
||||
else if (mV[3] > 1.f)
|
||||
else if (mV[VALPHA] > 1.f)
|
||||
{
|
||||
mV[3] = 1.f;
|
||||
mV[VALPHA] = 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the given linear space color value in gamma corrected (sRGB) space
|
||||
inline const LLColor4 srgbColor4(const LLColor4 &a) {
|
||||
inline const LLColor4 srgbColor4(const LLColor4& a)
|
||||
{
|
||||
LLColor4 srgbColor;
|
||||
|
||||
srgbColor.mV[0] = linearTosRGB(a.mV[0]);
|
||||
srgbColor.mV[1] = linearTosRGB(a.mV[1]);
|
||||
srgbColor.mV[2] = linearTosRGB(a.mV[2]);
|
||||
srgbColor.mV[3] = a.mV[3];
|
||||
srgbColor.mV[VRED] = linearTosRGB(a.mV[VRED]);
|
||||
srgbColor.mV[VGREEN] = linearTosRGB(a.mV[VGREEN]);
|
||||
srgbColor.mV[VBLUE] = linearTosRGB(a.mV[VBLUE]);
|
||||
srgbColor.mV[VALPHA] = a.mV[VALPHA];
|
||||
|
||||
return srgbColor;
|
||||
}
|
||||
|
||||
// Return the given gamma corrected (sRGB) color in linear space
|
||||
inline const LLColor4 linearColor4(const LLColor4 &a)
|
||||
inline const LLColor4 linearColor4(const LLColor4& a)
|
||||
{
|
||||
LLColor4 linearColor;
|
||||
linearColor.mV[0] = sRGBtoLinear(a.mV[0]);
|
||||
linearColor.mV[1] = sRGBtoLinear(a.mV[1]);
|
||||
linearColor.mV[2] = sRGBtoLinear(a.mV[2]);
|
||||
linearColor.mV[3] = a.mV[3];
|
||||
linearColor.mV[VRED] = sRGBtoLinear(a.mV[VRED]);
|
||||
linearColor.mV[VGREEN] = sRGBtoLinear(a.mV[VGREEN]);
|
||||
linearColor.mV[VBLUE] = sRGBtoLinear(a.mV[VBLUE]);
|
||||
linearColor.mV[VALPHA] = a.mV[VALPHA];
|
||||
|
||||
return linearColor;
|
||||
}
|
||||
|
|
@ -723,4 +679,3 @@ void LLColor4::write(std::vector<T>& v) const
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,7 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
//#include "v3coloru.h"
|
||||
#include "v4coloru.h"
|
||||
#include "v4color.h"
|
||||
//#include "vmath.h"
|
||||
#include "llmath.h"
|
||||
|
||||
// LLColor4U
|
||||
|
|
@ -39,49 +36,7 @@ LLColor4U LLColor4U::red (255, 0, 0, 255);
|
|||
LLColor4U LLColor4U::green( 0, 255, 0, 255);
|
||||
LLColor4U LLColor4U::blue ( 0, 0, 255, 255);
|
||||
|
||||
// conversion
|
||||
/* inlined to fix gcc compile link error
|
||||
LLColor4U::operator LLColor4()
|
||||
{
|
||||
return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f));
|
||||
}
|
||||
*/
|
||||
|
||||
// Constructors
|
||||
|
||||
|
||||
/*
|
||||
LLColor4U::LLColor4U(const LLColor3 &vec)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = 255;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// Clear and Assignment Functions
|
||||
|
||||
|
||||
|
||||
// LLColor4U Operators
|
||||
|
||||
/*
|
||||
LLColor4U LLColor4U::operator=(const LLColor3 &a)
|
||||
{
|
||||
mV[VRED] = a.mV[VRED];
|
||||
mV[VGREEN] = a.mV[VGREEN];
|
||||
mV[VBLUE] = a.mV[VBLUE];
|
||||
|
||||
// converting from an rgb sets a=1 (opaque)
|
||||
mV[VALPHA] = 255;
|
||||
return (*this);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLColor4U &a)
|
||||
std::ostream& operator<<(std::ostream& s, const LLColor4U& a)
|
||||
{
|
||||
s << "{ " << (S32)a.mV[VRED] << ", " << (S32)a.mV[VGREEN] << ", " << (S32)a.mV[VBLUE] << ", " << (S32)a.mV[VALPHA] << " }";
|
||||
return s;
|
||||
|
|
@ -90,31 +45,31 @@ std::ostream& operator<<(std::ostream& s, const LLColor4U &a)
|
|||
// static
|
||||
bool LLColor4U::parseColor4U(const std::string& buf, LLColor4U* value)
|
||||
{
|
||||
if( buf.empty() || value == nullptr)
|
||||
if (buf.empty() || value == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
U32 v[4];
|
||||
S32 count = sscanf( buf.c_str(), "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3 );
|
||||
if (1 == count )
|
||||
U32 v[4]{};
|
||||
S32 count = sscanf(buf.c_str(), "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3);
|
||||
if (1 == count)
|
||||
{
|
||||
// try this format
|
||||
count = sscanf( buf.c_str(), "%u %u %u %u", v + 0, v + 1, v + 2, v + 3 );
|
||||
count = sscanf(buf.c_str(), "%u %u %u %u", v + 0, v + 1, v + 2, v + 3);
|
||||
}
|
||||
if( 4 != count )
|
||||
if (4 != count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for( S32 i = 0; i < 4; i++ )
|
||||
for (S32 i = 0; i < 4; i++)
|
||||
{
|
||||
if( v[i] > U8_MAX )
|
||||
if (v[i] > U8_MAX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
value->set( U8(v[0]), U8(v[1]), U8(v[2]), U8(v[3]) );
|
||||
value->set(U8(v[VRED]), U8(v[VGREEN]), U8(v[VBLUE]), U8(v[VALPHA]));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,104 +28,93 @@
|
|||
#define LL_V4COLORU_H
|
||||
|
||||
#include "llerror.h"
|
||||
//#include "vmath.h"
|
||||
#include "llmath.h"
|
||||
//#include "v4color.h"
|
||||
|
||||
#include "v3color.h"
|
||||
#include "v4color.h"
|
||||
|
||||
//class LLColor3U;
|
||||
class LLColor4;
|
||||
|
||||
// LLColor4U = | red green blue alpha |
|
||||
|
||||
static const U32 LENGTHOFCOLOR4U = 4;
|
||||
|
||||
static constexpr U32 LENGTHOFCOLOR4U = 4;
|
||||
|
||||
class LLColor4U
|
||||
{
|
||||
public:
|
||||
|
||||
U8 mV[LENGTHOFCOLOR4U];
|
||||
|
||||
LLColor4U(); // Initializes LLColor4U to (0, 0, 0, 1)
|
||||
LLColor4U(U8 r, U8 g, U8 b); // Initializes LLColor4U to (r, g, b, 1)
|
||||
LLColor4U(U8 r, U8 g, U8 b, U8 a); // Initializes LLColor4U to (r. g, b, a)
|
||||
LLColor4U(const U8 *vec); // Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1)
|
||||
explicit LLColor4U(const LLSD& sd)
|
||||
{
|
||||
setValue(sd);
|
||||
}
|
||||
LLColor4U(); // Initializes LLColor4U to (0, 0, 0, 1)
|
||||
LLColor4U(U8 r, U8 g, U8 b); // Initializes LLColor4U to (r, g, b, 1)
|
||||
LLColor4U(U8 r, U8 g, U8 b, U8 a); // Initializes LLColor4U to (r. g, b, a)
|
||||
LLColor4U(const U8* vec); // Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1)
|
||||
explicit LLColor4U(const LLSD& sd) { setValue(sd); }
|
||||
|
||||
void setValue(const LLSD& sd)
|
||||
{
|
||||
mV[0] = sd[0].asInteger();
|
||||
mV[1] = sd[1].asInteger();
|
||||
mV[2] = sd[2].asInteger();
|
||||
mV[3] = sd[3].asInteger();
|
||||
mV[VRED] = sd[VRED].asInteger();
|
||||
mV[VGREEN] = sd[VGREEN].asInteger();
|
||||
mV[VBLUE] = sd[VBLUE].asInteger();
|
||||
mV[VALPHA] = sd[VALPHA].asInteger();
|
||||
}
|
||||
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mV[0];
|
||||
ret[1] = mV[1];
|
||||
ret[2] = mV[2];
|
||||
ret[3] = mV[3];
|
||||
ret[VRED] = mV[VRED];
|
||||
ret[VGREEN] = mV[VGREEN];
|
||||
ret[VBLUE] = mV[VBLUE];
|
||||
ret[VALPHA] = mV[VALPHA];
|
||||
return ret;
|
||||
}
|
||||
|
||||
const LLColor4U& setToBlack(); // zero LLColor4U to (0, 0, 0, 1)
|
||||
const LLColor4U& setToWhite(); // zero LLColor4U to (0, 0, 0, 1)
|
||||
const LLColor4U& setToBlack(); // zero LLColor4U to (0, 0, 0, 1)
|
||||
const LLColor4U& setToWhite(); // zero LLColor4U to (0, 0, 0, 1)
|
||||
|
||||
const LLColor4U& set(U8 r, U8 g, U8 b, U8 a);// Sets LLColor4U to (r, g, b, a)
|
||||
const LLColor4U& set(U8 r, U8 g, U8 b); // Sets LLColor4U to (r, g, b) (no change in a)
|
||||
const LLColor4U& set(const LLColor4U &vec); // Sets LLColor4U to vec
|
||||
const LLColor4U& set(const U8 *vec); // Sets LLColor4U to vec
|
||||
const LLColor4U& set(U8 r, U8 g, U8 b, U8 a); // Sets LLColor4U to (r, g, b, a)
|
||||
const LLColor4U& set(U8 r, U8 g, U8 b); // Sets LLColor4U to (r, g, b) (no change in a)
|
||||
const LLColor4U& set(const LLColor4U& vec); // Sets LLColor4U to vec
|
||||
const LLColor4U& set(const U8* vec); // Sets LLColor4U to vec
|
||||
|
||||
const LLColor4U& setVec(U8 r, U8 g, U8 b, U8 a); // deprecated -- use set()
|
||||
const LLColor4U& setVec(U8 r, U8 g, U8 b); // deprecated -- use set()
|
||||
const LLColor4U& setVec(const LLColor4U &vec); // deprecated -- use set()
|
||||
const LLColor4U& setVec(const U8 *vec); // deprecated -- use set()
|
||||
const LLColor4U& setVec(U8 r, U8 g, U8 b, U8 a); // deprecated -- use set()
|
||||
const LLColor4U& setVec(U8 r, U8 g, U8 b); // deprecated -- use set()
|
||||
const LLColor4U& setVec(const LLColor4U& vec); // deprecated -- use set()
|
||||
const LLColor4U& setVec(const U8* vec); // deprecated -- use set()
|
||||
|
||||
const LLColor4U& setAlpha(U8 a);
|
||||
const LLColor4U& setAlpha(U8 a);
|
||||
|
||||
F32 magVec() const; // deprecated -- use length()
|
||||
F32 magVecSquared() const; // deprecated -- use lengthSquared()
|
||||
F32 magVec() const; // deprecated -- use length()
|
||||
F32 magVecSquared() const; // deprecated -- use lengthSquared()
|
||||
|
||||
F32 length() const; // Returns magnitude squared of LLColor4U
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLColor4U
|
||||
F32 length() const; // Returns magnitude squared of LLColor4U
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLColor4U
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLColor4U &a); // Print a
|
||||
friend LLColor4U operator+(const LLColor4U &a, const LLColor4U &b); // Return vector a + b
|
||||
friend LLColor4U operator-(const LLColor4U &a, const LLColor4U &b); // Return vector a minus b
|
||||
friend LLColor4U operator*(const LLColor4U &a, const LLColor4U &b); // Return a * b
|
||||
friend bool operator==(const LLColor4U &a, const LLColor4U &b); // Return a == b
|
||||
friend bool operator!=(const LLColor4U &a, const LLColor4U &b); // Return a != b
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLColor4U& a); // Print a
|
||||
friend LLColor4U operator+(const LLColor4U& a, const LLColor4U& b); // Return vector a + b
|
||||
friend LLColor4U operator-(const LLColor4U& a, const LLColor4U& b); // Return vector a minus b
|
||||
friend LLColor4U operator*(const LLColor4U& a, const LLColor4U& b); // Return a * b
|
||||
friend bool operator==(const LLColor4U& a, const LLColor4U& b); // Return a == b
|
||||
friend bool operator!=(const LLColor4U& a, const LLColor4U& b); // Return a != b
|
||||
|
||||
friend const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b); // Return vector a + b
|
||||
friend const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b); // Return vector a minus b
|
||||
friend const LLColor4U& operator*=(LLColor4U &a, U8 k); // Return rgb times scaler k (no alpha change)
|
||||
friend const LLColor4U& operator%=(LLColor4U &a, U8 k); // Return alpha times scaler k (no rgb change)
|
||||
friend const LLColor4U& operator+=(LLColor4U& a, const LLColor4U& b); // Return vector a + b
|
||||
friend const LLColor4U& operator-=(LLColor4U& a, const LLColor4U& b); // Return vector a minus b
|
||||
friend const LLColor4U& operator*=(LLColor4U& a, U8 k); // Return rgb times scaler k (no alpha change)
|
||||
friend const LLColor4U& operator%=(LLColor4U& a, U8 k); // Return alpha times scaler k (no rgb change)
|
||||
|
||||
LLColor4U addClampMax(const LLColor4U &color); // Add and clamp the max
|
||||
LLColor4U addClampMax(const LLColor4U& color); // Add and clamp the max
|
||||
|
||||
LLColor4U multAll(const F32 k); // Multiply ALL channels by scalar k
|
||||
LLColor4U multAll(const F32 k); // Multiply ALL channels by scalar k
|
||||
|
||||
inline void setVecScaleClamp(const LLColor3 &color);
|
||||
inline void setVecScaleClamp(const LLColor4 &color);
|
||||
inline void setVecScaleClamp(const LLColor3& color);
|
||||
inline void setVecScaleClamp(const LLColor4& color);
|
||||
|
||||
static bool parseColor4U(const std::string& buf, LLColor4U* value);
|
||||
|
||||
// conversion
|
||||
operator LLColor4() const
|
||||
{
|
||||
return LLColor4(*this);
|
||||
}
|
||||
operator LLColor4() const { return LLColor4(*this); }
|
||||
|
||||
U32 asRGBA() const;
|
||||
void fromRGBA( U32 aVal );
|
||||
U32 asRGBA() const;
|
||||
void fromRGBA(U32 aVal);
|
||||
|
||||
static LLColor4U white;
|
||||
static LLColor4U black;
|
||||
|
|
@ -139,102 +128,94 @@ static_assert(std::is_trivially_move_assignable<LLColor4U>::value, "LLColor4U mu
|
|||
static_assert(std::is_standard_layout<LLColor4U>::value, "LLColor4U must be a standard layout type");
|
||||
|
||||
// Non-member functions
|
||||
F32 distVec(const LLColor4U &a, const LLColor4U &b); // Returns distance between a and b
|
||||
F32 distVec_squared(const LLColor4U &a, const LLColor4U &b); // Returns distance squared between a and b
|
||||
|
||||
F32 distVec(const LLColor4U& a, const LLColor4U& b); // Returns distance between a and b
|
||||
F32 distVec_squared(const LLColor4U& a, const LLColor4U& b); // Returns distance squared between a and b
|
||||
|
||||
inline LLColor4U::LLColor4U()
|
||||
{
|
||||
mV[VRED] = 0;
|
||||
mV[VRED] = 0;
|
||||
mV[VGREEN] = 0;
|
||||
mV[VBLUE] = 0;
|
||||
mV[VBLUE] = 0;
|
||||
mV[VALPHA] = 255;
|
||||
}
|
||||
|
||||
inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b)
|
||||
{
|
||||
mV[VRED] = r;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
mV[VBLUE] = b;
|
||||
mV[VALPHA] = 255;
|
||||
}
|
||||
|
||||
inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b, U8 a)
|
||||
{
|
||||
mV[VRED] = r;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
mV[VBLUE] = b;
|
||||
mV[VALPHA] = a;
|
||||
}
|
||||
|
||||
inline LLColor4U::LLColor4U(const U8 *vec)
|
||||
inline LLColor4U::LLColor4U(const U8* vec)
|
||||
{
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VALPHA] = vec[VALPHA];
|
||||
}
|
||||
|
||||
/*
|
||||
inline LLColor4U::operator LLColor4()
|
||||
{
|
||||
return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f));
|
||||
}
|
||||
*/
|
||||
|
||||
inline const LLColor4U& LLColor4U::setToBlack(void)
|
||||
{
|
||||
mV[VRED] = 0;
|
||||
mV[VRED] = 0;
|
||||
mV[VGREEN] = 0;
|
||||
mV[VBLUE] = 0;
|
||||
mV[VBLUE] = 0;
|
||||
mV[VALPHA] = 255;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4U& LLColor4U::setToWhite(void)
|
||||
{
|
||||
mV[VRED] = 255;
|
||||
mV[VRED] = 255;
|
||||
mV[VGREEN] = 255;
|
||||
mV[VBLUE] = 255;
|
||||
mV[VBLUE] = 255;
|
||||
mV[VALPHA] = 255;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4U& LLColor4U::set(const U8 x, const U8 y, const U8 z)
|
||||
{
|
||||
mV[VRED] = x;
|
||||
mV[VRED] = x;
|
||||
mV[VGREEN] = y;
|
||||
mV[VBLUE] = z;
|
||||
mV[VBLUE] = z;
|
||||
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 255;
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 255;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4U& LLColor4U::set(const U8 r, const U8 g, const U8 b, U8 a)
|
||||
{
|
||||
mV[0] = r;
|
||||
mV[1] = g;
|
||||
mV[2] = b;
|
||||
mV[3] = a;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
mV[VALPHA] = a;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4U& LLColor4U::set(const LLColor4U &vec)
|
||||
inline const LLColor4U& LLColor4U::set(const LLColor4U& vec)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = vec.mV[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline const LLColor4U& LLColor4U::set(const U8 *vec)
|
||||
inline const LLColor4U& LLColor4U::set(const U8* vec)
|
||||
{
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VALPHA] = vec[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
|
@ -242,12 +223,12 @@ inline const LLColor4U& LLColor4U::set(const U8 *vec)
|
|||
// deprecated
|
||||
inline const LLColor4U& LLColor4U::setVec(const U8 x, const U8 y, const U8 z)
|
||||
{
|
||||
mV[VRED] = x;
|
||||
mV[VRED] = x;
|
||||
mV[VGREEN] = y;
|
||||
mV[VBLUE] = z;
|
||||
mV[VBLUE] = z;
|
||||
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 255;
|
||||
// no change to alpha!
|
||||
// mV[VALPHA] = 255;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
|
@ -255,29 +236,29 @@ inline const LLColor4U& LLColor4U::setVec(const U8 x, const U8 y, const U8 z)
|
|||
// deprecated
|
||||
inline const LLColor4U& LLColor4U::setVec(const U8 r, const U8 g, const U8 b, U8 a)
|
||||
{
|
||||
mV[0] = r;
|
||||
mV[1] = g;
|
||||
mV[2] = b;
|
||||
mV[3] = a;
|
||||
mV[VRED] = r;
|
||||
mV[VGREEN] = g;
|
||||
mV[VBLUE] = b;
|
||||
mV[VALPHA] = a;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor4U& LLColor4U::setVec(const LLColor4U &vec)
|
||||
inline const LLColor4U& LLColor4U::setVec(const LLColor4U& vec)
|
||||
{
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VRED] = vec.mV[VRED];
|
||||
mV[VGREEN] = vec.mV[VGREEN];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VBLUE] = vec.mV[VBLUE];
|
||||
mV[VALPHA] = vec.mV[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline const LLColor4U& LLColor4U::setVec(const U8 *vec)
|
||||
inline const LLColor4U& LLColor4U::setVec(const U8* vec)
|
||||
{
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VRED] = vec[VRED];
|
||||
mV[VGREEN] = vec[VGREEN];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VBLUE] = vec[VBLUE];
|
||||
mV[VALPHA] = vec[VALPHA];
|
||||
return (*this);
|
||||
}
|
||||
|
|
@ -290,131 +271,68 @@ inline const LLColor4U& LLColor4U::setAlpha(U8 a)
|
|||
|
||||
// LLColor4U Magnitude and Normalization Functions
|
||||
|
||||
inline F32 LLColor4U::length(void) const
|
||||
inline F32 LLColor4U::length() const
|
||||
{
|
||||
return (F32) sqrt( ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE] );
|
||||
return sqrt(((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE]);
|
||||
}
|
||||
|
||||
inline F32 LLColor4U::lengthSquared(void) const
|
||||
inline F32 LLColor4U::lengthSquared() const
|
||||
{
|
||||
return ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE];
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor4U::magVec(void) const
|
||||
inline F32 LLColor4U::magVec() const
|
||||
{
|
||||
return (F32) sqrt( ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE] );
|
||||
return sqrt(((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE]);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLColor4U::magVecSquared(void) const
|
||||
inline F32 LLColor4U::magVecSquared() const
|
||||
{
|
||||
return ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE];
|
||||
}
|
||||
|
||||
inline LLColor4U operator+(const LLColor4U &a, const LLColor4U &b)
|
||||
inline LLColor4U operator+(const LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
return LLColor4U(
|
||||
a.mV[VRED] + b.mV[VRED],
|
||||
a.mV[VGREEN] + b.mV[VGREEN],
|
||||
a.mV[VBLUE] + b.mV[VBLUE],
|
||||
a.mV[VALPHA] + b.mV[VALPHA]);
|
||||
return LLColor4U(a.mV[VRED] + b.mV[VRED], a.mV[VGREEN] + b.mV[VGREEN], a.mV[VBLUE] + b.mV[VBLUE], a.mV[VALPHA] + b.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4U operator-(const LLColor4U &a, const LLColor4U &b)
|
||||
inline LLColor4U operator-(const LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
return LLColor4U(
|
||||
a.mV[VRED] - b.mV[VRED],
|
||||
a.mV[VGREEN] - b.mV[VGREEN],
|
||||
a.mV[VBLUE] - b.mV[VBLUE],
|
||||
a.mV[VALPHA] - b.mV[VALPHA]);
|
||||
return LLColor4U(a.mV[VRED] - b.mV[VRED], a.mV[VGREEN] - b.mV[VGREEN], a.mV[VBLUE] - b.mV[VBLUE], a.mV[VALPHA] - b.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4U operator*(const LLColor4U &a, const LLColor4U &b)
|
||||
inline LLColor4U operator*(const LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
return LLColor4U(
|
||||
a.mV[VRED] * b.mV[VRED],
|
||||
a.mV[VGREEN] * b.mV[VGREEN],
|
||||
a.mV[VBLUE] * b.mV[VBLUE],
|
||||
a.mV[VALPHA] * b.mV[VALPHA]);
|
||||
return LLColor4U(a.mV[VRED] * b.mV[VRED], a.mV[VGREEN] * b.mV[VGREEN], a.mV[VBLUE] * b.mV[VBLUE], a.mV[VALPHA] * b.mV[VALPHA]);
|
||||
}
|
||||
|
||||
inline LLColor4U LLColor4U::addClampMax(const LLColor4U &color)
|
||||
inline LLColor4U LLColor4U::addClampMax(const LLColor4U& color)
|
||||
{
|
||||
return LLColor4U(llmin((S32)mV[VRED] + color.mV[VRED], 255),
|
||||
llmin((S32)mV[VGREEN] + color.mV[VGREEN], 255),
|
||||
llmin((S32)mV[VBLUE] + color.mV[VBLUE], 255),
|
||||
llmin((S32)mV[VALPHA] + color.mV[VALPHA], 255));
|
||||
llmin((S32)mV[VGREEN] + color.mV[VGREEN], 255),
|
||||
llmin((S32)mV[VBLUE] + color.mV[VBLUE], 255),
|
||||
llmin((S32)mV[VALPHA] + color.mV[VALPHA], 255));
|
||||
}
|
||||
|
||||
inline LLColor4U LLColor4U::multAll(const F32 k)
|
||||
{
|
||||
// Round to nearest
|
||||
return LLColor4U(
|
||||
(U8)ll_round(mV[VRED] * k),
|
||||
(U8)ll_round(mV[VGREEN] * k),
|
||||
(U8)ll_round(mV[VBLUE] * k),
|
||||
(U8)ll_round(mV[VALPHA] * k));
|
||||
}
|
||||
/*
|
||||
inline LLColor4U operator*(const LLColor4U &a, U8 k)
|
||||
{
|
||||
// only affects rgb (not a!)
|
||||
return LLColor4U(
|
||||
a.mV[VRED] * k,
|
||||
a.mV[VGREEN] * k,
|
||||
a.mV[VBLUE] * k,
|
||||
a.mV[VALPHA]);
|
||||
return LLColor4U((U8)ll_round(mV[VRED] * k), (U8)ll_round(mV[VGREEN] * k), (U8)ll_round(mV[VBLUE] * k), (U8)ll_round(mV[VALPHA] * k));
|
||||
}
|
||||
|
||||
inline LLColor4U operator*(U8 k, const LLColor4U &a)
|
||||
inline bool operator==(const LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
// only affects rgb (not a!)
|
||||
return LLColor4U(
|
||||
a.mV[VRED] * k,
|
||||
a.mV[VGREEN] * k,
|
||||
a.mV[VBLUE] * k,
|
||||
a.mV[VALPHA]);
|
||||
return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE]) && (a.mV[VALPHA] == b.mV[VALPHA]));
|
||||
}
|
||||
|
||||
inline LLColor4U operator%(U8 k, const LLColor4U &a)
|
||||
inline bool operator!=(const LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
// only affects alpha (not rgb!)
|
||||
return LLColor4U(
|
||||
a.mV[VRED],
|
||||
a.mV[VGREEN],
|
||||
a.mV[VBLUE],
|
||||
a.mV[VALPHA] * k );
|
||||
return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE]) || (a.mV[VALPHA] != b.mV[VALPHA]));
|
||||
}
|
||||
|
||||
inline LLColor4U operator%(const LLColor4U &a, U8 k)
|
||||
{
|
||||
// only affects alpha (not rgb!)
|
||||
return LLColor4U(
|
||||
a.mV[VRED],
|
||||
a.mV[VGREEN],
|
||||
a.mV[VBLUE],
|
||||
a.mV[VALPHA] * k );
|
||||
}
|
||||
*/
|
||||
|
||||
inline bool operator==(const LLColor4U &a, const LLColor4U &b)
|
||||
{
|
||||
return ( (a.mV[VRED] == b.mV[VRED])
|
||||
&&(a.mV[VGREEN] == b.mV[VGREEN])
|
||||
&&(a.mV[VBLUE] == b.mV[VBLUE])
|
||||
&&(a.mV[VALPHA] == b.mV[VALPHA]));
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLColor4U &a, const LLColor4U &b)
|
||||
{
|
||||
return ( (a.mV[VRED] != b.mV[VRED])
|
||||
||(a.mV[VGREEN] != b.mV[VGREEN])
|
||||
||(a.mV[VBLUE] != b.mV[VBLUE])
|
||||
||(a.mV[VALPHA] != b.mV[VALPHA]));
|
||||
}
|
||||
|
||||
inline const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b)
|
||||
inline const LLColor4U& operator+=(LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
a.mV[VRED] += b.mV[VRED];
|
||||
a.mV[VGREEN] += b.mV[VGREEN];
|
||||
|
|
@ -423,7 +341,7 @@ inline const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b)
|
||||
inline const LLColor4U& operator-=(LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
a.mV[VRED] -= b.mV[VRED];
|
||||
a.mV[VGREEN] -= b.mV[VGREEN];
|
||||
|
|
@ -432,7 +350,7 @@ inline const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor4U& operator*=(LLColor4U &a, U8 k)
|
||||
inline const LLColor4U& operator*=(LLColor4U& a, U8 k)
|
||||
{
|
||||
// only affects rgb (not a!)
|
||||
a.mV[VRED] *= k;
|
||||
|
|
@ -441,20 +359,20 @@ inline const LLColor4U& operator*=(LLColor4U &a, U8 k)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLColor4U& operator%=(LLColor4U &a, U8 k)
|
||||
inline const LLColor4U& operator%=(LLColor4U& a, U8 k)
|
||||
{
|
||||
// only affects alpha (not rgb!)
|
||||
a.mV[VALPHA] *= k;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline F32 distVec(const LLColor4U &a, const LLColor4U &b)
|
||||
inline F32 distVec(const LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
LLColor4U vec = a - b;
|
||||
return (vec.length());
|
||||
}
|
||||
|
||||
inline F32 distVec_squared(const LLColor4U &a, const LLColor4U &b)
|
||||
inline F32 distVec_squared(const LLColor4U& a, const LLColor4U& b)
|
||||
{
|
||||
LLColor4U vec = a - b;
|
||||
return (vec.lengthSquared());
|
||||
|
|
@ -463,13 +381,13 @@ inline F32 distVec_squared(const LLColor4U &a, const LLColor4U &b)
|
|||
void LLColor4U::setVecScaleClamp(const LLColor4& color)
|
||||
{
|
||||
F32 color_scale_factor = 255.f;
|
||||
F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]);
|
||||
F32 max_color = llmax(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]);
|
||||
if (max_color > 1.f)
|
||||
{
|
||||
color_scale_factor /= max_color;
|
||||
}
|
||||
const S32 MAX_COLOR = 255;
|
||||
S32 r = ll_round(color.mV[0] * color_scale_factor);
|
||||
constexpr S32 MAX_COLOR = 255;
|
||||
S32 r = ll_round(color.mV[VRED] * color_scale_factor);
|
||||
if (r > MAX_COLOR)
|
||||
{
|
||||
r = MAX_COLOR;
|
||||
|
|
@ -478,9 +396,9 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color)
|
|||
{
|
||||
r = 0;
|
||||
}
|
||||
mV[0] = r;
|
||||
mV[VRED] = r;
|
||||
|
||||
S32 g = ll_round(color.mV[1] * color_scale_factor);
|
||||
S32 g = ll_round(color.mV[VGREEN] * color_scale_factor);
|
||||
if (g > MAX_COLOR)
|
||||
{
|
||||
g = MAX_COLOR;
|
||||
|
|
@ -489,9 +407,9 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color)
|
|||
{
|
||||
g = 0;
|
||||
}
|
||||
mV[1] = g;
|
||||
mV[VGREEN] = g;
|
||||
|
||||
S32 b = ll_round(color.mV[2] * color_scale_factor);
|
||||
S32 b = ll_round(color.mV[VBLUE] * color_scale_factor);
|
||||
if (b > MAX_COLOR)
|
||||
{
|
||||
b = MAX_COLOR;
|
||||
|
|
@ -500,10 +418,10 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color)
|
|||
{
|
||||
b = 0;
|
||||
}
|
||||
mV[2] = b;
|
||||
mV[VBLUE] = b;
|
||||
|
||||
// Alpha shouldn't be scaled, just clamped...
|
||||
S32 a = ll_round(color.mV[3] * MAX_COLOR);
|
||||
S32 a = ll_round(color.mV[VALPHA] * MAX_COLOR);
|
||||
if (a > MAX_COLOR)
|
||||
{
|
||||
a = MAX_COLOR;
|
||||
|
|
@ -512,44 +430,42 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color)
|
|||
{
|
||||
a = 0;
|
||||
}
|
||||
mV[3] = a;
|
||||
mV[VALPHA] = a;
|
||||
}
|
||||
|
||||
void LLColor4U::setVecScaleClamp(const LLColor3& color)
|
||||
{
|
||||
F32 color_scale_factor = 255.f;
|
||||
F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]);
|
||||
F32 max_color = llmax(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]);
|
||||
if (max_color > 1.f)
|
||||
{
|
||||
color_scale_factor /= max_color;
|
||||
}
|
||||
|
||||
const S32 MAX_COLOR = 255;
|
||||
S32 r = ll_round(color.mV[0] * color_scale_factor);
|
||||
S32 r = ll_round(color.mV[VRED] * color_scale_factor);
|
||||
if (r > MAX_COLOR)
|
||||
{
|
||||
r = MAX_COLOR;
|
||||
}
|
||||
else
|
||||
if (r < 0)
|
||||
else if (r < 0)
|
||||
{
|
||||
r = 0;
|
||||
}
|
||||
mV[0] = r;
|
||||
mV[VRED] = r;
|
||||
|
||||
S32 g = ll_round(color.mV[1] * color_scale_factor);
|
||||
S32 g = ll_round(color.mV[VGREEN] * color_scale_factor);
|
||||
if (g > MAX_COLOR)
|
||||
{
|
||||
g = MAX_COLOR;
|
||||
}
|
||||
else
|
||||
if (g < 0)
|
||||
else if (g < 0)
|
||||
{
|
||||
g = 0;
|
||||
}
|
||||
mV[1] = g;
|
||||
mV[VGREEN] = g;
|
||||
|
||||
S32 b = ll_round(color.mV[2] * color_scale_factor);
|
||||
S32 b = ll_round(color.mV[VBLUE] * color_scale_factor);
|
||||
if (b > MAX_COLOR)
|
||||
{
|
||||
b = MAX_COLOR;
|
||||
|
|
@ -558,31 +474,29 @@ void LLColor4U::setVecScaleClamp(const LLColor3& color)
|
|||
{
|
||||
b = 0;
|
||||
}
|
||||
mV[2] = b;
|
||||
mV[VBLUE] = b;
|
||||
|
||||
mV[3] = 255;
|
||||
mV[VALPHA] = 255;
|
||||
}
|
||||
|
||||
inline U32 LLColor4U::asRGBA() const
|
||||
{
|
||||
// Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here
|
||||
|
||||
return (mV[3] << 24) | (mV[2] << 16) | (mV[1] << 8) | mV[0];
|
||||
return (mV[VALPHA] << 24) | (mV[VBLUE] << 16) | (mV[VGREEN] << 8) | mV[VRED];
|
||||
}
|
||||
|
||||
inline void LLColor4U::fromRGBA( U32 aVal )
|
||||
inline void LLColor4U::fromRGBA(U32 aVal)
|
||||
{
|
||||
// Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here
|
||||
|
||||
mV[ 0 ] = aVal & 0xFF;
|
||||
mV[VRED] = aVal & 0xFF;
|
||||
aVal >>= 8;
|
||||
mV[ 1 ] = aVal & 0xFF;
|
||||
mV[VGREEN] = aVal & 0xFF;
|
||||
aVal >>= 8;
|
||||
mV[ 2 ] = aVal & 0xFF;
|
||||
mV[VBLUE] = aVal & 0xFF;
|
||||
aVal >>= 8;
|
||||
mV[ 3 ] = aVal & 0xFF;
|
||||
mV[VALPHA] = aVal & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
//#include "vmath.h"
|
||||
#include "v3math.h"
|
||||
#include "v4math.h"
|
||||
#include "m4math.h"
|
||||
|
|
@ -36,13 +35,13 @@
|
|||
// LLVector4
|
||||
|
||||
// Axis-Angle rotations
|
||||
const LLVector4& LLVector4::rotVec(const LLMatrix4 &mat)
|
||||
const LLVector4& LLVector4::rotVec(const LLMatrix4& mat)
|
||||
{
|
||||
*this = *this * mat;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector4& LLVector4::rotVec(const LLQuaternion &q)
|
||||
const LLVector4& LLVector4::rotVec(const LLQuaternion& q)
|
||||
{
|
||||
*this = *this * q;
|
||||
return *this;
|
||||
|
|
@ -64,16 +63,16 @@ bool LLVector4::abs()
|
|||
{
|
||||
bool ret{ false };
|
||||
|
||||
if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = true; }
|
||||
if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = true; }
|
||||
if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = true; }
|
||||
if (mV[3] < 0.f) { mV[3] = -mV[3]; ret = true; }
|
||||
if (mV[VX] < 0.f) { mV[VX] = -mV[VX]; ret = true; }
|
||||
if (mV[VY] < 0.f) { mV[VY] = -mV[VY]; ret = true; }
|
||||
if (mV[VZ] < 0.f) { mV[VZ] = -mV[VZ]; ret = true; }
|
||||
if (mV[VW] < 0.f) { mV[VW] = -mV[VW]; ret = true; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const LLVector4 &a)
|
||||
std::ostream& operator<<(std::ostream& s, const LLVector4& a)
|
||||
{
|
||||
s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << ", " << a.mV[VW] << " }";
|
||||
return s;
|
||||
|
|
@ -108,12 +107,12 @@ bool are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon)
|
|||
}
|
||||
|
||||
|
||||
LLVector3 vec4to3(const LLVector4 &vec)
|
||||
LLVector3 vec4to3(const LLVector4& vec)
|
||||
{
|
||||
return LLVector3( vec.mV[VX], vec.mV[VY], vec.mV[VZ] );
|
||||
}
|
||||
|
||||
LLVector4 vec3to4(const LLVector3 &vec)
|
||||
LLVector4 vec3to4(const LLVector3& vec)
|
||||
{
|
||||
return LLVector4(vec.mV[VX], vec.mV[VY], vec.mV[VZ]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,108 +42,108 @@ class LLQuaternion;
|
|||
|
||||
// LLVector4 = |x y z w|
|
||||
|
||||
static const U32 LENGTHOFVECTOR4 = 4;
|
||||
static constexpr U32 LENGTHOFVECTOR4 = 4;
|
||||
|
||||
class LLVector4
|
||||
{
|
||||
public:
|
||||
F32 mV[LENGTHOFVECTOR4];
|
||||
LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1)
|
||||
explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3])
|
||||
explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
|
||||
explicit LLVector4(const LLVector2 &vec);
|
||||
explicit LLVector4(const LLVector2 &vec, F32 z, F32 w);
|
||||
explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1)
|
||||
explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w)
|
||||
explicit LLVector4(const LLSD &sd);
|
||||
LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1)
|
||||
LLVector4(F32 x, F32 y, F32 z, F32 w);
|
||||
public:
|
||||
F32 mV[LENGTHOFVECTOR4];
|
||||
LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1)
|
||||
explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3])
|
||||
explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
|
||||
explicit LLVector4(const LLVector2 &vec);
|
||||
explicit LLVector4(const LLVector2 &vec, F32 z, F32 w);
|
||||
explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1)
|
||||
explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w)
|
||||
explicit LLVector4(const LLSD &sd);
|
||||
LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1)
|
||||
LLVector4(F32 x, F32 y, F32 z, F32 w);
|
||||
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mV[0];
|
||||
ret[1] = mV[1];
|
||||
ret[2] = mV[2];
|
||||
ret[3] = mV[3];
|
||||
return ret;
|
||||
}
|
||||
LLSD getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[VX] = mV[VX];
|
||||
ret[VY] = mV[VY];
|
||||
ret[VZ] = mV[VZ];
|
||||
ret[VW] = mV[VW];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setValue(const LLSD& sd)
|
||||
{
|
||||
mV[0] = (F32)sd[0].asReal();
|
||||
mV[1] = (F32)sd[1].asReal();
|
||||
mV[2] = (F32)sd[2].asReal();
|
||||
mV[3] = (F32)sd[3].asReal();
|
||||
}
|
||||
void setValue(const LLSD& sd)
|
||||
{
|
||||
mV[VX] = (F32)sd[VX].asReal();
|
||||
mV[VY] = (F32)sd[VY].asReal();
|
||||
mV[VZ] = (F32)sd[VZ].asReal();
|
||||
mV[VW] = (F32)sd[VW].asReal();
|
||||
}
|
||||
|
||||
// GLM interop
|
||||
explicit LLVector4(const glm::vec3& vec); // Initializes LLVector4 to (vec, 1)
|
||||
explicit LLVector4(const glm::vec4& vec); // Initializes LLVector4 to vec
|
||||
explicit operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2])
|
||||
explicit operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], vec[3])
|
||||
// GLM interop
|
||||
explicit LLVector4(const glm::vec3& vec); // Initializes LLVector4 to (vec, 1)
|
||||
explicit LLVector4(const glm::vec4& vec); // Initializes LLVector4 to vec
|
||||
explicit operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2])
|
||||
explicit operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], vec[3])
|
||||
|
||||
inline bool isFinite() const; // checks to see if all values of LLVector3 are finite
|
||||
inline bool isFinite() const; // checks to see if all values of LLVector3 are finite
|
||||
|
||||
inline void clear(); // Clears LLVector4 to (0, 0, 0, 1)
|
||||
inline void clearVec(); // deprecated
|
||||
inline void zeroVec(); // deprecated
|
||||
inline void clear(); // Clears LLVector4 to (0, 0, 0, 1)
|
||||
inline void clearVec(); // deprecated
|
||||
inline void zeroVec(); // deprecated
|
||||
|
||||
inline void set(F32 x, F32 y, F32 z); // Sets LLVector4 to (x, y, z, 1)
|
||||
inline void set(F32 x, F32 y, F32 z, F32 w); // Sets LLVector4 to (x, y, z, w)
|
||||
inline void set(const LLVector4 &vec); // Sets LLVector4 to vec
|
||||
inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec
|
||||
inline void set(const F32 *vec); // Sets LLVector4 to vec
|
||||
inline void set(const glm::vec4& vec); // Sets LLVector4 to vec
|
||||
inline void set(const glm::vec3& vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec with w defaulted to 1
|
||||
inline void set(F32 x, F32 y, F32 z); // Sets LLVector4 to (x, y, z, 1)
|
||||
inline void set(F32 x, F32 y, F32 z, F32 w); // Sets LLVector4 to (x, y, z, w)
|
||||
inline void set(const LLVector4 &vec); // Sets LLVector4 to vec
|
||||
inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec
|
||||
inline void set(const F32 *vec); // Sets LLVector4 to vec
|
||||
inline void set(const glm::vec4& vec); // Sets LLVector4 to vec
|
||||
inline void set(const glm::vec3& vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec with w defaulted to 1
|
||||
|
||||
inline void setVec(F32 x, F32 y, F32 z); // deprecated
|
||||
inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated
|
||||
inline void setVec(const LLVector4 &vec); // deprecated
|
||||
inline void setVec(const LLVector3 &vec, F32 w = 1.f); // deprecated
|
||||
inline void setVec(const F32 *vec); // deprecated
|
||||
inline void setVec(F32 x, F32 y, F32 z); // deprecated
|
||||
inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated
|
||||
inline void setVec(const LLVector4 &vec); // deprecated
|
||||
inline void setVec(const LLVector3 &vec, F32 w = 1.f); // deprecated
|
||||
inline void setVec(const F32 *vec); // deprecated
|
||||
|
||||
F32 length() const; // Returns magnitude of LLVector4
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLVector4
|
||||
F32 normalize(); // Normalizes and returns the magnitude of LLVector4
|
||||
F32 length() const; // Returns magnitude of LLVector4
|
||||
F32 lengthSquared() const; // Returns magnitude squared of LLVector4
|
||||
F32 normalize(); // Normalizes and returns the magnitude of LLVector4
|
||||
|
||||
F32 magVec() const; // deprecated
|
||||
F32 magVecSquared() const; // deprecated
|
||||
F32 normVec(); // deprecated
|
||||
F32 magVec() const; // deprecated
|
||||
F32 magVecSquared() const; // deprecated
|
||||
F32 normVec(); // deprecated
|
||||
|
||||
// Sets all values to absolute value of their original values
|
||||
// Returns true if data changed
|
||||
bool abs();
|
||||
// Sets all values to absolute value of their original values
|
||||
// Returns true if data changed
|
||||
bool abs();
|
||||
|
||||
bool isExactlyClear() const { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; }
|
||||
bool isExactlyZero() const { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; }
|
||||
bool isExactlyClear() const { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; }
|
||||
bool isExactlyZero() const { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; }
|
||||
|
||||
const LLVector4& rotVec(const LLMatrix4 &mat); // Rotates by MAT4 mat
|
||||
const LLVector4& rotVec(const LLQuaternion &q); // Rotates by QUAT q
|
||||
const LLVector4& rotVec(const LLMatrix4 &mat); // Rotates by MAT4 mat
|
||||
const LLVector4& rotVec(const LLQuaternion &q); // Rotates by QUAT q
|
||||
|
||||
const LLVector4& scaleVec(const LLVector4& vec); // Scales component-wise by vec
|
||||
const LLVector4& scaleVec(const LLVector4& vec); // Scales component-wise by vec
|
||||
|
||||
F32 operator[](int idx) const { return mV[idx]; }
|
||||
F32 &operator[](int idx) { return mV[idx]; }
|
||||
F32 operator[](int idx) const { return mV[idx]; }
|
||||
F32 &operator[](int idx) { return mV[idx]; }
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLVector4 &a); // Print a
|
||||
friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b); // Return vector a + b
|
||||
friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b); // Return vector a minus b
|
||||
friend F32 operator*(const LLVector4 &a, const LLVector4 &b); // Return a dot b
|
||||
friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b); // Return a cross b
|
||||
friend LLVector4 operator/(const LLVector4 &a, F32 k); // Return a divided by scaler k
|
||||
friend LLVector4 operator*(const LLVector4 &a, F32 k); // Return a times scaler k
|
||||
friend LLVector4 operator*(F32 k, const LLVector4 &a); // Return a times scaler k
|
||||
friend bool operator==(const LLVector4 &a, const LLVector4 &b); // Return a == b
|
||||
friend bool operator!=(const LLVector4 &a, const LLVector4 &b); // Return a != b
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLVector4 &a); // Print a
|
||||
friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b); // Return vector a + b
|
||||
friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b); // Return vector a minus b
|
||||
friend F32 operator*(const LLVector4 &a, const LLVector4 &b); // Return a dot b
|
||||
friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b); // Return a cross b
|
||||
friend LLVector4 operator/(const LLVector4 &a, F32 k); // Return a divided by scaler k
|
||||
friend LLVector4 operator*(const LLVector4 &a, F32 k); // Return a times scaler k
|
||||
friend LLVector4 operator*(F32 k, const LLVector4 &a); // Return a times scaler k
|
||||
friend bool operator==(const LLVector4 &a, const LLVector4 &b); // Return a == b
|
||||
friend bool operator!=(const LLVector4 &a, const LLVector4 &b); // Return a != b
|
||||
|
||||
friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b); // Return vector a + b
|
||||
friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b); // Return vector a minus b
|
||||
friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b); // Return a cross b
|
||||
friend const LLVector4& operator*=(LLVector4 &a, F32 k); // Return a times scaler k
|
||||
friend const LLVector4& operator/=(LLVector4 &a, F32 k); // Return a divided by scaler k
|
||||
friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b); // Return vector a + b
|
||||
friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b); // Return vector a minus b
|
||||
friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b); // Return a cross b
|
||||
friend const LLVector4& operator*=(LLVector4 &a, F32 k); // Return a times scaler k
|
||||
friend const LLVector4& operator/=(LLVector4 &a, F32 k); // Return a divided by scaler k
|
||||
|
||||
friend LLVector4 operator-(const LLVector4 &a); // Return vector -a
|
||||
friend LLVector4 operator-(const LLVector4 &a); // Return vector -a
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_copyable<LLVector4>::value, "LLVector4 must be trivial copy");
|
||||
|
|
@ -163,34 +163,22 @@ LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u); // Returns a vect
|
|||
|
||||
inline LLVector4::LLVector4(void)
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 1.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = 1.f;
|
||||
set(x, y, z, 1.f);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(F32 x, F32 y, F32 z, F32 w)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = w;
|
||||
set(x, y, z, w);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
mV[VW] = vec[VW];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const F64 *vec)
|
||||
|
|
@ -219,18 +207,12 @@ inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w)
|
|||
|
||||
inline LLVector4::LLVector4(const LLVector3 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = 1.f;
|
||||
set(vec, 1.f);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = w;
|
||||
set(vec, w);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const LLSD &sd)
|
||||
|
|
@ -256,43 +238,31 @@ inline LLVector4::LLVector4(const glm::vec4& vec)
|
|||
|
||||
inline bool LLVector4::isFinite() const
|
||||
{
|
||||
return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]));
|
||||
return llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]);
|
||||
}
|
||||
|
||||
// Clear and Assignment Functions
|
||||
|
||||
inline void LLVector4::clear(void)
|
||||
inline void LLVector4::clear()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 1.f;
|
||||
set(0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::clearVec(void)
|
||||
inline void LLVector4::clearVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 1.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::zeroVec(void)
|
||||
inline void LLVector4::zeroVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 0.f;
|
||||
set(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
inline void LLVector4::set(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = 1.f;
|
||||
set(x, y, z, 1.f);
|
||||
}
|
||||
|
||||
inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w)
|
||||
|
|
@ -303,15 +273,12 @@ inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w)
|
|||
mV[VW] = w;
|
||||
}
|
||||
|
||||
inline void LLVector4::set(const LLVector4 &vec)
|
||||
inline void LLVector4::set(const LLVector4& vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = vec.mV[VW];
|
||||
set(vec.mV);
|
||||
}
|
||||
|
||||
inline void LLVector4::set(const LLVector3 &vec, F32 w)
|
||||
inline void LLVector4::set(const LLVector3& vec, F32 w)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
|
|
@ -319,14 +286,13 @@ inline void LLVector4::set(const LLVector3 &vec, F32 w)
|
|||
mV[VW] = w;
|
||||
}
|
||||
|
||||
inline void LLVector4::set(const F32 *vec)
|
||||
inline void LLVector4::set(const F32* vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
mV[VW] = vec[VW];
|
||||
}
|
||||
|
||||
inline void LLVector4::set(const glm::vec4& vec)
|
||||
{
|
||||
mV[VX] = vec.x;
|
||||
|
|
@ -346,119 +312,104 @@ inline void LLVector4::set(const glm::vec3& vec, F32 w)
|
|||
// deprecated
|
||||
inline void LLVector4::setVec(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = 1.f;
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(F32 x, F32 y, F32 z, F32 w)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = w;
|
||||
set(x, y, z, w);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(const LLVector4 &vec)
|
||||
inline void LLVector4::setVec(const LLVector4& vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = vec.mV[VW];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(const LLVector3 &vec, F32 w)
|
||||
inline void LLVector4::setVec(const LLVector3& vec, F32 w)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = w;
|
||||
set(vec, w);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(const F32 *vec)
|
||||
inline void LLVector4::setVec(const F32* vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
mV[VW] = vec[VW];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// LLVector4 Magnitude and Normalization Functions
|
||||
|
||||
inline F32 LLVector4::length(void) const
|
||||
inline F32 LLVector4::length() const
|
||||
{
|
||||
return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
return sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
inline F32 LLVector4::lengthSquared(void) const
|
||||
inline F32 LLVector4::lengthSquared() const
|
||||
{
|
||||
return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
|
||||
}
|
||||
|
||||
inline F32 LLVector4::magVec(void) const
|
||||
inline F32 LLVector4::magVec() const
|
||||
{
|
||||
return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
return length();
|
||||
}
|
||||
|
||||
inline F32 LLVector4::magVecSquared(void) const
|
||||
inline F32 LLVector4::magVecSquared() const
|
||||
{
|
||||
return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
|
||||
return lengthSquared();
|
||||
}
|
||||
|
||||
// LLVector4 Operators
|
||||
|
||||
inline LLVector4 operator+(const LLVector4 &a, const LLVector4 &b)
|
||||
inline LLVector4 operator+(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
LLVector4 c(a);
|
||||
return c += b;
|
||||
}
|
||||
|
||||
inline LLVector4 operator-(const LLVector4 &a, const LLVector4 &b)
|
||||
inline LLVector4 operator-(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
LLVector4 c(a);
|
||||
return c -= b;
|
||||
}
|
||||
|
||||
inline F32 operator*(const LLVector4 &a, const LLVector4 &b)
|
||||
inline F32 operator*(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]);
|
||||
return a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ];
|
||||
}
|
||||
|
||||
inline LLVector4 operator%(const LLVector4 &a, const LLVector4 &b)
|
||||
inline LLVector4 operator%(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
return LLVector4(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]);
|
||||
}
|
||||
|
||||
inline LLVector4 operator/(const LLVector4 &a, F32 k)
|
||||
inline LLVector4 operator/(const LLVector4& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
return LLVector4( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t );
|
||||
}
|
||||
|
||||
|
||||
inline LLVector4 operator*(const LLVector4 &a, F32 k)
|
||||
inline LLVector4 operator*(const LLVector4& a, F32 k)
|
||||
{
|
||||
return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
|
||||
}
|
||||
|
||||
inline LLVector4 operator*(F32 k, const LLVector4 &a)
|
||||
inline LLVector4 operator*(F32 k, const LLVector4& a)
|
||||
{
|
||||
return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k );
|
||||
}
|
||||
|
||||
inline bool operator==(const LLVector4 &a, const LLVector4 &b)
|
||||
inline bool operator==(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
return ( (a.mV[VX] == b.mV[VX])
|
||||
&&(a.mV[VY] == b.mV[VY])
|
||||
&&(a.mV[VZ] == b.mV[VZ]));
|
||||
}
|
||||
|
||||
inline bool operator!=(const LLVector4 &a, const LLVector4 &b)
|
||||
inline bool operator!=(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
return ( (a.mV[VX] != b.mV[VX])
|
||||
||(a.mV[VY] != b.mV[VY])
|
||||
|
|
@ -466,7 +417,7 @@ inline bool operator!=(const LLVector4 &a, const LLVector4 &b)
|
|||
||(a.mV[VW] != b.mV[VW]) );
|
||||
}
|
||||
|
||||
inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b)
|
||||
inline const LLVector4& operator+=(LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
a.mV[VX] += b.mV[VX];
|
||||
a.mV[VY] += b.mV[VY];
|
||||
|
|
@ -474,7 +425,7 @@ inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b)
|
||||
inline const LLVector4& operator-=(LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
a.mV[VX] -= b.mV[VX];
|
||||
a.mV[VY] -= b.mV[VY];
|
||||
|
|
@ -482,14 +433,14 @@ inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b)
|
||||
inline const LLVector4& operator%=(LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
LLVector4 ret(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]);
|
||||
a = ret;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector4& operator*=(LLVector4 &a, F32 k)
|
||||
inline const LLVector4& operator*=(LLVector4& a, F32 k)
|
||||
{
|
||||
a.mV[VX] *= k;
|
||||
a.mV[VY] *= k;
|
||||
|
|
@ -497,16 +448,12 @@ inline const LLVector4& operator*=(LLVector4 &a, F32 k)
|
|||
return a;
|
||||
}
|
||||
|
||||
inline const LLVector4& operator/=(LLVector4 &a, F32 k)
|
||||
inline const LLVector4& operator/=(LLVector4& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
a.mV[VX] *= t;
|
||||
a.mV[VY] *= t;
|
||||
a.mV[VZ] *= t;
|
||||
return a;
|
||||
return a *= 1.f / k;
|
||||
}
|
||||
|
||||
inline LLVector4 operator-(const LLVector4 &a)
|
||||
inline LLVector4 operator-(const LLVector4& a)
|
||||
{
|
||||
return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );
|
||||
}
|
||||
|
|
@ -521,19 +468,19 @@ inline LLVector4::operator glm::vec4() const
|
|||
return glm::make_vec4(mV);
|
||||
}
|
||||
|
||||
inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b)
|
||||
inline F32 dist_vec(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
LLVector4 vec = a - b;
|
||||
return (vec.length());
|
||||
return vec.length();
|
||||
}
|
||||
|
||||
inline F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b)
|
||||
inline F32 dist_vec_squared(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
LLVector4 vec = a - b;
|
||||
return (vec.lengthSquared());
|
||||
return vec.lengthSquared();
|
||||
}
|
||||
|
||||
inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u)
|
||||
inline LLVector4 lerp(const LLVector4& a, const LLVector4& b, F32 u)
|
||||
{
|
||||
return LLVector4(
|
||||
a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
|
||||
|
|
@ -542,59 +489,39 @@ inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u)
|
|||
a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);
|
||||
}
|
||||
|
||||
inline F32 LLVector4::normalize(void)
|
||||
inline F32 LLVector4::normalize()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
F32 oomag;
|
||||
F32 mag = sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
mV[VZ] *= oomag;
|
||||
*this /= mag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
mag = 0;
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mag = 0.f;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector4::normVec(void)
|
||||
inline F32 LLVector4::normVec()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
mV[VZ] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[0] = 0.f;
|
||||
mV[1] = 0.f;
|
||||
mV[2] = 0.f;
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return normalize();
|
||||
}
|
||||
|
||||
// Because apparently some parts of the viewer use this for color info.
|
||||
inline const LLVector4 srgbVector4(const LLVector4 &a) {
|
||||
inline const LLVector4 srgbVector4(const LLVector4& a)
|
||||
{
|
||||
LLVector4 srgbColor;
|
||||
|
||||
srgbColor.mV[0] = linearTosRGB(a.mV[0]);
|
||||
srgbColor.mV[1] = linearTosRGB(a.mV[1]);
|
||||
srgbColor.mV[2] = linearTosRGB(a.mV[2]);
|
||||
srgbColor.mV[3] = a.mV[3];
|
||||
srgbColor.mV[VX] = linearTosRGB(a.mV[VX]);
|
||||
srgbColor.mV[VY] = linearTosRGB(a.mV[VY]);
|
||||
srgbColor.mV[VZ] = linearTosRGB(a.mV[VZ]);
|
||||
srgbColor.mV[VW] = a.mV[VW];
|
||||
|
||||
return srgbColor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ public:
|
|||
void clearChanged(U32 bits) { mChanged &= ~bits; }
|
||||
|
||||
void setScaleChildOffset(bool scale) { mScaleChildOffset = scale; }
|
||||
bool getScaleChildOffset() { return mScaleChildOffset; }
|
||||
bool getScaleChildOffset() const { return mScaleChildOffset; }
|
||||
|
||||
LLXform* getParent() const { return mParent; }
|
||||
LLXform* getRoot() const;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static const U32 DEFAULT_POOL_SIZE = 5;
|
|||
// SL-14399: When we teleport to a brand-new simulator, the coprocedure queue
|
||||
// gets absolutely slammed with fetch requests. Make this queue effectively
|
||||
// unlimited.
|
||||
const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*1024;
|
||||
const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*512;
|
||||
|
||||
//=========================================================================
|
||||
class LLCoprocedurePool: private boost::noncopyable
|
||||
|
|
@ -58,7 +58,7 @@ class LLCoprocedurePool: private boost::noncopyable
|
|||
public:
|
||||
typedef LLCoprocedureManager::CoProcedure_t CoProcedure_t;
|
||||
|
||||
LLCoprocedurePool(const std::string &name, size_t size);
|
||||
LLCoprocedurePool(const std::string &name, size_t size, size_t queue_size);
|
||||
~LLCoprocedurePool();
|
||||
|
||||
/// Places the coprocedure on the queue for processing.
|
||||
|
|
@ -118,7 +118,7 @@ private:
|
|||
typedef std::shared_ptr<CoprocQueue_t> CoprocQueuePtr;
|
||||
|
||||
std::string mPoolName;
|
||||
size_t mPoolSize, mActiveCoprocsCount, mPending;
|
||||
size_t mPoolSize, mQueueSize, mActiveCoprocsCount, mPending;
|
||||
CoprocQueuePtr mPendingCoprocs;
|
||||
LLTempBoundListener mStatusListener;
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ LLCoprocedureManager::~LLCoprocedureManager()
|
|||
close();
|
||||
}
|
||||
|
||||
void LLCoprocedureManager::initializePool(const std::string &poolName)
|
||||
void LLCoprocedureManager::initializePool(const std::string &poolName, size_t queue_size)
|
||||
{
|
||||
poolMap_t::iterator it = mPoolMap.find(poolName);
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ void LLCoprocedureManager::initializePool(const std::string &poolName)
|
|||
LL_WARNS("CoProcMgr") << "LLCoprocedureManager: No setting for \"" << keyName << "\" setting pool size to default of " << size << LL_ENDL;
|
||||
}
|
||||
|
||||
poolPtr_t pool(new LLCoprocedurePool(poolName, size));
|
||||
poolPtr_t pool(new LLCoprocedurePool(poolName, size, queue_size));
|
||||
LL_ERRS_IF(!pool, "CoprocedureManager") << "Unable to create pool named \"" << poolName << "\" FATAL!" << LL_ENDL;
|
||||
|
||||
bool inserted = mPoolMap.emplace(poolName, pool).second;
|
||||
|
|
@ -212,7 +212,8 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd
|
|||
mPropertyQueryFn = queryfn;
|
||||
mPropertyDefineFn = updatefn;
|
||||
|
||||
initializePool("Upload");
|
||||
constexpr size_t UPLOAD_QUEUE_SIZE = 2048;
|
||||
initializePool("Upload", UPLOAD_QUEUE_SIZE);
|
||||
initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS
|
||||
// "ExpCache" pool gets initialized in LLExperienceCache
|
||||
// asset storage pool gets initialized in LLViewerAssetStorage
|
||||
|
|
@ -296,17 +297,19 @@ void LLCoprocedureManager::close(const std::string &pool)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
|
||||
LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size, size_t queue_size):
|
||||
mPoolName(poolName),
|
||||
mPoolSize(size),
|
||||
mQueueSize(queue_size),
|
||||
mActiveCoprocsCount(0),
|
||||
mPending(0),
|
||||
mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mCoroMapping()
|
||||
{
|
||||
llassert_always(mQueueSize > mPoolSize); // queue should be able to fit pool
|
||||
try
|
||||
{
|
||||
mPendingCoprocs = std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE);
|
||||
mPendingCoprocs = std::make_shared<CoprocQueue_t>(mQueueSize);
|
||||
// store in our LLTempBoundListener so that when the LLCoprocedurePool is
|
||||
// destroyed, we implicitly disconnect from this LLEventPump
|
||||
// Monitores application status
|
||||
|
|
@ -357,7 +360,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
|
|||
mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter));
|
||||
}
|
||||
|
||||
LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL;
|
||||
LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << mQueueSize << LL_ENDL;
|
||||
}
|
||||
|
||||
LLCoprocedurePool::~LLCoprocedurePool()
|
||||
|
|
@ -376,7 +379,7 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced
|
|||
<< "\" at "
|
||||
<< mPending << LL_ENDL;
|
||||
|
||||
if (mPending >= (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1))
|
||||
if (mPending >= (mQueueSize - 1))
|
||||
{
|
||||
// If it's all used up (not supposed to happen,
|
||||
// fetched should cap it), we are going to crash
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public:
|
|||
void close();
|
||||
void close(const std::string &pool);
|
||||
|
||||
void initializePool(const std::string &poolName);
|
||||
void initializePool(const std::string &poolName, size_t queue_size = DEFAULT_QUEUE_SIZE);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ void LLExperienceCache::initSingleton()
|
|||
cache_stream >> (*this);
|
||||
}
|
||||
|
||||
LLCoprocedureManager::instance().initializePool("ExpCache");
|
||||
constexpr size_t CORO_QUEUE_SIZE = 2048;
|
||||
LLCoprocedureManager::instance().initializePool("ExpCache", CORO_QUEUE_SIZE);
|
||||
|
||||
LLCoros::instance().launch("LLExperienceCache::idleCoro",
|
||||
boost::bind(&LLExperienceCache::idleCoro, this));
|
||||
|
|
|
|||
|
|
@ -209,8 +209,14 @@ S32 LLPacketRing::receiveOrDropBufferedPacket(char *datap, bool drop)
|
|||
|
||||
if (!drop)
|
||||
{
|
||||
assert(packet_size > 0);
|
||||
memcpy(datap, packet->getData(), packet_size);
|
||||
if (packet_size > 0)
|
||||
{
|
||||
memcpy(datap, packet->getData(), packet_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -506,6 +506,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
|
|||
rv = apr_socket_recv(apr_socket, datain, &maxinlen);
|
||||
if (rv != APR_SUCCESS)
|
||||
{
|
||||
// if rv == 70060 it's WSAETIMEDOUT
|
||||
char buf[MAX_STRING];
|
||||
LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
|
||||
ll_apr_warn_status(rv);
|
||||
|
|
|
|||
|
|
@ -1402,3 +1402,4 @@ char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->ge
|
|||
char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
|
||||
char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
|
||||
char const* const _PREHASH_LargeGenericMessage = LLMessageStringTable::getInstance()->getString("LargeGenericMessage");
|
||||
char const* const _PREHASH_MetaData = LLMessageStringTable::getInstance()->getString("MetaData");
|
||||
|
|
|
|||
|
|
@ -1403,5 +1403,6 @@ extern char const* const _PREHASH_HoverHeight;
|
|||
extern char const* const _PREHASH_Experience;
|
||||
extern char const* const _PREHASH_ExperienceID;
|
||||
extern char const* const _PREHASH_LargeGenericMessage;
|
||||
extern char const* const _PREHASH_MetaData;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include "llmath.h"
|
||||
//#include "vmath.h"
|
||||
#include "v3math.h"
|
||||
#include "patch_dct.h"
|
||||
#include "patch_code.h"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue