├── src
├── logo.bmp
├── BerconNoise.rc
├── DLL
│ ├── BerconMaps_2021_64.dlt
│ ├── BerconMaps_2022_64.dlt
│ ├── BerconMaps_2023_64.dlt
│ ├── BerconMaps_2024_64.dlt
│ ├── BerconMaps_2025_64.dlt
│ └── BerconMaps_2026_64.dlt
├── BerconNoise.def
├── BerconNoise.vcxproj.DotSettings
├── BerconMap.h
├── worley.h
├── GradientMap.h
├── curvectrl.h
├── commonMath.cpp
├── BerconDlg.h
├── BerconRefMaker.h
├── IGradient.h
├── BerconMaps.sln
├── commonMath.h
├── NoiseAverages.h
├── perlin.h
├── noise.h
├── curvectrl.cpp
├── DllEntry.cpp
├── GradientRamp.h
├── fractal.h
├── BerconDistortion.h
├── tile.h
├── worley.cpp
├── BerconTile.h
├── IGradient.cpp
├── BerconNoise.vcxproj.filters
├── BerconWood.h
├── BerconNoise.h
├── BerconGradient.h
├── BerconSC.h
├── BerconDistortion.cpp
├── fractal.cpp
├── noise.cpp
├── BerconCommon.cpp
├── perlin.cpp
├── GradientRamp.cpp
└── tile.cpp
├── README.md
├── change notes.txt
├── .gitignore
└── LICENSE
/src/logo.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/logo.bmp
--------------------------------------------------------------------------------
/src/BerconNoise.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/BerconNoise.rc
--------------------------------------------------------------------------------
/src/DLL/BerconMaps_2021_64.dlt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/DLL/BerconMaps_2021_64.dlt
--------------------------------------------------------------------------------
/src/DLL/BerconMaps_2022_64.dlt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/DLL/BerconMaps_2022_64.dlt
--------------------------------------------------------------------------------
/src/DLL/BerconMaps_2023_64.dlt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/DLL/BerconMaps_2023_64.dlt
--------------------------------------------------------------------------------
/src/DLL/BerconMaps_2024_64.dlt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/DLL/BerconMaps_2024_64.dlt
--------------------------------------------------------------------------------
/src/DLL/BerconMaps_2025_64.dlt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/DLL/BerconMaps_2025_64.dlt
--------------------------------------------------------------------------------
/src/DLL/BerconMaps_2026_64.dlt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bercon/BerconMaps/HEAD/src/DLL/BerconMaps_2026_64.dlt
--------------------------------------------------------------------------------
/src/BerconNoise.def:
--------------------------------------------------------------------------------
1 | LIBRARY BerconNoise.dlt
2 | EXPORTS
3 | LibDescription @1 PRIVATE
4 | LibNumberClasses @2 PRIVATE
5 | LibClassDesc @3 PRIVATE
6 | LibVersion @4 PRIVATE
7 | LibInitialize @6 PRIVATE
8 | LibShutdown @7 PRIVATE
9 | SECTIONS
10 | .data READ WRITE
11 |
--------------------------------------------------------------------------------
/src/BerconNoise.vcxproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | Cpp17
--------------------------------------------------------------------------------
/src/BerconMap.h:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2008 Jerry Ylilammi
2 | // All rights reserved.
3 |
4 | /*
5 | Extra map interface that should be filled by all my maps that support extra features.
6 |
7 | Features:
8 | mapID Similar to mtlNum but aimed for maps not materials
9 |
10 | */
11 |
12 | #pragma once
13 |
14 | #include "BerconNoise.h"
15 |
16 | class BerconMap : public Texmap {
17 | public:
18 | virtual RGBA BerconEvalColor(ShadeContext& sc, int mapID) = 0;
19 | virtual float BerconEvalMono(ShadeContext& sc, int mapID) = 0;
20 | virtual Point3 BerconEvalNormalPerturb(ShadeContext& sc, int mapID) = 0;
21 | };
--------------------------------------------------------------------------------
/src/worley.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | // Based on Steven Worley's cellular noise
19 |
20 | class Worley {
21 | public:
22 | Worley() {}
23 | ~Worley() {}
24 |
25 | static void noise(double at[3], int order, double* F, int function);
26 |
27 | private:
28 | static void add(long xi, long yi, long zi, double at[3], int order, double *F, int function);
29 | };
--------------------------------------------------------------------------------
/src/GradientMap.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | /*
19 | Interface that has to be filled so gradient control can report users actions
20 | */
21 |
22 | #pragma once
23 |
24 | class GradientMap {
25 | public:
26 | virtual void gradAddKey(float pos) = 0;
27 | virtual void gradMoveKey(int n, float pos) = 0;
28 | virtual void gradDelKey(int n) = 0;
29 | virtual void gradSelKey() = 0;
30 | virtual void gradReset() = 0;
31 | };
--------------------------------------------------------------------------------
/src/curvectrl.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 |
19 | #include "Max.h"
20 | #include "resource.h"
21 | #include "istdplug.h"
22 | #include "icurvctl.h"
23 |
24 | // Handles basic operations on curve control
25 |
26 | class CurveCtrl {
27 | public:
28 | CurveCtrl() {}
29 | ~CurveCtrl() {}
30 |
31 | static void update(ICurveCtl *curve, HWND hParent, ReferenceMaker *resMaker);
32 | static void disable(ICurveCtl *curve);
33 | static void init(ICurveCtl *curve);
34 | };
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | BerconMaps
2 | ==========
3 |
4 | BerconMaps is a 3rd party texture plugin for Autodesk 3ds Max. It adds five new prodecural texture maps: Noise, Wood, Tile, Distortion and Gradient.
5 |
6 | For more information, pictures and binaries go to http://www.ylilammi.com/2013/09/berconmaps/
7 |
8 | Binaries
9 | -------------------------
10 | Binaries can be found under `src/DLL/` folder: https://github.com/Bercon/BerconMaps/tree/master/src/DLL
11 |
12 | License
13 | -------------------------
14 |
15 | Apache License, Version 2.0
16 |
17 | Read LICENSE file
18 |
19 | Contributing
20 | -------------------------
21 |
22 | - Fork
23 | - Improve
24 | - Submit a pull request
25 |
26 | Credits
27 | -------------------------
28 |
29 | - Jerry Ylilammi (author)
30 | - Vladimir Koylazov (bug fixes and support for 3ds Max 2015)
31 | - Ken Perlin (Perlin/Simplex noise)
32 | - Stefan Gustavson (C++ implementation of Perlin and Simplex noises)
33 | - Steven Worley (Worley noise and C implementation of it)
34 | - Blender team (Fractals)
35 | - John Burnett (Distortions max shadecontext implementation)
36 | - David Baker (Compiled Max 8 version of the plugin and edited source codes for Max 8)
37 | - Vladislav Gavrilov (Helped with integrating my custom gradient control into Max)
38 |
--------------------------------------------------------------------------------
/src/commonMath.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "commonMath.h"
19 |
20 | float smooth(float d) {
21 | return (d*d*(3.f-2.f*d));
22 | }
23 |
24 | float smooth(float d, float low, float high) {
25 | d = (d-low)/(high-low);
26 | if (d < 0) return 0.f;
27 | if (d > 1) return 1.f;
28 | return (d*d*(3.f-2.f*d));
29 | }
30 |
31 | float linear(float d, float low, float high) {
32 | d = (d-low)/(high-low);
33 | if (d < 0) return 0.f;
34 | if (d > 1) return 1.f;
35 | return d;
36 | }
37 |
38 | float lerp(float a, float b, float blend) {
39 | return b + blend * (a-b);
40 | }
--------------------------------------------------------------------------------
/src/BerconDlg.h:
--------------------------------------------------------------------------------
1 | #include "3dsmaxsdk_preinclude.h"
2 | #include "Max.h"
3 | #include "resource.h"
4 | #include "istdplug.h"
5 | #include "iparamb2.h"
6 | #include "iparamm2.h"
7 | #include "curvectrl.h"
8 |
9 | class BerconDlg: public ParamDlg {
10 | public:
11 | ParamDlg* pd;
12 | Class_ID id;
13 | int ref;
14 |
15 | BerconDlg(ParamDlg* pd, Class_ID id, int ref): pd (pd), id (id), ref (ref) {}
16 |
17 | Class_ID ClassID() { return pd->ClassID(); }
18 | void SetThing (ReferenceTarget *m) {
19 | ReferenceTarget* old = pd->GetThing();
20 | if (old->ClassID() == id && m->ClassID() == id && old != m) {
21 | ((ICurveCtl*)old->GetReference(ref))->SetActive(FALSE);
22 | ((ICurveCtl*)old->GetReference(ref))->EnableDraw(FALSE);
23 | }
24 | pd->SetThing(m);
25 | }
26 | ReferenceTarget * GetThing () { return pd->GetThing(); }
27 | void SetTime (TimeValue t) { pd->SetTime(t); }
28 | void ReloadDialog () { pd->ReloadDialog(); }
29 | void DeleteThis () { pd->DeleteThis(); delete this; }
30 | void ActivateDlg (BOOL onOff) { pd->ActivateDlg(onOff); }
31 | int FindSubTexFromHWND (HWND hwnd) { return pd->FindSubTexFromHWND(hwnd); }
32 | int FindSubMtlFromHWND (HWND hwnd) { return pd->FindSubMtlFromHWND(hwnd); }
33 | INT_PTR Execute (int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) { return pd->Execute(cmd, arg1, arg2, arg3); }
34 | };
--------------------------------------------------------------------------------
/src/BerconRefMaker.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "Max.h"
19 | #include "resource.h"
20 | #include "istdplug.h"
21 | #include "icurvctl.h"
22 |
23 | #ifndef NOTIFY_REF_CHANGED_ARGS
24 | #if MAX_RELEASE < 16900
25 | #define NOTIFY_REF_CHANGED_ARGS Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message
26 | #else
27 | #define NOTIFY_REF_CHANGED_ARGS const Interval &changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate
28 | #endif // MAX_RELEASE
29 | #endif // #ifndef NOTIFY_REF_CHANGED_ARGS
30 |
31 | class BerconRefMaker : public ReferenceMaker {
32 | public:
33 | BerconRefMaker(ResourceMakerCallback *m) {thing = m;}
34 | ResourceMakerCallback *thing;
35 | void DeleteThis() {delete this;}
36 | virtual void* GetInterface(ULONG id) {
37 | if(id == I_RESMAKER_INTERFACE)
38 | return (void *) thing;
39 | else
40 | return ReferenceMaker::GetInterface(id);
41 | }
42 | RefResult NotifyRefChanged(NOTIFY_REF_CHANGED_ARGS){return REF_DONTCARE;}
43 | };
--------------------------------------------------------------------------------
/src/IGradient.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "Max.h"
21 | #include "resource.h"
22 | #include "plugapi.h"
23 | //#include "3dsmaxport.h"
24 |
25 | #include "GradientRamp.h"
26 |
27 | class IGradient : public ICustomControl {
28 | private:
29 | HWND hWndMain;
30 | public:
31 | GradientRamp *gradient;
32 |
33 | IGradient(HWND hwRamp, GradientRamp *r) {
34 | hWndMain = hwRamp;
35 | gradient = r;
36 | DLSetWindowLongPtr(hWndMain, this);
37 | Execute(I_EXEC_CB_NO_BORDER);
38 | }
39 |
40 | ~IGradient() {
41 | DLSetWindowLongPtr(hWndMain, NULL);
42 | DestroyWindow(hWndMain);
43 | hWndMain = NULL;
44 | gradient = NULL;
45 | }
46 |
47 | void setGradient(GradientRamp *r) { gradient = r; }
48 |
49 | static LRESULT CALLBACK GradientProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // control window callback,
50 |
51 | //AColor getRampColor(float x) { return gradient->GetColor(x); }
52 |
53 | void Disable() {}
54 |
55 | void DeleteMe() {delete this;}
56 |
57 | int IsEnabled(){ return TRUE; }
58 |
59 | void Enable(int cmd) {}
60 |
61 | void Enable2(int cmd) {}
62 |
63 | HWND GetHwnd() { return hWndMain; }
64 |
65 | //void SetTooltip(bool bEnable, MCHAR* text) {}
66 | void SetTooltip(bool bEnable, const MCHAR* text) {}
67 |
68 | INT_PTR Execute(int cmd, ULONG_PTR arg1=0, ULONG_PTR arg2=0, ULONG_PTR arg3=0) { return 0; }
69 | };
70 |
--------------------------------------------------------------------------------
/src/BerconMaps.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.9.34723.18
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BerconMaps", "BerconNoise.vcxproj", "{E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Max2021|x64 = Max2021|x64
11 | Max2022|x64 = Max2022|x64
12 | Max2023|x64 = Max2023|x64
13 | Max2024_debug|x64 = Max2024_debug|x64
14 | Max2024|x64 = Max2024|x64
15 | Max2025|x64 = Max2025|x64
16 | Max2026|x64 = Max2026|x64
17 | EndGlobalSection
18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
19 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2021|x64.ActiveCfg = Max2021|x64
20 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2021|x64.Build.0 = Max2021|x64
21 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2022|x64.ActiveCfg = Max2022|x64
22 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2022|x64.Build.0 = Max2022|x64
23 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2023|x64.ActiveCfg = Max2023|x64
24 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2023|x64.Build.0 = Max2023|x64
25 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2024_debug|x64.ActiveCfg = Max2024_debug|x64
26 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2024_debug|x64.Build.0 = Max2024_debug|x64
27 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2024|x64.ActiveCfg = Max2024|x64
28 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2024|x64.Build.0 = Max2024|x64
29 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2025|x64.ActiveCfg = Max2025|x64
30 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2025|x64.Build.0 = Max2025|x64
31 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2026|x64.ActiveCfg = Max2026|x64
32 | {E7CB76AA-6113-46BA-8EBC-8AE1D2B81210}.Max2026|x64.Build.0 = Max2026|x64
33 | EndGlobalSection
34 | GlobalSection(SolutionProperties) = preSolution
35 | HideSolutionNode = FALSE
36 | EndGlobalSection
37 | GlobalSection(ExtensibilityGlobals) = postSolution
38 | SolutionGuid = {18F31B82-2705-494F-AAD9-4D1A23FB175F}
39 | EndGlobalSection
40 | EndGlobal
41 |
--------------------------------------------------------------------------------
/src/commonMath.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #pragma once
19 | //TODO: Use for v3.1
20 | #include "math.h"
21 |
22 | typedef float real;
23 | typedef double ireal;
24 |
25 | // Functions
26 |
27 | float smooth(float d);
28 |
29 | float smooth(float d, float low, float high);
30 |
31 | float linear(float d, float low, float high);
32 |
33 | float lerp(float a, float b, float blend);
34 |
35 | inline float avg(float a, float b) { return (a + b) / 2.f; }
36 | inline float avg(float a, float b, float c) { return (a + b + c) / 3.f; }
37 |
38 | inline float length(float a, float b) { return sqrtf(a*a + b*b); }
39 | inline float length(float a, float b, float c) { return sqrtf(a*a + b*b + c*c); }
40 |
41 | // Macros
42 |
43 | #define SMOOTH(d) (d*d*(3.f-2.f*d))
44 |
45 | #define MAX(a,b) (((a) > (b)) ? (a) : (b))
46 |
47 | #define MIN(a,b) (((a) > (b)) ? (b) : (a))
48 |
49 | #define FASTFLOOR(x) ((x) < 0 ? ((int)x-1) : ((int)x) )
50 |
51 | #define FASTFLOORI(x) ((x) < 0 ? ((int)x-1) : ((int)x) )
52 |
53 | #define FASTFLOORL(x) ((x) < 0 ? ((long)x-1) : ((long)x) )
54 |
55 | #define FADE(t) ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) )
56 |
57 | #define LERP(t, a, b) ((a) + (t)*((b)-(a)))
58 |
59 | #define ABS(x) ((x) < 0 ? (-x) : (x))
60 |
61 | //#define LERP(a, b, blend) (b + blend * (a-b))
62 |
63 | #define SFRAND() ((double)rand() / (double)RAND_MAX) // Random number (0..1)
64 |
65 | #define UFRAND() ((double)rand() / (double)RAND_MAX * 2. - 1.) // Random number (-1..1)
66 |
67 | #define SQRT2 1.41421356 // sqrt(2);
68 |
69 | #define DEG2RAD 0.0174532925f
--------------------------------------------------------------------------------
/src/NoiseAverages.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #define sfrand() ((double)rand() / (double)RAND_MAX)
19 | #define ufrand() ((double)rand() / (double)RAND_MAX * 2. - 1.)
20 |
21 | /*
22 | Used to compute average values for noise functions, these can be used in filtering
23 | Generally the average value should be 0.0
24 |
25 | Results for the code below are:
26 | Noise #0 = 0.000004
27 | Noise #1 = -0.000373
28 | Noise #2 = 0.000208
29 | Noise #3 = 0.000020
30 | Noise #4 = -0.000007
31 | Noise #5 = 0.000211
32 | Noise #6 = -0.000336
33 | Noise #7 = -0.000121
34 | Which means they all average out pretty near 0.0 so we can use it
35 | */
36 | class NoiseAverages {
37 | public:
38 | static void computeAverages() {
39 | CharStream *out = thread_local(current_stdout);
40 | srand(12345);
41 |
42 | int SAMPLES = 1000000; // Number of samples computed to get average
43 | float RANGE = 12345.0f; // The size of the area where samples are taken
44 |
45 | double noiseValue[8];
46 | for (int i=0;i<8;i++)
47 | noiseValue[i] = 0.;
48 |
49 | for (int i=0;iprintf("Noise #%d = %f\n", i, noiseValue[i] / (double)SAMPLES);
67 | }
68 | }
69 | };
70 |
--------------------------------------------------------------------------------
/change notes.txt:
--------------------------------------------------------------------------------
1 | v3.05 (tested with Max 2024 only)
2 | FIX: Berconmap types display their type (e.g., "BerconWood") instead of just a generic 'Texture' in Slate editor. An override was required on the localized name.
3 |
4 | FIX: xyz_tile only referencing IDS_XYZ_TILE_X [though in practice I don't think it matters]
5 |
6 | FIX: prevent setting tiling scale to zero in XYZ pblock
7 |
8 | FIX: Random by Material checkbox/XYZ pblock. Wrong parameter label for random by material checkbox, and so this function did not work.
9 |
10 | FIX: Prevent user from using Slate spinner to set tiling option to invalid value.
11 |
12 | FIX: Macros defining versions can't be used in place of values like 25900 without setting up a separate definitions file for them. Max 2021 does not know the version number of Max 2024. :)
13 |
14 | ADD comments for future maintainers
15 |
16 | CHANGE "BerconMapping" to "BerconDistortion"
17 |
18 | REFACTOR: berconcommon uvwgen switch cases. The "Filtering:" setting was never reached except in case 0 or 1. It is now active for all map coordinate systems.
19 |
20 | KNOWN ISSUE: Gradient keys will not sort. I suspect they are sorted, but the new sort is never actually sent to the dialog window handler. (Issue present in previous commit)
21 |
22 | KNOWN ISSUE: Gradient map will display "NO MAP" in a key slot even if there's a map assigned. It will only display if the dialog window is destroyed and refreshed by switching to another map/material and back. Conversely, if the gradient is 'reset' via the right-click option, the label will persist even though the map is no longer connected.
23 |
24 | OTHER: Tweaked dialog boxes for alignment and readability (words slightly cut off, more space for options to be readable, etc.)
25 |
26 | NOTE: In Slate editor, map channel is always preset to 0 (but correctly set to 1 in dialog box). This is a cosmetic issue, albeit an annoying one. I deem it to be an Autodesk issue.
27 |
28 | NOTE: The custom control curve slows things down in "Realistic Maps" mode, or when rendering. It takes only a few maps to bring the session down to a crawl on a Skylake-X chip with 24 threads, an RTX 4070, and 128GB of RAM.
29 |
30 | NOTE FOR USERS:
31 | Note for users, nitrous viewport only matches render if viewport is in Shaded Maps mode (not Realistic mode), Explicit Map Channel is set and object has no UVW map. Assigning a UVW map will enable both modes.
32 | If "variance" is used note that the same map applied to different objects will result in an incorrect preview. This is because the map is only evaluated once for the nitrous viewport; two or more objects sharing the same material with random variance are effectively multiple maps as far as 3DSMax is concerned. This is why you will only get one preview image in the material editor for any map.
33 |
--------------------------------------------------------------------------------
/src/perlin.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | // Based on Ken Perlin's perlin noise/simplex and Stefan Gustavson's
19 | // implementation of perlin/simplex noise, (Simplex)Noise1234
20 |
21 | #pragma once
22 |
23 | #include "commonMath.h"
24 |
25 | class Perlin {
26 | public:
27 | Perlin() {}
28 | ~Perlin() {}
29 |
30 | static float noise(float x);
31 | static float noise(float x, float y);
32 | static float noise(float x, float y, float z);
33 | static float noise(float x, float y, float z, float w);
34 |
35 | static float snoise(float x);
36 | static float snoise(float x, float y);
37 | static float snoise(float x, float y, float z);
38 | static float snoise(float x, float y, float z, float w);
39 |
40 | /* Filtered Noises, this means they'll fade to average value (0.0) when viewed from a distance
41 | to prevent noise caused by details smaller than pixel. Its worth pointing out that the 4D
42 | noise doesn't do filtering the fourth dimension, there is no point since you'll never render
43 | it as four dimensionsional pattern but choose some constant for the w paramater, basicly
44 | slicing the four dimensional noise into 3D space with using a plane. */
45 |
46 | static float fnoise2D(float x, float y, float d);
47 | static float fnoise3D(float x, float y, float z, float d);
48 | static float fnoise4D(float x, float y, float z, float w, float d);
49 |
50 | static float fsnoise2D(float x, float y, float d);
51 | static float fsnoise3D(float x, float y, float z, float d);
52 | static float fsnoise4D(float x, float y, float z, float w, float d);
53 |
54 | private:
55 | static float grad( int hash, float x);
56 | static float grad( int hash, float x, float y );
57 | static float grad( int hash, float x, float y , float z );
58 | static float grad( int hash, float x, float y, float z, float t );
59 |
60 | inline static float point(float x, int i);
61 | inline static float point(float x, float y, int i, int j);
62 | inline static float point(float x, float y, float z, int i, int j, int k);
63 | inline static float point(float x, float y, float z, float w, int i, int j, int k, int l);
64 | };
65 |
--------------------------------------------------------------------------------
/src/noise.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "Max.h"
21 |
22 | #include "texutil.h"
23 |
24 | #include "worley.h"
25 | #include "perlin.h"
26 |
27 | #include "commonMath.h"
28 |
29 | class NoiseParams {
30 | public:
31 | int noiseFunction;
32 | int fractalFunction;
33 | int worleyFunction;
34 |
35 | float phase;
36 | float spread;
37 | float F1, F2, F3, F4;
38 |
39 | float levels;
40 | float H;
41 | float lacunarity;
42 | float offset;
43 | float gain;
44 |
45 | float smoothWidth;
46 |
47 | float low, high;
48 | };
49 |
50 | class WoodParam { // Wood parameters
51 | public:
52 | int woodType;
53 | float randSeed;
54 | int samples;
55 |
56 | float lowTresh;
57 | float highTresh;
58 | float skew;
59 | float widthVar;
60 | float gainVar;
61 |
62 | float trunkStr;
63 | float trunkFreq;
64 |
65 | float radialStr;
66 | float radialFreq;
67 | float radialZ;
68 |
69 | float angleStr;
70 | float angleFreq;
71 | float angleRad;
72 | };
73 |
74 | class Noise {
75 | public:
76 | Noise() {}
77 | ~Noise() {}
78 |
79 | // The main noise function
80 | static float noise(Point3 p, NoiseParams& np);
81 | static float noise(Point3 p, float d, NoiseParams& np);
82 |
83 | // Wrapper for worley
84 | static float worleyWrapper(Point3 p, NoiseParams& np);
85 |
86 | // Wood function
87 | static float wood(Point3 p, Point3 &g, WoodParam& wp);
88 | static float wood(Point3 p, Point3 dPdx, Point3 dPdy, Point3 &g, WoodParam wp); // Filtered version
89 |
90 | // UVW
91 | static void alterUVW(Point3& p, int type);
92 |
93 | // Cell noise
94 | static float cellNoise(float x, float y, float z) {
95 | int xi = FASTFLOOR(x);
96 | int yi = FASTFLOOR(y);
97 | int zi = FASTFLOOR(z);
98 | unsigned int n = xi + yi*1301 + zi*314159;
99 | n ^= (n<<13);
100 | return ((float)(n*(n*n*15731 + 789221) + 1376312589) / 4294967296.0f);
101 | }
102 |
103 | static float limitedNoise(Point3 p, NoiseParams &np);
104 | static float limitedNoise(Point3 p, Point3 dpdx, Point3 dpdy, NoiseParams &np);
105 | };
106 |
107 |
--------------------------------------------------------------------------------
/src/curvectrl.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "curvectrl.h"
19 |
20 |
21 | void CurveCtrl::update(ICurveCtl *curve, HWND hParent, ReferenceMaker *resMaker) {
22 | curve->SetCustomParentWnd(hParent);
23 | // DebugPrint(_T("CCtrl UPDATED"));
24 | #if MAX_RELEASE >= 18900
25 | curve->RegisterResourceMaker(static_cast(resMaker));
26 | #else
27 | curve->RegisterResourceMaker(static_cast(resMaker));
28 | #endif
29 | BitArray ba = BitArray(1);
30 | ba.SetAll();
31 | curve->SetDisplayMode(ba);
32 | curve->EnableDraw(TRUE);
33 | curve->SetActive(TRUE);
34 | curve->SetZoomValues(256.f, 128.f);
35 | curve->SetScrollValues(-16, -45);
36 | curve->Redraw();
37 | }
38 | void CurveCtrl::disable(ICurveCtl *curve) {
39 | curve->SetActive(FALSE);
40 | curve->EnableDraw(FALSE);
41 | // DebugPrint(_T("CCtrl DISABLED"));
42 | }
43 |
44 | void CurveCtrl::init(ICurveCtl *curve) {
45 | curve->SetTitle(L"Function value curve");
46 | // DebugPrint(_T("Curve initialized!"));
47 |
48 | // UI
49 | DWORD flags = CC_NONE;
50 | flags |= CC_DRAWBG;
51 | flags |= CC_DRAWGRID;
52 | flags |= CC_DRAWUTOOLBAR;
53 | flags |= 0; //CC_DRAWLTOOLBAR;
54 | flags |= CC_SHOWRESET;
55 | // flags |= 0; //CC_DRAWSCROLLBARS;
56 | // flags |= 0; //CC_AUTOSCROLL;
57 | flags |= CC_DRAWRULER;
58 | // flags |= 0; //CC_ASPOPUP;
59 | flags |= CC_CONSTRAIN_Y;
60 | flags |= CC_HIDE_DISABLED_CURVES;
61 |
62 | // RC Menu
63 | flags |= CC_RCMENU_MOVE_XY;
64 | flags |= CC_RCMENU_MOVE_X;
65 | flags |= CC_RCMENU_MOVE_Y;
66 | flags |= CC_RCMENU_SCALE;
67 | flags |= CC_RCMENU_INSERT_CORNER;
68 | flags |= CC_RCMENU_INSERT_BEZIER;
69 | flags |= CC_RCMENU_DELETE;
70 |
71 | curve->SetCCFlags(flags);
72 |
73 | // Range
74 | curve->SetXRange(0.0f,1.0f);
75 | curve->SetYRange(0.0f,1.0f);
76 |
77 | // Setup curve
78 | curve->SetNumCurves(1, TRUE);
79 | // DebugPrint(_T("Curve SetNumCurves"));
80 | ICurve *pCurve = curve->GetControlCurve(0);
81 | pCurve->SetNumPts(2);
82 | pCurve->SetPenProperty( RGB(0,0,0));
83 | pCurve->SetDisabledPenProperty( RGB(128,128,128));
84 | //TODO: Implement user option for LUT for 3.1
85 | //pCurve->SetLookupTableSize(4096); // curve is x+y: a 2D xform. RGBA @ 16-bits per channel. Allow 64^2 bits = 4096 for max precision. (seems to work)
86 | TimeValue t = 0;
87 |
88 | // Point 0
89 | CurvePoint pt = pCurve->GetPoint(t,0);
90 | pt.p.y = 0.f;
91 | pCurve->SetPoint(t,0,&pt);
92 |
93 | // Point 1
94 | pt = pCurve->GetPoint(t,1);
95 | pt.p.y = 1.f;
96 | pCurve->SetPoint(t,1,&pt);
97 | }
--------------------------------------------------------------------------------
/src/DllEntry.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | //#define COMPILE_MULTIMAP 1
19 |
20 | #ifndef COMPILE_MULTIMAP
21 |
22 | #include "BerconWood.h"
23 |
24 | extern ClassDesc2* GetBerconNoiseDesc();
25 | extern ClassDesc2* GetBerconWoodDesc();
26 | extern ClassDesc2* GetBerconTileDesc();
27 | extern ClassDesc2* GetBerconDistortionDesc();
28 | extern ClassDesc2* GetBerconGradientDesc();
29 | extern void InitGradientControls();
30 |
31 | HINSTANCE hInstance;
32 | int controlsInit = FALSE;
33 |
34 | BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID /*lpvReserved*/) {
35 | if( fdwReason == DLL_PROCESS_ATTACH ) {
36 | hInstance = hinstDLL;
37 | DisableThreadLibraryCalls(hInstance);
38 | }
39 |
40 | if (!controlsInit) {
41 | controlsInit = TRUE;
42 | //InitCustomControls(hInstance); // Initialize MAX's custom controls
43 | InitCommonControls(); // Initialize Win95 controls [deprecated]
44 | InitGradientControls(); // Initialize my GradientRamp control
45 | }
46 | // DebugPrint(_T("Berconmaps is loaded!")); }
47 | return(TRUE);
48 | }
49 |
50 | __declspec( dllexport ) int LibNumberClasses() {
51 | return 5;
52 | }
53 |
54 | __declspec( dllexport ) ClassDesc* LibClassDesc(int i) {
55 | switch(i) {
56 | case 0: return GetBerconNoiseDesc();
57 | case 1: return GetBerconWoodDesc();
58 | case 2: return GetBerconTileDesc();
59 | case 3: return GetBerconDistortionDesc();
60 | case 4: return GetBerconGradientDesc();
61 | default: return 0;
62 | }
63 | }
64 |
65 | #else
66 |
67 | #include "MultiMap.h"
68 |
69 | extern ClassDesc2* GetMultiMapDesc();
70 | HINSTANCE hInstance;
71 | int controlsInit = FALSE;
72 | BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID /*lpvReserved*/) {
73 | if( fdwReason == DLL_PROCESS_ATTACH ) {
74 | hInstance = hinstDLL;
75 | DisableThreadLibraryCalls(hInstance);
76 | }
77 | return(TRUE);
78 | }
79 |
80 | __declspec( dllexport ) int LibNumberClasses() {
81 | return 1;
82 | }
83 |
84 | __declspec( dllexport ) ClassDesc* LibClassDesc(int i) {
85 | switch(i) {
86 | case 0: return GetMultiMapDesc();
87 | default: return 0;
88 | }
89 | }
90 |
91 | #endif
92 |
93 |
94 |
95 | __declspec( dllexport ) const TCHAR* LibDescription()
96 | {
97 | return GetString(IDS_LIBDESCRIPTION);
98 | }
99 |
100 | __declspec( dllexport ) ULONG LibVersion()
101 | {
102 | return VERSION_3DSMAX;
103 | }
104 |
105 | __declspec( dllexport ) int LibInitialize(void) {
106 | return TRUE;
107 | }
108 |
109 | __declspec( dllexport ) int LibShutdown(void) {
110 | return TRUE;
111 | }
112 |
113 |
--------------------------------------------------------------------------------
/src/GradientRamp.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | /*
19 | Gradient class
20 |
21 | Note that IGradient does NOT directly edit this class
22 | It reports UI actions to BerconGradient which then updates
23 | this to represent the changes done.
24 | */
25 |
26 | #pragma once
27 |
28 | #include "GradientMap.h"
29 | #include "BerconNoise.h"
30 |
31 | class GradientRamp {
32 | private:
33 | static const int PADDING = 6;
34 | static const int ARROWS = 6;
35 | static const COLORREF ARROWDESEL = RGB(0,0,0);
36 | static const COLORREF ARROWSEL = RGB(255,255,255);
37 |
38 | HWND m_hWnd;
39 | GradientMap* parent;
40 |
41 | int width;
42 | int height;
43 |
44 | // Key information, always sorted by postion. From left to right (0..1)
45 | Texmap** subtex;
46 | float* position;
47 | AColor* color;
48 | int* number;
49 |
50 | int keys;
51 |
52 | bool keyMoved;
53 |
54 | public:
55 | int selected; // Key number, not index
56 | int interpolation; // 0 linear 1 smooth 2 solid near 3 solid left 4 solid right
57 |
58 | GradientRamp(GradientMap* p) {
59 | m_hWnd = NULL;
60 | parent = p;
61 | selected = 0;
62 | interpolation = 0;
63 | keys = 0;
64 | subtex = NULL;
65 | position = NULL;
66 | color = NULL;
67 | number = NULL;
68 | reset();
69 | sort();
70 | }
71 |
72 | ~GradientRamp() {
73 | delete[] subtex;
74 | delete[] position;
75 | delete[] color;
76 | delete[] number;
77 | }
78 |
79 | void setHWND(HWND hWnd);
80 |
81 | // Paint
82 | void paint(HDC hDC);
83 | void paintArrow(int px, int py, bool up, HDC hDC, COLORREF colR);
84 | void invalidate();
85 |
86 | // Mouse methods
87 | int hit(int x, int y, bool broad = false);
88 | float toPos(int x);
89 |
90 | void leftDown(int x, int y, bool ctrl, bool shift, bool alt);
91 | void leftUp(int x, int y, bool ctrl, bool shift, bool alt);
92 | void dragging(int x, int y, bool ctrl, bool shift, bool alt);
93 |
94 | void popup(int x, int y, int sel);
95 |
96 | // Key methods
97 | int toIndex(int n);
98 | void selectKey(int n);
99 | //void moveKey(int n, float pos);
100 | void addKey(int n, float pos, AColor col, Texmap* sub = NULL);
101 | void reset();
102 | //sort before we swap
103 | void sort(); //TODO: Figure out why it refuses to sort
104 | void swap(int a, int b);
105 | Texmap* getSubtex(int n = -1);
106 | void setSubtex(int n, Texmap* sub);
107 | void setSubtex(Texmap* sub);
108 | int numKeys() { return keys; }
109 |
110 | // Shading methods
111 | int findHighKey(float x);
112 | float interpolate(float x, float low, float high);
113 | AColor getColor(float x); // Required for preview
114 | AColor getColor(float x, ShadeContext& sc); // ShadeContext required for maps
115 | Point3 getBump(float x, Point3 normal, ShadeContext& sc); // ShadeContext required for maps
116 | };
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Oo]bj/
18 |
19 | # MSTest test Results
20 | [Tt]est[Rr]esult*/
21 | [Bb]uild[Ll]og.*
22 |
23 | #NUNIT
24 | *.VisualState.xml
25 | TestResult.xml
26 |
27 | # Build Results of an ATL Project
28 | [Dd]ebugPS/
29 | [Rr]eleasePS/
30 | dlldata.c
31 |
32 | *_i.c
33 | *_p.c
34 | *_i.h
35 | *.ilk
36 | *.meta
37 | *.obj
38 | *.pch
39 | *.pdb
40 | *.pgc
41 | *.pgd
42 | *.rsp
43 | *.sbr
44 | *.tlb
45 | *.tli
46 | *.tlh
47 | *.tmp
48 | *.tmp_proj
49 | *.log
50 | *.vspscc
51 | *.vssscc
52 | .builds
53 | *.pidb
54 | *.svclog
55 | *.scc
56 |
57 | # Chutzpah Test files
58 | _Chutzpah*
59 |
60 | # Visual C++ cache files
61 | ipch/
62 | *.aps
63 | *.ncb
64 | *.opensdf
65 | *.sdf
66 | *.cachefile
67 |
68 | # Visual Studio profiler
69 | *.psess
70 | *.vsp
71 | *.vspx
72 |
73 | # TFS 2012 Local Workspace
74 | $tf/
75 |
76 | # Guidance Automation Toolkit
77 | *.gpState
78 |
79 | # ReSharper is a .NET coding add-in
80 | _ReSharper*/
81 | *.[Rr]e[Ss]harper
82 | *.DotSettings.user
83 |
84 | # JustCode is a .NET coding addin-in
85 | .JustCode
86 |
87 | # TeamCity is a build add-in
88 | _TeamCity*
89 |
90 | # DotCover is a Code Coverage Tool
91 | *.dotCover
92 |
93 | # NCrunch
94 | *.ncrunch*
95 | _NCrunch_*
96 | .*crunch*.local.xml
97 |
98 | # MightyMoose
99 | *.mm.*
100 | AutoTest.Net/
101 |
102 | # Web workbench (sass)
103 | .sass-cache/
104 |
105 | # Installshield output folder
106 | [Ee]xpress/
107 |
108 | # DocProject is a documentation generator add-in
109 | DocProject/buildhelp/
110 | DocProject/Help/*.HxT
111 | DocProject/Help/*.HxC
112 | DocProject/Help/*.hhc
113 | DocProject/Help/*.hhk
114 | DocProject/Help/*.hhp
115 | DocProject/Help/Html2
116 | DocProject/Help/html
117 |
118 | # Click-Once directory
119 | publish/
120 |
121 | # Publish Web Output
122 | *.[Pp]ublish.xml
123 | *.azurePubxml
124 |
125 | # NuGet Packages Directory
126 | packages/
127 | ## TODO: If the tool you use requires repositories.config uncomment the next line
128 | #!packages/repositories.config
129 |
130 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
131 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
132 | !packages/build/
133 |
134 | # Windows Azure Build Output
135 | csx/
136 | *.build.csdef
137 |
138 | # Windows Store app package directory
139 | AppPackages/
140 |
141 | # Others
142 | sql/
143 | *.Cache
144 | ClientBin/
145 | [Ss]tyle[Cc]op.*
146 | ~$*
147 | *~
148 | *.dbmdl
149 | *.dbproj.schemaview
150 | *.pfx
151 | *.publishsettings
152 | node_modules/
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | *.mdf
166 | *.ldf
167 |
168 | # Business Intelligence projects
169 | *.rdl.data
170 | *.bim.layout
171 | *.bim_*.settings
172 |
173 | # Microsoft Fakes
174 | FakesAssemblies/
175 | src/.vs/
176 | src/.vscode/
177 | .vscode/
178 | .vs/
179 | tempforcompare/
180 | *.asm
181 | *.cod
182 | *.sarif
183 | *.idb
184 | *.xml
185 | *.enc
186 | *.diagsession
187 | *.map
188 | src/Release_2024
189 | /src/ssecheck.cpp
190 | src/BerconDlg.h
191 | src/Release_2021/
192 | src/Release_2022/
193 | src/Release_2023/
194 | src/DLL/BerconMaps_2024_64_debug.dlt
195 |
196 |
--------------------------------------------------------------------------------
/src/fractal.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "noise.h"
19 |
20 | class Fractal {
21 | public:
22 | Fractal() {}
23 | ~Fractal() {}
24 |
25 | static float fractal(Point3 p, NoiseParams& np);
26 | static float turbulence(Point3 p, NoiseParams& np);
27 | static float fBm(Point3 p, NoiseParams& np);
28 | static float fBmTurb(Point3 p, NoiseParams& np);
29 | static float heteroTerrain(Point3 p, NoiseParams& np);
30 | static float hybridMultiFractal(Point3 p, NoiseParams& np);
31 | static float ridgedMultiFractal(Point3 p, NoiseParams& np);
32 |
33 | static float fractal(Point3 p, float d, NoiseParams& np);
34 | static float turbulence(Point3 p, float d, NoiseParams& np);
35 | static float fBm(Point3 p, float d, NoiseParams& np);
36 | static float fBmTurb(Point3 p, float d, NoiseParams& np);
37 | static float heteroTerrain(Point3 p, float d, NoiseParams& np);
38 | static float hybridMultiFractal(Point3 p, float d, NoiseParams& np);
39 | static float ridgedMultiFractal(Point3 p, float d, NoiseParams& np);
40 |
41 | static float marble(Point3 p, float d, NoiseParams& np);
42 |
43 | // Generic
44 | static float fBm(Point3 p, float levels, float lacunarity, float H);
45 | // Grain
46 | static float grain(Point3 p, float amount, float freq);
47 |
48 | static float f(Point3 p, NoiseParams &np) {
49 | switch (np.fractalFunction) {
50 | case 0: return (1.0f + Noise::noise(p, np)) * .5f;
51 | case 1: return fractal(p, np);
52 | case 2: return turbulence(p, np);
53 | case 3: return fBm(p, np);
54 | case 4: return fBmTurb(p, np);
55 | case 5: return heteroTerrain(p, np);
56 | case 6: return hybridMultiFractal(p, np);
57 | case 7: return ridgedMultiFractal(p, np);
58 | }
59 | return 0.f;
60 | }
61 |
62 | static float f(Point3 p, float d, NoiseParams &np) {
63 | switch (np.fractalFunction) {
64 | case 0: return (1.0f + Noise::noise(p, d, np)) * .5f;
65 | case 1: return fractal(p, d, np);
66 | case 2: return turbulence(p, d, np);
67 | case 3: return fBm(p, d, np);
68 | case 4: return fBmTurb(p, d, np);
69 | case 5: return heteroTerrain(p, np);
70 | case 6: return hybridMultiFractal(p, d, np);
71 | case 7: return ridgedMultiFractal(p, d, np);
72 | }
73 | return 0.f;
74 | }
75 | };
76 | /*
77 | float BerconNoise::noise(Point3 p, Point3 dp, NoiseParams &np) {
78 | float res;
79 | switch (noiseF.type) {
80 | case 0:
81 | res = (1.0f + noiseF.noise(p, dp, np)) * .5f;
82 | break;
83 | case 1:
84 | res = Fractal::fractal(noiseF, p, dp, np);
85 | break;
86 | case 2:
87 | res = Fractal::turbulence(noiseF, p, dp, np);
88 | break;
89 | case 3:
90 | res = Fractal::fBm(noiseF, p, dp, np);
91 | break;
92 | case 4:
93 | res = Fractal::heteroTerrain(noiseF, p, dp, np);
94 | break;
95 | case 5:
96 | res = Fractal::hybridMultiFractal(noiseF, p, dp, np);
97 | break;
98 | case 6:
99 | res = Fractal::ridgedMultiFractal(noiseF, p, dp, np);
100 | break;
101 | case 7:
102 | res = Fractal::fBmTurb(noiseF, p, dp, np);
103 | break;
104 | default: res = 1.0f;
105 | }
106 | return res;
107 | }
108 | };*/
--------------------------------------------------------------------------------
/src/BerconDistortion.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "BerconCommon.h"
21 |
22 | extern TCHAR *GetString(int id);
23 |
24 | extern HINSTANCE hInstance;
25 |
26 | #define DIST_NSUBTEX 3 // Number of subtextures
27 |
28 | class BerconDistortion;
29 |
30 | class BerconDistortion : public Texmap {
31 | public:
32 | // Distortion
33 | BOOL useDistortion;
34 | float distortionStr;
35 |
36 | Point3 getDistVector(ShadeContext& sc);
37 |
38 | // Parameter block
39 | IParamBlock2 *pblock; //ref 0
40 | Texmap *subtex[DIST_NSUBTEX]; //array of sub-materials
41 | Interval ivalid;
42 |
43 | IParamBlock2 *pbXYZ;
44 | BerconXYZ berconXYZ;
45 |
46 | // Interactive Display
47 | TexHandle *texHandle;
48 | Interval texHandleValid;
49 | void DiscardTexHandle() { if (texHandle) { texHandle->DeleteThis(); texHandle = NULL; } }
50 | BOOL SupportTexDisplay() { return TRUE; }
51 | void ActivateTexDisplay(BOOL onoff) { if (!onoff) DiscardTexHandle(); }
52 | DWORD_PTR GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
53 |
54 | //From MtlBase
55 | ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
56 | BOOL SetDlgThing(ParamDlg* dlg);
57 | void Update(TimeValue t, Interval& valid);
58 | void Reset();
59 | Interval Validity(TimeValue t);
60 | ULONG LocalRequirements(int subMtlNum) { return berconXYZ.req(); }
61 | void MappingsRequired(int subMtlNum, BitArray& mapreq, BitArray& bumpreq) { berconXYZ.map(subMtlNum, mapreq, bumpreq); }
62 |
63 | //TODO: Return the number of sub-textures
64 | int NumSubTexmaps() { return DIST_NSUBTEX; }
65 | //TODO: Return the pointer to the 'i-th' sub-texmap
66 | Texmap* GetSubTexmap(int i) { return subtex[i]; }
67 | void SetSubTexmap(int i, Texmap *m);
68 | TSTR GetSubTexmapSlotName(ARG_LOCALIZED(int i));
69 |
70 | //From Texmap
71 | RGBA EvalColor(ShadeContext& sc);
72 | float EvalMono(ShadeContext& sc);
73 | Point3 EvalNormalPerturb(ShadeContext& sc);
74 |
75 | //XYZGen *GetTheXYZGen() { return NULL; }
76 |
77 | //TODO: Return anim index to reference index
78 | int SubNumToRefNum(int subNum) { return subNum; }
79 |
80 | void ReadSXPData(TCHAR *name, void *sxpdata) { }
81 |
82 | //From Animatable
83 | Class_ID ClassID() {return BerconDistortion_CLASS_ID;}
84 | SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
85 | #if MAX_RELEASE < 23900
86 | void GetClassName(ARG_LOCALIZED(TSTR& s)) { s = GetString(IDS_BERCON_DIST); }
87 | #else
88 | void GetClassName(ARG_LOCALIZED(TSTR& s)) const override { s = GetString(IDS_BERCON_DIST); } //override for Slate editor
89 | #endif
90 |
91 | RefTargetHandle Clone( RemapDir &remap );
92 | RefResult NotifyRefChanged(NOTIFY_REF_CHANGED_ARGS);
93 |
94 | int NumSubs() { return 2+DIST_NSUBTEX; }
95 | Animatable* SubAnim(int i);
96 | TSTR SubAnimName(ARG_LOCALIZED(int i));
97 |
98 | // TODO: Maintain the number or references here
99 | int NumRefs() { return 5; }
100 | RefTargetHandle GetReference(int i);
101 | void SetReference(int i, RefTargetHandle rtarg);
102 |
103 | int NumParamBlocks() { return 2; } // return number of ParamBlocks in this instance
104 | IParamBlock2* GetParamBlock(int i) { return i ? pbXYZ : pblock; } // return i'th ParamBlock
105 | IParamBlock2* GetParamBlockByID(BlockID id) { return (pblock->ID() == id) ? pblock : pbXYZ; } // return id'd ParamBlock
106 |
107 | void DeleteThis() { delete this; }
108 |
109 | //Constructor/Destructor
110 | BerconDistortion();
111 | ~BerconDistortion();
112 | };
113 |
114 | class BerconDistortionClassDesc : public ClassDesc2 {
115 | public:
116 | BerconDistortionClassDesc() {}
117 | virtual ~BerconDistortionClassDesc() {}
118 | virtual int IsPublic() { return TRUE; }
119 | virtual void* Create(BOOL /*loading = FALSE*/) { return new BerconDistortion(); }
120 | virtual SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
121 | virtual Class_ID ClassID() { return BerconDistortion_CLASS_ID; }
122 | virtual const TCHAR* Category() { return TEXMAP_CAT_3D; }
123 |
124 | virtual const TCHAR* InternalName() { return _T("BerconDistortion"); } // returns fixed parsable name (scripter-visible name)
125 | virtual HINSTANCE HInstance() { return hInstance; } // returns owning module handle
126 | LOCALIZED_CLASS_NAME(IDS_BERCON_DIST)
127 | };
128 |
--------------------------------------------------------------------------------
/src/tile.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "noise.h"
19 | #include
20 | #include
21 | #include
22 |
23 | #pragma once
24 |
25 | /*
26 | x_offset, height, a, b, c, d... /
27 | x_offset, height, a, b, c, d... /
28 | x_offset, height, a, b, c, d... /
29 | x_offset, height, a, b, c, d... /
30 | ...
31 |
32 | Strecher Bond:
33 | 0, 1, 1 /
34 | 0.5, 1, 1
35 |
36 | Auto scaling
37 | scale to fit
38 | scale to fit no stretch
39 | scale to tile size
40 | no scale
41 |
42 | random offset xy
43 | random scale xy (lock)
44 | rotation (random amount -+) (0..180)
45 | random flip x axis, random flip y axis
46 |
47 | randomize z coordinate (for MultiTexture etc.)
48 |
49 | map tile center to channel X
50 |
51 |
52 |
53 | */
54 |
55 | class TileRow {
56 | public:
57 | TileRow(float offset) {this->offset = offset;}
58 |
59 | float offset;
60 | float totalWidth;
61 | std::vector tiles;
62 |
63 | void update() {
64 | totalWidth = 0.f;
65 | for (int i=0; i heights;
77 | std::vector rows;
78 |
79 | void setPattern(std::wstring s);
80 |
81 | void update() {
82 | totalHeight = 0.f;
83 | for (int i=0; i .5f) tileHeightVar = .5f;
136 | if (tileWidthVar > .5f) tileWidthVar = .5f;
137 | if (edgeHeightVar > 1.f) edgeHeightVar = 1.f;
138 | if (edgeWidthVar > 1.f) edgeWidthVar = 1.f;
139 |
140 | if (tilingType == 1) { // Herringbond can't have variation in these
141 | tileMaxHeight = tileWidth * .5f;
142 | tileMaxWidth = tileWidth;
143 | } else {
144 | tileMaxHeight = tileHeight * (1.f + tileHeightVar * 2.f);
145 | tileMaxWidth = tileWidth * (1.f + tileWidthVar * 2.f);
146 | }
147 |
148 | eW_var = edgeWidthVar > 0.0001f;
149 | eH_var = edgeHeightVar > 0.0001f;
150 |
151 | randScale = randSX > 0.0001f || randSY > 0.0001f;
152 | randOffset = randX > 0.0001f || randY > 0.0001f;
153 | }
154 | };
155 |
156 | class TilePoint { // TilePoint class is used to define point in tiling texture
157 | public:
158 |
159 | Point3 center; // Tile center
160 | Point3 uvw; // UVW
161 | float d; // Shade, -1 == edge, 0..1 = tile
162 | int id; // ID for MultiTexture
163 |
164 | TilePoint() {d = -1.f;}
165 | TilePoint(float y) {d = y;}
166 | TilePoint(Point3 x) {uvw = x;}
167 | TilePoint(Point3 x, float y) {uvw = x; d = y;}
168 | //TilePoint(Point3 x, float y, Color z) {p = x; d = y; c = z;}
169 | //TilePoint(Color z) {c = z; d = -3.f; }
170 | };
171 |
172 | class Tile {
173 | private:
174 | // Helpers
175 | static float edgeBlur(float d, float r, int type);
176 | static TilePoint corner(float rX, float rY, float w, float h, TileParam& t);
177 | static void rotatePoint2(Point3& d, float angle);
178 | static void rotateUV(int rotUV, float var, Point3& d);
179 |
180 | static void uvMapping(TilePoint& tp, Point3 p, float edges[4], TileParam& t, int dir=0);
181 | static TilePoint drawTile(Point3 p, float edges[4], TileParam& t, int id=0, int dir=0);
182 |
183 | // Patterns
184 | static TilePoint pat_xBond(Point3 p, TileParam& t);
185 | static TilePoint pat_herring(Point3 p, TileParam& t);
186 |
187 | public:
188 |
189 | static TilePoint draw(Point3 p, TileParam& t);
190 |
191 | };
192 |
193 |
--------------------------------------------------------------------------------
/src/worley.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | // Implementation of Steven Worley's cellular noise
19 |
20 | #include
21 | #include "worley.h"
22 |
23 | static char Poisson_count[256]= {
24 | 4,3,1,1,1,2,4,2,2,2,5,1,0,2,1,2,2,0,4,3,2,1,2,1,3,2,2,4,2,2,5,1,2,3,2,2,2,2,2,3,
25 | 2,4,2,5,3,2,2,2,5,3,3,5,2,1,3,3,4,4,2,3,0,4,2,2,2,1,3,2,2,2,3,3,3,1,2,0,2,1,1,2,
26 | 2,2,2,5,3,2,3,2,3,2,2,1,0,2,1,1,2,1,2,2,1,3,4,2,2,2,5,4,2,4,2,2,5,4,3,2,2,5,4,3,
27 | 3,3,5,2,2,2,2,2,3,1,1,4,2,1,3,3,4,3,2,4,3,3,3,4,5,1,4,2,4,3,1,2,3,5,3,2,1,3,1,3,
28 | 3,3,2,3,1,5,5,4,2,2,4,1,3,4,1,5,3,3,5,3,4,3,2,2,1,1,1,1,1,2,4,5,4,5,4,2,1,5,1,1,
29 | 2,3,3,3,2,5,2,3,3,2,0,2,1,1,4,2,1,3,2,1,2,2,3,2,5,5,3,4,5,5,2,4,4,5,3,2,2,2,1,4,
30 | 2,3,3,4,2,5,4,2,4,2,2,2,4,5,3,2};
31 |
32 | #define DENSITY_ADJUSTMENT 0.398150
33 | #define FASTFLOORL(x) ((x)<0 ? ((long)x-1) : ((long)x) )
34 | #define ADD(a,b,c) ( add(int_at[0]+a, int_at[1]+b, int_at[2]+c, new_at, order, F, function) )
35 |
36 | void Worley::noise(double at[3], int order, double *F, int function) {
37 | double x2, y2, z2, mx2, my2, mz2;
38 | double new_at[3];
39 | long int_at[3];
40 |
41 | for (int i=0; i>24];
105 | ROLL(seed);
106 |
107 | for (int j=0; jy)?x:y;
136 | d = ((z>t)?z:t);
137 | break; }
138 | case 4: // Minkovsky 0.5
139 | d = sqrt(fabs(d3[0])) + sqrt(fabs(d3[1])) + sqrt(fabs(d3[2]));
140 | d *= d;
141 | break;
142 | case 5: {// Minkovsky 4
143 | double x = d3[0]*d3[0];
144 | double y = d3[1]*d3[1];
145 | double z = d3[2]*d3[2];
146 | d = sqrt(sqrt(x*x + y*y + z*z));
147 | break; }
148 | }
149 |
150 | if (d < F[order-1]) {
151 | int index = order;
152 | while (index > 0 && d < F[index-1]) index--;
153 | for (int i=order-2; i>=index; i--)
154 | F[i+1] = F[i];
155 | F[index] = d;
156 | }
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/src/BerconTile.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "BerconCommon.h"
21 | #include "tile.h"
22 |
23 | extern TCHAR *GetString(int id);
24 |
25 | extern HINSTANCE hInstance;
26 |
27 | #define TILE_NSUBTEX 7 // Number of subtextures
28 |
29 | class BerconTile;
30 |
31 | class BerconTile : public Texmap, public ResourceMakerCallback {
32 | public:
33 | // Tiling parameters
34 | float tileSize;
35 |
36 | TileParam tileParam;
37 | int lockEdge, uvChan, uvChan2;
38 |
39 | TilePattern pattern;
40 |
41 | // Tiling
42 | bool mappedParameters;
43 | TileParam EvalParameters(ShadeContext& sc);
44 |
45 | // Distortion
46 | BOOL useDistortion;
47 | float distortionStr;
48 | Point3 getDistVector(ShadeContext& sc);
49 |
50 | // User Interface
51 | void EnableStuff(TimeValue t);
52 |
53 | // Parameter block
54 | IParamBlock2 *pblock; //ref 1
55 | IParamBlock2 *pbMap; //ref PBMAP_REF
56 | IParamBlock2 *pbXYZ; //ref COORDS
57 |
58 | BerconXYZ berconXYZ;
59 |
60 | Color col[3];
61 | Texmap *subtex[TILE_NSUBTEX]; //array of sub-materials
62 | BOOL mapOn[TILE_NSUBTEX];
63 | static ParamDlg* texoutDlg;
64 | TextureOutput *texout;
65 | Interval ivalid;
66 | //bool viewportPreview;
67 | // fixed compiler error 4596
68 | inline AColor getColor(ShadeContext &sc, int i) { return mapOn[i]&&subtex[i] ? subtex[i]->EvalColor(sc): col[i]; }
69 | inline float getFloat(ShadeContext &sc, int i) { return mapOn[i]&&subtex[i] ? subtex[i]->EvalMono(sc): Intens(col[i]); }
70 | inline Point3 getNormal(ShadeContext &sc, int i) { return mapOn[i]&&subtex[i] ? subtex[i]->EvalNormalPerturb(sc): Point3(0,0,0); }
71 |
72 | // Methods for interactive display
73 | TexHandle *texHandle;
74 | Interval texHandleValid;
75 | void DiscardTexHandle() { if (texHandle) { texHandle->DeleteThis(); texHandle = NULL; } }
76 | BOOL SupportTexDisplay() { return TRUE; }
77 | void ActivateTexDisplay(BOOL onoff) { if (!onoff) DiscardTexHandle(); }
78 | DWORD_PTR GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
79 |
80 | //From MtlBase
81 | ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
82 | BOOL SetDlgThing(ParamDlg* dlg);
83 | void Update(TimeValue t, Interval& valid);
84 | void Reset();
85 | Interval Validity(TimeValue t);
86 | ULONG LocalRequirements(int subMtlNum) { return berconXYZ.req(); }
87 | void MappingsRequired(int subMtlNum, BitArray& mapreq, BitArray& bumpreq) { berconXYZ.map(subMtlNum, mapreq, bumpreq); }
88 |
89 | int NumSubTexmaps() { return TILE_NSUBTEX; }
90 | Texmap* GetSubTexmap(int i) { return subtex[i]; }
91 | void SetSubTexmap(int i, Texmap *m);
92 | TSTR GetSubTexmapSlotName(ARG_LOCALIZED(int i));
93 |
94 | //From Texmap
95 | RGBA EvalColor(ShadeContext& sc);
96 | float EvalMono(ShadeContext& sc);
97 | Point3 EvalNormalPerturb(ShadeContext& sc);
98 |
99 | int SubNumToRefNum(int subNum) { return subNum; }
100 |
101 | void ReadSXPData(TCHAR *name, void *sxpdata) { }
102 |
103 | //From Animatable
104 | Class_ID ClassID() {return BerconTile_CLASS_ID;}
105 | SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
106 | #if MAX_RELEASE < 23900
107 | void GetClassName(ARG_LOCALIZED(TSTR& s)) {s = GetString(IDS_BERCON_TILE);} //override for Slate editor
108 | #else
109 | void GetClassName(ARG_LOCALIZED(TSTR& s)) const override { s = GetString(IDS_BERCON_TILE); } //override for Slate editor
110 | #endif
111 |
112 | RefTargetHandle Clone( RemapDir &remap );
113 | RefResult NotifyRefChanged(NOTIFY_REF_CHANGED_ARGS);
114 |
115 | int NumSubs() { return 11; }
116 | Animatable* SubAnim(int i);
117 | TSTR SubAnimName(ARG_LOCALIZED(int i));
118 |
119 | int NumRefs() { return 11; }
120 | RefTargetHandle GetReference(int i);
121 | void SetReference(int i, RefTargetHandle rtarg);
122 |
123 | int NumParamBlocks() { return 3; } // return number of ParamBlocks in this instance
124 | IParamBlock2* GetParamBlock(int i) { switch (i) { case 0: return pblock; case 1: return pbMap; case 2: return pbXYZ; } return NULL; }
125 | IParamBlock2* GetParamBlockByID(BlockID id) {
126 | if (pblock->ID() == id) return pblock;
127 | if (pbMap->ID() == id) return pbMap;
128 | if (pbXYZ->ID() == id) return pbXYZ;
129 | return NULL;
130 | }
131 | void DeleteThis() { delete this; }
132 |
133 | //Constructor/Destructor
134 | BerconTile();
135 | ~BerconTile();
136 |
137 | void* GetInterface(ULONG id) {
138 | if(id == I_RESMAKER_INTERFACE)
139 | return (void *) (ResourceMakerCallback*) this;
140 | else
141 | return Texmap::GetInterface(id);
142 | }
143 | };
144 |
145 | class BerconTileClassDesc : public ClassDesc2 {
146 | public:
147 | BerconTileClassDesc() {}
148 | virtual ~BerconTileClassDesc() {}
149 | virtual int IsPublic() { return TRUE; }
150 | virtual void* Create(BOOL /*loading = FALSE*/) { return new BerconTile(); }
151 | virtual SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
152 | virtual Class_ID ClassID() { return BerconTile_CLASS_ID; }
153 | virtual const TCHAR* Category() { return TEXMAP_CAT_3D; }
154 | virtual const TCHAR* InternalName() { return _T("BerconTile"); } // returns fixed parsable name (scripter-visible name)
155 | virtual HINSTANCE HInstance() { return hInstance; }
156 | LOCALIZED_CLASS_NAME(IDS_BERCON_TILE)
157 | };
158 |
--------------------------------------------------------------------------------
/src/IGradient.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "IGradient.h"
19 |
20 | /*
21 | mouse input
22 |
23 | * MK_LBUTTON - left
24 | * MK_MBUTTON - middle
25 | * MK_RBUTTON - right
26 | * MK_CONTROL - Ctrl pressed
27 | * MK_SHIFT - shift pressed
28 |
29 | To detect that the ALT key was pressed, check whether GetKeyState(VK_MENU) < 0. Note, this must not be GetAsyncKeyState.
30 |
31 | int mouse_x = (int)LOWORD(lparam);
32 | int mouse_y = (int)HIWORD(lparam);
33 | // get the button state
34 | int buttons = (int)wparam;
35 | sprintf(buffer,"Right Button = %d ",((buttons & MK_RBUTTON) ? 1 : 0));
36 |
37 | */
38 |
39 | LRESULT CALLBACK IGradient::GradientProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
40 | IGradient *grad = DLGetWindowLongPtr(hWnd);
41 | if(grad == NULL && msg != WM_CREATE)
42 | return DefWindowProc(hWnd, msg, wParam, lParam);
43 |
44 | switch(msg) {
45 | case WM_CREATE: {
46 | LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
47 | grad = (IGradient*)lpcs->lpCreateParams;
48 | DLSetWindowLongPtr(hWnd, grad);
49 | break;
50 | }
51 | /*
52 | case WM_KILLFOCUS:
53 | if (ctrl->m_bMouseOver) {
54 | ctrl->m_bMouseOver = false;
55 | ctrl->run_event_handler(n_mouseout, (short)LOWORD(lParam), (short)HIWORD(lParam), wParam, false);
56 | }
57 | break;
58 | */
59 | case WM_MOUSEMOVE: {
60 | int buttons = (int)wParam;
61 | if (buttons & MK_LBUTTON) {
62 | int mouse_x = (int)LOWORD(lParam);
63 | int mouse_y = (int)HIWORD(lParam);
64 | grad->gradient->dragging(mouse_x, mouse_y, buttons&MK_CONTROL, buttons&MK_SHIFT, GetKeyState(VK_MENU) < 0);
65 | //CharStream *out = thread_local(current_stdout);
66 | //out->printf("Dragging %d %d\n", mouse_x, mouse_y);
67 | }
68 | break;
69 | }
70 |
71 | case WM_LBUTTONDOWN: {
72 | CharStream *out = thread_local(current_stdout);
73 |
74 | int buttons = (int)wParam;
75 | int mouse_x = (int)LOWORD(lParam);
76 | int mouse_y = (int)HIWORD(lParam);
77 |
78 | grad->gradient->leftDown(mouse_x, mouse_y, buttons&MK_CONTROL, buttons&MK_SHIFT, GetKeyState(VK_MENU) < 0);
79 |
80 | /*
81 | if (buttons & MK_CONTROL) {
82 | out->printf("Left mouse DOWN + control\n");
83 | } else if (buttons & MK_SHIFT) {
84 | out->printf("Left mouse DOWN + shift\n");
85 | } else {
86 | out->printf("Left mouse DOWN %d %d\n", mouse_x, mouse_y);
87 | }*/
88 |
89 | break;
90 | }
91 |
92 | case WM_LBUTTONUP: {
93 | CharStream *out = thread_local(current_stdout);
94 |
95 | int buttons = (int)wParam;
96 | int mouse_x = (int)LOWORD(lParam);
97 | int mouse_y = (int)HIWORD(lParam);
98 | grad->gradient->leftUp(mouse_x, mouse_y, buttons&MK_CONTROL, buttons&MK_SHIFT, GetKeyState(VK_MENU) < 0);
99 |
100 | /*
101 | if (buttons & MK_CONTROL) {
102 | out->printf("Left mouse + control\n");
103 | } else if (buttons & MK_SHIFT) {
104 | out->printf("Left mouse + shift\n");
105 | } else {
106 | out->printf("Left mouse\n");
107 | } */
108 | break;
109 | }
110 |
111 | case WM_RBUTTONUP: {
112 | HMENU Popup;
113 | POINT pt;
114 | Popup = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_GRADIENTMENU));
115 | Popup = GetSubMenu(Popup, 0);
116 | GetCursorPos(&pt);
117 | int sel = TrackPopupMenuEx(Popup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, hWnd, NULL);
118 | if (sel > 0) {
119 | int mouse_x = (int)LOWORD(lParam);
120 | int mouse_y = (int)HIWORD(lParam);
121 | grad->gradient->popup(mouse_x, mouse_y, sel);
122 | }
123 | break;
124 | }
125 |
126 | case WM_MBUTTONUP: {
127 | /*
128 | CharStream *out = thread_local(current_stdout);
129 |
130 | int buttons = (int)wParam;
131 | if (buttons & MK_CONTROL) {
132 | out->printf("Middle mouse + control\n");
133 | } else if (buttons & MK_SHIFT) {
134 | out->printf("Middle mouse + shift\n");
135 | } else {
136 | out->printf("Middle mouse\n");
137 | } */
138 | break;
139 | }
140 |
141 | /*
142 | case WM_LBUTTONUP:
143 | return ctrl->ButtonUp((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, left);
144 |
145 | case WM_LBUTTONDBLCLK:
146 | return ctrl->ButtonDblClk((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, left);
147 |
148 | case WM_RBUTTONDOWN:
149 | return ctrl->ButtonDown((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, right);
150 |
151 | case WM_RBUTTONUP:
152 | return ctrl->ButtonUp((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, right);
153 |
154 | case WM_RBUTTONDBLCLK:
155 | return ctrl->ButtonDblClk((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, right);
156 |
157 | case WM_MBUTTONDOWN:
158 | return ctrl->ButtonDown((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, middle);
159 |
160 | case WM_MBUTTONUP:
161 | return ctrl->ButtonUp((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, middle);
162 |
163 | case WM_MBUTTONDBLCLK:
164 | return ctrl->ButtonDblClk((short)LOWORD(lParam), (short)HIWORD(lParam), wParam, middle);
165 |
166 | case WM_ERASEBKGND:
167 | return ctrl->EraseBkgnd((HDC)wParam);
168 |
169 | */
170 | case WM_PAINT: {
171 | //CharStream *out = thread_local(current_stdout);
172 | //out->printf("!!Paint!!\n");
173 | PAINTSTRUCT ps;
174 | BeginPaint(hWnd,&ps);
175 | grad->gradient->paint(ps.hdc);
176 | EndPaint(hWnd,&ps);
177 | return FALSE;
178 | }
179 | default:
180 | return DefWindowProc(hWnd, msg, wParam, lParam);
181 | }
182 | return FALSE;
183 | }
184 |
185 | void InitGradientControls() {
186 | WNDCLASSEX wc;
187 | wc.cbClsExtra = 0;
188 | wc.cbWndExtra = 0;
189 | wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
190 | wc.hCursor = LoadCursor(NULL, /*IDC_CROSS*/IDC_ARROW);
191 | wc.hIcon = NULL;
192 | wc.hIconSm = NULL;
193 | wc.hInstance = hInstance;
194 | wc.lpfnWndProc = IGradient::GradientProc; //DlgProc control
195 | wc.lpszClassName = L"CustGradient";
196 | wc.lpszMenuName = NULL;
197 | wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
198 | wc.cbSize = sizeof(wc);
199 | RegisterClassEx(&wc);
200 | }
201 |
--------------------------------------------------------------------------------
/src/BerconNoise.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {43067d0a-0e6f-4679-83b2-7a5b5fb21603}
6 | cpp;c;cxx;rc;def;r;odl;idl;hpj;bat
7 |
8 |
9 | {4971b58f-2900-4764-865b-561d35c7409a}
10 |
11 |
12 | {db93fbce-443f-45a7-8184-65c8eed4182a}
13 |
14 |
15 | {dc7a81ea-e5ca-446c-94da-34fe8824490b}
16 |
17 |
18 | {82fc4a5a-c3d4-45ac-803b-d459667eb4e6}
19 |
20 |
21 | {3a83a3f3-71e8-4f57-890e-0f46e6724ede}
22 |
23 |
24 | {d3a384ab-d0d5-4b7a-a8cc-7241b062b9dc}
25 | h;hpp;hxx;hm;inl
26 |
27 |
28 | {ee43c05d-259d-4f09-9ff5-1d262fcb0779}
29 |
30 |
31 | {f3d73eff-61be-4c8f-9e6c-c84e1660efcd}
32 |
33 |
34 | {bfe95d02-e91e-40a3-a0f3-4f4864626228}
35 |
36 |
37 | {1d9a5287-0d3c-4b7d-beca-15e9f20eb325}
38 |
39 |
40 | {53c9e9ad-0ae7-4739-bdf6-25a1e5401e51}
41 |
42 |
43 | {680604e9-378e-42b9-896f-596580a2bca7}
44 | ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe
45 |
46 |
47 |
48 |
49 | Source Files
50 |
51 |
52 | Resource Files
53 |
54 |
55 |
56 |
57 | Source Files\Main
58 |
59 |
60 | Source Files\Main
61 |
62 |
63 | Source Files\Main
64 |
65 |
66 | Source Files\Main
67 |
68 |
69 | Source Files\Main
70 |
71 |
72 | Source Files\Main
73 |
74 |
75 | Source Files\Gradient
76 |
77 |
78 | Source Files\Gradient
79 |
80 |
81 | Source Files\Curve
82 |
83 |
84 | Source Files\Patterns
85 |
86 |
87 | Source Files\Patterns
88 |
89 |
90 | Source Files\Patterns
91 |
92 |
93 | Source Files\Patterns
94 |
95 |
96 | Source Files\Patterns
97 |
98 |
99 | Source Files\Misc
100 |
101 |
102 | Source Files\Misc
103 |
104 |
105 |
106 |
107 | Header Files\Main
108 |
109 |
110 | Header Files\Main
111 |
112 |
113 | Header Files\Main
114 |
115 |
116 | Header Files\Main
117 |
118 |
119 | Header Files\Main
120 |
121 |
122 | Header Files\Main
123 |
124 |
125 | Header Files\Patterns
126 |
127 |
128 | Header Files\Patterns
129 |
130 |
131 | Header Files\Patterns
132 |
133 |
134 | Header Files\Patterns
135 |
136 |
137 | Header Files\Patterns
138 |
139 |
140 | Header Files\Gradient
141 |
142 |
143 | Header Files\Gradient
144 |
145 |
146 | Header Files\Gradient
147 |
148 |
149 | Header Files\Curve
150 |
151 |
152 | Header Files\Misc
153 |
154 |
155 | Header Files\Misc
156 |
157 |
158 | Header Files\Misc
159 |
160 |
161 | Header Files
162 |
163 |
164 |
165 |
166 | Resource Files
167 |
168 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/src/BerconWood.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "BerconCommon.h"
21 |
22 | extern TCHAR *GetString(int id);
23 |
24 | extern HINSTANCE hInstance;
25 |
26 | #define WOOD_NSUBTEX = 21
27 |
28 | class BerconWood : public Texmap, public ResourceMakerCallback {
29 | private:
30 | static const int NSUBTEX = 21;
31 | static const int NCOLS = 3;
32 | static const int NUMREF = 27;
33 |
34 | public:
35 | BOOL useCurve, useDistortion, lockGrain;
36 | float woodSize;
37 | float grainAmount, grainFreq;
38 |
39 | int woodType;
40 | float randSeed;
41 | int samples;
42 |
43 | float lowTresh;
44 | float highTresh;
45 | float skew;
46 | float widthVar;
47 | float gainVar;
48 |
49 | float trunkStr;
50 | float trunkFreq;
51 |
52 | float radialStr;
53 | float radialFreq;
54 | float radialZ;
55 |
56 | float angleStr;
57 | float angleFreq;
58 | float angleRad;
59 |
60 | // Distortion
61 | float distortionStr;
62 | void applyDistortion(ShadeContext& sc, Point3& p);
63 |
64 | // User Interface
65 | void EnableStuff();
66 |
67 | BerconXYZ berconXYZ;
68 |
69 | // Parameter block
70 | IParamBlock2 *pbXYZ; //ref 0
71 | IParamBlock2 *pblock; //ref 1
72 | IParamBlock2 *pbCurve; //ref CURVEPB_REF
73 | IParamBlock2 *pbMap; //ref PBMAP_REF
74 |
75 | Color col[NCOLS];
76 | Texmap *subtex[NSUBTEX]; //array of sub-materials
77 | BOOL mapOn[NSUBTEX];
78 |
79 | static ParamDlg* texoutDlg;
80 | TextureOutput *texout;
81 | Interval ivalid;
82 |
83 | bool mappedParameters;
84 | WoodParam EvalParameters(ShadeContext& sc);
85 |
86 | // Curve
87 | ICurveCtl* curve;
88 | // From ResourceMakerCallback
89 | BOOL SetCustomImageList(HIMAGELIST &hCTools,ICurveCtl *pCCtl) { return TRUE; };
90 | BOOL GetToolTip(int iButton, TSTR &ToolTip,ICurveCtl *pCCtl) { return TRUE; };
91 | void ResetCallback(int curvenum, ICurveCtl *pCCtl) { ICurve *pCurve = NULL; pCurve = pCCtl->GetControlCurve(curvenum); if(pCurve) { pCurve->SetNumPts(2); NewCurveCreatedCallback(curvenum, pCCtl); }}
92 | void NewCurveCreatedCallback(int curvenum, ICurveCtl *pCCtl) {
93 | ICurve *pCurve = NULL; pCurve = pCCtl->GetControlCurve(curvenum); TimeValue t = GetCOREInterface()->GetTime();
94 | CurvePoint pt = pCurve->GetPoint(t,0); pt.p.y = 0.f; pCurve->SetPoint(t,0,&pt);
95 | pCurve->SetPenProperty( RGB(0,0,0)); pCurve->SetDisabledPenProperty( RGB(128,128,128));
96 | pt = pCurve->GetPoint(t,1); pt.p.y = 1.f; pCurve->SetPoint(t,1,&pt);
97 | }
98 |
99 | // Interactive Display
100 | TexHandle *texHandle;
101 | Interval texHandleValid;
102 | void DiscardTexHandle() { if (texHandle) { texHandle->DeleteThis(); texHandle = NULL; } }
103 | BOOL SupportTexDisplay() { return TRUE; }
104 | void ActivateTexDisplay(BOOL onoff) { if (!onoff) DiscardTexHandle(); }
105 | DWORD_PTR GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
106 |
107 | //From MtlBase
108 | ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
109 | BOOL SetDlgThing(ParamDlg* dlg);
110 | void Update(TimeValue t, Interval& valid);
111 | void Reset();
112 | Interval Validity(TimeValue t);
113 | ULONG LocalRequirements(int subMtlNum) { return berconXYZ.req(); }
114 | void MappingsRequired(int subMtlNum, BitArray& mapreq, BitArray& bumpreq) { berconXYZ.map(subMtlNum, mapreq, bumpreq); }
115 |
116 | int NumSubTexmaps() { return NSUBTEX; }
117 | Texmap* GetSubTexmap(int i) { return subtex[i]; }
118 | void SetSubTexmap(int i, Texmap *m);
119 | TSTR GetSubTexmapSlotName(ARG_LOCALIZED(int i));
120 |
121 | //From Texmap
122 | RGBA EvalColor(ShadeContext& sc);
123 | float EvalMono(ShadeContext& sc);
124 | Point3 EvalNormalPerturb(ShadeContext& sc);
125 |
126 | int SubNumToRefNum(int subNum) { return subNum; }
127 |
128 | void ReadSXPData(TCHAR *name, void *sxpdata) { }
129 |
130 | //From Animatable
131 | Class_ID ClassID() {return BerconWood_CLASS_ID;}
132 | SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
133 | #if MAX_RELEASE < 23900
134 | void GetClassName(ARG_LOCALIZED(TSTR& s)) { s = GetString(IDS_BERCON_WOOD); }
135 | #else
136 | void GetClassName(ARG_LOCALIZED(TSTR& s)) const override { s = GetString(IDS_BERCON_WOOD); } //override for Slate editor
137 | #endif
138 |
139 | RefTargetHandle Clone( RemapDir &remap );
140 | RefResult NotifyRefChanged(NOTIFY_REF_CHANGED_ARGS);
141 |
142 | int NumSubs() { return NUMREF; }
143 | Animatable* SubAnim(int i);
144 | TSTR SubAnimName(ARG_LOCALIZED(int i));
145 |
146 | int NumRefs() { return NUMREF; }
147 | RefTargetHandle GetReference(int i);
148 | void SetReference(int i, RefTargetHandle rtarg);
149 |
150 | int NumParamBlocks() { return 4; }
151 | IParamBlock2* GetParamBlock(int i) { switch (i) { case 0: return pblock; case 1: return pbCurve; case 2: return pbMap; case 3: return pbXYZ; } return NULL; }
152 | IParamBlock2* GetParamBlockByID(BlockID id) {
153 | if (pblock->ID() == id) return pblock;
154 | if (pbCurve->ID() == id) return pbCurve;
155 | if (pbMap->ID() == id) return pbMap;
156 | if (pbXYZ->ID() == id) return pbXYZ;
157 | return NULL;
158 | }
159 |
160 | void DeleteThis() { delete this; }
161 |
162 | //Constructor/Destructor
163 | BerconWood();
164 | ~BerconWood();
165 |
166 | void* GetInterface(ULONG id) {
167 | if(id == I_RESMAKER_INTERFACE)
168 | return (void *) (ResourceMakerCallback*) this;
169 | else
170 | return Texmap::GetInterface(id);
171 | }
172 | };
173 |
174 | class BerconWoodClassDesc : public ClassDesc2 {
175 | public:
176 | virtual int IsPublic() { return TRUE; }
177 | virtual void* Create(BOOL /*loading = FALSE*/) { return new BerconWood(); }
178 | virtual SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
179 | virtual Class_ID ClassID() { return BerconWood_CLASS_ID; }
180 | virtual const TCHAR* Category() { return TEXMAP_CAT_3D; }
181 | virtual const TCHAR* InternalName() { return _T("BerconWood"); } // returns fixed parsable name (scripter-visible name)
182 | virtual HINSTANCE HInstance() { return hInstance; }
183 | LOCALIZED_CLASS_NAME(IDS_BERCON_WOOD)
184 | };
185 |
--------------------------------------------------------------------------------
/src/BerconNoise.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | /*
19 | This is the general include file, used by all maps.
20 | */
21 |
22 | #pragma once
23 |
24 | #include "BerconCommon.h"
25 |
26 | extern TCHAR *GetString(int id);
27 |
28 | extern HINSTANCE hInstance;
29 |
30 |
31 | #define NOISE_NSUBTEX 18 // Number of subtextures
32 |
33 | class BerconNoise;
34 |
35 | class BerconNoise : public Texmap, public ResourceMakerCallback/*, public imrShaderTranslation*/ {
36 | public:
37 | bool mappedParameters;
38 | NoiseParams EvalParameters(ShadeContext* sc);
39 |
40 | //void limitLevel(Point3 dp, NoiseParams &np, float nSize);
41 |
42 | //void calcAverage();
43 | //float average;
44 |
45 | // Noise variables
46 | float size;
47 | float phase;
48 | float spread;
49 | float F1, F2, F3, F4;
50 |
51 | int noiseFunction;
52 | int worleyFunction;
53 | int fractalFunction;
54 |
55 | // Fractal variables
56 | float levels;
57 | float low, high;
58 | float fractalH, fractalOffset, fractalGain, fractalLacunarity;
59 |
60 | // Distortion
61 | BOOL useDistortion;
62 | float distortionStr;
63 | void applyDistortion(ShadeContext& sc, Point3& p);
64 | int uvwDist;
65 |
66 | // User Interface
67 | void EnableStuff();
68 |
69 | // Parameter block
70 | IParamBlock2 *pbXYZ;
71 | IParamBlock2 *pblock; //ref 0
72 | IParamBlock2 *pbCurve; //ref CURVEPB_REF
73 | IParamBlock2 *pbMap; //ref PBMAP_REF
74 |
75 | BerconXYZ berconXYZ;
76 |
77 | Color col[2];
78 | Texmap *subtex[NOISE_NSUBTEX]; //array of sub-materials
79 | BOOL mapOn[NOISE_NSUBTEX];
80 | static ParamDlg* texoutDlg;
81 | TextureOutput *texout;
82 | Interval ivalid;
83 |
84 | // Curve
85 | ICurveCtl* curve;
86 | BOOL useCurve;
87 | // From ResourceMakerCallback
88 | BOOL SetCustomImageList(HIMAGELIST &hCTools,ICurveCtl *pCCtl) { return TRUE; };
89 | BOOL GetToolTip(int iButton, TSTR &ToolTip,ICurveCtl *pCCtl) { return TRUE; };
90 | void ResetCallback(int curvenum, ICurveCtl *pCCtl) { ICurve *pCurve = NULL; pCurve = pCCtl->GetControlCurve(curvenum); if(pCurve) { pCurve->SetNumPts(2); NewCurveCreatedCallback(curvenum, pCCtl); }}
91 | void NewCurveCreatedCallback(int curvenum, ICurveCtl *pCCtl) {
92 | ICurve *pCurve = NULL; pCurve = pCCtl->GetControlCurve(curvenum); TimeValue t = GetCOREInterface()->GetTime();
93 | CurvePoint pt = pCurve->GetPoint(t,0); pt.p.y = 0.f; pCurve->SetPoint(t,0,&pt);
94 | pCurve->SetPenProperty( RGB(0,0,0)); pCurve->SetDisabledPenProperty( RGB(128,128,128));
95 | pt = pCurve->GetPoint(t,1); pt.p.y = 1.f; pCurve->SetPoint(t,1,&pt);
96 | }
97 |
98 | // Interactive Display
99 | TexHandle *texHandle;
100 | Interval texHandleValid;
101 | void DiscardTexHandle() { if (texHandle) { texHandle->DeleteThis(); texHandle = NULL; } }
102 | BOOL SupportTexDisplay() { return TRUE; }
103 | void ActivateTexDisplay(BOOL onoff) { if (!onoff) DiscardTexHandle(); }
104 | DWORD_PTR GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
105 |
106 | //From MtlBase
107 | ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
108 | BOOL SetDlgThing(ParamDlg* dlg);
109 | void Update(TimeValue t, Interval& valid);
110 | void Reset();
111 | Interval Validity(TimeValue t);
112 | ULONG LocalRequirements(int subMtlNum) { return berconXYZ.req(); }
113 | void MappingsRequired(int subMtlNum, BitArray& mapreq, BitArray& bumpreq) { berconXYZ.map(subMtlNum, mapreq, bumpreq); }
114 |
115 |
116 | int NumSubTexmaps() { return NOISE_NSUBTEX; }
117 | Texmap* GetSubTexmap(int i) { return subtex[i]; }
118 | void SetSubTexmap(int i, Texmap *m);
119 | TSTR GetSubTexmapSlotName(ARG_LOCALIZED(int i));
120 |
121 | //From Texmap
122 | RGBA EvalColor(ShadeContext& sc);
123 | float EvalMono(ShadeContext& sc);
124 | Point3 EvalNormalPerturb(ShadeContext& sc);
125 |
126 | XYZGen *GetTheXYZGen() { return NULL; }
127 |
128 | int SubNumToRefNum(int subNum) { return subNum; }
129 |
130 | void ReadSXPData(TCHAR *name, void *sxpdata) { }
131 |
132 | //From Animatable
133 | Class_ID ClassID() {return BerconNoise_CLASS_ID;}
134 | SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
135 | #if MAX_RELEASE < 23900
136 | void GetClassName(ARG_LOCALIZED(TSTR& s)) { s = GetString(IDS_CLASS_NAME); } //override for Slate editor
137 | #else
138 | void GetClassName(ARG_LOCALIZED(TSTR& s)) const override { s = GetString(IDS_CLASS_NAME); } //override for Slate editor
139 | #endif
140 |
141 | RefTargetHandle Clone( RemapDir &remap );
142 | RefResult NotifyRefChanged(NOTIFY_REF_CHANGED_ARGS);
143 |
144 | int NumSubs() { return 24; }
145 | Animatable* SubAnim(int i);
146 | TSTR SubAnimName(ARG_LOCALIZED(int i));
147 |
148 | // TODO: Maintain the number or references here
149 | int NumRefs() { return 24; }
150 | RefTargetHandle GetReference(int i);
151 | void SetReference(int i, RefTargetHandle rtarg);
152 |
153 | int NumParamBlocks() { return 4; }
154 | IParamBlock2* GetParamBlock(int i) { switch (i) { case 0: return pblock; case 1: return pbCurve; case 2: return pbMap; case 3: return pbXYZ; } return NULL; }
155 | IParamBlock2* GetParamBlockByID(BlockID id) {
156 | if (pblock->ID() == id) return pblock;
157 | if (pbCurve->ID() == id) return pbCurve;
158 | if (pbMap->ID() == id) return pbMap;
159 | if (pbXYZ->ID() == id) return pbXYZ;
160 | return NULL;
161 | }
162 |
163 | void DeleteThis() { delete this; }
164 |
165 | //Constructor/Destructor
166 | BerconNoise();
167 | ~BerconNoise();
168 |
169 | void* GetInterface(ULONG id) {
170 | if(id == I_RESMAKER_INTERFACE)
171 | return (void *) (ResourceMakerCallback*) this;
172 | else
173 | return Texmap::GetInterface(id);
174 | }
175 | };
176 |
177 | class BerconNoiseClassDesc : public ClassDesc2 {
178 | public:
179 | virtual int IsPublic() { return TRUE; }
180 | virtual void* Create(BOOL) { return new BerconNoise(); }
181 | virtual SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
182 | virtual Class_ID ClassID() { return BerconNoise_CLASS_ID; }
183 | virtual const TCHAR* Category() { return TEXMAP_CAT_3D; }
184 | virtual const TCHAR* InternalName() { return _T("BerconNoise"); } // returns fixed parsable name (scripter-visible name)
185 | virtual HINSTANCE HInstance() { return hInstance; }
186 | LOCALIZED_CLASS_NAME(IDS_CLASS_NAME)
187 | };
188 |
--------------------------------------------------------------------------------
/src/BerconGradient.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "BerconCommon.h"
21 | #include "windows.h"
22 | #include "IGradient.h"
23 | #include "chkmtlapi.h"
24 |
25 | extern TCHAR *GetString(int id);
26 |
27 | extern HINSTANCE hInstance;
28 |
29 | //#define GRADIENT3D
30 |
31 | class BerconGradient : public Texmap, public GradientMap, public ResourceMakerCallback {
32 | public:
33 | // Parameter block
34 | IParamBlock2 *pblock;
35 | IParamBlock2 *pbCurve; //ref CURVEPB_REF
36 | IParamBlock2 *pbXYZ; //ref COORDS
37 |
38 | BerconXYZ berconXYZ;
39 | static ParamDlg* texoutDlg;
40 | TextureOutput *texout;
41 |
42 | Interval ivalid;
43 |
44 | // Values
45 | GradientRamp* gradient;
46 | IGradient* gradientUI;
47 | int dirty;
48 |
49 | int p_seed;
50 | int p_type;
51 | int p_randObj; int p_randMat; int p_randPar; int p_randTile;
52 | float p_rangeMin; float p_rangeMax;
53 | int p_rangeLoop;
54 | int p_uvwType;
55 | int p_reverse;
56 | int p_normalType;
57 | int p_normalFunction;
58 | float p_ior;
59 | int p_disOn;
60 | float p_disStr;
61 |
62 | // Helpers
63 | void seedRandomGen(ShadeContext& sc);
64 | int limitRange(float& d);
65 | void EnableStuff();
66 |
67 | // Shading
68 | float getGradientValueUVW(Point3 p);
69 | float getGradientValueDist(ShadeContext& sc);
70 | float getGradientValueNormal(ShadeContext& sc);
71 | float getGradientValue(ShadeContext& sc);
72 |
73 | // UI
74 | int previewMatIDMode;
75 |
76 | // Submaps
77 | Texmap* p_maptex;
78 | Texmap* p_distex;
79 | INode* p_node;
80 |
81 | void setKeyTex(Texmap* m);
82 | Texmap* getKeyTex();
83 |
84 | // Editing keys
85 | void keyColorChanged(AColor col);
86 | void keyNumChanged(int num);
87 | void keyPosChanged(float pos);
88 |
89 | // GradientRampInterface
90 | int countKeys();
91 | void resetKeys();
92 |
93 | // From GradientMap
94 | void gradAddKey(float pos);
95 | void gradMoveKey(int n, float pos);
96 | void gradDelKey(int n);
97 | void gradSelKey();
98 | void gradReset() { resetKeys(); }
99 |
100 | // Curve
101 | ICurveCtl* curve;
102 | BOOL p_curveOn;
103 | // From ResourceMakerCallback
104 | BOOL SetCustomImageList(HIMAGELIST &hCTools,ICurveCtl *pCCtl) { return TRUE; };
105 | BOOL GetToolTip(int iButton, TSTR &ToolTip,ICurveCtl *pCCtl) { return TRUE; };
106 | void ResetCallback(int curvenum, ICurveCtl *pCCtl) { ICurve *pCurve = NULL; pCurve = pCCtl->GetControlCurve(curvenum); if(pCurve) { pCurve->SetNumPts(2); NewCurveCreatedCallback(curvenum, pCCtl); }}
107 | void NewCurveCreatedCallback(int curvenum, ICurveCtl *pCCtl) {
108 | ICurve *pCurve = NULL; pCurve = pCCtl->GetControlCurve(curvenum); TimeValue t = GetCOREInterface()->GetTime();
109 | CurvePoint pt = pCurve->GetPoint(t,0); pt.p.y = 0.f; pCurve->SetPoint(t,0,&pt);
110 | pCurve->SetPenProperty( RGB(0,0,0)); pCurve->SetDisabledPenProperty( RGB(128,128,128));
111 | pt = pCurve->GetPoint(t,1); pt.p.y = 1.f; pCurve->SetPoint(t,1,&pt);
112 | }
113 |
114 | //From MtlBase
115 | ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
116 | BOOL SetDlgThing(ParamDlg* dlg);
117 | void Update(TimeValue t, Interval& valid);
118 | void Reset();
119 | Interval Validity(TimeValue t);
120 |
121 | ULONG LocalRequirements(int subMtlNum) { return berconXYZ.req(); }
122 | void MappingsRequired(int subMtlNum, BitArray& mapreq, BitArray& bumpreq) { berconXYZ.map(subMtlNum, mapreq, bumpreq); }
123 |
124 | int NumSubTexmaps() { return 3 + gradient->numKeys(); } // !! Update submap count !!
125 | Texmap* GetSubTexmap(int i);
126 | void SetSubTexmap(int i, Texmap *m);
127 | TSTR GetSubTexmapSlotName(ARG_LOCALIZED(int i));
128 |
129 | //From Texmap
130 | RGBA EvalColor(ShadeContext& sc);
131 | float EvalMono(ShadeContext& sc);
132 | Point3 EvalNormalPerturb(ShadeContext& sc);
133 | int SubNumToRefNum(int subNum) { return subNum; }
134 |
135 | void ReadSXPData(TCHAR *name, void *sxpdata) {}
136 |
137 | // Interactive Display
138 | TexHandle *texHandle;
139 | Interval texHandleValid;
140 | void DiscardTexHandle() { if (texHandle) { texHandle->DeleteThis(); texHandle = NULL; } }
141 | BOOL SupportTexDisplay() { return TRUE; }
142 | void ActivateTexDisplay(BOOL onoff) { if (!onoff) DiscardTexHandle(); }
143 | DWORD_PTR GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
144 |
145 | //From Animatable
146 | Class_ID ClassID() {return BerconGradient_CLASS_ID;}
147 | SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
148 | #if MAX_RELEASE < 23900
149 | void GetClassName(ARG_LOCALIZED(TSTR& s)) { s = GetString(IDS_BERCON_COLOR); }
150 | #else
151 | void GetClassName(ARG_LOCALIZED(TSTR& s)) const override { s = GetString(IDS_BERCON_COLOR); } //override for Slate editor
152 | #endif
153 |
154 | RefTargetHandle Clone( RemapDir &remap );
155 | RefResult NotifyRefChanged(NOTIFY_REF_CHANGED_ARGS);
156 |
157 | int NumSubs() { return 8+gradient->numKeys(); } // !! Update submap count !!
158 | Animatable* SubAnim(int i);
159 | TSTR SubAnimName(ARG_LOCALIZED(int i));
160 |
161 | int NumRefs() { return 8+gradient->numKeys(); } // !! Update submap count !!
162 | RefTargetHandle GetReference(int i);
163 | void SetReference(int i, RefTargetHandle rtarg);
164 |
165 | int NumParamBlocks() { return 3; }
166 | IParamBlock2* GetParamBlock(int i) { switch (i) { case 0: return pblock; case 1: return pbCurve; case 2: return pbXYZ; } return NULL; }
167 | IParamBlock2* GetParamBlockByID(BlockID id) {
168 | if (pblock->ID() == id) return pblock;
169 | if (pbCurve->ID() == id) return pbCurve;
170 | if (pbXYZ->ID() == id) return pbXYZ;
171 | return NULL;
172 | }
173 |
174 | int RenderBegin(TimeValue t, ULONG flags = 0) { if (!flags) previewMatIDMode = FALSE; return 1; }
175 | int RenderEnd(TimeValue t) { previewMatIDMode = TRUE; return 1; }
176 |
177 | void DeleteThis() { delete this; }
178 |
179 | BerconGradient();
180 | ~BerconGradient();
181 |
182 | void* GetInterface(ULONG id) {
183 | if(id == I_RESMAKER_INTERFACE)
184 | return (void *) (ResourceMakerCallback*) this;
185 | else
186 | return Texmap::GetInterface(id);
187 | }
188 | };
189 |
190 | class BerconGradientClassDesc : public ClassDesc2 {
191 | public:
192 | virtual int IsPublic() { return TRUE; }
193 | virtual void* Create(BOOL /*loading = FALSE*/) { return new BerconGradient(); }
194 | virtual SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
195 | virtual Class_ID ClassID() { return BerconGradient_CLASS_ID; }
196 | virtual const TCHAR* Category() { return TEXMAP_CAT_3D; }
197 | virtual const TCHAR* InternalName() { return _T("BerconGradient"); } // scripter-visible name
198 | virtual HINSTANCE HInstance() { return hInstance; }
199 | LOCALIZED_CLASS_NAME(IDS_BERCON_COLOR)
200 | };
201 |
--------------------------------------------------------------------------------
/src/BerconSC.h:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "max.h"
19 |
20 | #define BERCON_SHADE_CONTEXT_CLASS_ID Class_ID(0x7c0a38f1, 0x2f1a67f2)
21 |
22 | class BerconSC: public ShadeContext {
23 | private:
24 | ShadeContext* const sc;
25 |
26 | int type;
27 | Point3 uvPoint;
28 | Point3 uvPoint2;
29 | int uvChannel;
30 | int uvChannel2;
31 | bool useMultiTexture;
32 | float val;
33 |
34 | public:
35 | BerconSC(ShadeContext* const sc) : sc (sc) {
36 | mode = sc->mode;
37 | doMaps = sc->doMaps;
38 | filterMaps = sc->filterMaps;
39 | shadow = sc->shadow;
40 | backFace = sc->backFace;
41 | mtlNum = sc->mtlNum;
42 | ambientLight = sc->ambientLight;
43 | nLights = sc->nLights;
44 | rayLevel = sc->rayLevel;
45 | xshadeID = sc->xshadeID;
46 | atmosSkipLight = sc->atmosSkipLight;
47 | globContext = sc->globContext;
48 | out = sc->out;
49 |
50 | uvChannel = -1; uvChannel2 = -1; useMultiTexture = false; type = -1;
51 | }
52 |
53 | void setParams(Point3 p, int type, int chan=0) {
54 | uvPoint = p;
55 | this->type = type;
56 | uvChannel = chan;
57 | }
58 |
59 | void setUV1(Point3 uvw, int chan) {
60 | uvPoint = uvw;
61 | uvChannel = chan;
62 | }
63 |
64 | void setUV2(Point3 uvw, int chan) {
65 | uvPoint2 = uvw;
66 | uvChannel2 = chan;
67 | }
68 |
69 | void setMultiTexture(float val) {
70 | this->val = val;
71 | useMultiTexture = true;
72 | }
73 |
74 | void ResetOutput (int n) { sc->ResetOutput(n); }
75 | Class_ID ClassID () { return BERCON_SHADE_CONTEXT_CLASS_ID; }
76 | BOOL InMtlEditor () { return sc->InMtlEditor(); }
77 | int Antialias () { return sc->Antialias(); }
78 | int ProjType () { return sc->ProjType(); }
79 | LightDesc* Light (int n) { return sc->Light(n); }
80 | TimeValue CurTime () { return sc->CurTime(); }
81 | int NodeID () { return sc->NodeID(); }
82 | INode* Node () { return sc->Node(); }
83 | Object* GetEvalObject () { return sc->GetEvalObject(); }
84 | Point3 BarycentricCoords () { return sc->BarycentricCoords(); }
85 | int FaceNumber () { return sc->FaceNumber(); }
86 | Point3 Normal () { return sc->Normal(); }
87 | void SetNormal (Point3 p) { sc->SetNormal(p); }
88 | Point3 OrigNormal () { return sc->OrigNormal(); }
89 | Point3 GNormal () { return sc->GNormal(); }
90 | float Curve () { return sc->Curve(); }
91 | Point3 V () { return sc->V(); }
92 | void SetView (Point3 p) { sc->SetView(p); }
93 | Point3 OrigView () { return sc->OrigView(); }
94 | Point3 ReflectVector () { return sc->ReflectVector(); }
95 | Point3 RefractVector (float ior) { return sc->RefractVector(ior); }
96 | void SetIOR (float ior) { sc->SetIOR(ior); }
97 | float GetIOR () { return sc->GetIOR(); }
98 | Point3 CamPos () { return sc->CamPos(); }
99 | inline Point3 P (); // Overridden
100 | Point3 DP () { return sc->DP(); }
101 | void DP (Point3& dpdx, Point3& dpdy) { sc->DP(dpdx, dpdx); }
102 | inline Point3 PObj (); // Overridden
103 | Point3 DPObj () { return sc->DPObj(); }
104 | Box3 ObjectBox () { return sc->ObjectBox(); }
105 | inline Point3 PObjRelBox (); // Overridden
106 | Point3 DPObjRelBox () { return sc->DPObjRelBox(); }
107 | inline void ScreenUV (Point2& uv, Point2 &duv); // Overridden
108 | IPoint2 ScreenCoord () { return sc->ScreenCoord(); }
109 | Point2 SurfacePtScreen (){ return sc->SurfacePtScreen(); }
110 | inline Point3 UVW (int channel); // Overridden
111 | Point3 DUVW (int channel) { return sc->DUVW(channel); }
112 | void DPdUVW (Point3 dP[3], int channel){ sc->DPdUVW(dP, channel); }
113 | int BumpBasisVectors (Point3 dP[2], int axis, int channel){ return sc->BumpBasisVectors(dP, axis, channel); }
114 | BOOL IsSuperSampleOn () { return sc->IsSuperSampleOn(); }
115 | BOOL IsTextureSuperSampleOn () { return sc->IsTextureSuperSampleOn(); }
116 | int GetNSuperSample () { return sc->GetNSuperSample(); }
117 | float GetSampleSizeScale (){ return sc->GetSampleSizeScale(); }
118 | Point3 UVWNormal (int channel){ return sc->UVWNormal(channel); }
119 | float RayDiam (){ return sc->RayDiam(); }
120 | float RayConeAngle (){ return sc->RayConeAngle(); }
121 | AColor EvalEnvironMap (Texmap* map, Point3 view) { return sc->EvalEnvironMap(map, view); }
122 | void GetBGColor (Color& bgcol, Color& transp, BOOL fogBG){ sc->GetBGColor(bgcol, transp, fogBG); }
123 | float CamNearRange () { return sc->CamNearRange(); }
124 | float CamFarRange (){ return sc->CamFarRange(); }
125 | Point3 PointTo (const Point3& p, RefFrame ito) { return sc->PointTo(p, ito); }
126 | Point3 PointFrom (const Point3& p, RefFrame ifrom) { return sc->PointFrom(p, ifrom); }
127 | Point3 VectorTo (const Point3& p, RefFrame ito) { return sc->VectorTo(p, ito); }
128 | Point3 VectorFrom (const Point3& p, RefFrame ifrom) { return sc->VectorFrom(p, ifrom); }
129 | Point3 VectorToNoScale (const Point3& p, RefFrame ito) { return sc->VectorToNoScale(p, ito); }
130 | Point3 VectorFromNoScale (const Point3& p, RefFrame ifrom){ return sc->VectorFromNoScale(p, ifrom); }
131 | void SetGBufferID (int gbid){ sc->SetGBufferID(gbid); }
132 | FILE* DebugFile (){ return sc->DebugFile(); }
133 | AColor EvalGlobalEnvironMap (Point3 dir){ return sc->EvalGlobalEnvironMap(dir); }
134 | BOOL GetCache (Texmap* map, AColor &c) { return sc->GetCache(map, c); }
135 | BOOL GetCache (Texmap* map, float &f) { return sc->GetCache(map, f); }
136 | BOOL GetCache (Texmap* map, Point3 &p) { return sc->GetCache(map, p); }
137 | void PutCache (Texmap* map, const AColor &c) { sc->PutCache(map, c); }
138 | void PutCache (Texmap* map, const float f) { sc->PutCache(map, f); }
139 | void PutCache (Texmap* map, const Point3 &p) { sc->PutCache(map, p); }
140 | void TossCache (Texmap* map){ sc->TossCache(map); }
141 | INT_PTR Execute (int cmd, ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3){ return sc->Execute(cmd, arg1, arg2, arg3); }
142 | LightDesc* GetAtmosSkipLight () { return sc->GetAtmosSkipLight(); }
143 | void SetAtmosSkipLight (LightDesc* lt){ sc->SetAtmosSkipLight(lt); }
144 | int NRenderElements () { return sc->NRenderElements(); }
145 | IRenderElement* GetRenderElement (int n){ return sc->GetRenderElement(n); }
146 | Color DiffuseIllum (){ return sc->DiffuseIllum(); }
147 |
148 | #if MAX_RELEASE < 23900
149 | //#if MAX_RELEASE < MAX_RELEASE_R24_PREVIEW (2021 and earlier)
150 | bool IsPhysicalSpace () const{ return sc->IsPhysicalSpace(); }
151 | template void ScaledToRGB (T& energy) const { sc->ScaledToRGB(energy); }
152 | float ScaledToRGB (float energy) const{ return sc->ScaledToRGB(energy); }
153 | void ScaledToRGB (){ sc->ScaledToRGB(); }
154 | template void ScalePhysical (T& energy) const { sc->ScaledPhysical(energy); }
155 | float ScalePhysical (float energy) const{ return sc->ScalePhysical(energy); }
156 | template void ScaleRGB (T& energy) const { sc->ScaleRGB(energy); }
157 | float ScaleRGB (float energy) const{ return sc->ScaleRGB(energy); }
158 | #endif
159 |
160 | #if MAX_RELEASE >= 25900 // The 2023 Max SDK does not know the value of MAX_RELEASE_R26_PREVIEW
161 | //#if MAX_RELEASE >= MAX_RELEASE_R26_PREVIEW
162 | Matrix3 MatrixTo(RefFrame ito) override { return sc->MatrixTo(ito); }
163 |
164 | Matrix3 MatrixFrom(RefFrame ifrom) override { return sc->MatrixFrom(ifrom); }
165 | #endif
166 | };
167 |
168 | inline Point3 BerconSC::PObjRelBox() {
169 | return sc->PObjRelBox();
170 | }
171 |
172 | inline void BerconSC::ScreenUV(Point2& uv, Point2 &duv) {
173 | sc->ScreenUV(uv, duv);
174 | if (type == 4) {
175 | uv.x = uvPoint.x;
176 | uv.y = uvPoint.y;
177 | }
178 | }
179 |
180 | inline Point3 BerconSC::P() {
181 | return type == 3 ? uvPoint : sc->P();
182 | }
183 |
184 | inline Point3 BerconSC::PObj() {
185 | return type == 2 ? uvPoint : sc->PObj();
186 | }
187 |
188 | inline Point3 BerconSC::UVW(int channel) {
189 | if (useMultiTexture && 99 == channel)
190 | return Point3(val, val, val);
191 |
192 | if ((type == 0 || type == 1) && uvChannel == channel)
193 | return uvPoint;
194 |
195 | if (uvChannel > 0 && uvChannel == channel)
196 | return uvPoint;
197 |
198 | if (uvChannel2 > 0 && uvChannel2 == channel)
199 | return uvPoint2;
200 |
201 | return sc->UVW(channel);
202 | }
--------------------------------------------------------------------------------
/src/BerconDistortion.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "BerconDistortion.h"
19 |
20 | #define PBLOCK_REF 0
21 | #define MAP1_REF 1
22 | #define MAP2_REF 2
23 | #define MAP3_REF 3
24 | #define COORD_REF 4
25 |
26 | #define NAMELENGTH 64
27 | typedef TCHAR TChBuffer[NAMELENGTH];
28 |
29 | static BerconDistortionClassDesc BerconDistortionDesc;
30 | ClassDesc2* GetBerconDistortionDesc() { return &BerconDistortionDesc; }
31 |
32 | enum { BerconDistortion_params, xyz_params };
33 |
34 | XYZ_Desc xyz_blk(&BerconDistortionDesc, COORD_REF, xyz_params, 0, 1, 1, 1, 0);
35 |
36 | enum { map1, distortion_map, distortion_map2, use_distortion, distortion_str, };
37 |
38 | static ParamBlockDesc2 BerconDistortion_param_blk ( BerconDistortion_params, _T("params"), 0, &BerconDistortionDesc,
39 | P_AUTO_CONSTRUCT + P_AUTO_UI, PBLOCK_REF,
40 | IDD_PANEL_DISTORTION, IDS_PARAMS, 0, 0, NULL,
41 | // params
42 | // Distortion controls
43 |
44 | distortion_map, _T("map1"), TYPE_TEXMAP, P_OWNERS_REF, IDS_DISTORTION_MAP,
45 | p_refno, MAP1_REF,
46 | p_subtexno, 0,
47 | p_ui, TYPE_TEXMAPBUTTON, IDC_DISTORTION_TEX,
48 | p_end,
49 | distortion_map2, _T("map2"), TYPE_TEXMAP, P_OWNERS_REF, IDS_DISTORTION_MAP2,
50 | p_refno, MAP2_REF,
51 | p_subtexno, 1,
52 | p_ui, TYPE_TEXMAPBUTTON, IDC_DISTORTION_TEX2,
53 | p_end,
54 | map1, _T("map3"), TYPE_TEXMAP, P_OWNERS_REF, IDS_MAP1,
55 | p_refno, MAP3_REF,
56 | p_subtexno, 2,
57 | p_ui, TYPE_TEXMAPBUTTON, IDC_MAP1,
58 | p_end,
59 | distortion_str, _T("distortionStr"), TYPE_FLOAT, P_ANIMATABLE, IDS_DISTORTION_STRENGTH,
60 | p_default, 0.1f,
61 | p_range, 0.0f, 1000.0f,
62 | p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_DISTORTION_EDIT, IDC_DISTORTION_SPIN, 0.001f,
63 | p_end,
64 | use_distortion, _T("useDistortion"), TYPE_BOOL, 0, IDS_USE_DISTORTION,
65 | p_default, FALSE,
66 | p_ui, TYPE_SINGLECHEKBOX, IDC_USE_DISTORTION,
67 | p_end,
68 | p_end
69 | );
70 |
71 | //--- BerconDistortion -------------------------------------------------------
72 | BerconDistortion::BerconDistortion() {
73 | for (int i=0; iGetHandle();
94 | else DiscardTexHandle();
95 | }
96 | texHandle = thmaker.MakeHandle(GetVPDisplayDIB(t,thmaker,texHandleValid));
97 | return texHandle->GetHandle();
98 | }
99 |
100 | void BerconDistortion::Update(TimeValue t, Interval& valid) {
101 | if (pblock == NULL) return;
102 |
103 | if (!ivalid.InInterval(t)) {
104 | ivalid.SetInfinite();
105 | for (int i=0; iUpdate(t,ivalid);
108 | pblock->GetValue( distortion_str, t, distortionStr, ivalid);
109 | pblock->GetValue( use_distortion, t, useDistortion, ivalid);
110 |
111 | berconXYZ.update(pbXYZ, t, ivalid);
112 | }
113 | valid &= ivalid;
114 | }
115 |
116 | Interval BerconDistortion::Validity(TimeValue t) {
117 | Interval v;
118 | Update(t,v);
119 | return ivalid;
120 | }
121 |
122 | ParamDlg* BerconDistortion::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp) {
123 | IAutoMParamDlg* masterDlg = BerconDistortionDesc.CreateParamDlgs(hwMtlEdit, imp, this);
124 | xyz_blk.SetUserDlgProc(new BerconXYZDlgProc(this));
125 | return masterDlg;
126 | }
127 |
128 | BOOL BerconDistortion::SetDlgThing(ParamDlg* dlg) {
129 | return FALSE;
130 | }
131 |
132 | void BerconDistortion::SetSubTexmap(int i, Texmap *m) {
133 | ReplaceReference(i+1,m);
134 | if (i==0) {
135 | BerconDistortion_param_blk.InvalidateUI(distortion_map);
136 | ivalid.SetEmpty();
137 | } else if (i==1) {
138 | BerconDistortion_param_blk.InvalidateUI(distortion_map2);
139 | ivalid.SetEmpty();
140 | } else if (i==2) {
141 | BerconDistortion_param_blk.InvalidateUI(map1);
142 | ivalid.SetEmpty();
143 | }
144 | }
145 |
146 | TSTR BerconDistortion::GetSubTexmapSlotName(ARG_LOCALIZED(int i)) {
147 | switch(i) {
148 | case 0: return TSTR(GetString(IDS_DISTORTION_MAP));
149 | case 1: return TSTR(GetString(IDS_DISTORTION_MAP2));
150 | case 2: return TSTR(GetString(IDS_MAP1));
151 | default: return TSTR(_T(""));
152 | }
153 | }
154 |
155 | RefTargetHandle BerconDistortion::GetReference(int i) {
156 | switch (i) {
157 | case PBLOCK_REF: return pblock;
158 | case COORD_REF: return pbXYZ;
159 | default: return subtex[i-1];
160 | }
161 | }
162 |
163 | void BerconDistortion::SetReference(int i, RefTargetHandle rtarg) {
164 | switch(i) {
165 | case PBLOCK_REF: pblock = (IParamBlock2 *)rtarg; break;
166 | case COORD_REF: pbXYZ = (IParamBlock2 *)rtarg; break;
167 | default: subtex[i-1] = (Texmap *)rtarg; break;
168 | }
169 | }
170 |
171 | RefTargetHandle BerconDistortion::Clone(RemapDir &remap) {
172 | BerconDistortion *mnew = new BerconDistortion();
173 | *((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
174 | mnew->ReplaceReference(PBLOCK_REF,remap.CloneRef(pblock));
175 | mnew->ReplaceReference(COORD_REF,remap.CloneRef(pbXYZ));
176 | mnew->ivalid.SetEmpty();
177 | for (int i = 0; isubtex[i] = NULL;
179 | if (subtex[i])
180 | mnew->ReplaceReference(i+1,remap.CloneRef(subtex[i]));
181 | }
182 | BaseClone(this, mnew, remap);
183 | return (RefTargetHandle)mnew;
184 | }
185 |
186 | Animatable* BerconDistortion::SubAnim(int i) {
187 | switch (i) {
188 | case PBLOCK_REF: return pblock;
189 | case COORD_REF: return pbXYZ;
190 | default: return subtex[i-1];
191 | }
192 | }
193 |
194 | TSTR BerconDistortion::SubAnimName(ARG_LOCALIZED(int i)) {
195 | switch (i) {
196 | case PBLOCK_REF: return GetString(IDS_PARAMS);
197 | case COORD_REF: return GetString(IDS_XYZ);
198 | default: return GetSubTexmapTVName(FORWARD_ARG_LOCALIZED(i-1));
199 | }
200 | }
201 |
202 | RefResult BerconDistortion::NotifyRefChanged(NOTIFY_REF_CHANGED_ARGS) {
203 | switch (message) {
204 | case REFMSG_CHANGE:
205 | ivalid.SetEmpty();
206 | if (hTarget == pblock) {
207 | ParamID changing_param = pblock->LastNotifyParamID();
208 | BerconDistortion_param_blk.InvalidateUI(changing_param);
209 | if (changing_param != -1) DiscardTexHandle();
210 | }
211 | break;
212 | }
213 | return(REF_SUCCEED);
214 | }
215 |
216 | // Define some basic values
217 | static AColor black(0.0f,0.0f,0.0f,1.0f);
218 |
219 | Point3 BerconDistortion::getDistVector(ShadeContext& sc) {
220 | if (subtex[1])
221 | return subtex[0]->EvalNormalPerturb(sc)*distortionStr*subtex[1]->EvalMono(sc);
222 | else
223 | return subtex[0]->EvalNormalPerturb(sc)*distortionStr;
224 | }
225 |
226 | AColor BerconDistortion::EvalColor(ShadeContext& sc) {
227 | if (!subtex[2]) return black;
228 | Point3 p;
229 | berconXYZ.get(sc, p);
230 | BerconSC& bsc = BerconSC(&sc);
231 | if (useDistortion && subtex[0]) p += getDistVector(sc);
232 | bsc.setParams(p, berconXYZ.type(), berconXYZ.chan());
233 | return subtex[2]->EvalColor(bsc);
234 | }
235 |
236 | float BerconDistortion::EvalMono(ShadeContext& sc) {
237 | if (!subtex[2]) return 0.f;
238 | Point3 p;
239 | berconXYZ.get(sc, p);
240 | BerconSC& bsc = BerconSC(&sc);
241 | if (useDistortion && subtex[0]) p += getDistVector(sc);
242 | bsc.setParams(p, berconXYZ.type(), berconXYZ.chan());
243 | return subtex[2]->EvalMono(bsc);
244 | }
245 |
246 | Point3 BerconDistortion::EvalNormalPerturb(ShadeContext& sc) {
247 | if (!subtex[2]) return Point3(0.f, 0.f, 0.f);
248 | Point3 p;
249 | berconXYZ.get(sc, p);
250 | BerconSC& bsc = BerconSC(&sc);
251 | if (useDistortion && subtex[0]) p += getDistVector(sc);
252 | bsc.setParams(p, berconXYZ.type(), berconXYZ.chan());
253 | return subtex[2]->EvalNormalPerturb(bsc);
254 | }
--------------------------------------------------------------------------------
/src/fractal.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "fractal.h"
19 |
20 | float Fractal::fractal(Point3 p, NoiseParams& np) {
21 | float sum = 0.0f;
22 | float l, f = 1.0f;
23 | for (l = np.levels; l >= 1.0f; l-=1.0f) {
24 | sum += Noise::noise(p*f, np)/f;
25 | f *= 2.0f;
26 | }
27 | if (l>0.0f)
28 | sum += l*Noise::noise(p*f, np)/f;
29 | return 0.5f*(sum+1.0f);
30 | }
31 |
32 | float Fractal::turbulence(Point3 p, NoiseParams& np) {
33 | float sum = 0.0f;
34 | float l,f = 1.0f;
35 | for (l = np.levels; l >= 1.0f; l-=1.0f) {
36 | sum += fabs(Noise::noise(p*f, np))/f;
37 | f *= 2.0f;
38 | }
39 | if (l>0.0f)
40 | sum += l*fabs(Noise::noise(p*f, np))/f;
41 | return sum;
42 | }
43 |
44 | float Fractal::fBm(Point3 p, NoiseParams& np) {
45 | float sum = 0.0f;
46 | float pwr = 1.0f;
47 | float pwHL = pow(np.lacunarity, -np.H);
48 |
49 | for (int i=0; i<(int)np.levels; i++) {
50 | sum += Noise::noise(p, np) * pwr;
51 | pwr *= pwHL;
52 | p *= np.lacunarity;
53 | }
54 |
55 | float rmd = np.levels - FASTFLOOR(np.levels);
56 | if (rmd!=0.f) sum += rmd * Noise::noise(p, np) * pwr;
57 |
58 | return (sum+1.f)*.5f;
59 | }
60 |
61 | float Fractal::fBmTurb(Point3 p, NoiseParams& np) {
62 | float sum = 0.0f;
63 | float pwr = 1.0f;
64 | float pwHL = pow(np.lacunarity, -np.H);
65 |
66 | for (int i=0; i<(int)np.levels; i++) {
67 | sum += fabs(Noise::noise(p, np)) * pwr;
68 | pwr *= pwHL;
69 | p *= np.lacunarity;
70 | }
71 |
72 | float rmd = np.levels - FASTFLOOR(np.levels);
73 | if (rmd!=0.f) sum += rmd * fabs(Noise::noise(p, np)) * pwr;
74 |
75 | return sum;
76 | }
77 |
78 | float Fractal::heteroTerrain(Point3 p, NoiseParams& np) {
79 | float sum = 0.0f;
80 | float pwHL = pow(np.lacunarity, -np.H);
81 | float pwr = pwHL;
82 |
83 | sum = Noise::noise(p, np) + np.offset;
84 | p *= np.lacunarity;
85 |
86 | for (int i=0; i<(int)np.levels; i++) {
87 | sum += (Noise::noise(p, np) + np.offset) * pwr * sum;
88 | pwr *= pwHL;
89 | p *= np.lacunarity;
90 | }
91 |
92 | float rmd = np.levels - FASTFLOOR(np.levels);
93 | if (rmd!=0.f) sum += rmd * (Noise::noise(p, np) + np.offset) * pwr * sum;
94 |
95 | return (sum+1.f)*.5f;
96 | }
97 |
98 | float Fractal::hybridMultiFractal(Point3 p, NoiseParams& np) {
99 | float sum = 0.0f;
100 | float pwHL = pow(np.lacunarity, -np.H);
101 | float pwr = pwHL;
102 |
103 | float signal, weight, rmd;
104 |
105 | sum = Noise::noise(p, np) + np.offset;
106 | weight = np.gain * sum;
107 | p *= np.lacunarity;
108 |
109 | for (int i=1; (weight>0.001) && (i<(int)np.levels); i++) {
110 | if (weight>1.0) weight=1.0;
111 | signal = (Noise::noise(p, np) + np.offset) * pwr;
112 | pwr *= pwHL;
113 | sum += weight * signal;
114 | weight *= np.gain * signal;
115 | p *= np.lacunarity;
116 | }
117 |
118 | rmd = np.levels - FASTFLOOR(np.levels);
119 | if (rmd!=0.f) sum += rmd * (Noise::noise(p, np) + np.offset) * pwr;
120 |
121 | return (sum+1.f)*.5f;
122 | }
123 |
124 | float Fractal::ridgedMultiFractal(Point3 p, NoiseParams& np) {
125 | float sum = 0.0f;
126 | float pwHL = pow(np.lacunarity, -np.H);
127 | float pwr = pwHL;
128 |
129 | float signal, weight;
130 |
131 | signal = np.offset - fabs(Noise::noise(p, np));
132 | signal *= signal;
133 | sum = signal;
134 | weight = 1.f;
135 |
136 | for(int i=1; i<(int)np.levels; i++ ) {
137 | p *= np.lacunarity;
138 | weight = signal * np.gain;
139 | if (weight>1.0) weight=1.0; else if (weight<0.0) weight=0.0;
140 | signal = np.offset - fabs(Noise::noise(p, np));
141 | signal *= signal;
142 | signal *= weight;
143 | sum += signal * pwr;
144 | pwr *= pwHL;
145 | }
146 |
147 | return sum;
148 | }
149 |
150 | // Filtered
151 |
152 | float Fractal::fractal(Point3 p, float d, NoiseParams& np) {
153 | float sum = 0.0f;
154 | float l, f = 1.0f;
155 | for (l = np.levels; l >= 1.0f; l-=1.0f) {
156 | sum += Noise::noise(p*f, d*f, np)/f;
157 | f *= 2.0f;
158 | }
159 | if (l>0.0f)
160 | sum += l*Noise::noise(p*f, d*f, np)/f;
161 | return 0.5f*(sum+1.0f);
162 | }
163 |
164 | float Fractal::turbulence(Point3 p, float d, NoiseParams& np) {
165 | float sum = 0.0f;
166 | float l,f = 1.0f;
167 | for (l = np.levels; l >= 1.0f; l-=1.0f) {
168 | sum += fabs(Noise::noise(p*f, d*f, np))/f;
169 | f *= 2.0f;
170 | }
171 | if (l>0.0f)
172 | sum += l*fabs(Noise::noise(p*f, d*f, np))/f;
173 | return sum;
174 | }
175 |
176 | float Fractal::fBm(Point3 p, float d, NoiseParams& np) {
177 | float sum = 0.0f;
178 | float pwr = 1.0f;
179 | float pwHL = pow(np.lacunarity, -np.H);
180 |
181 | for (int i=0; i<(int)np.levels; i++) {
182 | sum += Noise::noise(p, d, np) * pwr;
183 | pwr *= pwHL;
184 | p *= np.lacunarity;
185 | d *= np.lacunarity;
186 | }
187 |
188 | float rmd = np.levels - FASTFLOOR(np.levels);
189 | if (rmd!=0.f) sum += rmd * Noise::noise(p, d, np) * pwr;
190 |
191 | return (sum+1.f)*.5f;
192 | }
193 |
194 | float Fractal::fBmTurb(Point3 p, float d, NoiseParams& np) {
195 | float sum = 0.0f;
196 | float pwr = 1.0f;
197 | float pwHL = pow(np.lacunarity, -np.H);
198 |
199 | for (int i=0; i<(int)np.levels; i++) {
200 | sum += fabs(Noise::noise(p, d, np)) * pwr;
201 | pwr *= pwHL;
202 | p *= np.lacunarity;
203 | d *= np.lacunarity;
204 | }
205 |
206 | float rmd = np.levels - FASTFLOOR(np.levels);
207 | if (rmd!=0.f) sum += rmd * fabs(Noise::noise(p, d, np)) * pwr;
208 |
209 | return sum;
210 | }
211 |
212 | float Fractal::heteroTerrain(Point3 p, float d, NoiseParams& np) {
213 | float sum = 0.0f;
214 | float pwHL = pow(np.lacunarity, -np.H);
215 | float pwr = pwHL;
216 |
217 | sum = Noise::noise(p, np) + np.offset;
218 | p *= np.lacunarity;
219 | d *= np.lacunarity;
220 |
221 | for (int i=0; i<(int)np.levels; i++) {
222 | sum += (Noise::noise(p, d, np) + np.offset) * pwr * sum;
223 | pwr *= pwHL;
224 | p *= np.lacunarity;
225 | d *= np.lacunarity;
226 | }
227 |
228 | float rmd = np.levels - FASTFLOOR(np.levels);
229 | if (rmd!=0.f) sum += rmd * (Noise::noise(p, d, np) + np.offset) * pwr * sum;
230 |
231 | return (sum+1.f)*.5f;
232 | }
233 |
234 | float Fractal::hybridMultiFractal(Point3 p, float d, NoiseParams& np) {
235 | float sum = 0.0f;
236 | float pwHL = pow(np.lacunarity, -np.H);
237 | float pwr = pwHL;
238 |
239 | float signal, weight, rmd;
240 |
241 | sum = Noise::noise(p, d, np) + np.offset;
242 | weight = np.gain * sum;
243 | p *= np.lacunarity;
244 | d *= np.lacunarity;
245 |
246 | for (int i=1; (weight>0.001) && (i<(int)np.levels); i++) {
247 | if (weight>1.0) weight=1.0;
248 | signal = (Noise::noise(p, d, np) + np.offset) * pwr;
249 | pwr *= pwHL;
250 | sum += weight * signal;
251 | weight *= np.gain * signal;
252 | p *= np.lacunarity;
253 | d *= np.lacunarity;
254 | }
255 |
256 | rmd = np.levels - FASTFLOOR(np.levels);
257 | if (rmd!=0.f) sum += rmd * (Noise::noise(p, d, np) + np.offset) * pwr;
258 |
259 | return (sum+1.f)*.5f;
260 | }
261 |
262 | float Fractal::ridgedMultiFractal(Point3 p, float d, NoiseParams& np) {
263 | float sum = 0.0f;
264 | float pwHL = pow(np.lacunarity, -np.H);
265 | float pwr = pwHL;
266 |
267 | float signal, weight;
268 |
269 | signal = np.offset - fabs(Noise::noise(p, d, np));
270 | signal *= signal;
271 | sum = signal;
272 | weight = 1.f;
273 |
274 | for(int i=1; i<(int)np.levels; i++ ) {
275 | p *= np.lacunarity;
276 | d *= np.lacunarity;
277 | weight = signal * np.gain;
278 | if (weight>1.0) weight=1.0; else if (weight<0.0) weight=0.0;
279 | signal = np.offset - fabs(Noise::noise(p, d, np));
280 | signal *= signal;
281 | signal *= weight;
282 | sum += signal * pwr;
283 | pwr *= pwHL;
284 | }
285 |
286 | return sum;
287 | }
288 |
289 | // Generic
290 | float Fractal::fBm(Point3 p, float levels, float lacunarity, float H) {
291 | float sum = 0.0f;
292 | float pwr = 1.0f;
293 | float pwHL = pow(lacunarity, -H);
294 |
295 | for (int i=0; i<(int)levels; i++) {
296 | sum += Perlin::noise(p.x, p.y, p.z) * pwr;
297 | pwr *= pwHL;
298 | p *= lacunarity;
299 | }
300 |
301 | float rmd = levels - FASTFLOOR(levels);
302 | if (rmd!=0.f) sum += rmd * Perlin::noise(p.x, p.y, p.z) * pwr;
303 |
304 | return (sum+1.f)*.5f;
305 | }
306 |
307 | // Wood specific
308 | float Fractal::grain(Point3 p, float amount, float freq) {
309 | p *= freq;
310 | p.z *= .05f;
311 | float g = (fBm(p, 4.f, 2.f, .5f)+1.f)*.5f;
312 | return smooth(g, (1.f-amount), 1.f);;
313 | }
314 |
--------------------------------------------------------------------------------
/src/noise.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "noise.h"
19 | #include "fractal.h"
20 |
21 | void Noise::alterUVW(Point3& p, int type) {
22 | switch (type) {
23 | case 1:
24 | p.x = sqrt(p.x * p.x + p.y * p.y);
25 | p.y = 0.f;
26 | break;
27 | case 2:
28 | p.x = sqrt(p.x * p.x + p.y * p.y + p.z * p.z);
29 | p.y = 0.f;
30 | p.z = 0.f;
31 | break;
32 | }
33 | }
34 |
35 | float Noise::noise(Point3 p, NoiseParams& np) {
36 | switch (np.noiseFunction) {
37 | case 0: return Perlin::noise(p.x, p.y);
38 | case 1: return Perlin::noise(p.x, p.y, p.z);
39 | case 2: return Perlin::noise(p.x, p.y, p.z, np.phase);
40 | case 3: return Perlin::snoise(p.x, p.y);
41 | case 4: return Perlin::snoise(p.x, p.y, p.z);
42 | case 5: return Perlin::snoise(p.x, p.y, p.z, np.phase);
43 | case 6: return worleyWrapper(p, np);
44 | default: return 0.0f;
45 | }
46 | }
47 |
48 | float Noise::noise(Point3 p, float d, NoiseParams& np) {
49 | switch (np.noiseFunction) {
50 | case 0: return Perlin::fnoise2D(p.x, p.y, d);
51 | case 1: return Perlin::fnoise3D(p.x, p.y, p.z, d);
52 | case 2: return Perlin::fnoise4D(p.x, p.y, p.z, np.phase, d);
53 | case 3: return Perlin::fsnoise2D(p.x, p.y, d);
54 | case 4: return Perlin::fsnoise3D(p.x, p.y, p.z, d);
55 | case 5: return Perlin::fsnoise4D(p.x, p.y, p.z, np.phase, d);
56 | case 6: return worleyWrapper(p, np);
57 | default: return 0.0f;
58 | }
59 | }
60 |
61 | float Noise::worleyWrapper(Point3 p, NoiseParams& np) {
62 | float val;
63 | double p3[3] = {(double)p.x, (double)p.y, (double)p.z};
64 | double f[4];
65 | int order = 1;
66 | // Calc order
67 | if (np.F4 > 0.0001f || np.F4 < -0.0001f)
68 | order = 4;
69 | else if (np.F3 > 0.0001f || np.F3 < -0.0001f)
70 | order = 3;
71 | else if (np.F2 > 0.0001f || np.F2 < -0.0001f)
72 | order = 2;
73 | // Worley
74 | Worley::noise(p3, order, f, np.worleyFunction);
75 | // Return value
76 | switch (order) {
77 | case 1: val = (float)f[0]*np.F1; break;
78 | case 2: val = (float)f[0]*np.F1 + (float)f[1]*np.F2; break;
79 | case 3: val = (float)f[0]*np.F1 + (float)f[1]*np.F2 + (float)f[2]*np.F3; break;
80 | case 4: val = (float)f[0]*np.F1 + (float)f[1]*np.F2 + (float)f[2]*np.F3 + (float)f[3]*np.F4; break;
81 | default: val = 0.0f;
82 | }
83 | val = val/np.spread*2.f-1.f;
84 | return val;
85 | }
86 |
87 | float Noise::wood(Point3 p, Point3 &g, WoodParam &wp) {
88 | // Radial noise
89 | p.x += Perlin::snoise(p.x*wp.radialFreq, p.y*wp.radialFreq, p.z*wp.radialZ, wp.randSeed-1.125f) * wp.radialStr;
90 | p.y += Perlin::snoise(p.x*wp.radialFreq, p.y*wp.radialFreq, p.z*wp.radialZ, wp.randSeed+1.125f) * wp.radialStr;
91 | g = p; // Store radial component for gain
92 | // Trunk wobble
93 | float angle = Perlin::snoise(p.z*wp.trunkFreq, wp.randSeed+3.f) * (float)pi; // Offset so we dont get the same value as below
94 | p += Point3(cos(angle), sin(angle), 0.f) * Perlin::snoise(p.z*wp.trunkFreq, wp.randSeed-5.5f) * wp.trunkStr;
95 | g = .5f*g + .5f*p; // We don't want trunk wobble to affect too much to grain
96 | // Distance
97 | float dist = 0.f;
98 | switch (wp.woodType) {
99 | case 0: dist = sqrt(p.x*p.x+p.y*p.y); break;
100 | case 1: p*=.05f; dist = (Perlin::noise(p.x, p.y, p.z, wp.randSeed-7.1f)+1.f) / .5f * 15.f; break;
101 | case 2: p*=.05f; dist = (Perlin::snoise(p.x, p.y, p.z, wp.randSeed+3.15f)+1.f) / .5f * 15.f; break;
102 | case 3: dist = p.x<0.f?-p.x:p.x; break;
103 | }
104 | // Width variation
105 | dist += Perlin::snoise(dist+wp.randSeed*2.f) * wp.widthVar;
106 | // Angular noise
107 | float d = dist;
108 | if (d > wp.angleRad) d = wp.angleRad;
109 | dist += smooth(d/wp.angleRad) * Perlin::noise(p.x*wp.angleFreq, p.y*wp.angleFreq, p.z*wp.angleFreq*.5f, wp.randSeed+10.6f) * wp.angleStr;
110 | // Mod
111 | float ipart = (float)(int)dist;
112 | dist -= ipart;
113 | // Skew
114 | if (dist < wp.skew)
115 | dist *= .5f / wp.skew;
116 | else
117 | dist = dist * .5f / (1.f-wp.skew) - wp.skew * (.5f/(1.f-wp.skew)) + .5f;
118 | // Reverse
119 | dist *= 2.f;
120 | if (dist > 1.f)
121 | dist = 2.f-dist;
122 | // Smooth and scale
123 | dist = smooth(dist, wp.lowTresh, wp.highTresh);
124 | // Gain variation
125 | float gain = (Perlin::snoise((ipart + wp.randSeed) * 314.134f) + 1.f) * .5f;
126 | dist *= (1.f-wp.gainVar) + gain * wp.gainVar;
127 | // Return
128 | return dist;
129 | }
130 |
131 | /*
132 | This version super samples the mod function to avoid aliasing
133 | Filtered versions of Noises are used, meaning they fade out once their frequency is too high compared to sampled area
134 | Noises are also asumed constant in the sampled area, meaning they are not super sampled, just calculated once and filtered
135 | With the optimizations above this filtered version shouldn't result in any significan performance loss
136 |
137 | 2 x Filtered 4D Simplex
138 | 2 x Filtered 2D Simplex
139 | 1 x Filtered 4D Perlin
140 | samples x samples x 2 x 1D Simplex
141 | */
142 |
143 | float Noise::wood(Point3 p, Point3 dPdx, Point3 dPdy, Point3 &g, WoodParam wp) {
144 | // Filtered noises are only intrested in maximum change in X, Y and Z axis.
145 | float lx = dPdx.Length();
146 | float ly = dPdy.Length();
147 | float filter = MAX(lx, ly);
148 | // Radial noise
149 | p.x += Perlin::fsnoise4D(p.x*wp.radialFreq, p.y*wp.radialFreq, p.z*wp.radialZ, wp.randSeed-1.125f, filter*wp.radialFreq) * wp.radialStr;
150 | p.y += Perlin::fsnoise4D(p.x*wp.radialFreq, p.y*wp.radialFreq, p.z*wp.radialZ, wp.randSeed+1.125f, filter*wp.radialFreq) * wp.radialStr;
151 | g = p; // Store radial component for gain
152 | // Trunk wobble
153 | float angle = Perlin::fsnoise2D(p.z*wp.trunkFreq, wp.randSeed+3.f, filter*wp.trunkFreq) * (float)pi;
154 | p += Point3(cos(angle), sin(angle), 0.f) * Perlin::fsnoise2D(p.z*wp.trunkFreq, wp.randSeed-5.5f, filter*wp.trunkFreq) * wp.trunkStr;
155 | g = .5f*g + .5f*p; // We don't want trunk wobble to affect too much to grain
156 | // Angular noise (applied inside super sampled code, but not dependant on it)
157 | float angNoise = Perlin::fnoise4D(p.x*wp.angleFreq, p.y*wp.angleFreq, p.z*wp.angleFreq*.5f, wp.randSeed+10.6f, filter*wp.angleFreq);
158 | // Super sampling the mod function and functions dependant on it starts here
159 | float samplesf = (float)wp.samples;
160 | float total = 0.f;
161 | Point3 fp = p - dPdx * .5f - dPdy * .5f;
162 | for (int i=0; i wp.angleRad) d = wp.angleRad;
178 | dist += SMOOTH(d/wp.angleRad) * angNoise * wp.angleStr;
179 | // Mod
180 | float ipart = (float)(int)dist;
181 | dist -= ipart;
182 | // Skew
183 | if (dist < wp.skew)
184 | dist *= .5f / wp.skew;
185 | else
186 | dist = dist * .5f / (1.f-wp.skew) - wp.skew * (.5f/(1.f-wp.skew)) + .5f;
187 | // Reverse
188 | dist *= 2.f;
189 | if (dist > 1.f)
190 | dist = 2.f - dist;
191 | // Smooth and scale
192 | dist = smooth(dist, wp.lowTresh, wp.highTresh);
193 | // Gain variation
194 | float gain = (Perlin::snoise((ipart + wp.randSeed) * 314.134f) + 1.f) * .5f; // Again we need FAST random function, in this case it doesn't have to be continous
195 | dist *= (1.f-wp.gainVar) + gain * wp.gainVar;
196 | // Add to total value
197 | total += dist;
198 | }
199 | // Return final value, just need to divide sum with number of samples taken
200 | return total / (float)(wp.samples * wp.samples);
201 | }
202 |
203 | float Noise::limitedNoise(Point3 p, NoiseParams &np) {
204 | float res = Fractal::f(p, np);
205 | if (np.low 1) return 1.0f;
208 | return res;
209 | }
210 |
211 | float Noise::limitedNoise(Point3 p, Point3 dpdx, Point3 dpdy, NoiseParams &np) {
212 | float lx = dpdx.Length();
213 | float ly = dpdy.Length();
214 | lx = MAX(lx, ly);
215 | float res = Fractal::f(p, lx, np);
216 | if (np.low 1) return 1.0f;
219 | return res;
220 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
--------------------------------------------------------------------------------
/src/BerconCommon.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "BerconCommon.h"
19 | #include "chkmtlapi.h"
20 |
21 | //BerconCommon is referenced by all the maps. This lets the DLL handler know which map we're in.
22 | //We match the map description to the ID specified in the header file and the DLLEntry.cpp file
23 | TCHAR *GetString(int id) {
24 | static TCHAR buf[256];
25 |
26 | if (hInstance)
27 | return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
28 | return NULL;
29 | }
30 |
31 | void BerconXYZ::reset(IParamBlock2* pblock, Interval& ivalid, int type, int x, int y, int z) {
32 | if (!pblock) return;
33 | //if (!pblock->GetMap()) return;
34 |
35 | TimeValue t = GetCOREInterface()->GetTime();
36 |
37 | pblockSetValue(xyz_offset_x, 0.f);
38 | pblockSetValue(xyz_offset_y, 0.f);
39 | pblockSetValue(xyz_offset_z, 0.f);
40 | pblockSetValue(xyz_size_x, 1.f);
41 | pblockSetValue(xyz_size_y, 1.f);
42 | pblockSetValue(xyz_size_z, 1.f);
43 | pblockSetValue(xyz_angle_x, 0.f);
44 | pblockSetValue(xyz_angle_y, 0.f);
45 | pblockSetValue(xyz_angle_z, 0.f);
46 |
47 | pblockSetValue(xyz_offset_x2, 0.f);
48 | pblockSetValue(xyz_offset_y2, 0.f);
49 | pblockSetValue(xyz_offset_z2, 0.f);
50 | pblockSetValue(xyz_size_x2, 0.f);
51 | pblockSetValue(xyz_size_y2, 0.f);
52 | pblockSetValue(xyz_size_z2, 0.f);
53 | pblockSetValue(xyz_angle_x2, 0.f);
54 | pblockSetValue(xyz_angle_y2, 0.f);
55 | pblockSetValue(xyz_angle_z2, 0.f);
56 |
57 | pblockSetValue(xyz_tile_x, x);
58 | pblockSetValue(xyz_tile_y, y);
59 | pblockSetValue(xyz_tile_z, z);
60 |
61 | pblockSetValue(xyz_seed, 12345);
62 | pblockSetValue(xyz_rand_obj, TRUE);
63 | pblockSetValue(xyz_rand_mat, FALSE);
64 | pblockSetValue(xyz_rand_par, FALSE);
65 |
66 | pblockSetValue(xyz_map, type);
67 | pblockSetValue(xyz_chan, 1);
68 |
69 | pblockSetValue(xyz_lock, TRUE);
70 |
71 | pblockSetValue(xyz_filtering, 1.f);
72 |
73 | ivalid.SetEmpty();
74 | }
75 |
76 | void BerconXYZ::update(IParamBlock2* pblock, TimeValue t, Interval& ivalid) {
77 | if (!pblock) return;
78 | //if (!pblock->GetMap()) return;
79 |
80 | pblockGetValue(xyz_offset_x, offX);
81 | pblockGetValue(xyz_offset_y, offY);
82 | pblockGetValue(xyz_offset_z, offZ);
83 | pblockGetValue(xyz_size_x, sizeX);
84 | pblockGetValue(xyz_size_y, sizeY);
85 | pblockGetValue(xyz_size_z, sizeZ);
86 | pblockGetValue(xyz_angle_x, angX);
87 | pblockGetValue(xyz_angle_y, angY);
88 | pblockGetValue(xyz_angle_z, angZ);
89 |
90 | pblockGetValue(xyz_offset_x2, offX2);
91 | pblockGetValue(xyz_offset_y2, offY2);
92 | pblockGetValue(xyz_offset_z2, offZ2);
93 | pblockGetValue(xyz_size_x2, sizeX2);
94 | pblockGetValue(xyz_size_y2, sizeY2);
95 | pblockGetValue(xyz_size_z2, sizeZ2);
96 | pblockGetValue(xyz_angle_x2, angX2);
97 | pblockGetValue(xyz_angle_y2, angY2);
98 | pblockGetValue(xyz_angle_z2, angZ2);
99 |
100 | pblockGetValue(xyz_tile_x, tileX);
101 | pblockGetValue(xyz_tile_y, tileY);
102 | pblockGetValue(xyz_tile_z, tileZ);
103 |
104 | pblockGetValue(xyz_seed, p_seed);
105 | pblockGetValue(xyz_rand_obj, p_randObj);
106 | pblockGetValue(xyz_rand_mat, p_randMat);
107 | pblockGetValue(xyz_rand_par, p_randPar);
108 |
109 | pblockGetValue(xyz_map, mappingType);
110 | pblockGetValue(xyz_chan, mappingChannel);
111 |
112 | pblockGetValue(xyz_lock, lock);
113 |
114 | pblockGetValue(xyz_filtering, filtering);
115 |
116 | //Override the spinner control's minval because we don't want tiling scale to be zero
117 | if (sizeX == 0.f) {
118 | pblockSetValue(xyz_size_x, 0.001f);
119 | }
120 | if (sizeY == 0.f) {
121 | pblockSetValue(xyz_size_y, 0.001f);
122 | }
123 | if (sizeZ == 0.f) {
124 | pblockSetValue(xyz_size_z, 0.001f);
125 | }
126 |
127 | angX *= DEG_TO_RAD; angY *= DEG_TO_RAD; angZ *= DEG_TO_RAD;
128 | angX2 *= DEG_TO_RAD; angY2 *= DEG_TO_RAD; angZ2 *= DEG_TO_RAD;
129 |
130 | EnableStuff(pblock, t);
131 | update();
132 | }
133 |
134 | void BerconXYZ::EnableStuff(IParamBlock2* pblock, TimeValue t) {
135 | if (pblock) {
136 | IParamMap2 *map = pblock->GetMap();
137 | if (map) {
138 | map->Enable(xyz_size_y2, !lock);
139 | map->Enable(xyz_size_z2, !lock);
140 |
141 | bool s = mappingType==0; // || mappingType==1;
142 | map->Enable(xyz_tile_x, s);
143 | map->Enable(xyz_tile_y, s);
144 | map->Enable(xyz_tile_z, s);
145 |
146 | int type = isRealworld();
147 |
148 | setSpinnerType(map, t, xyz_offset_x, IDC_OFF_X, IDC_OFF_X_SPIN, type, true);
149 | setSpinnerType(map, t, xyz_offset_y, IDC_OFF_Y, IDC_OFF_Y_SPIN, type, true);
150 | setSpinnerType(map, t, xyz_offset_z, IDC_OFF_Z, IDC_OFF_Z_SPIN, type, true);
151 | setSpinnerType(map, t, xyz_size_x, IDC_SIZ_X, IDC_SIZ_X_SPIN, type);
152 | setSpinnerType(map, t, xyz_size_y, IDC_SIZ_Y, IDC_SIZ_Y_SPIN, type);
153 | setSpinnerType(map, t, xyz_size_z, IDC_SIZ_Z, IDC_SIZ_Z_SPIN, type);
154 | setSpinnerType(map, t, xyz_offset_x2, IDC_OFF_X2, IDC_OFF_X_SPIN2, type);
155 | setSpinnerType(map, t, xyz_offset_y2, IDC_OFF_Y2, IDC_OFF_Y_SPIN2, type);
156 | setSpinnerType(map, t, xyz_offset_z2, IDC_OFF_Z2, IDC_OFF_Z_SPIN2, type);
157 | setSpinnerType(map, t, xyz_size_x2, IDC_SIZ_X2, IDC_SIZ_X_SPIN2, type);
158 | setSpinnerType(map, t, xyz_size_y2, IDC_SIZ_Y2, IDC_SIZ_Y_SPIN2, type);
159 | setSpinnerType(map, t, xyz_size_z2, IDC_SIZ_Z2, IDC_SIZ_Z_SPIN2, type);
160 | }
161 | }
162 | }
163 |
164 | void BerconXYZ::getBasis(Matrix3 transform, Point3* b) {
165 | if (mappingType==4&&mode2D) {
166 | Matrix3 temp = transform;
167 | temp.Invert();
168 | b[0] = Normalize(temp.GetRow(0));
169 | b[1] = Normalize(temp.GetRow(1));
170 | b[2] = Normalize(temp.GetRow(2));
171 | } else {
172 | b[0] = Normalize(transform.GetRow(0));
173 | b[1] = Normalize(transform.GetRow(1));
174 | b[2] = Normalize(transform.GetRow(2));
175 | }
176 | }
177 |
178 | #define NZERO(x) (x > 0.0001f)
179 | void BerconXYZ::update() {
180 | tm.IdentityMatrix();
181 | tm.Translate(Point3(offX, offY, offZ));
182 | tm.RotateX(angX);
183 | tm.RotateY(angY);
184 | tm.RotateZ(angZ);
185 |
186 | invNoScaleTm = tm;
187 | invNoScaleTm.Invert();
188 |
189 | tm.Scale(Point3(1.f/sizeX, 1.f/sizeY, 1.f/sizeZ));
190 |
191 | getBasis(tm, b);
192 |
193 | variance = NZERO(offX2) || NZERO(offY2) || NZERO(offZ2) || NZERO(sizeX2) || NZERO(sizeY2) || NZERO(sizeZ2) || NZERO(angX2) || NZERO(angY2) || NZERO(angZ2);
194 | }
195 |
196 | Matrix3 BerconXYZ::random(ShadeContext& sc, Matrix3* inv) {
197 | seedRandomGen(sc);
198 |
199 | Matrix3 transform;
200 | transform.IdentityMatrix();
201 | transform.Translate(Point3(offX+offX2*URANDF(), offY+offY2*URANDF(), offZ+offZ2*URANDF()));
202 | transform.RotateX(angX+angX2*URANDF());
203 | transform.RotateY(angY+angY2*URANDF());
204 | transform.RotateZ(angZ+angZ2*URANDF());
205 |
206 | if (inv) {
207 | *inv = transform;
208 | inv->Invert();
209 | }
210 |
211 | Point3 scale;
212 | if (lock) {
213 | float add = sizeX2*URANDF();
214 | scale = Point3(sizeX+add, sizeY+add, sizeZ+add);
215 | } else {
216 | scale = Point3(sizeX+sizeX2*URANDF(), sizeY+sizeY2*URANDF(), sizeZ+sizeZ2*URANDF());
217 | }
218 | if (scale.x < 0.0001f) scale.x = 0.0001f;
219 | if (scale.y < 0.0001f) scale.y = 0.0001f;
220 | if (scale.z < 0.0001f) scale.z = 0.0001f;
221 | scale.x = 1.f/scale.x; scale.y = 1.f/scale.y; scale.z = 1.f/scale.z;
222 | transform.Scale(scale);
223 |
224 | return transform;
225 | }
226 |
227 | // Random by Material, Object or Particle
228 | void BerconXYZ::seedRandomGen(ShadeContext& sc) {
229 | int seed = 1;
230 |
231 | if (p_randMat) {
232 | seed += sc.mtlNum;
233 | }
234 | if (p_randObj) {
235 | INode *node=sc.Node();
236 | if (node) {
237 | int hand = (int) node->GetHandle();
238 | seed += hand*(hand*hand*15731 + 789221);
239 | }
240 | }
241 | if (p_randPar) {
242 | Object *ob = sc.GetEvalObject();
243 | if (ob && ob->IsParticleSystem()) {
244 | ParticleObject *obj = (ParticleObject*)ob;
245 | IChkMtlAPI* chkMtlAPI = static_cast(obj->GetInterface(I_NEWMTLINTERFACE));
246 | if ((chkMtlAPI && chkMtlAPI->SupportsParticleIDbyFace())) {
247 | int id = chkMtlAPI->GetParticleFromFace(sc.FaceNumber());
248 | seed += id*(id*id*571 + 789221);
249 | }
250 | }
251 | }
252 |
253 | seed *= p_seed;
254 | srand(seed*(seed*seed*15731 + 789221));
255 | }
256 |
257 | //Continue, Stretch, Tile, Mirror, None
258 | inline static int tiling(int type, float& x) {
259 | switch (type) {
260 | //case 0 is "Continue"
261 | case 1: {D_STRE(x) return TRUE;}
262 | case 2: {D_LOOP(x) return TRUE;}
263 | case 3: {D_MIRR(x) return TRUE;}
264 | case 4: {if (x<0||x>1) return FALSE;}
265 | }
266 | return TRUE;
267 | }
268 |
269 | inline static int tiling(int type, float& x, int& flips) {
270 | switch (type) {
271 | case 1: {D_STRE(x) return TRUE;}
272 | case 2: {D_LOOP(x) return TRUE;}
273 | case 3: {
274 | if (x<0) x = -x;
275 | int ix = (int)x;
276 | if (ix%2==0) x = x - ix;
277 | else { x = 1.f - x + ix; flips = 1; }
278 | return TRUE;
279 | }
280 | case 4: {if (x<0||x>1) return FALSE;}
281 | }
282 | return TRUE;
283 | }
284 |
285 | #define OFFSET_5 Point3(0.5f, 0.5f, 0.f)
286 |
287 | // COORD_REF menu and UVWgen for render or Realistic Maps mode
288 | int BerconXYZ::get(ShadeContext& sc, Point3& p, Point3& dpdx, Point3& dpdy, Matrix3 transform, int* flips) {
289 |
290 | switch (mappingType) {
291 | case 0: // Explicit Map 2D
292 | p = transform * (sc.UVW(mappingChannel) - OFFSET_5) + OFFSET_5;
293 | {
294 | Point3 duvw = VectorTransform(transform, sc.DUVW(mappingChannel));
295 | dpdx = Point3(duvw.x, 0.f, 0.f);
296 | dpdy = Point3(0.f, duvw.y, 0.f);
297 | }
298 | if (flips) { if (!tiling(tileX, p.x, flips[0])) return FALSE; }
299 | else { if (!tiling(tileX, p.x)) return FALSE; }
300 | if (flips) { if (!tiling(tileY, p.y, flips[1])) return FALSE; }
301 | else { if (!tiling(tileY, p.y)) return FALSE; }
302 | if (flips) { if (!tiling(tileZ, p.z, flips[2])) return FALSE; }
303 | else { if (!tiling(tileZ, p.z)) return FALSE; }
304 | dpdx = dpdx * filtering; dpdy = dpdy * filtering;
305 | break;
306 | case 1: // Explicit Map 2D Real World
307 | p = transform * sc.UVW(mappingChannel);
308 | {
309 | Point3 duvw = VectorTransform(transform, sc.DUVW(mappingChannel));
310 | dpdx = Point3(duvw.x, 0.f, 0.f);
311 | dpdy = Point3(0.f, duvw.y, 0.f);
312 | }
313 | dpdx = dpdx * filtering; dpdy = dpdy * filtering;
314 | break;
315 | case 2: // Object XYZ
316 | p = transform * sc.PointTo(sc.P(), REF_OBJECT);
317 | sc.DP(dpdx, dpdy);
318 | dpdx = VectorTransform(transform, sc.VectorTo(dpdx, REF_OBJECT));
319 | dpdy = VectorTransform(transform, sc.VectorTo(dpdy, REF_OBJECT));
320 | dpdx = dpdx * filtering; dpdy = dpdy * filtering;
321 | break;
322 | case 3: // World XYZ
323 | p = transform * sc.PointTo(sc.P(),REF_WORLD);
324 | sc.DP(dpdx, dpdy);
325 | dpdx = VectorTransform(transform, sc.VectorTo(dpdx, REF_WORLD));
326 | dpdy = VectorTransform(transform, sc.VectorTo(dpdy, REF_WORLD));
327 | dpdx = dpdx * filtering; dpdy = dpdy * filtering;
328 | break;
329 | case 4: // Screen (2d mode)
330 | Point2 uv, duv;
331 | sc.ScreenUV(uv, duv);
332 | p = transform * Point3(uv.x, uv.y, 0.f);
333 | dpdx = VectorTransform(transform, Point3(duv.x, 0.f, 0.f));
334 | dpdy = VectorTransform(transform, Point3(0.f, duv.y, 0.f));
335 | dpdx = dpdx * filtering; dpdy = dpdy * filtering;
336 | break;
337 | }
338 | return TRUE;
339 | }
340 |
341 | // COORD_REF menu and UVWgen for Shaded Maps mode
342 | int BerconXYZ::get(ShadeContext& sc, Point3& p, Matrix3 transform, int* flips) {
343 | switch (mappingType) {
344 | case 0:
345 | p = transform * (sc.UVW(mappingChannel) - OFFSET_5) + OFFSET_5;
346 | if (flips) { if (!tiling(tileX, p.x, flips[0])) return FALSE; }
347 | else { if (!tiling(tileX, p.x)) return FALSE; }
348 | if (flips) { if (!tiling(tileY, p.y, flips[1])) return FALSE; }
349 | else { if (!tiling(tileY, p.y)) return FALSE; }
350 | if (flips) { if (!tiling(tileZ, p.z, flips[2])) return FALSE; }
351 | else { if (!tiling(tileZ, p.z)) return FALSE; }
352 | break;
353 | case 1:
354 | p = transform * sc.UVW(mappingChannel);
355 | break;
356 | case 2:
357 | p = transform * sc.PointTo(sc.P(),REF_OBJECT);
358 | break;
359 | case 3:
360 | p = transform * sc.PointTo(sc.P(),REF_WORLD);
361 | break;
362 | case 4:
363 | Point2 uv, duv;
364 | sc.ScreenUV(uv, duv);
365 | p = transform * Point3(uv.x, uv.y, 0.f);
366 | break;
367 | }
368 | return TRUE;
369 | }
370 |
371 | // A random variation is set and we're rendering or in Realistic Maps mode
372 | int BerconXYZ::get(ShadeContext& sc, Point3& p, Point3& dpdx, Point3& dpdy) {
373 | return get(sc, p, dpdx, dpdy, variance?random(sc):tm);
374 | }
375 |
376 | // A random variation is set and we're in Shaded Materials mode
377 | int BerconXYZ::get(ShadeContext& sc, Point3& p) {
378 | return get(sc, p, variance?random(sc):tm);
379 | }
380 |
381 | // Map is in a bump map slot and we're rendering or in a Realistic Maps mode
382 | int BerconXYZ::get(ShadeContext& sc, Point3& p, Point3& dpdx, Point3& dpdy, Point3* basis) {
383 |
384 | if ((mappingType == 0 || mappingType == 1) && mode2D) {
385 | Matrix3 inv;
386 | Matrix3 transform = variance?random(sc, &inv):tm;
387 | if (!variance) inv = invNoScaleTm;
388 |
389 | if (!get(sc, p, dpdx, dpdy, transform)) {return FALSE;}
390 | Point3 dp[3];
391 |
392 | if (sc.BumpBasisVectors(dp, AXIS_UV, mappingChannel)) {
393 | basis[0] = VectorTransform(inv, dp[0]);
394 | basis[1] = VectorTransform(inv, dp[1]);
395 | basis[2] = VectorTransform(inv, dp[0]^dp[1]);
396 | } else {
397 | sc.DPdUVW(dp, mappingChannel);
398 | transform.Invert();
399 | basis[0] = VectorTransform(inv, dp[0]);
400 | basis[1] = VectorTransform(inv, dp[1]);
401 | basis[2] = VectorTransform(inv, dp[2]);
402 | }
403 | } else {
404 | Matrix3 transform = variance?random(sc):tm;
405 | if (!get(sc, p, dpdx, dpdy, transform)) {return FALSE;}
406 | if (variance)
407 | getBasis(transform, basis);
408 | else
409 | for (int i=0; i<3; i++)
410 | basis[i] = b[i];
411 | }
412 | return TRUE;
413 | }
414 |
415 | // Map is in a bump map slot and we're in Shaded Materials mode
416 | int BerconXYZ::get(ShadeContext& sc, Point3& p, Point3* basis) {
417 | /*int* flips = NULL;
418 | if (mappingType == 0) {
419 | flips = new int[3];
420 | flips[0]=0;flips[1]=0;flips[2]=0;
421 | }*/
422 |
423 | // BerconGradient + BerconTile are 2D maps, mode2D = TRUE
424 | if ((mappingType == 0 || mappingType == 1) && mode2D) {
425 | Matrix3 inv;
426 | Matrix3 transform = variance?random(sc, &inv):tm;
427 | if (!variance) inv = invNoScaleTm;
428 |
429 | if (!get(sc, p, transform)) {return FALSE;}
430 | Point3 dp[3];
431 |
432 | if (sc.BumpBasisVectors(dp, AXIS_UV, mappingChannel)) {
433 | basis[0] = VectorTransform(inv, dp[0]);
434 | basis[1] = VectorTransform(inv, dp[1]);
435 | basis[2] = VectorTransform(inv, dp[0]^dp[1]);
436 | } else {
437 | sc.DPdUVW(dp, mappingChannel);
438 | transform.Invert();
439 | basis[0] = VectorTransform(inv, dp[0]);
440 | basis[1] = VectorTransform(inv, dp[1]);
441 | basis[2] = VectorTransform(inv, dp[2]);
442 | }
443 |
444 | } else {
445 | Matrix3 transform = variance?random(sc):tm;
446 | if (!get(sc, p, transform)) {return FALSE;}
447 | if (variance)
448 | getBasis(transform, basis);
449 | else
450 | for (int i=0; i<3; i++)
451 | basis[i] = b[i];
452 | }
453 |
454 | return TRUE;
455 | }
456 |
457 | //CharStream *out = thread_local(current_stdout);
458 | //out->printf("Val: %d\n", mappingChannel);
--------------------------------------------------------------------------------
/src/perlin.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | // Based on Ken Perlin's perlin noise/simplex and Stefan Gustavson's
19 | // implementation of perlin/simplex noise, (Simplex)Noise1234
20 |
21 | #include "perlin.h"
22 |
23 | // Chart given by Ken Perlin, using the same to get identical results
24 | static unsigned char perm[] = {
25 | 151,160,137,91,90,15,
26 | 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
27 | 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
28 | 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
29 | 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
30 | 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
31 | 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
32 | 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
33 | 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
34 | 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
35 | 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
36 | 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
37 | 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
38 | 151,160,137,91,90,15,
39 | 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
40 | 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
41 | 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
42 | 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
43 | 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
44 | 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
45 | 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
46 | 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
47 | 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
48 | 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49 | 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
50 | 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
51 | };
52 |
53 | static unsigned char simplex[64][4] = {
54 | {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0},
55 | {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0},
56 | {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
57 | {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0},
58 | {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0},
59 | {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
60 | {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0},
61 | {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0}};
62 |
63 | float lerp2(float t, float a,float b) {return a+t*(b-a);}
64 |
65 | // #################### // Gradients \\ ####################
66 |
67 | float Perlin::grad( int hash, float x ) {
68 | int h = hash & 15;
69 | float grad = 1.0f + (h & 7);
70 | if (h&8) grad = -grad;
71 | return ( grad * x );
72 | }
73 |
74 | float Perlin::grad(int hash, float x, float y) {
75 | int h = hash & 7;
76 | float i = h<4 ? x : y;
77 | float j = h<4 ? y : x;
78 | return ((h&1)? -i : i) + ((h&2)? -2.f*j : 2.f*j);
79 | }
80 |
81 | float Perlin::grad(int hash, float x, float y, float z) {
82 | int h = hash & 15;
83 | float i = h<8 ? x : y;
84 | float j = h<4 ? y : h==12||h==14 ? x : z;
85 | return ((h&1) ? -i : i) + ((h&2) ? -j : j);
86 | }
87 |
88 | float Perlin::grad(int hash, float x, float y, float z, float w) {
89 | int h = hash & 31;
90 | float i = h<24 ? x : y;
91 | float j = h<16 ? y : z;
92 | float k = h<8 ? z : w;
93 | return ((h&1)? -i : i) + ((h&2)? -j : j) + ((h&4)? -k : k);
94 | }
95 |
96 | // #################### // Perlin \\ ####################
97 |
98 | float Perlin::noise(float x) {
99 | int ix0 = FASTFLOOR(x);
100 | int ix1 = (ix0+1) & 255;
101 | float xf0 = x - ix0;
102 | float xf1 = xf0 - 1.0f;
103 | ix0 = ix0 & 0xff; // Wrap to 0..255
104 | float s = FADE(xf0);
105 | return lerp2(s, grad(perm[ix0], xf0),
106 | grad(perm[ix1], xf1)) * 0.188f;
107 | }
108 |
109 | float Perlin::noise(float x, float y) {
110 | int xi = FASTFLOOR(x);
111 | int yi = FASTFLOOR(y);
112 | float xf0 = x - xi;
113 | float yf0 = y - yi;
114 | float xf1 = xf0 - 1.0f;
115 | float yf1 = yf0 - 1.0f;
116 | xi = xi & 255;
117 | yi = yi & 255;
118 | float i = FADE(xf0);
119 | float j = FADE(yf0);
120 | int A = perm[xi ] + yi;
121 | int B = perm[xi+1] + yi;
122 |
123 | return lerp2(j, lerp2(i, grad(perm[A ], xf0, yf0),
124 | grad(perm[B ], xf1, yf0)),
125 | lerp2(i, grad(perm[A+1], xf0, yf1),
126 | grad(perm[B+1], xf1, yf1))) * 0.507f;
127 | }
128 |
129 | float Perlin::noise(float x, float y, float z) {
130 | int xi = FASTFLOOR(x);
131 | int yi = FASTFLOOR(y);
132 | int zi = FASTFLOOR(z);
133 | float xf = x - (float)xi;
134 | float yf = y - (float)yi;
135 | float zf = z - (float)zi;
136 | xi = xi & 255;
137 | yi = yi & 255;
138 | zi = zi & 255;
139 | float i = FADE(xf);
140 | float j = FADE(yf);
141 | float k = FADE(zf);
142 | int A = perm[xi ]+yi, AA = perm[A]+zi, AB = perm[A+1]+zi;
143 | int B = perm[xi+1]+yi, BA = perm[B]+zi, BB = perm[B+1]+zi;
144 |
145 | return lerp2(k, lerp2(j, lerp2(i, grad(perm[AA ], xf , yf , zf ),
146 | grad(perm[BA ], xf-1, yf , zf )),
147 | lerp2(i, grad(perm[AB ], xf , yf-1, zf ),
148 | grad(perm[BB ], xf-1, yf-1, zf ))),
149 | lerp2(j, lerp2(i, grad(perm[AA+1], xf , yf , zf-1 ),
150 | grad(perm[BA+1], xf-1, yf , zf-1 )),
151 | lerp2(i, grad(perm[AB+1], xf , yf-1, zf-1 ),
152 | grad(perm[BB+1], xf-1, yf-1, zf-1 )))) * 0.936f;
153 | }
154 |
155 | float Perlin::noise(float x, float y, float z, float w) {
156 | int xi = FASTFLOOR(x);
157 | int yi = FASTFLOOR(y);
158 | int zi = FASTFLOOR(z);
159 | int wi = FASTFLOOR(w);
160 | float xf0 = x - xi;
161 | float yf0 = y - yi;
162 | float zf0 = z - zi;
163 | float wf0 = w - wi;
164 | float xf1 = xf0 - 1.0f;
165 | float yf1 = yf0 - 1.0f;
166 | float zf1 = zf0 - 1.0f;
167 | float wf1 = wf0 - 1.0f;
168 | xi = xi & 255;
169 | yi = yi & 255;
170 | zi = zi & 255;
171 | wi = wi & 255;
172 | float i = FADE(xf0);
173 | float j = FADE(yf0);
174 | float k = FADE(zf0);
175 | float l = FADE(wf0);
176 |
177 | int A = perm[xi] +yi, AA = perm[A] +zi, AAA = perm[AA] +wi,
178 | AAB = perm[AA+1]+wi,
179 | AB = perm[A+1]+zi, ABA = perm[AB] +wi,
180 | ABB = perm[AB+1]+wi;
181 | int B = perm[xi+1]+yi, BA = perm[B] +zi, BAA = perm[BA] +wi,
182 | BAB = perm[BA+1]+wi,
183 | BB = perm[B+1]+zi, BBA = perm[BB] +wi,
184 | BBB = perm[BB+1]+wi;
185 |
186 |
187 | float l1 = lerp2(i, grad(perm[AAA ], xf0, yf0, zf0, wf0), grad(perm[BAA ], xf1, yf0, zf0, wf0));
188 | float l2 = lerp2(i, grad(perm[ABA ], xf0, yf1, zf0, wf0), grad(perm[BBA ], xf1, yf1, zf0, wf0));
189 | float l3 = lerp2(i, grad(perm[AAB ], xf0, yf0, zf1, wf0), grad(perm[BAB ], xf1, yf0, zf1, wf0));
190 | float l4 = lerp2(i, grad(perm[ABB ], xf0, yf1, zf1, wf0), grad(perm[BBB ], xf1, yf1, zf1, wf0));
191 | float l5 = lerp2(i, grad(perm[AAA+1], xf0, yf0, zf0, wf1), grad(perm[BAA+1], xf1, yf0, zf0, wf1));
192 | float l6 = lerp2(i, grad(perm[ABA+1], xf0, yf1, zf0, wf1), grad(perm[BBA+1], xf1, yf1, zf0, wf1));
193 | float l7 = lerp2(i, grad(perm[AAB+1], xf0, yf0, zf1, wf1), grad(perm[BAB+1], xf1, yf0, zf1, wf1));
194 | float l8 = lerp2(i, grad(perm[ABB+1], xf0, yf1, zf1, wf1), grad(perm[BBB+1], xf1, yf1, zf1, wf1));
195 |
196 | l1 = lerp2(j, l1, l2);
197 | l2 = lerp2(j, l3, l4);
198 | l3 = lerp2(j, l5, l6);
199 | l4 = lerp2(j, l7, l8);
200 |
201 | l1 = lerp2(k, l1, l2);
202 | l2 = lerp2(k, l3, l4);
203 |
204 | return lerp2(l, l1, l2) * 0.87f;
205 | }
206 |
207 | // #################### // Simplex points \\ ####################
208 |
209 | inline float Perlin::point(float x, int i) {
210 | float t = 1.0f - x*x;
211 | t *= t;
212 | return t * t * grad(perm[i & 255], x);
213 | }
214 |
215 | inline float Perlin::point(float x, float y, int i, int j) {
216 | float t = 0.5f - x*x - y*y;
217 | if(t < 0.0f)
218 | return 0.0f;
219 | t *= t;
220 | return t * t * grad(perm[i+perm[j]], x, y);
221 | }
222 |
223 | inline float Perlin::point(float x, float y, float z, int i, int j, int k) {
224 | float t = 0.6f - x*x - y*y - z*z;
225 | if(t < 0.0f)
226 | return 0.0f;
227 | t *= t;
228 | return t * t * grad(perm[i+perm[j+perm[k]]], x, y, z);
229 | }
230 |
231 | inline float Perlin::point(float x, float y, float z, float w, int i, int j, int k, int l) {
232 | float t = 0.6f - x*x - y*y - z*z - w*w;
233 | if(t < 0.0f)
234 | return 0.0f;
235 | t *= t;
236 | return t * t * grad(perm[i+perm[j+perm[k+perm[l]]]], x, y, z, w);
237 | }
238 |
239 | // #################### // Simplex \\ ####################
240 |
241 | float Perlin::snoise(float x) {
242 | int i0 = FASTFLOOR(x);
243 | int i1 = i0 + 1;
244 | float x0 = x - i0;
245 | float x1 = x0 - 1.0f;
246 | return (1.f/2.53125f) * (point(x0, i0) + point(x1, i1));
247 | }
248 |
249 | float Perlin::snoise(float x, float y) {
250 |
251 | #define F2 0.366025403f // F2 = 0.5*(sqrt(3.0)-1.0)
252 | #define G2 0.211324865f // G2 = (3.0-Math.sqrt(3.0))/6.0
253 |
254 | float s = (x+y)*F2;
255 | float xs = x + s;
256 | float ys = y + s;
257 | int i = FASTFLOOR(xs);
258 | int j = FASTFLOOR(ys);
259 |
260 | float t = (float)(i+j)*G2;
261 | float X0 = i-t;
262 | float Y0 = j-t;
263 | float x0 = x-X0;
264 | float y0 = y-Y0;
265 |
266 | int i1, j1;
267 | if(x0>y0) {i1=1; j1=0;}
268 | else {i1=0; j1=1;}
269 |
270 | float x1 = x0 - i1 + G2, x2 = x0 - 1.0f + 2.0f * G2;
271 | float y1 = y0 - j1 + G2, y2 = y0 - 1.0f + 2.0f * G2;
272 |
273 | int ii = i & 0xff;
274 | int jj = j & 0xff;
275 |
276 | return 40.0f * (point(x0, y0, ii, jj) +
277 | point(x1, y1, ii+i1, jj+j1) +
278 | point(x2, y2, ii+1, jj+1));
279 | }
280 |
281 | float Perlin::snoise(float x, float y, float z) {
282 |
283 | #define F3 0.333333333f
284 | #define G3 0.166666667f
285 | #define G3a (2.0f * G3)
286 | #define G3b (3.0f * G3 - 1.0f)
287 |
288 | float s = (x+y+z)*F3;
289 | float xs = x+s;
290 | float ys = y+s;
291 | float zs = z+s;
292 | int i = FASTFLOOR(xs);
293 | int j = FASTFLOOR(ys);
294 | int k = FASTFLOOR(zs);
295 |
296 | float t = (float)(i+j+k)*G3;
297 | float X0 = i-t;
298 | float Y0 = j-t;
299 | float Z0 = k-t;
300 | float x0 = x-X0;
301 | float y0 = y-Y0;
302 | float z0 = z-Z0;
303 |
304 | int i1, j1, k1;
305 | int i2, j2, k2;
306 |
307 | if(x0>=y0) {
308 | if(y0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; }
309 | else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; }
310 | else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; }
311 | } else {
312 | if(y0 y0) ? 32 : 0;
361 | int c2 = (x0 > z0) ? 16 : 0;
362 | int c3 = (y0 > z0) ? 8 : 0;
363 | int c4 = (x0 > w0) ? 4 : 0;
364 | int c5 = (y0 > w0) ? 2 : 0;
365 | int c6 = (z0 > w0) ? 1 : 0;
366 | int c = c1 + c2 + c3 + c4 + c5 + c6;
367 |
368 | int i1, j1, k1, l1;
369 | int i2, j2, k2, l2;
370 | int i3, j3, k3, l3;
371 |
372 | i1 = simplex[c][0]>=3 ? 1 : 0; i2 = simplex[c][0]>=2 ? 1 : 0; i3 = simplex[c][0]>=1 ? 1 : 0;
373 | j1 = simplex[c][1]>=3 ? 1 : 0; j2 = simplex[c][1]>=2 ? 1 : 0; j3 = simplex[c][1]>=1 ? 1 : 0;
374 | k1 = simplex[c][2]>=3 ? 1 : 0; k2 = simplex[c][2]>=2 ? 1 : 0; k3 = simplex[c][2]>=1 ? 1 : 0;
375 | l1 = simplex[c][3]>=3 ? 1 : 0; l2 = simplex[c][3]>=2 ? 1 : 0; l3 = simplex[c][3]>=1 ? 1 : 0;
376 |
377 | float x1 = x0 - i1 + G4, x2 = x0 - i2 + G4a, x3 = x0 - i3 + G4b, x4 = x0 + G4c;
378 | float y1 = y0 - j1 + G4, y2 = y0 - j2 + G4a, y3 = y0 - j3 + G4b, y4 = y0 + G4c;
379 | float z1 = z0 - k1 + G4, z2 = z0 - k2 + G4a, z3 = z0 - k3 + G4b, z4 = z0 + G4c;
380 | float w1 = w0 - l1 + G4, w2 = w0 - l2 + G4a, w3 = w0 - l3 + G4b, w4 = w0 + G4c;
381 |
382 | int ii = i & 0xff;
383 | int jj = j & 0xff;
384 | int kk = k & 0xff;
385 | int ll = l & 0xff;
386 |
387 | return 27.0f * (point(x0, y0, z0, w0, ii, jj, kk, ll) +
388 | point(x1, y1, z1, w1, ii+i1, jj+j1, kk+k1, ll+l1) +
389 | point(x2, y2, z2, w2, ii+i2, jj+j2, kk+k2, ll+l2) +
390 | point(x3, y3, z3, w3, ii+i3, jj+j3, kk+k3, ll+l3) +
391 | point(x4, y4, z4, w4, ii+1, jj+1, kk+1, ll+1));
392 | }
393 |
394 | /*
395 | Filtered functions, simply add the fading functinality once the size of the sampled
396 | area becomes larger than the details.
397 | */
398 |
399 | #define FILTDIV 1.2f
400 | #define FILTSTART 1.2f
401 | #define FILTEND 2.2f
402 |
403 | #define FILTER(d) d = smooth(d / FILTDIV, FILTSTART, FILTEND); \
404 | if (d >= .9999f) return 0.f;
405 |
406 | float Perlin::fnoise2D(float x, float y, float d) {
407 | FILTER(d)
408 | return lerp2(d, noise(x,y), 0.f);
409 | }
410 |
411 | float Perlin::fnoise3D(float x, float y, float z, float d) {
412 | FILTER(d)
413 | return lerp2(d, noise(x,y,z), 0.f);
414 | }
415 |
416 | float Perlin::fnoise4D(float x, float y, float z, float w, float d) {
417 | FILTER(d)
418 | return lerp2(d, noise(x,y,z,w), 0.f);
419 | }
420 |
421 | float Perlin::fsnoise2D(float x, float y, float d) {
422 | FILTER(d)
423 | return lerp2(d, snoise(x,y), 0.f);
424 | }
425 |
426 | float Perlin::fsnoise3D(float x, float y, float z, float d) {
427 | FILTER(d)
428 | return lerp2(d, snoise(x,y,z), 0.f);
429 | }
430 |
431 | float Perlin::fsnoise4D(float x, float y, float z, float w, float d) {
432 | FILTER(d)
433 | return lerp2(d, snoise(x,y,z,w), 0.f);
434 | }
--------------------------------------------------------------------------------
/src/GradientRamp.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | /*
19 |
20 | #include "Max.h"
21 | #include "resource.h"
22 | #include "plugapi.h"
23 | #include "3dsmaxport.h"
24 |
25 | #include "maxscrpt/MAXScrpt.h"*/
26 |
27 | #include "GradientRamp.h"
28 |
29 |
30 | void GradientRamp::setHWND(HWND hWnd) {
31 | m_hWnd = hWnd;
32 | RECT rect;
33 | GetWindowRect(m_hWnd, &rect);
34 | width = rect.right - rect.left;
35 | height = rect.bottom - rect.top;
36 | }
37 |
38 | // #############################################################################################
39 | // #################################/ Paint \################################
40 | // #############################################################################################
41 |
42 | void GradientRamp::paint(HDC hDC) {
43 | if (m_hWnd == NULL) return;
44 | //SetBkMode(hDC, TRANSPARENT);
45 |
46 | //RECT rect;
47 | //GetClientRect(m_hWnd, &rect);
48 |
49 | /*SelectObject(hdc,red_pen);
50 | MoveToEx(hdc,10,20,NULL);
51 | LineTo(hdc,10,40,NULL);
52 | LineTo(hdc,50,150,NULL);*/
53 | /*
54 | int width = rect.right - rect.left;
55 | int height = rect.top - rect.bottom;
56 |
57 | RECT rect2;
58 | GetWindowRect(m_hWnd, &rect2);
59 |
60 | CharStream *out = thread_local(current_stdout);
61 | out->printf("Rectangle: %d %d %d %d\n", rect.left, rect.right, rect.top, rect.bottom);
62 | out->printf("Rectangle2: %d %d %d %d\n", (int)(rect2.left, (int)(rect2.right), (int)(rect2.top), (int)(rect2.bottom));
63 | */
64 |
65 | HDC tempHDC = CreateCompatibleDC(hDC);
66 | HBITMAP hbm_Buffer = CreateCompatibleBitmap(hDC, width, height);
67 | HBITMAP hbm_oldBuffer = (HBITMAP)SelectObject(tempHDC, hbm_Buffer);
68 |
69 | // Borders
70 | RECT rect;
71 | HBRUSH gray = CreateSolidBrush(RGB(175,175,175));
72 | rect.left = 0; rect.top = 0; rect.right = width; rect.bottom = PADDING;
73 | FillRect(tempHDC,&rect,gray);
74 | rect.right = PADDING; rect.bottom = height;
75 | FillRect(tempHDC,&rect,gray);
76 | rect.left = width-PADDING; rect.right = width;
77 | FillRect(tempHDC,&rect,gray);
78 | rect.left = 0; rect.top = height-PADDING;
79 | FillRect(tempHDC,&rect,gray);
80 |
81 | int g_Width = width - PADDING * 2;
82 | int g_Height = height - PADDING *2;
83 | float f_Width = (float)g_Width;
84 |
85 | // Gradient
86 | for (int x=PADDING; xprintf("Key pos: %f\n", position[i]);
101 | if (number[i] != selected) {
102 | int x = (int)(f_Width * position[i]) + PADDING;
103 | paintArrow(x, yTop, false, tempHDC, ARROWDESEL);
104 | paintArrow(x, yBottom, true, tempHDC, ARROWDESEL);
105 | } else {
106 | sel = i;
107 | }
108 | }
109 | if (sel != -1) {
110 | paintArrow((int)(f_Width * position[sel]) + PADDING, yTop, false, tempHDC, ARROWSEL);
111 | paintArrow((int)(f_Width * position[sel]) + PADDING, yBottom, true, tempHDC, ARROWSEL);
112 | }
113 |
114 | //GetClientRect(m_hWnd, &rect);
115 | BitBlt(hDC, 0, 0, width, height, tempHDC, 0, 0, SRCCOPY);
116 | //BitBlt(hDC, rect.left, rect.top, rect.right, rect.bottom, tempHDC, 0, 0, SRCCOPY);
117 |
118 | SelectObject(tempHDC, hbm_oldBuffer);
119 | DeleteDC(tempHDC);
120 | DeleteObject(hbm_Buffer);
121 | }
122 |
123 | void GradientRamp::paintArrow(int px, int py, bool up, HDC hDC, COLORREF colR) {
124 | int offset = 0;
125 | for (int y=0;y width - PADDING)
152 | pos = 1.f;
153 | else if (x > PADDING)
154 | pos = (float)(x - PADDING) / (float)(width - PADDING * 2);
155 | return pos;
156 | }
157 |
158 | int GradientRamp::toIndex(int n) {
159 | for (int i=0;i PADDING && y < (height - PADDING) && !broad)
170 | return -1;
171 |
172 | // Distance from gradient
173 | int dist = 0;
174 | if (broad)
175 | dist = ARROWS;
176 | else if (y < PADDING)
177 | dist = PADDING - y;
178 | else
179 | dist = y - height + PADDING;
180 |
181 | //CharStream *out = thread_local(current_stdout);
182 | // Intersect all keys
183 | float f_Width = (float)(width - PADDING * 2);
184 | for (int i=0;iprintf("Hit key: %d %d %d\n", x-dist, x+dist, x);
187 | if (kx-dist <= x && kx+dist >= x)
188 | return i;
189 | }
190 |
191 | // No keys found
192 | return -1;
193 | }
194 |
195 | void GradientRamp::leftDown(int x, int y, bool ctrl, bool shift, bool alt) {
196 | int key = hit(x,y,true);
197 |
198 | //CharStream *out = thread_local(current_stdout);
199 | //out->printf("Hit key: %d %d\n", key, selected);
200 | //out->printf("Left down\n");
201 |
202 | if (!alt && key >= 0) {
203 | selectKey(number[key]);
204 | } else if (key == -1) {
205 | selectKey(-1);
206 | }
207 |
208 | //out->printf("Selected key: %d\n", selected);
209 | //out->printf("## Seletion DONE! ##\n", selected);
210 | }
211 |
212 | void GradientRamp::leftUp(int x, int y, bool ctrl, bool shift, bool alt) {
213 | int key = hit(x,y);
214 | if (alt && key == -1) {
215 | parent->gradAddKey(toPos(x));
216 | selected = keys - 1; // New key gets the last id
217 | parent->gradSelKey();
218 |
219 | //CharStream *out = thread_local(current_stdout);
220 | //out->printf("Key added!\n");
221 |
222 | } else if (alt && key >= 0) {
223 | if (selected == number[key]) selected = -1;
224 | parent->gradDelKey(number[key]);
225 | }
226 | }
227 |
228 | void GradientRamp::dragging(int x, int y, bool ctrl, bool shift, bool alt) {
229 | if (selected <= 1) // Refuse to move ends and empty
230 | return;
231 | if (selected < keys)
232 | parent->gradMoveKey(selected, toPos(x));
233 | //CharStream *out = thread_local(current_stdout);
234 | //out->printf("Move key: %d %f\n", number[selected], pos);
235 | }
236 |
237 | void GradientRamp::popup(int x, int y, int sel) {
238 | int key = hit(x,y,true);
239 | switch (sel) {
240 | case ID_MENU_ADDKEY:
241 | if (key == -1) {
242 | parent->gradAddKey(toPos(x));
243 | selected = keys - 1; // New key gets the last id
244 | parent->gradSelKey();
245 | }
246 | break;
247 | case ID_MENU_REMOVEKEY:
248 | if (key >= 0) {
249 | if (selected == number[key]) selected = -1;
250 | parent->gradDelKey(number[key]);
251 | } else if (selected >= 0) {
252 | int k = selected;
253 | selected = -1;
254 | parent->gradDelKey(k);
255 | }
256 | break;
257 | case ID_RESET_RESET:
258 | selected = -1;
259 | parent->gradReset();
260 | break;
261 | }
262 | }
263 |
264 |
265 | // #############################################################################################
266 | // #################################/ Keys \################################
267 | // #############################################################################################
268 |
269 | void GradientRamp::selectKey(int n) {
270 | selected = n;
271 | //CharStream *out = thread_local(current_stdout);
272 | //out->printf("Selection sent (%d)\n", selected);
273 | parent->gradSelKey();
274 | //out->printf("Invalidate\n");
275 | //invalidate();
276 | }
277 |
278 | /*
279 | // n is the number of the key
280 | void GradientRamp::moveKey(int n, float pos) {
281 | if (n == 0 || n == 1) // Refuse to move ends
282 | return;
283 |
284 | for (int i=0;imoveKey(n, pos);
293 | }
294 | */
295 |
296 | void GradientRamp::addKey(int n, float pos, AColor col, Texmap* sub) {
297 | if (pos < 0.f) pos = 0.f;
298 | else if (pos > 1.f) pos = 1.f;
299 |
300 | int key = -1;
301 | for (int i=0;i= 0) { // update only, no keys added
306 | subtex[key] = sub;
307 | position[key] = pos;
308 | color[key] = col;
309 | return;
310 | }
311 |
312 | keys++;
313 | Texmap** t_subtex = new Texmap*[keys];
314 | float* t_position = new float[keys];
315 | AColor* t_color = new AColor[keys];
316 | int* t_number = new int[keys];
317 | keys--;
318 |
319 | for (int i=0;i position[i]) {
399 | swap(i - 1, i);
400 | swapped = true;
401 | }
402 | }
403 | } while (swapped);
404 | } */
405 |
406 | // #############################################################################################
407 | // #################################/ Subtex \################################
408 | // #############################################################################################
409 |
410 | Texmap* GradientRamp::getSubtex(int n) {
411 | if (n == -1)
412 | if (selected >= 0 && selected < keys)
413 | return subtex[toIndex(selected)];
414 | else
415 | return NULL;
416 | else
417 | return subtex[toIndex(n)];
418 | }
419 |
420 |
421 | void GradientRamp::setSubtex(int n, Texmap* sub) {
422 | subtex[toIndex(n)] = sub;
423 | }
424 |
425 | void GradientRamp::setSubtex(Texmap* sub) {
426 | if (selected >= 0 && selected < keys)
427 | setSubtex(selected, sub);
428 | }
429 |
430 | // #############################################################################################
431 | // #################################/ Color \################################
432 | // #############################################################################################
433 |
434 | // Linear Search
435 | // O(N)
436 | /*
437 | int GradientRamp::findHighKey(float x) {
438 | int high = 1; // Always 2 keys so we start from key number two since they are ordered by position
439 | while (x > position[high]) {
440 | high++;
441 | if (high >= keys)
442 | return (keys - 1);
443 | }
444 | return high;
445 | }
446 | */
447 |
448 | // More intelligent search
449 | // O(log N)
450 | int GradientRamp::findHighKey(float x) {
451 | int low = 0;
452 | int high = keys-1;
453 | int mid;
454 | if (x < position[low])
455 | return low;
456 | while (low < (high-1)) {
457 | mid = (low + high) / 2;
458 | if (x < position[mid])
459 | high = mid;
460 | else
461 | low = mid;
462 | }
463 | return high;
464 | }
465 |
466 | float GradientRamp::interpolate(float x, float low, float high) {
467 | //int interpolation; // 0 linear 1 smooth 2 solid near 3 solid left 4 solid right
468 | switch (interpolation) {
469 | case 0:
470 | return (x - low) / (high - low);
471 | case 1:
472 | x = (x-low)/(high-low);
473 | if (x < 0.f) x = 0.f;
474 | else if (x > 1.f) x = 1.f;
475 | return (x*x*(3.f-2.f*x));
476 | }
477 | return 0.f;
478 | }
479 |
480 | AColor GradientRamp::getColor(float x) {
481 | if (x<=0) return color[0];
482 | if (x>=1) return color[keys-1];
483 | int high = findHighKey(x);
484 | if (interpolation == 4) return color[high];
485 | int low = (high > 0 ? high - 1 : 0); // should never happen but just in case
486 | if (interpolation == 3) return color[low];
487 | if (interpolation == 2) return color[x-position[low]EvalColor(sc):color[0];
494 | if (x>=1) return subtex[keys-1]?subtex[keys-1]->EvalColor(sc):color[keys-1];
495 | int high = findHighKey(x);
496 | if (interpolation == 4) return subtex[high]?subtex[high]->EvalColor(sc):color[high];
497 | int low = (high > 0 ? high - 1 : 0); // should never happen but just in case
498 | if (interpolation == 3) return subtex[low]?subtex[low]->EvalColor(sc):color[low];
499 | if (interpolation == 2) {
500 | int key = x-position[low]EvalColor(sc):color[key];
502 | }
503 | float mult = interpolate(x, position[low], position[high]);
504 | return (subtex[low]?subtex[low]->EvalColor(sc):color[low])
505 | * (1.f - mult) + (subtex[high]?subtex[high]->EvalColor(sc):color[high]) * mult;
506 | }
507 |
508 | #define NOBUMP Point3(0.f,0.f,0.f)
509 | Point3 GradientRamp::getBump(float x, Point3 normal, ShadeContext& sc) {
510 | if (x<=0) return subtex[0]?subtex[0]->EvalNormalPerturb(sc):NOBUMP;
511 | if (x>=1) return subtex[keys-1]?subtex[keys-1]->EvalNormalPerturb(sc):NOBUMP;
512 | int high = findHighKey(x);
513 | if (interpolation == 4) return subtex[high]?subtex[high]->EvalNormalPerturb(sc):NOBUMP;
514 | int low = high - 1;
515 | if (interpolation == 3) return subtex[low]?subtex[low]->EvalNormalPerturb(sc):NOBUMP;
516 | if (interpolation == 2) {
517 | int key = x-position[low]EvalNormalPerturb(sc):NOBUMP;
519 | }
520 |
521 | //float f1, f2;
522 | Point3 v1, v2;
523 | bool maps = false;
524 | if (subtex[0]) {
525 | //f1 = subtex[low]->EvalMono(sc);
526 | v1 = subtex[low]->EvalNormalPerturb(sc);
527 | maps = true;
528 | } else {
529 | //f1 = Intens(color[low]);
530 | v1 = Point3(0.f, 0.f, 0.f);
531 | }
532 | if (subtex[1]) {
533 | //f2 = subtex[high]->EvalMono(sc);
534 | v2 = subtex[high]->EvalNormalPerturb(sc);
535 | maps = true;
536 | } else {
537 | //f2 = Intens(color[high]);
538 | v2 = Point3(0.f, 0.f, 0.f);
539 | }
540 |
541 | // Calculate vector
542 | if (maps) {
543 | float mult = interpolate(x, position[low], position[high]);
544 | v1 = /*(f2-f1)**/ normal + mult*v2 + (1.f-mult)*v1;
545 | } else {
546 | v1 = normal; // * (f2 - f1);
547 | }
548 |
549 | return v1;
550 | }
551 |
--------------------------------------------------------------------------------
/src/tile.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Licensed to the Apache Software Foundation (ASF) under one
3 | or more contributor license agreements. The ASF licenses this
4 | file to you under the Apache License, Version 2.0 (the
5 | "License"); you may not use this file except in compliance
6 | with the License. You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing,
11 | software distributed under the License is distributed on an
12 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13 | KIND, either express or implied. See the License for the
14 | specific language governing permissions and limitations
15 | under the License.
16 | */
17 |
18 | #include "tile.h"
19 | #include "perlin.h"
20 |
21 | inline static int generateID(int x, int y) { return (y-101) * 1000 + x; }
22 |
23 | inline static float noise(float x, float rand) { return Perlin::snoise(x * 31.4 + rand); }
24 |
25 | inline static int STEPUP(int n, int m) {
26 | return (n + 1) % m;
27 | }
28 |
29 | inline static void rotate90(float& x, float& y) { float temp = y; y = x; x = -temp; }
30 | inline static void rotate270(float& x, float& y) { float temp = x; x = y; y = -temp; }
31 |
32 | inline static int STEPDOWN(int n, int m) {
33 | if (n-1 < 0) return m-1;
34 | return n-1;
35 | }
36 |
37 |
38 | float Tile::edgeBlur(float d, float r, int type) {
39 | switch (type) {
40 | case 1: return d/r; // Linear
41 | case 2: // Cubic
42 | d = 1.f - (d/r);
43 | return sqrt(1-d*d);
44 | case 3: return smooth(d, 0.f, r); // Smooth
45 | default: return 1.f;
46 | }
47 | }
48 |
49 | TilePoint Tile::corner(float rX, float rY, float w, float h, TileParam& t) {
50 | // Evaluate maps
51 | if (t.tileRound) {
52 | bool inCorner = false;
53 | float cX=0.0f, cY=0.0f;
54 | // Detect corner
55 | if (rX < t.tileCrnrRad) {
56 | if (rY < t.tileCrnrRad) { // Bottom left
57 | cX = t.tileCrnrRad - rX;
58 | cY = t.tileCrnrRad - rY;
59 | inCorner = true;
60 | } else if (rY > h - t.tileCrnrRad) { // Top left
61 | cX = t.tileCrnrRad - rX;
62 | cY = h - rY - t.tileCrnrRad;
63 | inCorner = true;
64 | }
65 | } else if (rX > w - t.tileCrnrRad) {
66 | if (rY < t.tileCrnrRad) { // Bottom right
67 | cX = w - rX - t.tileCrnrRad;
68 | cY = t.tileCrnrRad - rY;
69 | inCorner = true;
70 | } else if (rY > h - t.tileCrnrRad) { // Top right
71 | cX = w - rX - t.tileCrnrRad;
72 | cY = h - rY - t.tileCrnrRad;
73 | inCorner = true;
74 | }
75 | }
76 | float d = cY*cY + cX*cX;
77 | if (inCorner) {
78 | if (d > t.tileCrnrRad*t.tileCrnrRad)
79 | return TilePoint();
80 | // Calculate corner blur
81 | d = t.tileCrnrRad - sqrt(d);
82 | if (t.tileBlur > 0 && d w - t.tileBlurRad) {
94 | dX = w - rX;
95 | inCorner = true;
96 | }
97 | // Distance to horizontal walls
98 | if (rY < t.tileBlurRad) {
99 | inCorner = true;
100 | } else if (rY > h - t.tileBlurRad) {
101 | dY = h - rY;
102 | inCorner = true;
103 | }
104 | if (inCorner)
105 | return dX 0 ? -angle : angle, HALFPI) + QUATPI);
209 | scaleX *= scale;
210 | scaleY *= scale;
211 | }
212 |
213 | // Apply auto scale
214 | if (t.autoScale) {
215 | uvw.x /= scaleX;
216 | uvw.y /= scaleY;
217 | }
218 |
219 | // Flip
220 | if (t.flipX) if (rand() % 2) uvw.x = -uvw.x;
221 | if (t.flipY) if (rand() % 2) uvw.y = -uvw.y;
222 |
223 | // Random scale
224 | if (t.randScale) {
225 | if (t.lock) {
226 | float s = 1.f + SFRAND() * t.randSX;
227 | scaleX = s;
228 | scaleY = s;
229 | } else {
230 | scaleX = 1.f + SFRAND() * t.randSX;
231 | scaleY = 1.f + SFRAND() * t.randSY;
232 | }
233 |
234 | if (scaleX < 0) scaleX = 0.f;
235 | if (scaleY < 0) scaleY = 0.f;
236 |
237 | uvw.x /= scaleX;
238 | uvw.y /= scaleY;
239 | }
240 |
241 | // Offset
242 | if (t.randOffset) {
243 | uvw.x += UFRAND() * t.randX;
244 | uvw.y += UFRAND() * t.randY;
245 | }
246 |
247 | // Rotate
248 | if (t.rotUV)
249 | rotatePoint2(uvw, angle);
250 |
251 | // Offset to 0..1
252 | if (t.autoScale) {
253 | uvw.x += .5f;
254 | uvw.y += .5f;
255 | }
256 |
257 | // Return
258 | tp.uvw = uvw;
259 | }
260 |
261 | // All parameters are in world space (p,edges,width,height)
262 | // edges = left top right down
263 |
264 | static void offsetEdges(float edges[4], float x, float y) {
265 | edges[0] += x;
266 | edges[2] += x;
267 | edges[3] += y;
268 | edges[1] += y;
269 | }
270 |
271 | TilePoint Tile::drawTile(Point3 p, float edges[4], TileParam& t, int id, int dir) {
272 | float hEdgeW = t.edgeWidth * .5f;
273 | float hEdgeH = t.edgeHeight * .5f;
274 |
275 | float randomSeed = (float)id * 1.23f + 0.1234f;
276 | if (dir) {
277 | edges[0] += t.eH_var ? hEdgeH * (1.f + noise(edges[0], randomSeed) * t.edgeHeightVar) : hEdgeH;
278 | edges[2] -= t.eH_var ? hEdgeH * (1.f + noise(edges[2], randomSeed) * t.edgeHeightVar) : hEdgeH;
279 | edges[3] += t.eW_var ? hEdgeW * (1.f + noise(edges[3], randomSeed) * t.edgeWidthVar) : hEdgeW;
280 | edges[1] -= t.eW_var ? hEdgeW * (1.f + noise(edges[1], randomSeed) * t.edgeWidthVar) : hEdgeW;
281 | } else {
282 | edges[0] += t.eW_var ? hEdgeW * (1.f + noise(edges[0], randomSeed) * t.edgeWidthVar) : hEdgeW;
283 | edges[2] -= t.eW_var ? hEdgeW * (1.f + noise(edges[2], randomSeed) * t.edgeWidthVar) : hEdgeW;
284 | edges[3] += t.eH_var ? hEdgeH * (1.f + noise(edges[3], randomSeed) * t.edgeHeightVar) : hEdgeH;
285 | edges[1] -= t.eH_var ? hEdgeH * (1.f + noise(edges[1], randomSeed) * t.edgeHeightVar) : hEdgeH;
286 | }
287 |
288 | if (p.x < edges[0]) return TilePoint();
289 | if (p.x > edges[2]) return TilePoint();
290 | if (p.y < edges[3]) return TilePoint();
291 | if (p.y > edges[1]) return TilePoint();
292 |
293 | float width = edges[2] - edges[0];
294 | float height = edges[1] - edges[3];
295 | if (width < 0 || height < 0) return TilePoint();
296 |
297 | TilePoint tp = corner(p.x - edges[0], p.y - edges[3], width, height, t);
298 | if (tp.d < 0) return tp; // On edge
299 |
300 | //if (t.tileID || t.mapUV)
301 | tp.id = id;
302 |
303 | if (t.center || (t.mapUV && dir))
304 | tp.center = Point3(edges[0] + (edges[2] - edges[0]) * .5f,
305 | edges[3] + (edges[1] - edges[3]) * .5f, p.z);
306 |
307 | if (dir) {
308 | offsetEdges(edges, -tp.center.x, -tp.center.y);
309 | rotate90(edges[0], edges[3]);
310 | rotate90(edges[2], edges[1]);
311 | offsetEdges(edges, tp.center.x, tp.center.y);
312 | p -= tp.center; rotate90(p.x, p.y); p += tp.center;
313 | }
314 |
315 | if (t.mapUV)
316 | uvMapping(tp, p, edges, t, dir);
317 |
318 | if (dir) {
319 | offsetEdges(edges, -tp.center.x, -tp.center.y);
320 | rotate270(edges[0], edges[3]);
321 | rotate270(edges[2], edges[1]);
322 | offsetEdges(edges, tp.center.x, tp.center.y);
323 | p -= tp.center; rotate270(p.x, p.y); p += tp.center;
324 | }
325 |
326 | return tp;
327 | }
328 |
329 | static int rowcol(float& low, float& high, int& id, float pos, float total, std::vector& arr, float size, float var, float rand) {
330 | int num = int(arr.size());
331 | float h = total * size;
332 | float y = pos / h;
333 | float yi = (float)FASTFLOOR(y); // group ID
334 | y = pos - yi * h; // pos within group
335 |
336 | float sumY = 0.f;
337 | float tileHeight = 0.f;
338 | int cur = 0;
339 | while (cur < num) {
340 | tileHeight = arr[cur] * size;
341 | if (y < sumY + tileHeight)
342 | break;
343 | sumY += tileHeight;
344 | cur++;
345 | }
346 | if (cur < 0 || cur >= num) // Necessary due floating point error
347 | return -1;
348 |
349 | id = yi * num + cur;
350 |
351 | // Variance
352 | // ----------- To determine max var
353 | // ----------- If we rose
354 | // ----------- eTop -> neTop
355 | // x
356 | // ----------- eBot -> neBot
357 | // ----------- If we droped
358 | // ----------- To determine max var
359 |
360 | float eBot = yi * h + sumY;
361 | float eTop = eBot + tileHeight;
362 |
363 | if (var > 0.0001f) {
364 | float n;
365 |
366 | float bTileHeight = arr[STEPDOWN(cur, num)]*size;
367 | float tTileHeight = arr[STEPUP(cur, num)]*size;
368 |
369 | n = noise(eBot, rand);
370 | float neBot = eBot + (n>0 ? tileHeight : bTileHeight) * n * var;
371 | n = noise(eTop, rand);
372 | float neTop = eTop + (n<0 ? tileHeight : tTileHeight) * n * var;
373 |
374 | if (pos < neBot) { // We droped one cur down
375 | id--;
376 | cur = STEPDOWN(cur, num);
377 | low = eBot-bTileHeight;
378 | n = noise(low, rand);
379 | low += (n>0 ? bTileHeight : arr[STEPDOWN(cur, num)]*size) * n * var;
380 | high = neBot;
381 |
382 | } else if (pos > neTop) { // We rose one cur up
383 | id++;
384 | cur = STEPUP(cur, num);
385 | high = eTop+tTileHeight;
386 | n = noise(high, rand);
387 | high += (n<0 ? tTileHeight : arr[STEPUP(cur, num)]*size) * n * var;
388 | low = neTop;
389 |
390 | } else { // Still in the same cur
391 | low = neBot;
392 | high = neTop;
393 | }
394 | } else {
395 | low = eBot;
396 | high = eTop;
397 | }
398 |
399 | return cur;
400 | }
401 |
402 | TilePoint Tile::pat_xBond(Point3 p, TileParam& t) {
403 | TilePattern* pat = t.pattern;
404 |
405 | if (!pat) return TilePoint();
406 |
407 | float edges[4];
408 | int id = 0;
409 | int id2 = 0;
410 |
411 | // Tile top and bottom
412 | float rand = 3.14f;
413 | int row = rowcol(edges[3], edges[1], id, p.y, pat->totalHeight, pat->heights, t.tileHeight, t.tileHeightVar, rand);
414 | if (row == -1) return TilePoint();
415 |
416 | // Tile sides
417 | rand = edges[3] * 1.325f + 31.41213f;
418 | float offset = pat->rows[row].offset * t.tileWidth;
419 | if (offset < 0) offset *= -id;
420 |
421 | row = rowcol(edges[0], edges[2], id2, p.x + offset, pat->rows[row].totalWidth, pat->rows[row].tiles, t.tileWidth, t.tileWidthVar, rand);
422 | if (row == -1) return TilePoint();
423 |
424 | edges[0] -= offset;
425 | edges[2] -= offset;
426 |
427 | id = generateID(id2, id);
428 |
429 | // Draw it
430 | return drawTile(p, edges, t, id);
431 | }
432 |
433 | static unsigned char pat_herring_dir[] = {
434 | 0, 0, 1, 1,
435 | 0, 1, 1, 0,
436 | 1, 1, 0, 0,
437 | 1, 0, 0, 1
438 | };
439 |
440 | static float pat_herring_x[] = {
441 | 1.0f, 1.0f, 2.5f, 3.5f,
442 | 0.0f, 1.5f, 2.5f, 4.0f,
443 | 0.5f, 1.5f, 3.0f, 3.0f,
444 | 0.5f, 2.0f, 2.0f, 3.5f
445 | };
446 |
447 | static float pat_herring_y[] = {
448 | 0.5f, 0.5f, 1.0f, 0.0f,
449 | 1.5f, 2.0f, 1.0f, 1.5f,
450 | 3.0f, 2.0f, 2.5f, 2.5f,
451 | 3.0f, 3.5f, 3.5f, 4.0f
452 | };
453 |
454 | static unsigned char pat_herring_id[] = {
455 | 1, 1, 1, 0,
456 | 0, 2, 1, 4,
457 | 3, 2, 3, 3,
458 | 3, 2, 2, 4
459 | };
460 |
461 | TilePoint Tile::pat_herring(Point3 p, TileParam& t) {
462 | float s = t.tileWidth * 2.f;
463 | float h = t.tileWidth * .5f;
464 | float x = p.x / s;
465 | float y = p.y / s;
466 | int xi = FASTFLOOR(x);
467 | int yi = FASTFLOOR(y);
468 | x = xi * s;
469 | y = yi * s;
470 | int x_id = (int)((p.x - x) / h) % 4;
471 | int y_id = (int)((p.y - y) / h) % 4;
472 | int id = x_id + 4 * y_id;
473 |
474 | //Point3 center = Point3(pat_herring_x[id]*h+x, pat_herring_y[id]*h+y, p.z);
475 |
476 | float edges[4];
477 |
478 | if (!pat_herring_dir[id]) {
479 | edges[0] = (pat_herring_x[id]-1.f) * h + x;
480 | edges[2] = edges[0] + t.tileWidth;
481 | edges[3] = (pat_herring_y[id]-.5f) * h + y;
482 | edges[1] = edges[3] + h;
483 | } else {
484 | edges[0] = (pat_herring_x[id]-.5f) * h + x;
485 | edges[2] = edges[0] + h;
486 | edges[3] = (pat_herring_y[id]-1.f) * h + y;
487 | edges[1] = edges[3] + t.tileWidth;
488 | }
489 |
490 | int tid = generateID(xi*4 + (pat_herring_dir[id] ? 0 : pat_herring_id[id]),
491 | yi*4 + (pat_herring_dir[id] ? pat_herring_id[id] : 0));
492 |
493 | return drawTile(p, edges, t, tid, pat_herring_dir[id]);
494 | }
495 |
496 | void TilePattern::setPreset(int preset) {
497 | switch (preset) {
498 | case 0: setPattern(L"0, 1, 1"); break; // Stack
499 | case 1: setPattern(L"0, 1, 1 / 0.5, 1, 1"); break; // Stretcher
500 | case 2: setPattern(L".25, 1, 1, .5 / -.5, 1, 1 / -.5, 1, 1 / -.5, 1, 1 / -.5, 1, 1"); break; // Flemish Strecher
501 | case 3: setPattern(L".25, 1, .5 / -.5, 1, 1 / -.5, 1, 1 / -.5, 1, 1 / -.5, 1, 1"); break; // Common
502 | case 4: setPattern(L"0, 1, 1, .5 / .75, 1, 1, .5"); break; // Flemish
503 | case 5: setPattern(L"0, 1, 1, 1, .5 / 1.25, 1, 1, 1, .5"); break; // Monk Bond
504 | case 6: setPattern(L"0, 1, 1, 1, 1, .5 / 1.75, 1, 1, 1, 1, .5"); break; // Flemish Garden Wall
505 | case 7: setPattern(L".25, 1, .5 / 0, 1, 1"); break; // English
506 | case 8: setPattern(L"0,1,1 / -.25,1,.5 / -.25,1,1 / -.25,1,.5"); break; // English Cross
507 | case 9: setPattern(L"0,1,.5 / -.25,1,.5 / -.25,1,1 / -.25,1,1"); break; // Double English Cross
508 | }
509 | }
510 |
511 | TilePoint Tile::draw(Point3 p, TileParam& t) {
512 | if (t.tilingType == 1)
513 | return pat_herring(p, t);
514 | return pat_xBond(p, t);
515 | }
516 |
517 | static void tokenize(const std::wstring& str, std::vector& tokens, const std::wstring& delimiters) {
518 | std::wstring::size_type lastPos = str.find_first_not_of(delimiters, 0);
519 | std::wstring::size_type pos = str.find_first_of(delimiters, lastPos);
520 |
521 | while (std::wstring::npos != pos || std::wstring::npos != lastPos) {
522 | tokens.push_back(str.substr(lastPos, pos - lastPos));
523 | lastPos = str.find_first_not_of(delimiters, pos);
524 | pos = str.find_first_of(delimiters, lastPos);
525 | }
526 | }
527 |
528 | static int parsePattern(std::wstring str, TilePattern* pat) {
529 | pat->rows.clear();
530 | pat->heights.clear();
531 |
532 | std::vector rowStrings = std::vector();
533 | tokenize(str, rowStrings, L"/");
534 |
535 | for (int i=0; i row = std::vector();
537 | tokenize(rowStrings[i], row, L",");
538 |
539 | if (row.size() < 3)
540 | return FALSE;
541 |
542 | double offset, height, width;
543 | std::wstringstream s0(row[0]);
544 | s0 >> offset;
545 | std::wstringstream s1(row[1]);
546 | s1 >> height;
547 |
548 | TileRow r = TileRow(offset);
549 |
550 | for (int j=2; j> width;
553 |
554 | r.tiles.push_back(width);
555 | }
556 |
557 | pat->rows.push_back(r);
558 | pat->heights.push_back((float)height);
559 | }
560 |
561 | return TRUE;
562 | }
563 |
564 | void TilePattern::setPattern(std::wstring s) {
565 | parsePattern(s, this);
566 | update();
567 | }
568 |
--------------------------------------------------------------------------------