diff --git a/src/common/models/voxels.h b/src/common/models/voxels.h index 52299434a9f..fe583fd936f 100644 --- a/src/common/models/voxels.h +++ b/src/common/models/voxels.h @@ -73,6 +73,9 @@ struct FVoxelDef int VoxeldefIndex; // Needed by GZDoom double Scale; DAngle AngleOffset;// added to actor's angle to compensate for wrong-facing voxels + double xoffset; + double yoffset; + double zoffset; bool PitchFromMomentum; bool UseActorPitch; bool UseActorRoll; diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index c2268cef81a..f63a15ef6a2 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -616,6 +616,9 @@ void InitModels() smf.animationIDs[0] = -1; smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale; smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees(); + smf.xoffset = VoxelDefs[i]->xoffset; + smf.yoffset = VoxelDefs[i]->yoffset; + smf.zoffset = VoxelDefs[i]->zoffset; // this helps catching uninitialized data. assert(VoxelDefs[i]->PitchFromMomentum == true || VoxelDefs[i]->PitchFromMomentum == false); if (VoxelDefs[i]->PitchFromMomentum) smf.flags |= MDL_PITCHFROMMOMENTUM; diff --git a/src/r_data/voxeldef.cpp b/src/r_data/voxeldef.cpp index 35037158b9c..a2eee3c35f1 100644 --- a/src/r_data/voxeldef.cpp +++ b/src/r_data/voxeldef.cpp @@ -58,6 +58,9 @@ struct VoxelOptions int PlacedSpin = 0; double Scale = 1; DAngle AngleOffset = DAngle90; + double xoffset = 0.0; + double yoffset = 0.0; + double zoffset = 0.0; bool OverridePalette = false; bool PitchFromMomentum = false; bool UseActorPitch = false; @@ -177,6 +180,54 @@ static void VOX_ReadOptions(FScanner &sc, VoxelOptions &opts) } opts.AngleOffset = DAngle::fromDeg(mul * sc.Float + 90.); } + else if (sc.Compare("xoffset")) + { + int mul = 1; + sc.MustGetToken('='); + if (sc.CheckToken('-')) mul = -1; + sc.MustGetAnyToken(); + if (sc.TokenType == TK_IntConst) + { + sc.Float = sc.Number; + } + else + { + sc.TokenMustBe(TK_FloatConst); + } + opts.xoffset = sc.Float * mul; + } + else if (sc.Compare("yoffset")) + { + int mul = 1; + sc.MustGetToken('='); + if (sc.CheckToken('-')) mul = -1; + sc.MustGetAnyToken(); + if (sc.TokenType == TK_IntConst) + { + sc.Float = sc.Number; + } + else + { + sc.TokenMustBe(TK_FloatConst); + } + opts.yoffset = sc.Float * mul; + } + else if (sc.Compare("zoffset")) + { + int mul = 1; + sc.MustGetToken('='); + if (sc.CheckToken('-')) mul = -1; + sc.MustGetAnyToken(); + if (sc.TokenType == TK_IntConst) + { + sc.Float = sc.Number; + } + else + { + sc.TokenMustBe(TK_FloatConst); + } + opts.zoffset = sc.Float * mul; + } else if (sc.Compare("overridepalette")) { opts.OverridePalette = true; @@ -262,6 +313,9 @@ void R_InitVoxels() def->DroppedSpin = opts.DroppedSpin; def->PlacedSpin = opts.PlacedSpin; def->AngleOffset = opts.AngleOffset; + def->xoffset = opts.xoffset; + def->yoffset = opts.yoffset; + def->zoffset = opts.zoffset; def->PitchFromMomentum = opts.PitchFromMomentum; def->UseActorPitch = opts.UseActorPitch; def->UseActorRoll = opts.UseActorRoll; diff --git a/src/rendering/swrenderer/things/r_voxel.cpp b/src/rendering/swrenderer/things/r_voxel.cpp index 28d8921f071..a75b66e31bf 100644 --- a/src/rendering/swrenderer/things/r_voxel.cpp +++ b/src/rendering/swrenderer/things/r_voxel.cpp @@ -148,6 +148,9 @@ namespace swrenderer vis->depth = (float)tz; vis->gpos = { (float)pos.X, (float)pos.Y, (float)pos.Z }; + vis->gpos.X += (float)voxel->xoffset; + vis->gpos.Y += (float)voxel->yoffset; + vis->gpos.Z += (float)voxel->zoffset; vis->gzb = (float)gzb; // [RH] use gzb, not thing->z vis->gzt = (float)gzt; // killough 3/27/98 vis->deltax = float(pos.X - thread->Viewport->viewpoint.Pos.X);