Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support "mapping extensions" beatmaps #192

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 29 additions & 18 deletions src/components/beat-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,6 @@ AFRAME.registerComponent('beat-generator', {
'downright'
],

horizontalPositions: [-0.75, -0.25, 0.25, 0.75],

horizontalPositionsHumanized: {
0: 'left',
1: 'middleleft',
2: 'middleright',
3: 'right'
},

positionHumanized: {
topLeft: { layer: 2, index: 0 },
topCenterLeft: { layer: 2, index: 1 },
Expand All @@ -73,12 +64,6 @@ AFRAME.registerComponent('beat-generator', {
bottomRight: { layer: 0, index: 3 }
},

verticalPositionsHumanized: {
0: 'bottom',
1: 'middle',
2: 'top'
},

init: function () {
this.audioAnalyserEl = document.getElementById('audioanalyser');
this.beatContainer = document.getElementById('beatContainer');
Expand All @@ -88,6 +73,7 @@ AFRAME.registerComponent('beat-generator', {
this.preloadTime = 0;
this.songTime = undefined;
this.bpm = undefined;
this.mappingExtensions = false;
this.curve = null;
this.curveEl = document.getElementById('curve');
this.curveFollowRigEl = document.getElementById('curveFollowRig');
Expand Down Expand Up @@ -164,6 +150,7 @@ AFRAME.registerComponent('beat-generator', {
this.beatData._obstacles.sort(lessThan);
this.beatData._notes.sort(lessThan);
this.bpm = this.beatData._beatsPerMinute;
this.mappingExtensions = this.beatData.mappingExtensions;

// Performance: Remove all obstacles if there are more than 256 (often used with Noodle Extensions)
if (this.beatData._obstacles.length > 256) {
Expand Down Expand Up @@ -286,8 +273,32 @@ AFRAME.registerComponent('beat-generator', {

// Apply sword offset. Blocks arrive on beat in front of the user.
const cutDirection = this.orientationsHumanized[noteInfo._cutDirection];
const horizontalPosition = this.horizontalPositionsHumanized[noteInfo._lineIndex] || 'left';
const verticalPosition = this.verticalPositionsHumanized[noteInfo._lineLayer] || 'middle';
let horizontalPosition;
let verticalPosition;
if (this.mappingExtensions) {
// Normally, notes go from 0 to 3 for lineIndex, and 0 to 2 for lineLayer.
// With custom grids, this could be -99 to 99 for both, in theory.
// But, because we want to support decimal values, we need to switch to the
// alternate format, where the values omit everything from -999 to 999.
//
// 0 -> 1000
// 1 -> 2000
// 2 -> 3000
// -1 -> -2000
horizontalPosition =
noteInfo._lineIndex < 0
? noteInfo._lineIndex / 1000 + 1
: noteInfo._lineIndex / 1000 - 1;
verticalPosition =
noteInfo._lineLayer < 0
? noteInfo._lineLayer / 1000 + 1
: noteInfo._lineLayer / 1000 - 1;
} else {
horizontalPosition = noteInfo._lineIndex;
verticalPosition = noteInfo._lineLayer;
}
if (horizontalPosition === undefined) horizontalPosition = 0 /* left */;
if (verticalPosition === undefined) verticalPosition = 1 /* middle */;

// Factor in sword offset and beat anticipation time (percentage).
const weaponOffset = this.data.gameMode === 'classic' ? SWORD_OFFSET : PUNCH_OFFSET;
Expand Down Expand Up @@ -336,7 +347,7 @@ AFRAME.registerComponent('beat-generator', {
if (data.has3DOFVR && data.gameMode !== 'viewer') { return; }

const durationSeconds = 60 * (wallInfo._duration / this.bpm);
const horizontalPosition = this.horizontalPositionsHumanized[wallInfo._lineIndex] || 'none';
const horizontalPosition = wallInfo._lineIndex;
const isCeiling = wallInfo._type === 1;
const length = durationSeconds * data.speed;
const width = wallInfo._width / 2; // We want half the reported width.
Expand Down
49 changes: 25 additions & 24 deletions src/components/beat.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,19 @@ AFRAME.registerComponent('beat-system', {
}
},

horizontalPositions: {},
horizontalPositions: {
value: function (noteSpace) {
return this.offset + this.scale * noteSpace;
},
get middle() { return this.value(1.5); }
},

verticalPositions: {},
verticalPositions: {
value: function (noteSpace) {
return this.offset + this.scale * noteSpace;
},
get middle() { return this.value(1); }
},

/**
* Update positioning between blocks, vertically and horizontally depending on
Expand Down Expand Up @@ -236,26 +246,17 @@ AFRAME.registerComponent('beat-system', {
// of extra margin.
// For punch mode, we want a wider horizontal spread in punch range, but not vertical.
const hMargin = gameMode === CLASSIC ? size : size * 1.2;
horizontalPositions.left = -1.5 * hMargin;
horizontalPositions.middleleft = -0.5 * hMargin;
horizontalPositions.middle = hMargin;
horizontalPositions.middleright = 0.5 * hMargin;
horizontalPositions.right = 1.5 * hMargin;
horizontalPositions.scale = hMargin;
horizontalPositions.offset = -1.5 * hMargin;

// Vertical margin based on size of blocks so they don't overlap.
// And then overall shifted up and down based on user height (camera Y).
// But not too low to go underneath the ground.
const bottomHeight = BOTTOM_HEIGHTS[gameMode];
const vMargin = size;
verticalPositions.bottom = Math.max(
BOTTOM_HEIGHT_MIN,
bottomHeight + heightOffset);
verticalPositions.middle = Math.max(
BOTTOM_HEIGHT_MIN + vMargin,
bottomHeight + vMargin + heightOffset);
verticalPositions.top = Math.max(
BOTTOM_HEIGHT_MIN + vMargin * 2,
bottomHeight + (vMargin * 2) + heightOffset);
const vOffset = Math.max(BOTTOM_HEIGHT_MIN, bottomHeight + heightOffset);
verticalPositions.scale = vMargin;
verticalPositions.offset = vOffset;
};
})(),

Expand Down Expand Up @@ -394,7 +395,7 @@ AFRAME.registerComponent('beat', {
const supercurve = this.curveEl.components.supercurve;
supercurve.getPointAt(songPosition, el.object3D.position);
supercurve.alignToCurve(songPosition, el.object3D);
el.object3D.position.x += this.beatSystem.horizontalPositions[horizontalPosition];
el.object3D.position.x += this.beatSystem.horizontalPositions.value(horizontalPosition);

if (data.type !== DOT) {
el.object3D.rotation.z = THREE.Math.degToRad(ROTATIONS[cutDirection]);
Expand All @@ -409,7 +410,7 @@ AFRAME.registerComponent('beat', {
const offset = 0.5;
el.object3D.position.y -= offset;
this.positionStart = el.object3D.position.y;
this.positionChange = this.verticalPositions[verticalPosition] + offset + heightOffset;
this.positionChange = this.verticalPositions.value(verticalPosition) + offset + heightOffset;
},

/**
Expand Down Expand Up @@ -635,7 +636,7 @@ AFRAME.registerComponent('beat', {
* Load OBJ from already parsed and loaded OBJ template.
*/
const geometries = {};
function setObjModelFromTemplate (el, templateId) {
function setObjModelFromTemplate(el, templateId) {
// Load into cache.
if (!geometries[templateId]) {
const templateEl = document.getElementById(templateId);
Expand All @@ -659,12 +660,12 @@ function setObjModelFromTemplate (el, templateId) {
}
}

function getElasticEasing (a, p) {
function getElasticEasing(a, p) {
return t => 1 - elastic(a, p)(1 - t);
}

function elastic (amplitude, period) {
function minMax (val, min, max) {
function elastic(amplitude, period) {
function minMax(val, min, max) {
return Math.min(Math.max(val, min), max);
}

Expand All @@ -679,10 +680,10 @@ function elastic (amplitude, period) {
};
}

function remap (value, low1, high1, low2, high2) {
function remap(value, low1, high1, low2, high2) {
return low2 + (high2 - low2) * (value - low1) / (high1 - low1);
}

function clamp (val, min, max) {
function clamp(val, min, max) {
return Math.min(Math.max(val, min), max);
}
4 changes: 1 addition & 3 deletions src/components/blade.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ AFRAME.registerComponent('blade', {
const bladeLocalPositions = [new THREE.Vector3(), new THREE.Vector3(),
new THREE.Vector3(), new THREE.Vector3()];
const bladeLocalTriangle = new THREE.Triangle();
const LEFT = 'left';
const RIGHT = 'right';

return function (beat) {
if (this.strokeSpeed < 1) { return false; }
Expand All @@ -107,7 +105,7 @@ AFRAME.registerComponent('blade', {
// Increase hitbox for high beats.
bbox.copy(beat.bbox);
bbox.expandByScalar(0.02);
if (beat.horizontalPosition === LEFT || beat.horizontalPosition === RIGHT) {
if (beat.horizontalPosition < 0.5 || beat.horizontalPosition > 2.5) {
bbox.expandByScalar(0.07);
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/debug-beat-positioning.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const horizontalPositions = ['left', 'middleleft', 'middleright', 'right'];
const verticalPositions = ['bottom', 'middle', 'top'];
const horizontalPositions = [0, 1, 2, 3];
const verticalPositions = [0, 1, 2];

/**
* Display all beat positions at once.
Expand Down
23 changes: 9 additions & 14 deletions src/components/plume.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
AFRAME.registerComponent('plume', {
schema: {
color: {default: ''},
cutDirection: {default: ''},
horizontalPosition: {default: 'middleleft', oneOf: ['left', 'middleleft', 'middleright', 'right']},
songPosition: {default: 0},
type: {default: 'arrow', oneOf: ['arrow', 'dot', 'mine']},
verticalPosition: {default: 'middle', oneOf: ['bottom', 'middle', 'top']}
color: { default: '' },
cutDirection: { default: '' },
songPosition: { default: 0 },
type: { default: 'arrow', oneOf: ['arrow', 'dot', 'mine'] },
},

horizontalPositions: {
left: -0.95,
middleleft: -0.6,
middleright: 0.6,
right: 0.95
getHorizontalPosition: noteSpace => {
const centered = noteSpace - 1.5;
return centered < 0 ? 0.35 * centered - 0.425 : 0.35 * centered + 0.425;
},

init: function () {
Expand All @@ -34,14 +30,13 @@ AFRAME.registerComponent('plume', {
},

onGenerate: function (songPosition, horizontalPosition, verticalPosition, heightOffset) {
const data = this.data;
const el = this.el;
// Set position.
const supercurve = this.curveEl.components.supercurve;
supercurve.getPointAt(songPosition, el.object3D.position);
supercurve.alignToCurve(songPosition, el.object3D);
el.object3D.position.x += this.horizontalPositions[horizontalPosition];
el.object3D.position.y += this.verticalPositions[verticalPosition] + heightOffset;
el.object3D.position.x += this.getHorizontalPosition(horizontalPosition);
el.object3D.position.y += this.verticalPositions.value(verticalPosition) + heightOffset;
el.object3D.rotation.z = Math.random() * Math.PI * 2;

this.songPosition = songPosition;
Expand Down
4 changes: 2 additions & 2 deletions src/components/wall.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ AFRAME.registerComponent('wall', {
// Offset vectors to get the left / right vertex points to pass into curve helper.
// Note that curve is upside down so the positions are reversed...normally, this would
// read as `+ (width / 2) - 0.25`.
const centerPosition = (-1 * beatSystem.horizontalPositions[horizontalPosition]) -
(width / 2) + 0.25;
const origPosition = beatSystem.horizontalPositions.value(horizontalPosition);
const centerPosition = (-1 * origPosition) - (width / 2) + 0.25;
left.x = centerPosition - (width / 2);
right.x = centerPosition + (width / 2);

Expand Down
4 changes: 4 additions & 0 deletions src/workers/zip.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ addEventListener('message', function (evt) {
const id = beatmapCharacteristicName + '-' + difficulty;
if (data.beats[id] === undefined) {
data.beats[id] = beatFiles[beatmapFilename];

data.beats[id].mappingExtensions =
Array.isArray(difficultyBeatmap._customData._requirements) &&
difficultyBeatmap._customData._requirements.includes('Mapping Extensions');
}
}
}
Expand Down