Skip to content

Commit

Permalink
create density mystery screen random materials only once. AND support…
Browse files Browse the repository at this point in the history
… initial materialProperty value as custom, #275

Signed-off-by: Michael Kauzmann <[email protected]>
  • Loading branch information
zepumph committed Jul 19, 2024
1 parent 9b381d1 commit a3016dc
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 142 deletions.
31 changes: 18 additions & 13 deletions js/buoyancy/model/applications/Bottle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,22 +196,23 @@ export default class Bottle extends ApplicationsMass {

const vertices = Bottle.getFlatIntersectionVertices();

// The overall composite material for the bottle + inside material system.
// This is not used for colorizing, since the bottle + liquid composite system is rendered separately, it just
// needs to be a superset of all possible values across the different inside materials
const customMaterial = new CustomSolidMaterial( providedOptions.tandem.createTandem( 'customMaterial' ), {
nameProperty: DensityBuoyancyCommonStrings.systemAStringProperty,
density: ( BOTTLE_MASS + BOTTLE_INITIAL_INTERIOR_MATERIAL.density * BOTTLE_INITIAL_INTERIOR_VOLUME ) / BOTTLE_VOLUME,
densityRange: new Range( 0, 1000000000 )
} );

const options = optionize<BottleOptions, EmptySelfOptions, InstrumentedMassOptions>()( {
body: engine.createFromVertices( vertices, true ),
shape: Shape.polygon( vertices ),
volume: BOTTLE_VOLUME,
material: customMaterial,
material: 'CUSTOM',
materialPropertyOptions: {
validValues: [ customMaterial ]
phetioReadOnly: true
},

// The overall composite material for the bottle + inside material system.
// This is not used for colorizing, since the bottle + liquid composite system is rendered separately, it just
// needs to be a superset of all possible values across the different inside materials
customMaterialOptions: {
nameProperty: DensityBuoyancyCommonStrings.systemAStringProperty,
density: ( BOTTLE_MASS + BOTTLE_INITIAL_INTERIOR_MATERIAL.density * BOTTLE_INITIAL_INTERIOR_VOLUME ) / BOTTLE_VOLUME,
densityRange: new Range( 0, 1000000000 )
},
massShape: MassShape.BLOCK,

Expand All @@ -225,13 +226,17 @@ export default class Bottle extends ApplicationsMass {

const materialInsideTandem = options.tandem.createTandem( 'materialInside' );

this.materialInsideProperty = new MaterialProperty( BOTTLE_INITIAL_INTERIOR_MATERIAL, tandem => new CustomSolidMaterial( tandem, {
const materialInsidePropertyTandem = materialInsideTandem.createTandem( 'materialProperty' );

const customInsideMaterial = new CustomSolidMaterial( materialInsidePropertyTandem.createTandem( 'customMaterial' ), {
density: BOTTLE_INITIAL_INTERIOR_MATERIAL.density,
densityRange: new Range( 50, 20000 )
} ), {
} );

this.materialInsideProperty = new MaterialProperty( BOTTLE_INITIAL_INTERIOR_MATERIAL, customInsideMaterial, {
valueType: Material,
reentrant: true,
tandem: materialInsideTandem.createTandem( 'materialProperty' ),
tandem: materialInsidePropertyTandem,
phetioValueType: ReferenceIO( IOType.ObjectIO )
} );

Expand Down
2 changes: 1 addition & 1 deletion js/buoyancy/model/shapes/BuoyancyShapesModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default class BuoyancyShapesModel extends DensityBuoyancyModel {
this.materialProperty = new MaterialProperty( Material.WOOD,

// This hack is a way of saying, we do not create or support a custom material in this case.
() => Material.WOOD, {
Material.WOOD, {
tandem: objectsTandem.createTandem( 'materialProperty' ),
phetioValueType: ReferenceIO( IOType.ObjectIO )
} );
Expand Down
14 changes: 11 additions & 3 deletions js/common/model/Cube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default class Cube extends Cuboid {
/**
* Creates a Cube with a defined volume
*/
public static createWithVolume( engine: PhysicsEngine, material: Material, position: Vector2, volume: number, options?: StrictOmit<CubeOptions, 'matrix' | 'material'> ): Cube {
public static createWithVolume( engine: PhysicsEngine, material: Material | 'CUSTOM', position: Vector2, volume: number, options?: StrictOmit<CubeOptions, 'matrix' | 'material'> ): Cube {
return new Cube( engine, volume, combineOptions<CubeOptions>( {
matrix: Matrix3.translation( position.x, position.y ),
minVolume: Cuboid.MIN_VOLUME,
Expand All @@ -89,8 +89,16 @@ export default class Cube extends Cuboid {
/**
* Creates a Cube with a defined volume
*/
public static createWithMass( engine: PhysicsEngine, material: Material, position: Vector2, mass: number, options?: StrictOmit<CubeOptions, 'matrix' | 'material'> ): Cube {
return Cube.createWithVolume( engine, material, position, mass / material.density, options );
public static createWithMass( engine: PhysicsEngine, material: Material | 'CUSTOM', position: Vector2, mass: number, options?: StrictOmit<CubeOptions, 'matrix' | 'material'> ): Cube {
let density: number;
if ( material === 'CUSTOM' ) {
assert && assert( options?.customMaterialOptions?.density, 'density needed to create with mass' );
density = options!.customMaterialOptions!.density!;
}
else {
density = material.density;
}
return Cube.createWithVolume( engine, material, position, mass / density, options );
}
}

Expand Down
41 changes: 22 additions & 19 deletions js/common/model/Mass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import BooleanProperty, { BooleanPropertyOptions } from '../../../../axon/js/Boo
import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import Emitter from '../../../../axon/js/Emitter.js';
import NumberProperty, { NumberPropertyOptions } from '../../../../axon/js/NumberProperty.js';
import Property, { PropertyOptions } from '../../../../axon/js/Property.js';
import Property from '../../../../axon/js/Property.js';
import Matrix3, { Matrix3StateObject } from '../../../../dot/js/Matrix3.js';
import Range from '../../../../dot/js/Range.js';
import Utils from '../../../../dot/js/Utils.js';
Expand All @@ -27,7 +27,7 @@ import BooleanIO from '../../../../tandem/js/types/BooleanIO.js';
import IOType from '../../../../tandem/js/types/IOType.js';
import densityBuoyancyCommon from '../../densityBuoyancyCommon.js';
import InterpolatedProperty from './InterpolatedProperty.js';
import Material, { CustomSolidMaterial } from './Material.js';
import Material, { CustomSolidMaterial, MaterialOptions } from './Material.js';
import PhysicsEngine, { PhysicsEngineBody } from './PhysicsEngine.js';
import Basin from './Basin.js';
import TReadOnlyProperty from '../../../../axon/js/TReadOnlyProperty.js';
Expand All @@ -41,7 +41,7 @@ import Bounds3 from '../../../../dot/js/Bounds3.js';
import BlendedVector2Property from './BlendedVector2Property.js';
import { GuardedNumberProperty, GuardedNumberPropertyOptions } from './GuardedNumberProperty.js';
import DensityBuoyancyCommonConstants from '../DensityBuoyancyCommonConstants.js';
import MaterialProperty from './MaterialProperty.js';
import MaterialProperty, { MaterialPropertyOptions } from './MaterialProperty.js';
import ReferenceIO from '../../../../tandem/js/types/ReferenceIO.js';

// For the Buoyancy Shapes screen, but needed here because setRatios is included in each core type
Expand All @@ -54,7 +54,9 @@ type SelfOptions = {
// Required
body: PhysicsEngineBody;
shape: Shape;
material: Material;

// Use "CUSTOM" to tell the MaterialProperty to take the initial value from the internal customMaterial it creates.
material: Material | 'CUSTOM';
volume: number;
massShape: MassShape;

Expand All @@ -73,7 +75,8 @@ type SelfOptions = {
tag?: MassTag;
accessibleName?: PDOMValueType | null;
inputEnabledPropertyOptions?: BooleanPropertyOptions;
materialPropertyOptions?: PropertyOptions<Material>;
materialPropertyOptions?: Partial<MaterialPropertyOptions>;
customMaterialOptions?: MaterialOptions;
volumePropertyOptions?: NumberPropertyOptions;
massPropertyOptions?: NumberPropertyOptions;

Expand Down Expand Up @@ -199,7 +202,13 @@ export default abstract class Mass extends PhetioObject {
accessibleName: null,
phetioType: Mass.MassIO,
inputEnabledPropertyOptions: {},
materialPropertyOptions: {},
materialPropertyOptions: {
valueType: Material,
reentrant: true,
phetioValueType: ReferenceIO( IOType.ObjectIO ),
phetioFeatured: true
},
customMaterialOptions: {},
volumePropertyOptions: {},
massPropertyOptions: {},
minVolume: 0,
Expand All @@ -212,7 +221,7 @@ export default abstract class Mass extends PhetioObject {
super( options );

// TODO: Why did the question mark disappear? See https://github.com/phetsims/density-buoyancy-common/issues/243
const tandem: Tandem = options.tandem;
const tandem = options.tandem;

this.engine = engine;
this.body = options.body;
Expand Down Expand Up @@ -245,19 +254,13 @@ export default abstract class Mass extends PhetioObject {

this.visibleProperty = new GatedVisibleProperty( this.internalVisibleProperty, tandem );

this.materialProperty = new MaterialProperty( options.material, tandem => new CustomSolidMaterial( tandem, {
density: options.material.density,

// TODO: It is incorrect to take the range of the default value, this affects the color, see https://github.com/phetsims/density-buoyancy-common/issues/268
densityRange: options.material.densityProperty.range
} ), combineOptions<PropertyOptions<Material> & PickRequired<PhetioObjectOptions, 'tandem'>>( {
valueType: Material,
reentrant: true,
options.materialPropertyOptions.tandem = options.materialPropertyOptions.tandem || tandem.createTandem( 'materialProperty' );
const customSolidMaterial = new CustomSolidMaterial( options.materialPropertyOptions.tandem.createTandem( 'customMaterial' ), combineOptions<MaterialOptions>( {
density: options.material === 'CUSTOM' ? undefined : options.material.density
}, options.customMaterialOptions ) );

tandem: tandem?.createTandem( 'materialProperty' ),
phetioValueType: ReferenceIO( IOType.ObjectIO ),
phetioFeatured: true
}, options.materialPropertyOptions ) );
const initialMaterial = options.material === 'CUSTOM' ? customSolidMaterial : options.material;
this.materialProperty = new MaterialProperty( initialMaterial, customSolidMaterial, options.materialPropertyOptions as MaterialPropertyOptions );

this.volumeProperty = new NumberProperty( options.volume, combineOptions<NumberPropertyOptions>( {
tandem: tandem?.createTandem( 'volumeProperty' ),
Expand Down
7 changes: 3 additions & 4 deletions js/common/model/MaterialProperty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,19 @@ import Material from './Material.js';
import TReadOnlyProperty from '../../../../axon/js/TReadOnlyProperty.js';
import MappedWrappedProperty from './MappedWrappedProperty.js';
import { combineOptions, EmptySelfOptions } from '../../../../phet-core/js/optionize.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import PickRequired from '../../../../phet-core/js/types/PickRequired.js';
import { PhetioObjectOptions } from '../../../../tandem/js/PhetioObject.js';

type SelfOptions = EmptySelfOptions;

type MaterialPropertyOptions = SelfOptions & PropertyOptions<Material> & PickRequired<PhetioObjectOptions, 'tandem'>;
export type MaterialPropertyOptions = SelfOptions & PropertyOptions<Material> & PickRequired<PhetioObjectOptions, 'tandem'>;

export default class MaterialProperty extends MappedWrappedProperty<Material> {
public readonly densityProperty: TReadOnlyProperty<number>;
public readonly customMaterial: Material;

public constructor( material: Material, createCustomMaterial: ( tandem: Tandem ) => Material, providedOptions: MaterialPropertyOptions ) {
const customMaterial = createCustomMaterial( providedOptions.tandem.createTandem( 'customMaterial' ) );
// Note the material could be the customMaterial
public constructor( material: Material, customMaterial: Material, providedOptions: MaterialPropertyOptions ) {
super( material, customMaterial, combineOptions<MaterialPropertyOptions>( {
phetioFeatured: true
}, providedOptions ) );
Expand Down
10 changes: 7 additions & 3 deletions js/common/model/Pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,17 @@ export default class Pool extends Basin {
this.stepBottom = bounds.minY;
this.stepTop = bounds.maxY;

this.fluidMaterialProperty = new MaterialProperty( Material.WATER, tandem => new CustomLiquidMaterial( tandem, {
const fluidMaterialPropertyTandem = this.fluidTandem.createTandem( 'materialProperty' );

const customFluidMaterial = new CustomLiquidMaterial( fluidMaterialPropertyTandem.createTandem( 'customMaterial' ), {
density: Material.WATER.density,
densityRange: DensityBuoyancyCommonConstants.FLUID_DENSITY_RANGE_PER_M3
} ), {
} );

this.fluidMaterialProperty = new MaterialProperty( Material.WATER, customFluidMaterial, {
valueType: Material,
phetioValueType: ReferenceIO( IOType.ObjectIO ),
tandem: this.fluidTandem.createTandem( 'materialProperty' ),
tandem: fluidMaterialPropertyTandem,
phetioDocumentation: 'The material of the fluid in the pool'
} );

Expand Down
Loading

0 comments on commit a3016dc

Please sign in to comment.