Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

compute normals based on cross product of triangle vertices #1

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions TerrainMesh3D.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
972B7A1926D7ECAE0048CFE2 /* SCN_Math.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SCN_Math.h; sourceTree = "<group>"; };
C901C20B1DCFC07200FC1F5A /* TerrainMesh3D.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TerrainMesh3D.app; sourceTree = BUILT_PRODUCTS_DIR; };
C901C20E1DCFC07200FC1F5A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
C901C20F1DCFC07200FC1F5A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -67,6 +68,7 @@
C901C20D1DCFC07200FC1F5A /* TerrainMesh3D */ = {
isa = PBXGroup;
children = (
972B7A1926D7ECAE0048CFE2 /* SCN_Math.h */,
C901C2261DCFC0BC00FC1F5A /* TerrainMesh.h */,
C901C2271DCFC0BC00FC1F5A /* TerrainMesh.m */,
C901C22C1DCFD5CF00FC1F5A /* TerrainView.h */,
Expand Down Expand Up @@ -139,6 +141,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand Down
82 changes: 55 additions & 27 deletions TerrainMesh3D/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
//
// web page: <http://mattreagandev.com/?article=20161108>
// github sources: <https://github.com/matthewreagan/TerrainMesh3D>
//
// Modifications by <[email protected]> on Aug 26, 2021
// Added orbiting omni light
//

#import "AppDelegate.h"
#import <SceneKit/SceneKit.h>
#import "TerrainMesh.h"
#import "TerrainView.h"

#define BIGRANDOMVAL 9999999
#define RANDOMPERCENTAGE ((float)((arc4random()%BIGRANDOMVAL) / (float)BIGRANDOMVAL))
#define RANDOMPERCENTAGE ((CGFloat) (arc4random() / (CGFloat) RAND_MAX))

@interface AppDelegate ()

Expand All @@ -44,52 +50,63 @@ @interface AppDelegate ()
@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

//resize our window to our main monitor screen size
NSScreen *screen = [[NSScreen screens] objectAtIndex: 0];

//set the window's orgin and frame based on the screen's orgin and frame
NSRect screenFrame = [screen visibleFrame];
[self.window setFrameOrigin:screenFrame.origin];
[self.window setFrame:screen.frame display:YES animate:NO];

/* Set up our TerrainView. This is a simple SCNView subclass which
handles the mouse events and passes those clicks along to the mesh
so we can deform the terrain in the demo. */

TerrainView *terrainView = [[TerrainView alloc] initWithFrame:self.window.contentView.bounds
options:nil];
terrainView.allowsCameraControl = NO;
terrainView.autoenablesDefaultLighting = NO;
terrainView.showsStatistics = YES;
//terrainView.debugOptions = SCNDebugOptionRenderAsWireframe;
[self.window.contentView addSubview:terrainView];
self.terrainView = terrainView;

/* Create a simple scene with a sky background */
SCNScene *scene = [SCNScene scene];
scene.background.contents = [NSImage imageNamed:@"sky2"];
terrainView.scene = scene;

/* Give our scene some basic lighting */
[self configureDefaultLighting];

/* Create the terrain mesh */
const int kMeshResolution = 40;
TerrainMesh *mesh = [TerrainMesh terrainMeshWithResolution:kMeshResolution sideLength:10.0];

/* Give the terrain a nice terrain-y texture */
SCNMaterial *mat = [SCNMaterial material];
mat.diffuse.contents = [NSImage imageNamed:@"grass1"];
mat.doubleSided = YES;
mesh.geometry.materials = @[mat];

/* Add the terrain to the scene */
[scene.rootNode addChildNode:mesh];
self.mesh = mesh;


[self exampleClicked:NULL]; // add a mountain

/* Give the starting terrain a nice little spin intro for the Demo */
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:2.2];
mesh.rotation = SCNVector4Make(1.0, 0.2, 0, -M_PI_4);
mesh.position = SCNVector3Make(0.0, 2.0, 0.0);
// mesh.rotation = SCNVector4Make(1.0, 0.2, 0, -M_PI_4);
// mesh.position = SCNVector3Make(0.0, 2.0, 0.0);
scene.rootNode.rotation = SCNVector4Make(1.0, 0.0, 0, -M_PI_4);
[SCNTransaction commit];

/* Add the tools view, make sure it's above the SCNView debug controls */
[self.window.contentView addSubview:self.toolsView positioned:NSWindowAbove relativeTo:terrainView];
NSRect toolsFrame = self.toolsView.frame;
toolsFrame.origin.y += 20.0;
toolsFrame.origin.y += 20;
self.toolsView.frame = toolsFrame;
}

Expand All @@ -98,21 +115,33 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
- (void)configureDefaultLighting
{
SCNScene *scene = self.terrainView.scene;

SCNNode *ambientLightNode = [SCNNode node];
ambientLightNode.light = [SCNLight light];
ambientLightNode.light.type = SCNLightTypeAmbient;
ambientLightNode.light.color = [NSColor colorWithRed:1.0 green:1.0 blue:0.7 alpha:1.0];
ambientLightNode.light.color = [NSColor colorWithRed:1 green:1 blue:0.7 alpha:1];
ambientLightNode.light.intensity = 300;
[scene.rootNode addChildNode:ambientLightNode];

SCNNode *spotLightNode = [SCNNode node];
spotLightNode.light = [SCNLight light];
spotLightNode.light.type = SCNLightTypeSpot;
spotLightNode.light.type = SCNLightTypeOmni;
spotLightNode.light.color = [NSColor colorWithWhite:1.0 alpha:0.0];
spotLightNode.light.intensity = 1000;
spotLightNode.position = SCNVector3Make(5.0, 5.0, 10);
spotLightNode.position = SCNVector3Make(0, 5, 3);
[scene.rootNode addChildNode:spotLightNode];

SCNNode *planetNode = [SCNNode node];
planetNode.geometry = [SCNSphere sphereWithRadius:.1];
[spotLightNode addChildNode:planetNode];

NSTimeInterval duration = 6;
[spotLightNode runAction:[SCNAction repeatActionForever:[SCNAction customActionWithDuration:duration
actionBlock:^(SCNNode * _Nonnull node, CGFloat elapsedTime) {
double angleRAD = elapsedTime * M_PI * 2 / duration;
CGFloat orbit_radius = 3;
node.position = SCNVector3Make(5 + (orbit_radius * sin(angleRAD)), 5 + (orbit_radius * cos(angleRAD)), 3);
}]]];
}

#pragma mark - Demo Actions
Expand All @@ -132,28 +161,27 @@ - (IBAction)resetClicked:(id)sender
/* Reset the mesh to be completely flat. */

[self.mesh updateGeometry:^double(int x, int y) {
return 0.0;
return 0;
}];
}

- (IBAction)exampleClicked:(id)sender
{
int meshResolution = self.mesh.verticesPerSide;

int mapHalf = (meshResolution/2);

[self.mesh updateGeometry:^double(int x, int y) {
/* Randomize terrain to be slightly bumpy
with a small mountain in the center. */

int mapHalf = (meshResolution/2);

double xDelta = (x - mapHalf);
double yDelta = (y - mapHalf);
double distance = sqrt((xDelta * xDelta) + (yDelta * yDelta));
distance /= mapHalf;
distance /= 1;
distance = 1.0 - distance;
distance = 1 - distance;
distance = sin((distance * distance) * M_PI_2);
return (distance * 2.75) + (RANDOMPERCENTAGE * .10);

return (distance * 2.75) + (RANDOMPERCENTAGE * .1);
}];
}

Expand Down
64 changes: 45 additions & 19 deletions TerrainMesh3D/Base.lproj/MainMenu.xib
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11201"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
Expand Down Expand Up @@ -326,24 +326,25 @@
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ"/>
</menuItem>
</items>
<point key="canvasLocation" x="141" y="154"/>
</menu>
<window title="Terrain Mesh 3D" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="335" y="390" width="1024" height="768"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1080"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
<autoresizingMask key="autoresizingMask"/>
</view>
<point key="canvasLocation" x="189" y="-1442"/>
</window>
<customView id="zfp-rx-qiY">
<rect key="frame" x="0.0" y="0.0" width="479" height="171"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Duo-56-uVf">
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Duo-56-uVf">
<rect key="frame" x="16" y="34" width="129" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<buttonCell key="cell" type="push" title="Paint Brush" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="J49-Hk-1B6">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
Expand All @@ -352,28 +353,32 @@
<action selector="paintBrushToolClicked:" target="Voe-Tx-rLC" id="wV9-84-2Mf"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="E7E-Vq-4uD">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="E7E-Vq-4uD">
<rect key="frame" x="20" y="122" width="248" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="244" id="alW-CV-C0e"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Terrain Mesh 3D Demo" id="Iqn-B6-0x6">
<font key="font" metaFont="systemBold" size="19"/>
<color key="textColor" red="1" green="1" blue="0.46107313368055558" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Rka-a1-ZqA">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Rka-a1-ZqA">
<rect key="frame" x="20" y="75" width="394" height="54"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<constraints>
<constraint firstAttribute="width" constant="390" id="XqS-P5-WJD"/>
<constraint firstAttribute="height" constant="54" id="q5K-SY-T9g"/>
</constraints>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="QWu-Js-Op2">
<font key="font" metaFont="systemBold" size="14"/>
<string key="title">Click 'Paint Brush' and then click on the terrain to deform. Click 'Adjust Camera' and then drag around to move. Tip: Option-click with Paint Brush lowers terrain.</string>
<color key="textColor" red="1" green="1" blue="0.46107313370000003" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="b2F-MI-4ha">
<rect key="frame" x="16" y="8" width="129" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="b2F-MI-4ha">
<rect key="frame" x="21" y="8" width="124" height="32"/>
<buttonCell key="cell" type="push" title="Adjust Camera" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="qSv-qw-yCC">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
Expand All @@ -382,9 +387,8 @@
<action selector="cameraToolClicked:" target="Voe-Tx-rLC" id="h9h-EZ-O47"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="52y-fH-GEN">
<rect key="frame" x="145" y="34" width="107" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="52y-fH-GEN">
<rect key="frame" x="145" y="34" width="92" height="32"/>
<buttonCell key="cell" type="push" title="Reset" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Sv7-IS-7Jj">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
Expand All @@ -393,9 +397,11 @@
<action selector="resetClicked:" target="Voe-Tx-rLC" id="L9v-zm-GXa"/>
</connections>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="1HK-1C-Hmr">
<rect key="frame" x="145" y="8" width="107" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1HK-1C-Hmr">
<rect key="frame" x="145" y="8" width="92" height="32"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="70" id="Egb-LF-j4t"/>
</constraints>
<buttonCell key="cell" type="push" title="Mountain" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="hq7-3x-guB">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
Expand All @@ -405,6 +411,26 @@
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="E7E-Vq-4uD" secondAttribute="trailing" constant="20" symbolic="YES" id="8WU-UK-7zA"/>
<constraint firstItem="Rka-a1-ZqA" firstAttribute="leading" secondItem="zfp-rx-qiY" secondAttribute="leading" constant="22" id="HmD-jx-QgO"/>
<constraint firstItem="1HK-1C-Hmr" firstAttribute="leading" secondItem="52y-fH-GEN" secondAttribute="leading" id="JfC-3G-PNP"/>
<constraint firstItem="E7E-Vq-4uD" firstAttribute="top" secondItem="zfp-rx-qiY" secondAttribute="top" constant="20" symbolic="YES" id="QF7-xg-wU2"/>
<constraint firstItem="1HK-1C-Hmr" firstAttribute="baseline" secondItem="b2F-MI-4ha" secondAttribute="baseline" id="Qaj-LF-q6f"/>
<constraint firstItem="1HK-1C-Hmr" firstAttribute="leading" secondItem="zfp-rx-qiY" secondAttribute="leading" constant="152" id="RdO-Tb-sbs"/>
<constraint firstItem="Rka-a1-ZqA" firstAttribute="top" secondItem="zfp-rx-qiY" secondAttribute="top" constant="42" id="bOI-o6-smp"/>
<constraint firstItem="1HK-1C-Hmr" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="b2F-MI-4ha" secondAttribute="trailing" constant="12" symbolic="YES" id="beQ-C3-SGR"/>
<constraint firstAttribute="bottom" secondItem="1HK-1C-Hmr" secondAttribute="bottom" constant="15" id="dMB-lu-UpN"/>
<constraint firstItem="b2F-MI-4ha" firstAttribute="leading" secondItem="zfp-rx-qiY" secondAttribute="leading" constant="28" id="fA0-Hb-Ne0"/>
<constraint firstItem="Duo-56-uVf" firstAttribute="top" secondItem="E7E-Vq-4uD" secondAttribute="bottom" constant="61" id="hNv-N5-Mj2"/>
<constraint firstItem="Duo-56-uVf" firstAttribute="trailing" secondItem="b2F-MI-4ha" secondAttribute="trailing" id="oKK-vb-sR9"/>
<constraint firstItem="Duo-56-uVf" firstAttribute="leading" secondItem="zfp-rx-qiY" secondAttribute="leading" constant="23" id="t5J-Tt-1VG"/>
<constraint firstItem="Duo-56-uVf" firstAttribute="top" secondItem="Rka-a1-ZqA" secondAttribute="bottom" constant="14" id="tCt-22-zW1"/>
<constraint firstItem="Rka-a1-ZqA" firstAttribute="leading" secondItem="E7E-Vq-4uD" secondAttribute="leading" id="tJZ-Yq-rXF"/>
<constraint firstItem="1HK-1C-Hmr" firstAttribute="top" secondItem="52y-fH-GEN" secondAttribute="bottom" constant="6" id="uuK-o4-qwR"/>
<constraint firstItem="1HK-1C-Hmr" firstAttribute="trailing" secondItem="52y-fH-GEN" secondAttribute="trailing" id="vb2-SB-odW"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Rka-a1-ZqA" secondAttribute="trailing" constant="20" symbolic="YES" id="wRd-zB-lfK"/>
</constraints>
<point key="canvasLocation" x="289.5" y="-886.5"/>
</customView>
</objects>
Expand Down
Loading